Completed
Push — master ( 4dfee6...88ca40 )
by Matteo
02:15
created

Manager::getLastConnection()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
c 2
b 1
f 0
dl 0
loc 10
rs 9.4285
cc 2
eloc 5
nc 2
nop 0
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
     * @return Connection
39
     */
40
    public function connect($dsn, $username = '', $password = '')
41
    {
42
        $connectionId = "{$username}@{$dsn}";
43
44
        // If the same connection is present, do not open a new one
45
        if ($connection = $this->getConnection($connectionId)) {
46
            $this->setLastConnection($connectionId);
47
48
            return $connection;
49
        }
50
51
        // Otherwise create a new connection
52
        $connection = $this->connectionFactory->createConnection($dsn, $username, $password);
53
        $this->addConnection($connectionId, $connection);
54
55
        return $connection;
56
    }
57
58
    /**
59
     * Close the connection. If no connection is passed, it closes the last.
60
     *
61
     * @param  Connection|null $connection
62
     * @return bool
63
     * @throws NoConnectionException
64
     */
65
    public function disconnect(Connection $connection = null)
66
    {
67
        if ($connection === null) {
68
            $connection = $this->getLastConnection();
69
        }
70
71
        $connection->close();
72
        $connectionId = array_search($connection, $this->connections);
73
        unset($this->connections[$connectionId]);
74
75
        return true;
76
    }
77
78
    /**
79
     * Get a connection.
80
     *
81
     * @param  string $id
82
     * @return Connection
83
     */
84
    public function getConnection($id)
85
    {
86
        if (array_key_exists($id, $this->connections)) {
87
            return $this->connections[$id];
88
        }
89
    }
90
91
    /**
92
     * Select the database to use. If the connection is omitted, the last one is used.
93
     *
94
     * @param $databaseName
95
     * @param Connection|null $connection
96
     * @return bool
97
     */
98
    public function useDatabase($databaseName, Connection $connection = null)
99
    {
100
        $connection = $this->getOpenConnectionOrFail($connection);
101
        $connection->useDatabase($databaseName);
102
103
        return true;
104
    }
105
106
    /**
107
     * Execute a query. If the connection is omitted, the last one is used.
108
     *
109
     * @param $query
110
     * @param Connection|null $connection
111
     * @return mixed
112
     */
113
    public function query($query, Connection $connection = null)
114
    {
115
        $connection = $this->getOpenConnectionOrFail($connection);
116
117
        return $connection->query($query);
118
    }
119
    
120
    /**
121
     * Return the last used connection.
122
     *
123
     * @return Connection
124
     * @throws NoConnectionException
125
     */
126
    public function getLastConnection()
127
    {
128
        $connection = end($this->connections);
129
130
        if (!$connection) {
131
            throw new NoConnectionException("There is no open connection.");
132
        }
133
134
        return $connection;
135
    }
136
137
    public function getOpenConnectionOrFail(Connection $connection = null)
138
    {
139
        if ($connection && $this->checkConnection($connection)) {
140
            return $connection;
141
        }
142
143
        return $this->getLastConnection();
144
    }
145
146
    public function checkConnection(Connection $connection)
147
    {
148
        if ($connection->isOpen()) {
149
            return true;
150
        }
151
152
        throw new ClosedConnectionException("Cannot use a closed connection.");
153
    }
154
155
    public function getConnections()
156
    {
157
        return $this->connections;
158
    }
159
160
    public function setLastConnection($id)
161
    {
162
        uksort($this->connections, function ($a, $b) use ($id) {
163
            if ($a === $id) return 1;
164
            if ($b === $id) return -1;
165
            return 0;
166
        });
167
    }
168
169
    public function addConnection($id, Connection $connection)
170
    {
171
        $this->connections[$id] = $connection;
172
    }
173
}
174