Projekt

Obecné

Profil

Stáhnout (8.53 KB) Statistiky
| Větev: | Revize:
1 cb15593b Cajova-Houba
<?php
2
3
namespace Illuminate\Database;
4
5
use PDO;
6
use Illuminate\Support\Arr;
7
use Illuminate\Support\Str;
8
use InvalidArgumentException;
9
use Illuminate\Database\Connectors\ConnectionFactory;
10
11
class DatabaseManager implements ConnectionResolverInterface
12
{
13
    /**
14
     * The application instance.
15
     *
16
     * @var \Illuminate\Foundation\Application
17
     */
18
    protected $app;
19
20
    /**
21
     * The database connection factory instance.
22
     *
23
     * @var \Illuminate\Database\Connectors\ConnectionFactory
24
     */
25
    protected $factory;
26
27
    /**
28
     * The active connection instances.
29
     *
30
     * @var array
31
     */
32
    protected $connections = [];
33
34
    /**
35
     * The custom connection resolvers.
36
     *
37
     * @var array
38
     */
39
    protected $extensions = [];
40
41
    /**
42
     * Create a new database manager instance.
43
     *
44
     * @param  \Illuminate\Foundation\Application  $app
45
     * @param  \Illuminate\Database\Connectors\ConnectionFactory  $factory
46
     * @return void
47
     */
48
    public function __construct($app, ConnectionFactory $factory)
49
    {
50
        $this->app = $app;
51
        $this->factory = $factory;
52
    }
53
54
    /**
55
     * Get a database connection instance.
56
     *
57
     * @param  string  $name
58
     * @return \Illuminate\Database\Connection
59
     */
60
    public function connection($name = null)
61
    {
62
        list($name, $type) = $this->parseConnectionName($name);
63
64
        // If we haven't created this connection, we'll create it based on the config
65
        // provided in the application. Once we've created the connections we will
66
        // set the "fetch mode" for PDO which determines the query return types.
67
        if (! isset($this->connections[$name])) {
68
            $connection = $this->makeConnection($name);
69
70
            $this->setPdoForType($connection, $type);
71
72
            $this->connections[$name] = $this->prepare($connection);
73
        }
74
75
        return $this->connections[$name];
76
    }
77
78
    /**
79
     * Parse the connection into an array of the name and read / write type.
80
     *
81
     * @param  string  $name
82
     * @return array
83
     */
84
    protected function parseConnectionName($name)
85
    {
86
        $name = $name ?: $this->getDefaultConnection();
87
88
        return Str::endsWith($name, ['::read', '::write'])
89
                            ? explode('::', $name, 2) : [$name, null];
90
    }
91
92
    /**
93
     * Disconnect from the given database and remove from local cache.
94
     *
95
     * @param  string  $name
96
     * @return void
97
     */
98
    public function purge($name = null)
99
    {
100
        $this->disconnect($name);
101
102
        unset($this->connections[$name]);
103
    }
104
105
    /**
106
     * Disconnect from the given database.
107
     *
108
     * @param  string  $name
109
     * @return void
110
     */
111
    public function disconnect($name = null)
112
    {
113
        if (isset($this->connections[$name = $name ?: $this->getDefaultConnection()])) {
114
            $this->connections[$name]->disconnect();
115
        }
116
    }
117
118
    /**
119
     * Reconnect to the given database.
120
     *
121
     * @param  string  $name
122
     * @return \Illuminate\Database\Connection
123
     */
124
    public function reconnect($name = null)
125
    {
126
        $this->disconnect($name = $name ?: $this->getDefaultConnection());
127
128
        if (! isset($this->connections[$name])) {
129
            return $this->connection($name);
130
        }
131
132
        return $this->refreshPdoConnections($name);
133
    }
134
135
    /**
136
     * Refresh the PDO connections on a given connection.
137
     *
138
     * @param  string  $name
139
     * @return \Illuminate\Database\Connection
140
     */
141
    protected function refreshPdoConnections($name)
142
    {
143
        $fresh = $this->makeConnection($name);
144
145
        return $this->connections[$name]
146
                                ->setPdo($fresh->getPdo())
147
                                ->setReadPdo($fresh->getReadPdo());
148
    }
149
150
    /**
151
     * Make the database connection instance.
152
     *
153
     * @param  string  $name
154
     * @return \Illuminate\Database\Connection
155
     */
156
    protected function makeConnection($name)
157
    {
158
        $config = $this->getConfig($name);
159
160
        // First we will check by the connection name to see if an extension has been
161
        // registered specifically for that connection. If it has we will call the
162
        // Closure and pass it the config allowing it to resolve the connection.
163
        if (isset($this->extensions[$name])) {
164
            return call_user_func($this->extensions[$name], $config, $name);
165
        }
166
167
        $driver = $config['driver'];
168
169
        // Next we will check to see if an extension has been registered for a driver
170
        // and will call the Closure if so, which allows us to have a more generic
171
        // resolver for the drivers themselves which applies to all connections.
172
        if (isset($this->extensions[$driver])) {
173
            return call_user_func($this->extensions[$driver], $config, $name);
174
        }
175
176
        return $this->factory->make($config, $name);
177
    }
178
179
    /**
180
     * Prepare the database connection instance.
181
     *
182
     * @param  \Illuminate\Database\Connection  $connection
183
     * @return \Illuminate\Database\Connection
184
     */
185
    protected function prepare(Connection $connection)
186
    {
187
        $connection->setFetchMode($this->app['config']['database.fetch']);
188
189
        if ($this->app->bound('events')) {
190
            $connection->setEventDispatcher($this->app['events']);
191
        }
192
193
        // Here we'll set a reconnector callback. This reconnector can be any callable
194
        // so we will set a Closure to reconnect from this manager with the name of
195
        // the connection, which will allow us to reconnect from the connections.
196
        $connection->setReconnector(function ($connection) {
197
            $this->reconnect($connection->getName());
198
        });
199
200
        return $connection;
201
    }
202
203
    /**
204
     * Prepare the read write mode for database connection instance.
205
     *
206
     * @param  \Illuminate\Database\Connection  $connection
207
     * @param  string  $type
208
     * @return \Illuminate\Database\Connection
209
     */
210
    protected function setPdoForType(Connection $connection, $type = null)
211
    {
212
        if ($type == 'read') {
213
            $connection->setPdo($connection->getReadPdo());
214
        } elseif ($type == 'write') {
215
            $connection->setReadPdo($connection->getPdo());
216
        }
217
218
        return $connection;
219
    }
220
221
    /**
222
     * Get the configuration for a connection.
223
     *
224
     * @param  string  $name
225
     * @return array
226
     *
227
     * @throws \InvalidArgumentException
228
     */
229
    protected function getConfig($name)
230
    {
231
        $name = $name ?: $this->getDefaultConnection();
232
233
        // To get the database connection configuration, we will just pull each of the
234
        // connection configurations and get the configurations for the given name.
235
        // If the configuration doesn't exist, we'll throw an exception and bail.
236
        $connections = $this->app['config']['database.connections'];
237
238
        if (is_null($config = Arr::get($connections, $name))) {
239
            throw new InvalidArgumentException("Database [$name] not configured.");
240
        }
241
242
        return $config;
243
    }
244
245
    /**
246
     * Get the default connection name.
247
     *
248
     * @return string
249
     */
250
    public function getDefaultConnection()
251
    {
252
        return $this->app['config']['database.default'];
253
    }
254
255
    /**
256
     * Set the default connection name.
257
     *
258
     * @param  string  $name
259
     * @return void
260
     */
261
    public function setDefaultConnection($name)
262
    {
263
        $this->app['config']['database.default'] = $name;
264
    }
265
266
    /**
267
     * Get all of the support drivers.
268
     *
269
     * @return array
270
     */
271
    public function supportedDrivers()
272
    {
273
        return ['mysql', 'pgsql', 'sqlite', 'sqlsrv'];
274
    }
275
276
    /**
277
     * Get all of the drivers that are actually available.
278
     *
279
     * @return array
280
     */
281
    public function availableDrivers()
282
    {
283
        return array_intersect($this->supportedDrivers(), str_replace('dblib', 'sqlsrv', PDO::getAvailableDrivers()));
284
    }
285
286
    /**
287
     * Register an extension connection resolver.
288
     *
289
     * @param  string    $name
290
     * @param  callable  $resolver
291
     * @return void
292
     */
293
    public function extend($name, callable $resolver)
294
    {
295
        $this->extensions[$name] = $resolver;
296
    }
297
298
    /**
299
     * Return all of the created connections.
300
     *
301
     * @return array
302
     */
303
    public function getConnections()
304
    {
305
        return $this->connections;
306
    }
307
308
    /**
309
     * Dynamically pass methods to the default connection.
310
     *
311
     * @param  string  $method
312
     * @param  array   $parameters
313
     * @return mixed
314
     */
315
    public function __call($method, $parameters)
316
    {
317
        return call_user_func_array([$this->connection(), $method], $parameters);
318
    }
319
}