Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 19
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
DbFactory
0.00% covered (danger)
0.00%
0 / 19
0.00% covered (danger)
0.00%
0 / 6
132
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 forcePrimary
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getDB
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
6
 getLB
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 getWikiDB
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 waitForReplicas
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2
3namespace Flow;
4
5use MediaWiki\MediaWikiServices;
6use Wikimedia\Rdbms\DBReplicationWaitError;
7use Wikimedia\Rdbms\IDatabase;
8use Wikimedia\Rdbms\IReadableDatabase;
9
10/**
11 * All classes within Flow that need to access the Flow db will go through
12 * this class.  Having it separated into an object greatly simplifies testing
13 * anything that needs to talk to the database.
14 *
15 * The factory receives, in its constructor, the wiki name and cluster name
16 * that Flow-specific data is stored on.  Multiple wiki's can and should be
17 * using the same wiki name and cluster to share Flow-specific data. These values
18 * are used.
19 *
20 * There are also get getWikiLB and getWikiDB for the main wiki database.
21 */
22class DbFactory {
23    /**
24     * @var string|false Wiki ID, or false for the current wiki
25     */
26    protected $wiki;
27
28    /**
29     * @var string|false External storage cluster, or false for core
30     */
31    protected $cluster;
32
33    /**
34     * @var bool When true only DB_PRIMARY will be returned
35     */
36    protected $forcePrimary = false;
37
38    /**
39     * @param string|false $wiki Wiki ID, or false for the current wiki
40     * @param string|false $cluster External storage cluster, or false for core
41     */
42    public function __construct( $wiki, $cluster ) {
43        $this->wiki = $wiki;
44        $this->cluster = $cluster;
45
46        // Ensure maintenance scripts do not encounter replication errors
47        if ( MW_ENTRY_POINT === 'cli' ) {
48            $this->forcePrimary();
49        }
50    }
51
52    public function forcePrimary() {
53        $this->forcePrimary = true;
54    }
55
56    /**
57     * Gets a database connection for the Flow-specific database.
58     *
59     * @param int $db index of the connection to get.  DB_PRIMARY|DB_REPLICA.
60     * @return IDatabase|IReadableDatabase
61     */
62    public function getDB( $db ) {
63        return $this->getLB()->getConnection( $this->forcePrimary ? DB_PRIMARY : $db, [], $this->wiki );
64    }
65
66    /**
67     * Gets a load balancer for the Flow-specific database.
68     *
69     * @return \Wikimedia\Rdbms\ILoadBalancer
70     */
71    private function getLB() {
72        $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
73        if ( $this->cluster !== false ) {
74            return $lbFactory->getExternalLB( $this->cluster );
75        } else {
76            return $lbFactory->getMainLB( $this->wiki );
77        }
78    }
79
80    /**
81     * Gets a database connection for the main wiki database.  Mockable version of wfGetDB.
82     *
83     * @param int $db index of the connection to get.  DB_PRIMARY|DB_REPLICA.
84     * @param string|bool $wiki The wiki ID, or false for the current wiki
85     * @return IDatabase|IReadableDatabase
86     */
87    public function getWikiDB( $db, $wiki = false ) {
88        $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
89        return $lbFactory->getMainLB( $wiki )->getConnection( $this->forcePrimary ? DB_PRIMARY : $db, [], $wiki );
90    }
91
92    /**
93     * Wait for the replicas of the Flow database
94     */
95    public function waitForReplicas() {
96        $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
97        try {
98            $lbFactory->waitForReplication( [
99                'wiki' => $this->wiki,
100                'cluster' => $this->cluster,
101                'ifWritesSince' => false
102            ] );
103        } catch ( DBReplicationWaitError ) {
104        }
105    }
106
107}