]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - includes/libs/rdbms/database/DBConnRef.php
MediaWiki 1.30.2
[autoinstallsdev/mediawiki.git] / includes / libs / rdbms / database / DBConnRef.php
1 <?php
2
3 namespace Wikimedia\Rdbms;
4
5 use InvalidArgumentException;
6
7 /**
8  * Helper class to handle automatically marking connections as reusable (via RAII pattern)
9  * as well handling deferring the actual network connection until the handle is used
10  *
11  * @note: proxy methods are defined explicitly to avoid interface errors
12  * @ingroup Database
13  * @since 1.22
14  */
15 class DBConnRef implements IDatabase {
16         /** @var ILoadBalancer */
17         private $lb;
18         /** @var Database|null Live connection handle */
19         private $conn;
20         /** @var array|null N-tuple of (server index, group, DatabaseDomain|string) */
21         private $params;
22
23         const FLD_INDEX = 0;
24         const FLD_GROUP = 1;
25         const FLD_DOMAIN = 2;
26         const FLD_FLAGS = 3;
27
28         /**
29          * @param ILoadBalancer $lb Connection manager for $conn
30          * @param Database|array $conn Database handle or (server index, query groups, domain, flags)
31          */
32         public function __construct( ILoadBalancer $lb, $conn ) {
33                 $this->lb = $lb;
34                 if ( $conn instanceof Database ) {
35                         $this->conn = $conn; // live handle
36                 } elseif ( count( $conn ) >= 4 && $conn[self::FLD_DOMAIN] !== false ) {
37                         $this->params = $conn;
38                 } else {
39                         throw new InvalidArgumentException( "Missing lazy connection arguments." );
40                 }
41         }
42
43         function __call( $name, array $arguments ) {
44                 if ( $this->conn === null ) {
45                         list( $db, $groups, $wiki, $flags ) = $this->params;
46                         $this->conn = $this->lb->getConnection( $db, $groups, $wiki, $flags );
47                 }
48
49                 return call_user_func_array( [ $this->conn, $name ], $arguments );
50         }
51
52         public function getServerInfo() {
53                 return $this->__call( __FUNCTION__, func_get_args() );
54         }
55
56         public function bufferResults( $buffer = null ) {
57                 return $this->__call( __FUNCTION__, func_get_args() );
58         }
59
60         public function trxLevel() {
61                 return $this->__call( __FUNCTION__, func_get_args() );
62         }
63
64         public function trxTimestamp() {
65                 return $this->__call( __FUNCTION__, func_get_args() );
66         }
67
68         public function explicitTrxActive() {
69                 return $this->__call( __FUNCTION__, func_get_args() );
70         }
71
72         public function tablePrefix( $prefix = null ) {
73                 return $this->__call( __FUNCTION__, func_get_args() );
74         }
75
76         public function dbSchema( $schema = null ) {
77                 return $this->__call( __FUNCTION__, func_get_args() );
78         }
79
80         public function getLBInfo( $name = null ) {
81                 return $this->__call( __FUNCTION__, func_get_args() );
82         }
83
84         public function setLBInfo( $name, $value = null ) {
85                 return $this->__call( __FUNCTION__, func_get_args() );
86         }
87
88         public function setLazyMasterHandle( IDatabase $conn ) {
89                 return $this->__call( __FUNCTION__, func_get_args() );
90         }
91
92         public function implicitGroupby() {
93                 return $this->__call( __FUNCTION__, func_get_args() );
94         }
95
96         public function implicitOrderby() {
97                 return $this->__call( __FUNCTION__, func_get_args() );
98         }
99
100         public function lastQuery() {
101                 return $this->__call( __FUNCTION__, func_get_args() );
102         }
103
104         public function doneWrites() {
105                 return $this->__call( __FUNCTION__, func_get_args() );
106         }
107
108         public function lastDoneWrites() {
109                 return $this->__call( __FUNCTION__, func_get_args() );
110         }
111
112         public function writesPending() {
113                 return $this->__call( __FUNCTION__, func_get_args() );
114         }
115
116         public function writesOrCallbacksPending() {
117                 return $this->__call( __FUNCTION__, func_get_args() );
118         }
119
120         public function pendingWriteQueryDuration( $type = self::ESTIMATE_TOTAL ) {
121                 return $this->__call( __FUNCTION__, func_get_args() );
122         }
123
124         public function pendingWriteCallers() {
125                 return $this->__call( __FUNCTION__, func_get_args() );
126         }
127
128         public function pendingWriteRowsAffected() {
129                 return $this->__call( __FUNCTION__, func_get_args() );
130         }
131
132         public function isOpen() {
133                 return $this->__call( __FUNCTION__, func_get_args() );
134         }
135
136         public function setFlag( $flag, $remember = self::REMEMBER_NOTHING ) {
137                 return $this->__call( __FUNCTION__, func_get_args() );
138         }
139
140         public function clearFlag( $flag, $remember = self::REMEMBER_NOTHING ) {
141                 return $this->__call( __FUNCTION__, func_get_args() );
142         }
143
144         public function restoreFlags( $state = self::RESTORE_PRIOR ) {
145                 return $this->__call( __FUNCTION__, func_get_args() );
146         }
147
148         public function getFlag( $flag ) {
149                 return $this->__call( __FUNCTION__, func_get_args() );
150         }
151
152         public function getProperty( $name ) {
153                 return $this->__call( __FUNCTION__, func_get_args() );
154         }
155
156         public function getDomainID() {
157                 if ( $this->conn === null ) {
158                         $domain = $this->params[self::FLD_DOMAIN];
159                         // Avoid triggering a database connection
160                         return $domain instanceof DatabaseDomain ? $domain->getId() : $domain;
161                 }
162
163                 return $this->__call( __FUNCTION__, func_get_args() );
164         }
165
166         public function getWikiID() {
167                 return $this->getDomainID();
168         }
169
170         public function getType() {
171                 return $this->__call( __FUNCTION__, func_get_args() );
172         }
173
174         public function open( $server, $user, $password, $dbName ) {
175                 return $this->__call( __FUNCTION__, func_get_args() );
176         }
177
178         public function fetchObject( $res ) {
179                 return $this->__call( __FUNCTION__, func_get_args() );
180         }
181
182         public function fetchRow( $res ) {
183                 return $this->__call( __FUNCTION__, func_get_args() );
184         }
185
186         public function numRows( $res ) {
187                 return $this->__call( __FUNCTION__, func_get_args() );
188         }
189
190         public function numFields( $res ) {
191                 return $this->__call( __FUNCTION__, func_get_args() );
192         }
193
194         public function fieldName( $res, $n ) {
195                 return $this->__call( __FUNCTION__, func_get_args() );
196         }
197
198         public function insertId() {
199                 return $this->__call( __FUNCTION__, func_get_args() );
200         }
201
202         public function dataSeek( $res, $row ) {
203                 return $this->__call( __FUNCTION__, func_get_args() );
204         }
205
206         public function lastErrno() {
207                 return $this->__call( __FUNCTION__, func_get_args() );
208         }
209
210         public function lastError() {
211                 return $this->__call( __FUNCTION__, func_get_args() );
212         }
213
214         public function fieldInfo( $table, $field ) {
215                 return $this->__call( __FUNCTION__, func_get_args() );
216         }
217
218         public function affectedRows() {
219                 return $this->__call( __FUNCTION__, func_get_args() );
220         }
221
222         public function getSoftwareLink() {
223                 return $this->__call( __FUNCTION__, func_get_args() );
224         }
225
226         public function getServerVersion() {
227                 return $this->__call( __FUNCTION__, func_get_args() );
228         }
229
230         public function close() {
231                 return $this->__call( __FUNCTION__, func_get_args() );
232         }
233
234         public function reportConnectionError( $error = 'Unknown error' ) {
235                 return $this->__call( __FUNCTION__, func_get_args() );
236         }
237
238         public function query( $sql, $fname = __METHOD__, $tempIgnore = false ) {
239                 return $this->__call( __FUNCTION__, func_get_args() );
240         }
241
242         public function reportQueryError( $error, $errno, $sql, $fname, $tempIgnore = false ) {
243                 return $this->__call( __FUNCTION__, func_get_args() );
244         }
245
246         public function freeResult( $res ) {
247                 return $this->__call( __FUNCTION__, func_get_args() );
248         }
249
250         public function selectField(
251                 $table, $var, $cond = '', $fname = __METHOD__, $options = [], $join_conds = []
252         ) {
253                 return $this->__call( __FUNCTION__, func_get_args() );
254         }
255
256         public function selectFieldValues(
257                 $table, $var, $cond = '', $fname = __METHOD__, $options = [], $join_conds = []
258         ) {
259                 return $this->__call( __FUNCTION__, func_get_args() );
260         }
261
262         public function select(
263                 $table, $vars, $conds = '', $fname = __METHOD__,
264                 $options = [], $join_conds = []
265         ) {
266                 return $this->__call( __FUNCTION__, func_get_args() );
267         }
268
269         public function selectSQLText(
270                 $table, $vars, $conds = '', $fname = __METHOD__,
271                 $options = [], $join_conds = []
272         ) {
273                 return $this->__call( __FUNCTION__, func_get_args() );
274         }
275
276         public function selectRow(
277                 $table, $vars, $conds, $fname = __METHOD__,
278                 $options = [], $join_conds = []
279         ) {
280                 return $this->__call( __FUNCTION__, func_get_args() );
281         }
282
283         public function estimateRowCount(
284                 $table, $vars = '*', $conds = '', $fname = __METHOD__, $options = []
285         ) {
286                 return $this->__call( __FUNCTION__, func_get_args() );
287         }
288
289         public function selectRowCount(
290                 $tables, $vars = '*', $conds = '', $fname = __METHOD__, $options = [], $join_conds = []
291         ) {
292                 return $this->__call( __FUNCTION__, func_get_args() );
293         }
294
295         public function fieldExists( $table, $field, $fname = __METHOD__ ) {
296                 return $this->__call( __FUNCTION__, func_get_args() );
297         }
298
299         public function indexExists( $table, $index, $fname = __METHOD__ ) {
300                 return $this->__call( __FUNCTION__, func_get_args() );
301         }
302
303         public function tableExists( $table, $fname = __METHOD__ ) {
304                 return $this->__call( __FUNCTION__, func_get_args() );
305         }
306
307         public function indexUnique( $table, $index ) {
308                 return $this->__call( __FUNCTION__, func_get_args() );
309         }
310
311         public function insert( $table, $a, $fname = __METHOD__, $options = [] ) {
312                 return $this->__call( __FUNCTION__, func_get_args() );
313         }
314
315         public function update( $table, $values, $conds, $fname = __METHOD__, $options = [] ) {
316                 return $this->__call( __FUNCTION__, func_get_args() );
317         }
318
319         public function makeList( $a, $mode = self::LIST_COMMA ) {
320                 return $this->__call( __FUNCTION__, func_get_args() );
321         }
322
323         public function makeWhereFrom2d( $data, $baseKey, $subKey ) {
324                 return $this->__call( __FUNCTION__, func_get_args() );
325         }
326
327         public function aggregateValue( $valuedata, $valuename = 'value' ) {
328                 return $this->__call( __FUNCTION__, func_get_args() );
329         }
330
331         public function bitNot( $field ) {
332                 return $this->__call( __FUNCTION__, func_get_args() );
333         }
334
335         public function bitAnd( $fieldLeft, $fieldRight ) {
336                 return $this->__call( __FUNCTION__, func_get_args() );
337         }
338
339         public function bitOr( $fieldLeft, $fieldRight ) {
340                 return $this->__call( __FUNCTION__, func_get_args() );
341         }
342
343         public function buildConcat( $stringList ) {
344                 return $this->__call( __FUNCTION__, func_get_args() );
345         }
346
347         public function buildGroupConcatField(
348                 $delim, $table, $field, $conds = '', $join_conds = []
349         ) {
350                 return $this->__call( __FUNCTION__, func_get_args() );
351         }
352
353         public function buildStringCast( $field ) {
354                 return $this->__call( __FUNCTION__, func_get_args() );
355         }
356
357         public function databasesAreIndependent() {
358                 return $this->__call( __FUNCTION__, func_get_args() );
359         }
360
361         public function selectDB( $db ) {
362                 return $this->__call( __FUNCTION__, func_get_args() );
363         }
364
365         public function getDBname() {
366                 return $this->__call( __FUNCTION__, func_get_args() );
367         }
368
369         public function getServer() {
370                 return $this->__call( __FUNCTION__, func_get_args() );
371         }
372
373         public function addQuotes( $s ) {
374                 return $this->__call( __FUNCTION__, func_get_args() );
375         }
376
377         public function buildLike() {
378                 return $this->__call( __FUNCTION__, func_get_args() );
379         }
380
381         public function anyChar() {
382                 return $this->__call( __FUNCTION__, func_get_args() );
383         }
384
385         public function anyString() {
386                 return $this->__call( __FUNCTION__, func_get_args() );
387         }
388
389         public function nextSequenceValue( $seqName ) {
390                 return $this->__call( __FUNCTION__, func_get_args() );
391         }
392
393         public function replace( $table, $uniqueIndexes, $rows, $fname = __METHOD__ ) {
394                 return $this->__call( __FUNCTION__, func_get_args() );
395         }
396
397         public function upsert(
398                 $table, array $rows, array $uniqueIndexes, array $set, $fname = __METHOD__
399         ) {
400                 return $this->__call( __FUNCTION__, func_get_args() );
401         }
402
403         public function deleteJoin(
404                 $delTable, $joinTable, $delVar, $joinVar, $conds, $fname = __METHOD__
405         ) {
406                 return $this->__call( __FUNCTION__, func_get_args() );
407         }
408
409         public function delete( $table, $conds, $fname = __METHOD__ ) {
410                 return $this->__call( __FUNCTION__, func_get_args() );
411         }
412
413         public function insertSelect(
414                 $destTable, $srcTable, $varMap, $conds,
415                 $fname = __METHOD__, $insertOptions = [], $selectOptions = [], $selectJoinConds = []
416         ) {
417                 return $this->__call( __FUNCTION__, func_get_args() );
418         }
419
420         public function unionSupportsOrderAndLimit() {
421                 return $this->__call( __FUNCTION__, func_get_args() );
422         }
423
424         public function unionQueries( $sqls, $all ) {
425                 return $this->__call( __FUNCTION__, func_get_args() );
426         }
427
428         public function unionConditionPermutations(
429                 $table, $vars, array $permute_conds, $extra_conds = '', $fname = __METHOD__,
430                 $options = [], $join_conds = []
431         ) {
432                 return $this->__call( __FUNCTION__, func_get_args() );
433         }
434
435         public function conditional( $cond, $trueVal, $falseVal ) {
436                 return $this->__call( __FUNCTION__, func_get_args() );
437         }
438
439         public function strreplace( $orig, $old, $new ) {
440                 return $this->__call( __FUNCTION__, func_get_args() );
441         }
442
443         public function getServerUptime() {
444                 return $this->__call( __FUNCTION__, func_get_args() );
445         }
446
447         public function wasDeadlock() {
448                 return $this->__call( __FUNCTION__, func_get_args() );
449         }
450
451         public function wasLockTimeout() {
452                 return $this->__call( __FUNCTION__, func_get_args() );
453         }
454
455         public function wasErrorReissuable() {
456                 return $this->__call( __FUNCTION__, func_get_args() );
457         }
458
459         public function wasReadOnlyError() {
460                 return $this->__call( __FUNCTION__, func_get_args() );
461         }
462
463         public function masterPosWait( DBMasterPos $pos, $timeout ) {
464                 return $this->__call( __FUNCTION__, func_get_args() );
465         }
466
467         public function getReplicaPos() {
468                 return $this->__call( __FUNCTION__, func_get_args() );
469         }
470
471         public function getMasterPos() {
472                 return $this->__call( __FUNCTION__, func_get_args() );
473         }
474
475         public function serverIsReadOnly() {
476                 return $this->__call( __FUNCTION__, func_get_args() );
477         }
478
479         public function onTransactionResolution( callable $callback, $fname = __METHOD__ ) {
480                 return $this->__call( __FUNCTION__, func_get_args() );
481         }
482
483         public function onTransactionIdle( callable $callback, $fname = __METHOD__ ) {
484                 return $this->__call( __FUNCTION__, func_get_args() );
485         }
486
487         public function onTransactionPreCommitOrIdle( callable $callback, $fname = __METHOD__ ) {
488                 return $this->__call( __FUNCTION__, func_get_args() );
489         }
490
491         public function setTransactionListener( $name, callable $callback = null ) {
492                 return $this->__call( __FUNCTION__, func_get_args() );
493         }
494
495         public function startAtomic( $fname = __METHOD__ ) {
496                 return $this->__call( __FUNCTION__, func_get_args() );
497         }
498
499         public function endAtomic( $fname = __METHOD__ ) {
500                 return $this->__call( __FUNCTION__, func_get_args() );
501         }
502
503         public function doAtomicSection( $fname, callable $callback ) {
504                 return $this->__call( __FUNCTION__, func_get_args() );
505         }
506
507         public function begin( $fname = __METHOD__, $mode = IDatabase::TRANSACTION_EXPLICIT ) {
508                 return $this->__call( __FUNCTION__, func_get_args() );
509         }
510
511         public function commit( $fname = __METHOD__, $flush = '' ) {
512                 return $this->__call( __FUNCTION__, func_get_args() );
513         }
514
515         public function rollback( $fname = __METHOD__, $flush = '' ) {
516                 return $this->__call( __FUNCTION__, func_get_args() );
517         }
518
519         public function flushSnapshot( $fname = __METHOD__ ) {
520                 return $this->__call( __FUNCTION__, func_get_args() );
521         }
522
523         public function listTables( $prefix = null, $fname = __METHOD__ ) {
524                 return $this->__call( __FUNCTION__, func_get_args() );
525         }
526
527         public function timestamp( $ts = 0 ) {
528                 return $this->__call( __FUNCTION__, func_get_args() );
529         }
530
531         public function timestampOrNull( $ts = null ) {
532                 return $this->__call( __FUNCTION__, func_get_args() );
533         }
534
535         public function ping( &$rtt = null ) {
536                 return func_num_args()
537                         ? $this->__call( __FUNCTION__, [ &$rtt ] )
538                         : $this->__call( __FUNCTION__, [] ); // method cares about null vs missing
539         }
540
541         public function getLag() {
542                 return $this->__call( __FUNCTION__, func_get_args() );
543         }
544
545         public function getSessionLagStatus() {
546                 return $this->__call( __FUNCTION__, func_get_args() );
547         }
548
549         public function maxListLen() {
550                 return $this->__call( __FUNCTION__, func_get_args() );
551         }
552
553         public function encodeBlob( $b ) {
554                 return $this->__call( __FUNCTION__, func_get_args() );
555         }
556
557         public function decodeBlob( $b ) {
558                 return $this->__call( __FUNCTION__, func_get_args() );
559         }
560
561         public function setSessionOptions( array $options ) {
562                 return $this->__call( __FUNCTION__, func_get_args() );
563         }
564
565         public function setSchemaVars( $vars ) {
566                 return $this->__call( __FUNCTION__, func_get_args() );
567         }
568
569         public function lockIsFree( $lockName, $method ) {
570                 return $this->__call( __FUNCTION__, func_get_args() );
571         }
572
573         public function lock( $lockName, $method, $timeout = 5 ) {
574                 return $this->__call( __FUNCTION__, func_get_args() );
575         }
576
577         public function unlock( $lockName, $method ) {
578                 return $this->__call( __FUNCTION__, func_get_args() );
579         }
580
581         public function getScopedLockAndFlush( $lockKey, $fname, $timeout ) {
582                 return $this->__call( __FUNCTION__, func_get_args() );
583         }
584
585         public function namedLocksEnqueue() {
586                 return $this->__call( __FUNCTION__, func_get_args() );
587         }
588
589         public function getInfinity() {
590                 return $this->__call( __FUNCTION__, func_get_args() );
591         }
592
593         public function encodeExpiry( $expiry ) {
594                 return $this->__call( __FUNCTION__, func_get_args() );
595         }
596
597         public function decodeExpiry( $expiry, $format = TS_MW ) {
598                 return $this->__call( __FUNCTION__, func_get_args() );
599         }
600
601         public function setBigSelects( $value = true ) {
602                 return $this->__call( __FUNCTION__, func_get_args() );
603         }
604
605         public function isReadOnly() {
606                 return $this->__call( __FUNCTION__, func_get_args() );
607         }
608
609         public function setTableAliases( array $aliases ) {
610                 return $this->__call( __FUNCTION__, func_get_args() );
611         }
612
613         /**
614          * Clean up the connection when out of scope
615          */
616         function __destruct() {
617                 if ( $this->conn ) {
618                         $this->lb->reuseConnection( $this->conn );
619                 }
620         }
621 }
622
623 class_alias( DBConnRef::class, 'DBConnRef' );