X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FStorage%2FSlotRecord.php;h=c7eb735db37f71ce29b5ae1f5ee1220e7f524fce;hb=4df0c71911500466a6330b8fe29c623ef5b51e41;hp=9462518ffe5c3bd5df1794710523e41a8b1deaf8;hpb=3c90317ee54ad2aa4ab0b3286e3c2eb83f364b1e;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/Storage/SlotRecord.php b/includes/Storage/SlotRecord.php index 9462518ffe..c7eb735db3 100644 --- a/includes/Storage/SlotRecord.php +++ b/includes/Storage/SlotRecord.php @@ -38,7 +38,9 @@ use Wikimedia\Assert\Assert; class SlotRecord { /** - * @var object database result row, as a raw object + * @var object database result row, as a raw object. Callbacks are supported for field values, + * to enable on-demand emulation of these values. This is primarily intended for use + * during schema migration. */ private $row; @@ -142,11 +144,11 @@ class SlotRecord { /** * Constructs a complete SlotRecord for a newly saved revision, based on the incomplete * proto-slot. This adds information that has only become available during saving, - * particularly the revision ID and content address. + * particularly the revision ID, content ID and content address. * * @param int $revisionId the revision the slot is to be associated with (field slot_revision_id). * If $protoSlot already has a revision, it must be the same. - * @param int $contentId the ID of the row in the content table describing the content + * @param int|null $contentId the ID of the row in the content table describing the content * referenced by $contentAddress (field slot_content_id). * If $protoSlot already has a content ID, it must be the same. * @param string $contentAddress the slot's content address (field content_address). @@ -163,7 +165,8 @@ class SlotRecord { SlotRecord $protoSlot ) { Assert::parameterType( 'integer', $revisionId, '$revisionId' ); - Assert::parameterType( 'integer', $contentId, '$contentId' ); + // TODO once migration is over $contentId must be an integer + Assert::parameterType( 'integer|null', $contentId, '$contentId' ); Assert::parameterType( 'string', $contentAddress, '$contentAddress' ); if ( $protoSlot->hasRevision() && $protoSlot->getRevision() !== $revisionId ) { @@ -181,7 +184,7 @@ class SlotRecord { ); } - if ( $protoSlot->hasAddress() && $protoSlot->getContentId() !== $contentId ) { + if ( $protoSlot->hasContentId() && $protoSlot->getContentId() !== $contentId ) { throw new LogicException( "Mismatching content ID $contentId: " . "The slot already has content row {$protoSlot->getContentId()} associated." @@ -231,11 +234,6 @@ class SlotRecord { Assert::parameterType( 'object', $row, '$row' ); Assert::parameterType( 'Content|callable', $content, '$content' ); - Assert::parameter( - property_exists( $row, 'slot_id' ), - '$row->slot_id', - 'must exist' - ); Assert::parameter( property_exists( $row, 'slot_revision_id' ), '$row->slot_revision_id', @@ -379,6 +377,13 @@ class SlotRecord { * @return bool whether this record contains the given field */ private function hasField( $name ) { + if ( isset( $this->row->$name ) ) { + // if the field is a callback, resolve first, then re-check + if ( !is_string( $this->row->$name ) && is_callable( $this->row->$name ) ) { + $this->getField( $name ); + } + } + return isset( $this->row->$name ); } @@ -430,6 +435,40 @@ class SlotRecord { return $this->hasField( 'content_address' ); } + /** + * Whether this slot has an origin (revision ID that originated the slot's content. + * + * @since 1.32 + * + * @return bool + */ + public function hasOrigin() { + return $this->hasField( 'slot_origin' ); + } + + /** + * Whether this slot has a content ID. Slots will have a content ID if their + * content has been stored in the content table. While building a new revision, + * SlotRecords will not have an ID associated. + * + * Also, during schema migration, hasContentId() may return false when encountering an + * un-migrated database entry in SCHEMA_COMPAT_WRITE_BOTH mode. + * It will however always return true for saved revisions on SCHEMA_COMPAT_READ_NEW mode, + * or without SCHEMA_COMPAT_WRITE_NEW mode. In the latter case, an emulated content ID + * is used, derived from the revision's text ID. + * + * Note that hasContentId() returning false while hasRevision() returns true always + * indicates an unmigrated row in SCHEMA_COMPAT_WRITE_BOTH mode, as described above. + * For an unsaved slot, both these methods would return false. + * + * @since 1.32 + * + * @return bool + */ + public function hasContentId() { + return $this->hasField( 'slot_content_id' ); + } + /** * Whether this slot has revision ID associated. Slots will have a revision ID associated * only if they were loaded as part of an existing revision. While building a new revision, @@ -465,6 +504,9 @@ class SlotRecord { * This information should be irrelevant to application logic, it is here to allow * the construction of a full row for the revision table. * + * Note that this method may return an emulated value during schema migration in + * SCHEMA_COMPAT_WRITE_OLD mode. See RevisionStore::emulateContentId for more information. + * * @return int */ public function getContentId() {