MediaWiki master
DatabaseDomain.php
Go to the documentation of this file.
1<?php
6namespace Wikimedia\Rdbms;
7
8use InvalidArgumentException;
9use Stringable;
10
28class DatabaseDomain implements Stringable {
30 private $database;
32 private $schema;
34 private $prefix;
35
37 private $equivalentString;
38
44 public function __construct( $database, $schema, $prefix ) {
45 if ( $database !== null && ( !is_string( $database ) || $database === '' ) ) {
46 throw new InvalidArgumentException( 'Database must be null or a non-empty string.' );
47 }
48 $this->database = $database;
49 if ( $schema !== null && ( !is_string( $schema ) || $schema === '' ) ) {
50 throw new InvalidArgumentException( 'Schema must be null or a non-empty string.' );
51 } elseif ( $database === null && $schema !== null ) {
52 throw new InvalidArgumentException( 'Schema must be null if database is null.' );
53 }
54 $this->schema = $schema;
55 if ( !is_string( $prefix ) ) {
56 throw new InvalidArgumentException( "Prefix must be a string." );
57 }
58 $this->prefix = $prefix;
59 }
60
65 public static function newFromId( DatabaseDomain|string $domain ): self {
66 if ( $domain instanceof self ) {
67 return $domain;
68 }
69
70 $parts = explode( '-', $domain );
71 foreach ( $parts as &$part ) {
72 $part = strtr( $part, [ '?h' => '-', '??' => '?' ] );
73 }
74
75 $schema = null;
76 $prefix = '';
77
78 if ( count( $parts ) == 1 ) {
79 $database = $parts[0];
80 } elseif ( count( $parts ) == 2 ) {
81 [ $database, $prefix ] = $parts;
82 } elseif ( count( $parts ) == 3 ) {
83 [ $database, $schema, $prefix ] = $parts;
84 } else {
85 throw new InvalidArgumentException( "Domain '$domain' has too few or too many parts." );
86 }
87
88 if ( $database === '' ) {
89 $database = null;
90 }
91
92 if ( $schema === '' ) {
93 $schema = null;
94 }
95
96 $instance = new self( $database, $schema, $prefix );
97 $instance->equivalentString = $domain;
98
99 return $instance;
100 }
101
105 public static function newUnspecified() {
106 return new self( null, null, '' );
107 }
108
113 public function equals( $other ) {
114 if ( $other instanceof self ) {
115 return (
116 $this->database === $other->database &&
117 $this->schema === $other->schema &&
118 $this->prefix === $other->prefix
119 );
120 }
121
122 return ( $this->getId() === $other );
123 }
124
139 public function isCompatible( $other ) {
140 if ( $this->isUnspecified() ) {
141 return true; // even the prefix doesn't matter
142 }
143
144 $other = self::newFromId( $other );
145
146 return (
147 ( $this->database === $other->database || $this->database === null ) &&
148 ( $this->schema === $other->schema || $this->schema === null ) &&
149 $this->prefix === $other->prefix
150 );
151 }
152
157 public function isUnspecified() {
158 return (
159 $this->database === null && $this->schema === null && $this->prefix === ''
160 );
161 }
162
166 public function getDatabase() {
167 return $this->database;
168 }
169
173 public function getSchema() {
174 return $this->schema;
175 }
176
180 public function getTablePrefix() {
181 return $this->prefix;
182 }
183
184 public function getId(): string {
185 $this->equivalentString ??= $this->convertToString();
186
187 return $this->equivalentString;
188 }
189
190 private function convertToString(): string {
191 $parts = [ (string)$this->database ];
192 if ( $this->schema !== null ) {
193 $parts[] = $this->schema;
194 }
195 if ( $this->prefix != '' || $this->schema !== null ) {
196 // If there is a schema, then we need the prefix to disambiguate.
197 // For engines like Postgres that use schemas, this awkwardness is hopefully
198 // avoided since it is easy to have one DB per server (to avoid having many users)
199 // and use schema/prefix to have wiki farms. For example, a domain schemes could be
200 // wiki-<project>-<language>, e.g. "wiki-fitness-es"/"wiki-sports-fr"/"wiki-news-en".
201 $parts[] = $this->prefix;
202 }
203
204 foreach ( $parts as &$part ) {
205 $part = strtr( $part, [ '-' => '?h', '?' => '??' ] );
206 }
207 return implode( '-', $parts );
208 }
209
213 public function __toString() {
214 return $this->getId();
215 }
216}
if(!defined('MW_SETUP_CALLBACK'))
Definition WebStart.php:68
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)
static newFromId(DatabaseDomain|string $domain)