Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/*
3
 *  $Id: Pgsql.php 7490 2010-03-29 19:53:27Z jwage $
4
 *
5
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
6
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
7
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
8
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
9
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
10
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
11
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
12
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
13
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
14
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
15
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16
 *
17
 * This software consists of voluntary contributions made by many individuals
18
 * and is licensed under the LGPL. For more information, see
19
 * <http://www.doctrine-project.org>.
20
 */
21
 
22
/**
23
 * Doctrine_Connection_Pgsql
24
 *
25
 * @package     Doctrine
26
 * @subpackage  Connection
27
 * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
28
 * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
29
 * @author      Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
30
 * @version     $Revision: 7490 $
31
 * @link        www.doctrine-project.org
32
 * @since       1.0
33
 */
34
class Doctrine_Connection_Pgsql extends Doctrine_Connection_Common
35
{
36
    /**
37
     * @var string $driverName                  the name of this connection driver
38
     */
39
    protected $driverName = 'Pgsql';
40
 
41
    /**
42
     * the constructor
43
     *
44
     * @param Doctrine_Manager $manager
45
     * @param PDO $pdo                          database handle
46
     */
47
    public function __construct(Doctrine_Manager $manager, $adapter)
48
    {
49
        // initialize all driver options
50
        $this->supported = array(
51
                          'sequences'               => true,
52
                          'indexes'                 => true,
53
                          'affected_rows'           => true,
54
                          'summary_functions'       => true,
55
                          'order_by_text'           => true,
56
                          'transactions'            => true,
57
                          'savepoints'              => true,
58
                          'current_id'              => true,
59
                          'limit_queries'           => true,
60
                          'LOBs'                    => true,
61
                          'replace'                 => 'emulated',
62
                          'sub_selects'             => true,
63
                          'auto_increment'          => 'emulated',
64
                          'primary_key'             => true,
65
                          'result_introspection'    => true,
66
                          'prepared_statements'     => true,
67
                          'identifier_quoting'      => true,
68
                          'pattern_escaping'        => true,
69
                          );
70
 
71
        $this->properties['string_quoting'] = array('start' => "'",
72
                                                    'end' => "'",
73
                                                    'escape' => "'",
74
                                                    'escape_pattern' => '\\');
75
 
76
        $this->properties['identifier_quoting'] = array('start' => '"',
77
                                                        'end' => '"',
78
                                                        'escape' => '"');
79
        parent::__construct($manager, $adapter);
80
    }
81
 
82
    /**
83
     * Set the charset on the current connection
84
     *
85
     * @param string    charset
86
     *
87
     * @return void
88
     */
89
    public function setCharset($charset)
90
    {
91
        $query = 'SET NAMES '.$this->quote($charset);
92
        $this->exec($query);
93
        parent::setCharset($charset);
94
    }
95
 
96
    /**
97
     * convertBoolean
98
     * some drivers need the boolean values to be converted into integers
99
     * when using DQL API
100
     *
101
     * This method takes care of that conversion
102
     *
103
     * @param array $item
104
     * @return void
105
     */
106
    public function convertBooleans($item)
107
    {
108
        if (is_array($item)) {
109
            foreach ($item as $key => $value) {
110
                if (is_bool($value)) {
111
                    $item[$key] = ($value) ? 'true' : 'false';
112
                }
113
            }
114
        } else {
115
           if (is_bool($item) || is_numeric($item)) {
116
               $item = ($item) ? 'true' : 'false';
117
           }
118
        }
119
        return $item;
120
    }
121
 
122
    /**
123
     * Changes a query string for various DBMS specific reasons
124
     *
125
     * @param string $query         query to modify
126
     * @param integer $limit        limit the number of rows
127
     * @param integer $offset       start reading from given offset
128
     * @param boolean $isManip      if the query is a DML query
129
     * @return string               modified query
130
     */
131
    public function modifyLimitQuery($query, $limit = false, $offset = false, $isManip = false)
132
    {
133
        if ($limit > 0) {
134
            $query = rtrim($query);
135
 
136
            if (substr($query, -1) == ';') {
137
                $query = substr($query, 0, -1);
138
            }
139
 
140
            if ($isManip) {
141
                $manip = preg_replace('/^(DELETE FROM|UPDATE).*$/', '\\1', $query);
142
                $from  = $match[2];
143
                $where = $match[3];
144
                $query = $manip . ' ' . $from . ' WHERE ctid=(SELECT ctid FROM '
145
                       . $from . ' ' . $where . ' LIMIT ' . (int)$limit . ')';
146
 
147
            } else {
148
                if ( ! empty($limit)) {
149
                  $query .= ' LIMIT ' . (int)$limit;
150
                }
151
                if ( ! empty($offset)) {
152
                  $query .= ' OFFSET ' . (int)$offset;
153
                }
154
            }
155
        }
156
        return $query;
157
    }
158
 
159
    /**
160
     * return version information about the server
161
     *
162
     * @param string $native    determines if the raw version string should be returned
163
     * @return array|string     an array or string with version information
164
     */
165
    public function getServerVersion($native = false)
166
    {
167
        $query = 'SHOW SERVER_VERSION';
168
 
169
        $serverInfo = $this->fetchOne($query);
170
 
171
        if ( ! $native) {
172
            $tmp = explode('.', $serverInfo, 3);
173
 
174
            if (empty($tmp[2]) && isset($tmp[1])
175
                && preg_match('/(\d+)(.*)/', $tmp[1], $tmp2)
176
            ) {
177
                $serverInfo = array(
178
                    'major' => $tmp[0],
179
                    'minor' => $tmp2[1],
180
                    'patch' => null,
181
                    'extra' => $tmp2[2],
182
                    'native' => $serverInfo,
183
                );
184
            } else {
185
                $serverInfo = array(
186
                    'major' => isset($tmp[0]) ? $tmp[0] : null,
187
                    'minor' => isset($tmp[1]) ? $tmp[1] : null,
188
                    'patch' => isset($tmp[2]) ? $tmp[2] : null,
189
                    'extra' => null,
190
                    'native' => $serverInfo,
191
                );
192
            }
193
        }
194
        return $serverInfo;
195
    }
196
 
197
    /**
198
     * Inserts a table row with specified data.
199
     *
200
     * @param Doctrine_Table $table     The table to insert data into.
201
     * @param array $values             An associative array containing column-value pairs.
202
     *                                  Values can be strings or Doctrine_Expression instances.
203
     * @return integer                  the number of affected rows. Boolean false if empty value array was given,
204
     */
205
    public function insert(Doctrine_Table $table, array $fields)
206
    {
207
        $tableName = $table->getTableName();
208
 
209
        // column names are specified as array keys
210
        $cols = array();
211
        // the query VALUES will contain either expresions (eg 'NOW()') or ?
212
        $a = array();
213
 
214
        foreach ($fields as $fieldName => $value) {
215
        	if ($table->isIdentifier($fieldName)
216
        	           && $table->isIdentifierAutoincrement()
217
        	           && $value == null) {
218
        		// Autoincrement fields should not be added to the insert statement
219
        		// if their value is null
220
        		unset($fields[$fieldName]);
221
        		continue;
222
        	}
223
            $cols[] = $this->quoteIdentifier($table->getColumnName($fieldName));
224
            if ($value instanceof Doctrine_Expression) {
225
                $a[] = $value->getSql();
226
                unset($fields[$fieldName]);
227
            } else {
228
                $a[] = '?';
229
            }
230
        }
231
 
232
        if (count($fields) == 0) {
233
        	// Real fix #1786 and #2327 (default values when table is just 'id' as PK)
234
            return $this->exec('INSERT INTO ' . $this->quoteIdentifier($tableName)
235
                              . ' '
236
                              . ' VALUES (DEFAULT)');
237
        }
238
 
239
        // build the statement
240
        $query = 'INSERT INTO ' . $this->quoteIdentifier($tableName)
241
                . ' (' . implode(', ', $cols) . ')'
242
                . ' VALUES (' . implode(', ', $a) . ')';
243
 
244
        return $this->exec($query, array_values($fields));
245
    }
246
}