MediaWiki REL1_40
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
86 public function create( $type, $params = [], $connect = Database::NEW_CONNECTED ) {
87 $class = $this->getClass( $type, $params['driver'] ?? null );
88
89 if ( class_exists( $class ) && is_subclass_of( $class, IDatabase::class ) ) {
90 $params += [
91 // Default configuration
92 'host' => null,
93 'user' => null,
94 'password' => null,
95 'dbname' => null,
96 'schema' => null,
97 'tablePrefix' => '',
98 'flags' => 0,
99 'variables' => [],
100 'lbInfo' => [],
101 'cliMode' => ( PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg' ),
102 'agent' => '',
103 'serverName' => null,
104 'topologyRole' => null,
105 // Objects and callbacks
106 'srvCache' => $params['srvCache'] ?? new HashBagOStuff(),
107 'profiler' => $params['profiler'] ?? null,
108 'trxProfiler' => $params['trxProfiler'] ?? new TransactionProfiler(),
109 'logger' => $params['logger'] ?? new NullLogger(),
110 'errorLogger' => $params['errorLogger'] ?? static function ( Throwable $e ) {
111 trigger_error( get_class( $e ) . ': ' . $e->getMessage(), E_USER_WARNING );
112 },
113 'deprecationLogger' => $params['deprecationLogger'] ?? static function ( $msg ) {
114 trigger_error( $msg, E_USER_DEPRECATED );
115 }
116 ];
117
119 $conn = new $class( $params );
120 if ( $connect === Database::NEW_CONNECTED ) {
121 $conn->initConnection();
122 }
123 } else {
124 $conn = null;
125 }
126
127 return $conn;
128 }
129
136 public function attributesFromType( $dbType, $driver = null ) {
137 static $defaults = [
138 Database::ATTR_DB_IS_FILE => false,
139 Database::ATTR_DB_LEVEL_LOCKING => false,
140 Database::ATTR_SCHEMAS_AS_TABLE_GROUPS => false
141 ];
142
143 $class = $this->getClass( $dbType, $driver );
144 if ( class_exists( $class ) ) {
145 return call_user_func( [ $class, 'getAttributes' ] ) + $defaults;
146 } else {
147 throw new DBUnexpectedError( null, "$dbType is not a supported database type." );
148 }
149 }
150
157 protected function getClass( $dbType, $driver = null ) {
158 // For database types with built-in support, the below maps type to IDatabase
159 // implementations. For types with multiple driver implementations (PHP extensions),
160 // an array can be used, keyed by extension name. In case of an array, the
161 // optional 'driver' parameter can be used to force a specific driver. Otherwise,
162 // we auto-detect the first available driver. For types without built-in support,
163 // an class named "Database<Type>" us used, eg. DatabaseFoo for type 'foo'.
164 static $builtinTypes = [
165 'mysql' => [ 'mysqli' => DatabaseMysqli::class ],
166 'sqlite' => DatabaseSqlite::class,
167 'postgres' => DatabasePostgres::class,
168 ];
169
170 $dbType = strtolower( $dbType );
171
172 if ( !isset( $builtinTypes[$dbType] ) ) {
173 // Not a built in type, assume standard naming scheme
174 return 'Database' . ucfirst( $dbType );
175 }
176
177 $class = false;
178 $possibleDrivers = $builtinTypes[$dbType];
179 if ( is_string( $possibleDrivers ) ) {
180 $class = $possibleDrivers;
181 } elseif ( (string)$driver !== '' ) {
182 if ( !isset( $possibleDrivers[$driver] ) ) {
183 throw new InvalidArgumentException( __METHOD__ .
184 " type '$dbType' does not support driver '{$driver}'" );
185 }
186
187 $class = $possibleDrivers[$driver];
188 } else {
189 foreach ( $possibleDrivers as $posDriver => $possibleClass ) {
190 if ( extension_loaded( $posDriver ) ) {
191 $class = $possibleClass;
192 break;
193 }
194 }
195 }
196
197 if ( $class === false ) {
198 throw new InvalidArgumentException( __METHOD__ .
199 " no viable database extension found for type '$dbType'" );
200 }
201
202 return $class;
203 }
204}
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.