Manager   A
last analyzed

Complexity

Total Complexity 23

Size/Duplication

Total Lines 186
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
dl 0
loc 186
rs 10
c 0
b 0
f 0
wmc 23
lcom 1
cbo 4

12 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A connect() 0 17 3
A disconnect() 0 12 2
A getConnection() 0 6 2
A useDatabase() 0 7 1
A query() 0 6 1
A getLastConnection() 0 10 2
A getOpenConnectionOrFail() 0 8 3
A checkConnection() 0 8 2
A getConnections() 0 4 1
A setLastConnection() 0 13 3
A addConnection() 0 10 2
1
<?php
2
3
namespace Mattbit\MysqlCompat;
4
5
use Mattbit\MysqlCompat\Exception\NoConnectionException;
6
use Mattbit\MysqlCompat\Exception\ClosedConnectionException;
7
8
class Manager
9
{
10
    /**
11
     * The array of open connections.
12
     *
13
     * @var array
14
     */
15
    protected $connections = [];
16
17
    /**
18
     * @var ConnectionFactory
19
     */
20
    protected $connectionFactory;
21
22
    /**
23
     * Create a Manager instance.
24
     *
25
     * @param ConnectionFactory $connectionFactory
26
     */
27
    public function __construct(ConnectionFactory $connectionFactory)
28
    {
29
        $this->connectionFactory = $connectionFactory;
30
    }
31
32
    /**
33
     * Return a connection to the database, creating a new one if needed.
34
     *
35
     * @param string $dsn
36
     * @param string $username
37
     * @param string $password
38
     * @param array  $options
39
     * @param bool   $forceNew
40
     *
41
     * @return Connection
42
     */
43
    public function connect($dsn, $username = '', $password = '', array $options = [], $forceNew = false)
44
    {
45
        $connectionId = "{$username}@{$dsn}";
46
47
        // If the same connection is present, do not open a new one
48
        if (!$forceNew && $connection = $this->getConnection($connectionId)) {
49
            $this->setLastConnection($connectionId);
50
51
            return $connection;
52
        }
53
54
        // Otherwise create a new connection
55
        $connection = $this->connectionFactory->createConnection($dsn, $username, $password, $options);
56
        $this->addConnection($connectionId, $connection);
57
58
        return $connection;
59
    }
60
61
    /**
62
     * Close the connection. If no connection is passed, it closes the last.
63
     *
64
     * @param Connection|null $connection
65
     *
66
     * @return bool
67
     *
68
     * @throws NoConnectionException
69
     */
70
    public function disconnect(Connection $connection = null)
71
    {
72
        if ($connection === null) {
73
            $connection = $this->getLastConnection();
74
        }
75
76
        $connection->close();
77
        $connectionId = array_search($connection, $this->connections);
78
        unset($this->connections[$connectionId]);
79
80
        return true;
81
    }
82
83
    /**
84
     * Get a connection.
85
     *
86
     * @param string $id
87
     *
88
     * @return Connection
89
     */
90
    public function getConnection($id)
91
    {
92
        if (array_key_exists($id, $this->connections)) {
93
            return $this->connections[$id];
94
        }
95
    }
96
97
    /**
98
     * Select the database to use. If the connection is omitted, the last one is used.
99
     *
100
     * @param $databaseName
101
     * @param Connection|null $connection
102
     *
103
     * @return bool
104
     */
105
    public function useDatabase($databaseName, Connection $connection = null)
106
    {
107
        $connection = $this->getOpenConnectionOrFail($connection);
108
        $connection->useDatabase($databaseName);
109
110
        return true;
111
    }
112
113
    /**
114
     * Execute a query. If the connection is omitted, the last one is used.
115
     *
116
     * @param $query
117
     * @param Connection|null $connection
118
     *
119
     * @return mixed
120
     */
121
    public function query($query, Connection $connection = null)
122
    {
123
        $connection = $this->getOpenConnectionOrFail($connection);
124
125
        return $connection->query($query);
126
    }
127
128
    /**
129
     * Return the last used connection.
130
     *
131
     * @return Connection
132
     *
133
     * @throws NoConnectionException
134
     */
135
    public function getLastConnection()
136
    {
137
        $connection = end($this->connections);
138
139
        if (!$connection) {
140
            throw new NoConnectionException('There is no open connection.');
141
        }
142
143
        return $connection;
144
    }
145
146
    public function getOpenConnectionOrFail(Connection $connection = null)
147
    {
148
        if ($connection && $this->checkConnection($connection)) {
149
            return $connection;
150
        }
151
152
        return $this->getLastConnection();
153
    }
154
155
    public function checkConnection(Connection $connection)
156
    {
157
        if ($connection->isOpen()) {
158
            return true;
159
        }
160
161
        throw new ClosedConnectionException('Cannot use a closed connection.');
162
    }
163
164
    public function getConnections()
165
    {
166
        return $this->connections;
167
    }
168
169
    public function setLastConnection($id)
170
    {
171
        uksort($this->connections, function ($a, $b) use ($id) {
172
            if ($a === $id) {
173
                return 1;
174
            }
175
            if ($b === $id) {
176
                return -1;
177
            }
178
179
            return 0;
180
        });
181
    }
182
183
    public function addConnection($id, Connection $connection)
184
    {
185
        if (isset($this->connections[$id])) {
186
            $this->addConnection('_'.$id, $connection);
187
188
            return;
189
        }
190
191
        $this->connections[$id] = $connection;
192
    }
193
}
194