Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
namespace Illuminate\Database\Connectors;
4
 
5
use Illuminate\Contracts\Container\Container;
6
use Illuminate\Database\Connection;
7
use Illuminate\Database\MySqlConnection;
8
use Illuminate\Database\PostgresConnection;
9
use Illuminate\Database\SQLiteConnection;
10
use Illuminate\Database\SqlServerConnection;
11
use Illuminate\Support\Arr;
12
use InvalidArgumentException;
13
use PDOException;
14
 
15
class ConnectionFactory
16
{
17
    /**
18
     * The IoC container instance.
19
     *
20
     * @var \Illuminate\Contracts\Container\Container
21
     */
22
    protected $container;
23
 
24
    /**
25
     * Create a new connection factory instance.
26
     *
27
     * @param  \Illuminate\Contracts\Container\Container  $container
28
     * @return void
29
     */
30
    public function __construct(Container $container)
31
    {
32
        $this->container = $container;
33
    }
34
 
35
    /**
36
     * Establish a PDO connection based on the configuration.
37
     *
38
     * @param  array  $config
39
     * @param  string|null  $name
40
     * @return \Illuminate\Database\Connection
41
     */
42
    public function make(array $config, $name = null)
43
    {
44
        $config = $this->parseConfig($config, $name);
45
 
46
        if (isset($config['read'])) {
47
            return $this->createReadWriteConnection($config);
48
        }
49
 
50
        return $this->createSingleConnection($config);
51
    }
52
 
53
    /**
54
     * Parse and prepare the database configuration.
55
     *
56
     * @param  array  $config
57
     * @param  string  $name
58
     * @return array
59
     */
60
    protected function parseConfig(array $config, $name)
61
    {
62
        return Arr::add(Arr::add($config, 'prefix', ''), 'name', $name);
63
    }
64
 
65
    /**
66
     * Create a single database connection instance.
67
     *
68
     * @param  array  $config
69
     * @return \Illuminate\Database\Connection
70
     */
71
    protected function createSingleConnection(array $config)
72
    {
73
        $pdo = $this->createPdoResolver($config);
74
 
75
        return $this->createConnection(
76
            $config['driver'], $pdo, $config['database'], $config['prefix'], $config
77
        );
78
    }
79
 
80
    /**
81
     * Create a read / write database connection instance.
82
     *
83
     * @param  array  $config
84
     * @return \Illuminate\Database\Connection
85
     */
86
    protected function createReadWriteConnection(array $config)
87
    {
88
        $connection = $this->createSingleConnection($this->getWriteConfig($config));
89
 
90
        return $connection->setReadPdo($this->createReadPdo($config));
91
    }
92
 
93
    /**
94
     * Create a new PDO instance for reading.
95
     *
96
     * @param  array  $config
97
     * @return \Closure
98
     */
99
    protected function createReadPdo(array $config)
100
    {
101
        return $this->createPdoResolver($this->getReadConfig($config));
102
    }
103
 
104
    /**
105
     * Get the read configuration for a read / write connection.
106
     *
107
     * @param  array  $config
108
     * @return array
109
     */
110
    protected function getReadConfig(array $config)
111
    {
112
        return $this->mergeReadWriteConfig(
113
            $config, $this->getReadWriteConfig($config, 'read')
114
        );
115
    }
116
 
117
    /**
118
     * Get the write configuration for a read / write connection.
119
     *
120
     * @param  array  $config
121
     * @return array
122
     */
123
    protected function getWriteConfig(array $config)
124
    {
125
        return $this->mergeReadWriteConfig(
126
            $config, $this->getReadWriteConfig($config, 'write')
127
        );
128
    }
129
 
130
    /**
131
     * Get a read / write level configuration.
132
     *
133
     * @param  array  $config
134
     * @param  string  $type
135
     * @return array
136
     */
137
    protected function getReadWriteConfig(array $config, $type)
138
    {
139
        return isset($config[$type][0])
140
                        ? Arr::random($config[$type])
141
                        : $config[$type];
142
    }
143
 
144
    /**
145
     * Merge a configuration for a read / write connection.
146
     *
147
     * @param  array  $config
148
     * @param  array  $merge
149
     * @return array
150
     */
151
    protected function mergeReadWriteConfig(array $config, array $merge)
152
    {
153
        return Arr::except(array_merge($config, $merge), ['read', 'write']);
154
    }
155
 
156
    /**
157
     * Create a new Closure that resolves to a PDO instance.
158
     *
159
     * @param  array  $config
160
     * @return \Closure
161
     */
162
    protected function createPdoResolver(array $config)
163
    {
164
        return array_key_exists('host', $config)
165
                            ? $this->createPdoResolverWithHosts($config)
166
                            : $this->createPdoResolverWithoutHosts($config);
167
    }
168
 
169
    /**
170
     * Create a new Closure that resolves to a PDO instance with a specific host or an array of hosts.
171
     *
172
     * @param  array  $config
173
     * @return \Closure
174
     *
175
     * @throws \PDOException
176
     */
177
    protected function createPdoResolverWithHosts(array $config)
178
    {
179
        return function () use ($config) {
180
            foreach (Arr::shuffle($this->parseHosts($config)) as $host) {
181
                $config['host'] = $host;
182
 
183
                try {
184
                    return $this->createConnector($config)->connect($config);
185
                } catch (PDOException $e) {
186
                    continue;
187
                }
188
            }
189
 
190
            throw $e;
191
        };
192
    }
193
 
194
    /**
195
     * Parse the hosts configuration item into an array.
196
     *
197
     * @param  array  $config
198
     * @return array
199
     *
200
     * @throws \InvalidArgumentException
201
     */
202
    protected function parseHosts(array $config)
203
    {
204
        $hosts = Arr::wrap($config['host']);
205
 
206
        if (empty($hosts)) {
207
            throw new InvalidArgumentException('Database hosts array is empty.');
208
        }
209
 
210
        return $hosts;
211
    }
212
 
213
    /**
214
     * Create a new Closure that resolves to a PDO instance where there is no configured host.
215
     *
216
     * @param  array  $config
217
     * @return \Closure
218
     */
219
    protected function createPdoResolverWithoutHosts(array $config)
220
    {
221
        return fn () => $this->createConnector($config)->connect($config);
222
    }
223
 
224
    /**
225
     * Create a connector instance based on the configuration.
226
     *
227
     * @param  array  $config
228
     * @return \Illuminate\Database\Connectors\ConnectorInterface
229
     *
230
     * @throws \InvalidArgumentException
231
     */
232
    public function createConnector(array $config)
233
    {
234
        if (! isset($config['driver'])) {
235
            throw new InvalidArgumentException('A driver must be specified.');
236
        }
237
 
238
        if ($this->container->bound($key = "db.connector.{$config['driver']}")) {
239
            return $this->container->make($key);
240
        }
241
 
242
        return match ($config['driver']) {
243
            'mysql' => new MySqlConnector,
244
            'pgsql' => new PostgresConnector,
245
            'sqlite' => new SQLiteConnector,
246
            'sqlsrv' => new SqlServerConnector,
247
            default => throw new InvalidArgumentException("Unsupported driver [{$config['driver']}]."),
248
        };
249
    }
250
 
251
    /**
252
     * Create a new connection instance.
253
     *
254
     * @param  string  $driver
255
     * @param  \PDO|\Closure  $connection
256
     * @param  string  $database
257
     * @param  string  $prefix
258
     * @param  array  $config
259
     * @return \Illuminate\Database\Connection
260
     *
261
     * @throws \InvalidArgumentException
262
     */
263
    protected function createConnection($driver, $connection, $database, $prefix = '', array $config = [])
264
    {
265
        if ($resolver = Connection::getResolver($driver)) {
266
            return $resolver($connection, $database, $prefix, $config);
267
        }
268
 
269
        return match ($driver) {
270
            'mysql' => new MySqlConnection($connection, $database, $prefix, $config),
271
            'pgsql' => new PostgresConnection($connection, $database, $prefix, $config),
272
            'sqlite' => new SQLiteConnection($connection, $database, $prefix, $config),
273
            'sqlsrv' => new SqlServerConnection($connection, $database, $prefix, $config),
274
            default => throw new InvalidArgumentException("Unsupported driver [{$driver}]."),
275
        };
276
    }
277
}