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\Database\Concerns\ParsesSearchPath;
6
use PDO;
7
 
8
class PostgresConnector extends Connector implements ConnectorInterface
9
{
10
    use ParsesSearchPath;
11
 
12
    /**
13
     * The default PDO connection options.
14
     *
15
     * @var array
16
     */
17
    protected $options = [
18
        PDO::ATTR_CASE => PDO::CASE_NATURAL,
19
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
20
        PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL,
21
        PDO::ATTR_STRINGIFY_FETCHES => false,
22
    ];
23
 
24
    /**
25
     * Establish a database connection.
26
     *
27
     * @param  array  $config
28
     * @return \PDO
29
     */
30
    public function connect(array $config)
31
    {
32
        // First we'll create the basic DSN and connection instance connecting to the
33
        // using the configuration option specified by the developer. We will also
34
        // set the default character set on the connections to UTF-8 by default.
35
        $connection = $this->createConnection(
36
            $this->getDsn($config), $config, $this->getOptions($config)
37
        );
38
 
39
        $this->configureIsolationLevel($connection, $config);
40
 
41
        $this->configureEncoding($connection, $config);
42
 
43
        // Next, we will check to see if a timezone has been specified in this config
44
        // and if it has we will issue a statement to modify the timezone with the
45
        // database. Setting this DB timezone is an optional configuration item.
46
        $this->configureTimezone($connection, $config);
47
 
48
        $this->configureSearchPath($connection, $config);
49
 
50
        // Postgres allows an application_name to be set by the user and this name is
51
        // used to when monitoring the application with pg_stat_activity. So we'll
52
        // determine if the option has been specified and run a statement if so.
53
        $this->configureApplicationName($connection, $config);
54
 
55
        $this->configureSynchronousCommit($connection, $config);
56
 
57
        return $connection;
58
    }
59
 
60
    /**
61
     * Set the connection transaction isolation level.
62
     *
63
     * @param  \PDO  $connection
64
     * @param  array  $config
65
     * @return void
66
     */
67
    protected function configureIsolationLevel($connection, array $config)
68
    {
69
        if (isset($config['isolation_level'])) {
70
            $connection->prepare("set session characteristics as transaction isolation level {$config['isolation_level']}")->execute();
71
        }
72
    }
73
 
74
    /**
75
     * Set the connection character set and collation.
76
     *
77
     * @param  \PDO  $connection
78
     * @param  array  $config
79
     * @return void
80
     */
81
    protected function configureEncoding($connection, $config)
82
    {
83
        if (! isset($config['charset'])) {
84
            return;
85
        }
86
 
87
        $connection->prepare("set names '{$config['charset']}'")->execute();
88
    }
89
 
90
    /**
91
     * Set the timezone on the connection.
92
     *
93
     * @param  \PDO  $connection
94
     * @param  array  $config
95
     * @return void
96
     */
97
    protected function configureTimezone($connection, array $config)
98
    {
99
        if (isset($config['timezone'])) {
100
            $timezone = $config['timezone'];
101
 
102
            $connection->prepare("set time zone '{$timezone}'")->execute();
103
        }
104
    }
105
 
106
    /**
107
     * Set the "search_path" on the database connection.
108
     *
109
     * @param  \PDO  $connection
110
     * @param  array  $config
111
     * @return void
112
     */
113
    protected function configureSearchPath($connection, $config)
114
    {
115
        if (isset($config['search_path']) || isset($config['schema'])) {
116
            $searchPath = $this->quoteSearchPath(
117
                $this->parseSearchPath($config['search_path'] ?? $config['schema'])
118
            );
119
 
120
            $connection->prepare("set search_path to {$searchPath}")->execute();
121
        }
122
    }
123
 
124
    /**
125
     * Format the search path for the DSN.
126
     *
127
     * @param  array  $searchPath
128
     * @return string
129
     */
130
    protected function quoteSearchPath($searchPath)
131
    {
132
        return count($searchPath) === 1 ? '"'.$searchPath[0].'"' : '"'.implode('", "', $searchPath).'"';
133
    }
134
 
135
    /**
136
     * Set the application name on the connection.
137
     *
138
     * @param  \PDO  $connection
139
     * @param  array  $config
140
     * @return void
141
     */
142
    protected function configureApplicationName($connection, $config)
143
    {
144
        if (isset($config['application_name'])) {
145
            $applicationName = $config['application_name'];
146
 
147
            $connection->prepare("set application_name to '$applicationName'")->execute();
148
        }
149
    }
150
 
151
    /**
152
     * Create a DSN string from a configuration.
153
     *
154
     * @param  array  $config
155
     * @return string
156
     */
157
    protected function getDsn(array $config)
158
    {
159
        // First we will create the basic DSN setup as well as the port if it is in
160
        // in the configuration options. This will give us the basic DSN we will
161
        // need to establish the PDO connections and return them back for use.
162
        extract($config, EXTR_SKIP);
163
 
164
        $host = isset($host) ? "host={$host};" : '';
165
 
166
        // Sometimes - users may need to connect to a database that has a different
167
        // name than the database used for "information_schema" queries. This is
168
        // typically the case if using "pgbouncer" type software when pooling.
169
        $database = $connect_via_database ?? $database;
170
 
171
        $dsn = "pgsql:{$host}dbname='{$database}'";
172
 
173
        // If a port was specified, we will add it to this Postgres DSN connections
174
        // format. Once we have done that we are ready to return this connection
175
        // string back out for usage, as this has been fully constructed here.
176
        if (isset($config['port'])) {
177
            $dsn .= ";port={$port}";
178
        }
179
 
180
        return $this->addSslOptions($dsn, $config);
181
    }
182
 
183
    /**
184
     * Add the SSL options to the DSN.
185
     *
186
     * @param  string  $dsn
187
     * @param  array  $config
188
     * @return string
189
     */
190
    protected function addSslOptions($dsn, array $config)
191
    {
192
        foreach (['sslmode', 'sslcert', 'sslkey', 'sslrootcert'] as $option) {
193
            if (isset($config[$option])) {
194
                $dsn .= ";{$option}={$config[$option]}";
195
            }
196
        }
197
 
198
        return $dsn;
199
    }
200
 
201
    /**
202
     * Configure the synchronous_commit setting.
203
     *
204
     * @param  \PDO  $connection
205
     * @param  array  $config
206
     * @return void
207
     */
208
    protected function configureSynchronousCommit($connection, array $config)
209
    {
210
        if (! isset($config['synchronous_commit'])) {
211
            return;
212
        }
213
 
214
        $connection->prepare("set synchronous_commit to '{$config['synchronous_commit']}'")->execute();
215
    }
216
}