MediaWiki master
DatabaseDomain.php
Go to the documentation of this file.
1<?php
20namespace Wikimedia\Rdbms;
21
22use InvalidArgumentException;
23use Stringable;
24
42class DatabaseDomain implements Stringable {
44 private $database;
46 private $schema;
48 private $prefix;
49
51 private $equivalentString;
52
58 public function __construct( $database, $schema, $prefix ) {
59 if ( $database !== null && ( !is_string( $database ) || $database === '' ) ) {
60 throw new InvalidArgumentException( 'Database must be null or a non-empty string.' );
61 }
62 $this->database = $database;
63 if ( $schema !== null && ( !is_string( $schema ) || $schema === '' ) ) {
64 throw new InvalidArgumentException( 'Schema must be null or a non-empty string.' );
65 } elseif ( $database === null && $schema !== null ) {
66 throw new InvalidArgumentException( 'Schema must be null if database is null.' );
67 }
68 $this->schema = $schema;
69 if ( !is_string( $prefix ) ) {
70 throw new InvalidArgumentException( "Prefix must be a string." );
71 }
72 $this->prefix = $prefix;
73 }
74
79 public static function newFromId( $domain ): self {
80 if ( $domain instanceof self ) {
81 return $domain;
82 }
83
84 if ( !is_string( $domain ) ) {
85 throw new InvalidArgumentException( "Domain must be a string or " . __CLASS__ );
86 }
87
88 $parts = explode( '-', $domain );
89 foreach ( $parts as &$part ) {
90 $part = strtr( $part, [ '?h' => '-', '??' => '?' ] );
91 }
92
93 $schema = null;
94 $prefix = '';
95
96 if ( count( $parts ) == 1 ) {
97 $database = $parts[0];
98 } elseif ( count( $parts ) == 2 ) {
99 [ $database, $prefix ] = $parts;
100 } elseif ( count( $parts ) == 3 ) {
101 [ $database, $schema, $prefix ] = $parts;
102 } else {
103 throw new InvalidArgumentException( "Domain '$domain' has too few or too many parts." );
104 }
105
106 if ( $database === '' ) {
107 $database = null;
108 }
109
110 if ( $schema === '' ) {
111 $schema = null;
112 }
113
114 $instance = new self( $database, $schema, $prefix );
115 $instance->equivalentString = $domain;
116
117 return $instance;
118 }
119
123 public static function newUnspecified() {
124 return new self( null, null, '' );
125 }
126
131 public function equals( $other ) {
132 if ( $other instanceof self ) {
133 return (
134 $this->database === $other->database &&
135 $this->schema === $other->schema &&
136 $this->prefix === $other->prefix
137 );
138 }
139
140 return ( $this->getId() === $other );
141 }
142
157 public function isCompatible( $other ) {
158 if ( $this->isUnspecified() ) {
159 return true; // even the prefix doesn't matter
160 }
161
162 $other = self::newFromId( $other );
163
164 return (
165 ( $this->database === $other->database || $this->database === null ) &&
166 ( $this->schema === $other->schema || $this->schema === null ) &&
167 $this->prefix === $other->prefix
168 );
169 }
170
175 public function isUnspecified() {
176 return (
177 $this->database === null && $this->schema === null && $this->prefix === ''
178 );
179 }
180
184 public function getDatabase() {
185 return $this->database;
186 }
187
191 public function getSchema() {
192 return $this->schema;
193 }
194
198 public function getTablePrefix() {
199 return $this->prefix;
200 }
201
205 public function getId(): string {
206 $this->equivalentString ??= $this->convertToString();
207
208 return $this->equivalentString;
209 }
210
214 private function convertToString(): string {
215 $parts = [ (string)$this->database ];
216 if ( $this->schema !== null ) {
217 $parts[] = $this->schema;
218 }
219 if ( $this->prefix != '' || $this->schema !== null ) {
220 // If there is a schema, then we need the prefix to disambiguate.
221 // For engines like Postgres that use schemas, this awkwardness is hopefully
222 // avoided since it is easy to have one DB per server (to avoid having many users)
223 // and use schema/prefix to have wiki farms. For example, a domain schemes could be
224 // wiki-<project>-<language>, e.g. "wiki-fitness-es"/"wiki-sports-fr"/"wiki-news-en".
225 $parts[] = $this->prefix;
226 }
227
228 foreach ( $parts as &$part ) {
229 $part = strtr( $part, [ '-' => '?h', '?' => '??' ] );
230 }
231 return implode( '-', $parts );
232 }
233
237 public function __toString() {
238 return $this->getId();
239 }
240}
if(!defined('MW_SETUP_CALLBACK'))
Definition WebStart.php:81
Class to handle database/schema/prefix specifications for IDatabase.
isCompatible( $other)
Check whether the domain $other meets the specifications of this domain.
__construct( $database, $schema, $prefix)