From: Aaron Schulz Date: Tue, 26 Mar 2019 05:39:24 +0000 (-0700) Subject: rdbms: move some files under rdbms/database to subfolders X-Git-Tag: 1.34.0-rc.0~2260^2 X-Git-Url: http://git.cyclocoop.org/%7B%24admin_url%7Dcompta/comptes/journal.php?a=commitdiff_plain;h=7ff25118ee35279597008639c87d123cd9217fed;p=lhc%2Fweb%2Fwiklou.git rdbms: move some files under rdbms/database to subfolders Change-Id: I627398d2cfe9fda93a16f94a94e75cf5f8833613 --- diff --git a/autoload.php b/autoload.php index 0d2bac98f7..2abf2f8829 100644 --- a/autoload.php +++ b/autoload.php @@ -1625,7 +1625,7 @@ $wgAutoloadLocalClasses = [ 'WikiTextStructure' => __DIR__ . '/includes/content/WikiTextStructure.php', 'Wikimedia\\Http\\HttpAcceptNegotiator' => __DIR__ . '/includes/libs/http/HttpAcceptNegotiator.php', 'Wikimedia\\Http\\HttpAcceptParser' => __DIR__ . '/includes/libs/http/HttpAcceptParser.php', - 'Wikimedia\\Rdbms\\AtomicSectionIdentifier' => __DIR__ . '/includes/libs/rdbms/database/AtomicSectionIdentifier.php', + 'Wikimedia\\Rdbms\\AtomicSectionIdentifier' => __DIR__ . '/includes/libs/rdbms/database/utils/AtomicSectionIdentifier.php', 'Wikimedia\\Rdbms\\Blob' => __DIR__ . '/includes/libs/rdbms/encasing/Blob.php', 'Wikimedia\\Rdbms\\ChronologyProtector' => __DIR__ . '/includes/libs/rdbms/ChronologyProtector.php', 'Wikimedia\\Rdbms\\ConnectionManager' => __DIR__ . '/includes/libs/rdbms/connectionmanager/ConnectionManager.php', @@ -1644,7 +1644,7 @@ $wgAutoloadLocalClasses = [ 'Wikimedia\\Rdbms\\DBTransactionStateError' => __DIR__ . '/includes/libs/rdbms/exception/DBTransactionStateError.php', 'Wikimedia\\Rdbms\\DBUnexpectedError' => __DIR__ . '/includes/libs/rdbms/exception/DBUnexpectedError.php', 'Wikimedia\\Rdbms\\Database' => __DIR__ . '/includes/libs/rdbms/database/Database.php', - 'Wikimedia\\Rdbms\\DatabaseDomain' => __DIR__ . '/includes/libs/rdbms/database/DatabaseDomain.php', + 'Wikimedia\\Rdbms\\DatabaseDomain' => __DIR__ . '/includes/libs/rdbms/database/domain/DatabaseDomain.php', 'Wikimedia\\Rdbms\\DatabaseMssql' => __DIR__ . '/includes/libs/rdbms/database/DatabaseMssql.php', 'Wikimedia\\Rdbms\\DatabaseMysqlBase' => __DIR__ . '/includes/libs/rdbms/database/DatabaseMysqlBase.php', 'Wikimedia\\Rdbms\\DatabaseMysqli' => __DIR__ . '/includes/libs/rdbms/database/DatabaseMysqli.php', diff --git a/includes/libs/rdbms/database/AtomicSectionIdentifier.php b/includes/libs/rdbms/database/AtomicSectionIdentifier.php deleted file mode 100644 index c6e3d44c0d..0000000000 --- a/includes/libs/rdbms/database/AtomicSectionIdentifier.php +++ /dev/null @@ -1,27 +0,0 @@ -database = $database; - if ( $schema !== null && ( !is_string( $schema ) || $schema === '' ) ) { - throw new InvalidArgumentException( 'Schema must be null or a non-empty string.' ); - } - $this->schema = $schema; - if ( !is_string( $prefix ) ) { - throw new InvalidArgumentException( 'Prefix must be a string.' ); - } elseif ( $prefix !== '' && substr( $prefix, -1, 1 ) !== '_' ) { - throw new InvalidArgumentException( 'A non-empty prefix must end with "_".' ); - } - $this->prefix = $prefix; - } - - /** - * @param DatabaseDomain|string $domain Result of DatabaseDomain::toString() - * @return DatabaseDomain - */ - public static function newFromId( $domain ) { - if ( $domain instanceof self ) { - return $domain; - } - - $parts = array_map( [ __CLASS__, 'decode' ], explode( '-', $domain ) ); - - $schema = null; - $prefix = ''; - - if ( count( $parts ) == 1 ) { - $database = $parts[0]; - } elseif ( count( $parts ) == 2 ) { - list( $database, $prefix ) = $parts; - } elseif ( count( $parts ) == 3 ) { - list( $database, $schema, $prefix ) = $parts; - } else { - throw new InvalidArgumentException( "Domain '$domain' has too few or too many parts." ); - } - - if ( $database === '' ) { - $database = null; - } - - if ( $schema === '' ) { - $schema = null; - } - - return new self( $database, $schema, $prefix ); - } - - /** - * @return DatabaseDomain - */ - public static function newUnspecified() { - return new self( null, null, '' ); - } - - /** - * @param DatabaseDomain|string $other - * @return bool Whether the domain instances are the same by value - */ - public function equals( $other ) { - if ( $other instanceof self ) { - return ( - $this->database === $other->database && - $this->schema === $other->schema && - $this->prefix === $other->prefix - ); - } - - return ( $this->getId() === $other ); - } - - /** - * Check whether the domain $other meets the specifications of this domain - * - * If this instance has a null database specifier, then $other can have any database - * specified, including the null, and likewise if the schema specifier is null. This - * is not transitive like equals() since a domain that explicitly wants a certain - * database or schema cannot be satisfied by one of another (nor null). If the prefix - * is empty and the DB and schema are both null, then the entire domain is considered - * unspecified, and any prefix of $other is considered compatible. - * - * @param DatabaseDomain|string $other - * @return bool - * @since 1.32 - */ - public function isCompatible( $other ) { - if ( $this->isUnspecified() ) { - return true; // even the prefix doesn't matter - } - - $other = self::newFromId( $other ); - - return ( - ( $this->database === $other->database || $this->database === null ) && - ( $this->schema === $other->schema || $this->schema === null ) && - $this->prefix === $other->prefix - ); - } - - /** - * @return bool - * @since 1.32 - */ - public function isUnspecified() { - return ( - $this->database === null && $this->schema === null && $this->prefix === '' - ); - } - - /** - * @return string|null Database name - */ - public function getDatabase() { - return $this->database; - } - - /** - * @return string|null Database schema - */ - public function getSchema() { - return $this->schema; - } - - /** - * @return string Table prefix - */ - public function getTablePrefix() { - return $this->prefix; - } - - /** - * @return string - */ - public function getId() { - if ( $this->equivalentString === null ) { - $this->equivalentString = $this->convertToString(); - } - - return $this->equivalentString; - } - - /** - * @return string - */ - private function convertToString() { - $parts = [ (string)$this->database ]; - if ( $this->schema !== null ) { - $parts[] = $this->schema; - } - if ( $this->prefix != '' || $this->schema !== null ) { - // If there is a schema, then we need the prefix to disambiguate. - // For engines like Postgres that use schemas, this awkwardness is hopefully - // avoided since it is easy to have one DB per server (to avoid having many users) - // and use schema/prefix to have wiki farms. For example, a domain schemes could be - // wiki--, e.g. "wiki-fitness-es"/"wiki-sports-fr"/"wiki-news-en". - $parts[] = $this->prefix; - } - - return implode( '-', array_map( [ __CLASS__, 'encode' ], $parts ) ); - } - - private static function encode( $decoded ) { - $encoded = ''; - - $length = strlen( $decoded ); - for ( $i = 0; $i < $length; ++$i ) { - $char = $decoded[$i]; - if ( $char === '-' ) { - $encoded .= '?h'; - } elseif ( $char === '?' ) { - $encoded .= '??'; - } else { - $encoded .= $char; - } - } - - return $encoded; - } - - private static function decode( $encoded ) { - $decoded = ''; - - $length = strlen( $encoded ); - for ( $i = 0; $i < $length; ++$i ) { - $char = $encoded[$i]; - if ( $char === '?' ) { - $nextChar = $encoded[$i + 1] ?? null; - if ( $nextChar === 'h' ) { - $decoded .= '-'; - ++$i; - } elseif ( $nextChar === '?' ) { - $decoded .= '?'; - ++$i; - } else { - $decoded .= $char; - } - } else { - $decoded .= $char; - } - } - - return $decoded; - } - - /** - * @return string - */ - function __toString() { - return $this->getId(); - } -} diff --git a/includes/libs/rdbms/database/domain/DatabaseDomain.php b/includes/libs/rdbms/database/domain/DatabaseDomain.php new file mode 100644 index 0000000000..ca57938f2e --- /dev/null +++ b/includes/libs/rdbms/database/domain/DatabaseDomain.php @@ -0,0 +1,258 @@ +database = $database; + if ( $schema !== null && ( !is_string( $schema ) || $schema === '' ) ) { + throw new InvalidArgumentException( 'Schema must be null or a non-empty string.' ); + } + $this->schema = $schema; + if ( !is_string( $prefix ) ) { + throw new InvalidArgumentException( 'Prefix must be a string.' ); + } elseif ( $prefix !== '' && substr( $prefix, -1, 1 ) !== '_' ) { + throw new InvalidArgumentException( 'A non-empty prefix must end with "_".' ); + } + $this->prefix = $prefix; + } + + /** + * @param DatabaseDomain|string $domain Result of DatabaseDomain::toString() + * @return DatabaseDomain + */ + public static function newFromId( $domain ) { + if ( $domain instanceof self ) { + return $domain; + } + + $parts = array_map( [ __CLASS__, 'decode' ], explode( '-', $domain ) ); + + $schema = null; + $prefix = ''; + + if ( count( $parts ) == 1 ) { + $database = $parts[0]; + } elseif ( count( $parts ) == 2 ) { + list( $database, $prefix ) = $parts; + } elseif ( count( $parts ) == 3 ) { + list( $database, $schema, $prefix ) = $parts; + } else { + throw new InvalidArgumentException( "Domain '$domain' has too few or too many parts." ); + } + + if ( $database === '' ) { + $database = null; + } + + if ( $schema === '' ) { + $schema = null; + } + + return new self( $database, $schema, $prefix ); + } + + /** + * @return DatabaseDomain + */ + public static function newUnspecified() { + return new self( null, null, '' ); + } + + /** + * @param DatabaseDomain|string $other + * @return bool Whether the domain instances are the same by value + */ + public function equals( $other ) { + if ( $other instanceof self ) { + return ( + $this->database === $other->database && + $this->schema === $other->schema && + $this->prefix === $other->prefix + ); + } + + return ( $this->getId() === $other ); + } + + /** + * Check whether the domain $other meets the specifications of this domain + * + * If this instance has a null database specifier, then $other can have any database + * specified, including the null, and likewise if the schema specifier is null. This + * is not transitive like equals() since a domain that explicitly wants a certain + * database or schema cannot be satisfied by one of another (nor null). If the prefix + * is empty and the DB and schema are both null, then the entire domain is considered + * unspecified, and any prefix of $other is considered compatible. + * + * @param DatabaseDomain|string $other + * @return bool + * @since 1.32 + */ + public function isCompatible( $other ) { + if ( $this->isUnspecified() ) { + return true; // even the prefix doesn't matter + } + + $other = self::newFromId( $other ); + + return ( + ( $this->database === $other->database || $this->database === null ) && + ( $this->schema === $other->schema || $this->schema === null ) && + $this->prefix === $other->prefix + ); + } + + /** + * @return bool + * @since 1.32 + */ + public function isUnspecified() { + return ( + $this->database === null && $this->schema === null && $this->prefix === '' + ); + } + + /** + * @return string|null Database name + */ + public function getDatabase() { + return $this->database; + } + + /** + * @return string|null Database schema + */ + public function getSchema() { + return $this->schema; + } + + /** + * @return string Table prefix + */ + public function getTablePrefix() { + return $this->prefix; + } + + /** + * @return string + */ + public function getId() { + if ( $this->equivalentString === null ) { + $this->equivalentString = $this->convertToString(); + } + + return $this->equivalentString; + } + + /** + * @return string + */ + private function convertToString() { + $parts = [ (string)$this->database ]; + if ( $this->schema !== null ) { + $parts[] = $this->schema; + } + if ( $this->prefix != '' || $this->schema !== null ) { + // If there is a schema, then we need the prefix to disambiguate. + // For engines like Postgres that use schemas, this awkwardness is hopefully + // avoided since it is easy to have one DB per server (to avoid having many users) + // and use schema/prefix to have wiki farms. For example, a domain schemes could be + // wiki--, e.g. "wiki-fitness-es"/"wiki-sports-fr"/"wiki-news-en". + $parts[] = $this->prefix; + } + + return implode( '-', array_map( [ __CLASS__, 'encode' ], $parts ) ); + } + + private static function encode( $decoded ) { + $encoded = ''; + + $length = strlen( $decoded ); + for ( $i = 0; $i < $length; ++$i ) { + $char = $decoded[$i]; + if ( $char === '-' ) { + $encoded .= '?h'; + } elseif ( $char === '?' ) { + $encoded .= '??'; + } else { + $encoded .= $char; + } + } + + return $encoded; + } + + private static function decode( $encoded ) { + $decoded = ''; + + $length = strlen( $encoded ); + for ( $i = 0; $i < $length; ++$i ) { + $char = $encoded[$i]; + if ( $char === '?' ) { + $nextChar = $encoded[$i + 1] ?? null; + if ( $nextChar === 'h' ) { + $decoded .= '-'; + ++$i; + } elseif ( $nextChar === '?' ) { + $decoded .= '?'; + ++$i; + } else { + $decoded .= $char; + } + } else { + $decoded .= $char; + } + } + + return $decoded; + } + + /** + * @return string + */ + function __toString() { + return $this->getId(); + } +} diff --git a/includes/libs/rdbms/database/utils/AtomicSectionIdentifier.php b/includes/libs/rdbms/database/utils/AtomicSectionIdentifier.php new file mode 100644 index 0000000000..c6e3d44c0d --- /dev/null +++ b/includes/libs/rdbms/database/utils/AtomicSectionIdentifier.php @@ -0,0 +1,27 @@ +