MediaWiki REL1_39
DatabaseFactory.php
Go to the documentation of this file.
1<?php
20namespace Wikimedia\Rdbms;
21
23use InvalidArgumentException;
24use Psr\Log\NullLogger;
25use Throwable;
26
34
87 public function create( $type, $params = [], $connect = Database::NEW_CONNECTED ) {
88 $class = $this->getClass( $type, $params['driver'] ?? null );
89
90 if ( class_exists( $class ) && is_subclass_of( $class, IDatabase::class ) ) {
91 $params += [
92 // Default configuration
93 'host' => null,
94 'user' => null,
95 'password' => null,
96 'dbname' => null,
97 'schema' => null,
98 'tablePrefix' => '',
99 'flags' => 0,
100 'variables' => [],
101 'lbInfo' => [],
102 'cliMode' => ( PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg' ),
103 'agent' => '',
104 'serverName' => null,
105 'topologyRole' => null,
106 // Objects and callbacks
107 'topologicalPrimaryConnRef' => $params['topologicalPrimaryConnRef'] ?? null,
108 'srvCache' => $params['srvCache'] ?? new HashBagOStuff(),
109 'profiler' => $params['profiler'] ?? null,
110 'trxProfiler' => $params['trxProfiler'] ?? new TransactionProfiler(),
111 'connLogger' => $params['connLogger'] ?? new NullLogger(),
112 'queryLogger' => $params['queryLogger'] ?? new NullLogger(),
113 'replLogger' => $params['replLogger'] ?? new NullLogger(),
114 'errorLogger' => $params['errorLogger'] ?? static function ( Throwable $e ) {
115 trigger_error( get_class( $e ) . ': ' . $e->getMessage(), E_USER_WARNING );
116 },
117 'deprecationLogger' => $params['deprecationLogger'] ?? static function ( $msg ) {
118 trigger_error( $msg, E_USER_DEPRECATED );
119 }
120 ];
121
123 $conn = new $class( $params );
124 if ( $connect === Database::NEW_CONNECTED ) {
125 $conn->initConnection();
126 }
127 } else {
128 $conn = null;
129 }
130
131 return $conn;
132 }
133
140 public function attributesFromType( $dbType, $driver = null ) {
141 static $defaults = [
142 Database::ATTR_DB_IS_FILE => false,
143 Database::ATTR_DB_LEVEL_LOCKING => false,
144 Database::ATTR_SCHEMAS_AS_TABLE_GROUPS => false
145 ];
146
147 $class = $this->getClass( $dbType, $driver );
148 if ( class_exists( $class ) ) {
149 return call_user_func( [ $class, 'getAttributes' ] ) + $defaults;
150 } else {
151 throw new DBUnexpectedError( null, "$dbType is not a supported database type." );
152 }
153 }
154
161 protected function getClass( $dbType, $driver = null ) {
162 // For database types with built-in support, the below maps type to IDatabase
163 // implementations. For types with multiple driver implementations (PHP extensions),
164 // an array can be used, keyed by extension name. In case of an array, the
165 // optional 'driver' parameter can be used to force a specific driver. Otherwise,
166 // we auto-detect the first available driver. For types without built-in support,
167 // an class named "Database<Type>" us used, eg. DatabaseFoo for type 'foo'.
168 static $builtinTypes = [
169 'mysql' => [ 'mysqli' => DatabaseMysqli::class ],
170 'sqlite' => DatabaseSqlite::class,
171 'postgres' => DatabasePostgres::class,
172 ];
173
174 $dbType = strtolower( $dbType );
175
176 if ( !isset( $builtinTypes[$dbType] ) ) {
177 // Not a built in type, assume standard naming scheme
178 return 'Database' . ucfirst( $dbType );
179 }
180
181 $class = false;
182 $possibleDrivers = $builtinTypes[$dbType];
183 if ( is_string( $possibleDrivers ) ) {
184 $class = $possibleDrivers;
185 } elseif ( (string)$driver !== '' ) {
186 if ( !isset( $possibleDrivers[$driver] ) ) {
187 throw new InvalidArgumentException( __METHOD__ .
188 " type '$dbType' does not support driver '{$driver}'" );
189 }
190
191 $class = $possibleDrivers[$driver];
192 } else {
193 foreach ( $possibleDrivers as $posDriver => $possibleClass ) {
194 if ( extension_loaded( $posDriver ) ) {
195 $class = $possibleClass;
196 break;
197 }
198 }
199 }
200
201 if ( $class === false ) {
202 throw new InvalidArgumentException( __METHOD__ .
203 " no viable database extension found for type '$dbType'" );
204 }
205
206 return $class;
207 }
208}
Simple store for keeping values in an associative array for the current process.
Constructs Database objects.
attributesFromType( $dbType, $driver=null)
getClass( $dbType, $driver=null)
create( $type, $params=[], $connect=Database::NEW_CONNECTED)
Construct a Database subclass instance given a database type and parameters.
Detect high-contention DB queries via profiling calls.