This file is indexed.

/usr/share/php/Horde/Db/Adapter/Pdo/Pgsql.php is in php-horde-db 2.3.1-1ubuntu2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
<?php
/**
 * Copyright 2007 Maintainable Software, LLC
 * Copyright 2008-2016 Horde LLC (http://www.horde.org/)
 *
 * @author     Mike Naberezny <mike@maintainable.com>
 * @author     Derek DeVries <derek@maintainable.com>
 * @author     Chuck Hagenbuch <chuck@horde.org>
 * @license    http://www.horde.org/licenses/bsd
 * @category   Horde
 * @package    Db
 * @subpackage Adapter
 */

/**
 * PDO_PostgreSQL Horde_Db_Adapter
 *
 * @author     Mike Naberezny <mike@maintainable.com>
 * @author     Derek DeVries <derek@maintainable.com>
 * @author     Chuck Hagenbuch <chuck@horde.org>
 * @license    http://www.horde.org/licenses/bsd
 * @category   Horde
 * @package    Db
 * @subpackage Adapter
 */
class Horde_Db_Adapter_Pdo_Pgsql extends Horde_Db_Adapter_Pdo_Base
{
    /**
     * @var string
     */
    protected $_schemaClass = 'Horde_Db_Adapter_Postgresql_Schema';

    /**
     * @return  string
     */
    public function adapterName()
    {
        return 'PDO_PostgreSQL';
    }

    /**
     * @return  boolean
     */
    public function supportsMigrations()
    {
        return true;
    }

    /**
     * Does PostgreSQL support standard conforming strings?
     * @return  boolean
     */
    public function supportsStandardConformingStrings()
    {
        // Temporarily set the client message level above error to prevent unintentional
        // error messages in the logs when working on a PostgreSQL database server that
        // does not support standard conforming strings.
        $clientMinMessagesOld = $this->getClientMinMessages();
        $this->setClientMinMessages('panic');

        $hasSupport = $this->selectValue('SHOW standard_conforming_strings');

        $this->setClientMinMessages($clientMinMessageOld);
        return $hasSupport;
    }

    public function supportsInsertWithReturning()
    {
        return true;
    }


    /*##########################################################################
    # Connection Management
    ##########################################################################*/

    /**
     * Connect to the db.
     *
     * @throws Horde_Db_Exception
     */
    public function connect()
    {
        if ($this->_active) {
            return;
        }

        parent::connect();

        $this->_lastQuery = $sql = "SET datestyle TO 'iso'";
        $retval = $this->_connection->exec($sql);
        if ($retval === false) {
            $error = $this->_connection->errorInfo();
            throw new Horde_Db_Exception($error[2]);
        }

        $this->_configureConnection();
    }


    /*##########################################################################
    # Database Statements
    ##########################################################################*/

    /**
     * Inserts a row into a table.
     *
     * @param string $sql           SQL statement.
     * @param array|string $arg1    Either an array of bound parameters or a
     *                              query name.
     * @param string $arg2          If $arg1 contains bound parameters, the
     *                              query name.
     * @param string $pk            The primary key column.
     * @param integer $idValue      The primary key value. This parameter is
     *                              required if the primary key is inserted
     *                              manually.
     * @param string $sequenceName  The sequence name.
     *
     * @return integer  Last inserted ID.
     * @throws Horde_Db_Exception
     */
    public function insert($sql, $arg1 = null, $arg2 = null, $pk = null,
                           $idValue = null, $sequenceName = null)
    {
        // Extract the table from the insert sql. Yuck.
        $temp = explode(' ', trim($sql), 4);
        $table = str_replace('"', '', $temp[2]);

        // Try an insert with 'returning id' if available (PG >= 8.2)
        if ($this->supportsInsertWithReturning()) {
            if (!$pk) {
                list($pk, $sequenceName) = $this->pkAndSequenceFor($table);
            }
            if ($pk) {
                $id = $this->selectValue($sql . ' RETURNING ' . $this->quoteColumnName($pk), $arg1, $arg2);
                $this->resetPkSequence($table, $pk, $sequenceName);
                return $id;
            }
        }

        // If neither pk nor sequence name is given, look them up.
        if (!($pk || $sequenceName)) {
            list($pk, $sequenceName) = $this->pkAndSequenceFor($table);
        }

        // Otherwise, insert then grab last_insert_id.
        if ($insertId = parent::insert($sql, $arg1, $arg2, $pk, $idValue, $sequenceName)) {
            $this->resetPkSequence($table, $pk, $sequenceName);
            return $insertId;
        }

        // If a pk is given, fallback to default sequence name.
        // Don't fetch last insert id for a table without a pk.
        if ($pk &&
            ($sequenceName ||
             $sequenceName = $this->defaultSequenceName($table, $pk))) {
            $this->resetPkSequence($table, $pk, $sequenceName);
            return $this->_lastInsertId($table, $sequenceName);
        }
    }

    /**
     * Appends LIMIT and OFFSET options to a SQL statement.
     *
     * @param string $sql     SQL statement.
     * @param array $options  Hash with 'limit' and (optional) 'offset' values.
     *
     * @return string
     */
    public function addLimitOffset($sql, $options)
    {
        if (isset($options['limit']) && $limit = $options['limit']) {
            $sql .= " LIMIT $limit";
        }
        if (isset($options['offset']) && $offset = $options['offset']) {
            $sql .= " OFFSET $offset";
        }
        return $sql;
    }


    /*##########################################################################
    # Protected
    ##########################################################################*/

    /**
     * Parse configuration array into options for PDO constructor.
     *
     * @throws  Horde_Db_Exception
     * @return  array  [dsn, username, password]
     */
    protected function _parseConfig()
    {
        $this->_config['adapter'] = 'pgsql';

        // PDO for PostgreSQL does not accept a socket argument
        // in the connection string; the location can be set via the
        // "host" argument instead.
        if (!empty($this->_config['socket'])) {
            $this->_config['host'] = $this->_config['socket'];
            unset($this->_config['socket']);
        }

        return parent::_parseConfig();
    }

    /**
     * Configures the encoding, verbosity, and schema search path of the connection.
     * This is called by connect() and should not be called manually.
     */
    protected function _configureConnection()
    {
        if (!empty($this->_config['charset'])) {
            $this->_lastQuery = $sql = 'SET client_encoding TO '.$this->quoteString($this->_config['charset']);
            $this->execute($sql);
        }

        if (!empty($this->_config['client_min_messages'])) $this->setClientMinMessages($this->_config['client_min_messages']);
        $this->setSchemaSearchPath(!empty($this->_config['schema_search_path']) || !empty($this->_config['schema_order']));
    }

    /**
     * @TODO
     */
    protected function _selectRaw($sql, $arg1=null, $arg2=null)
    {
        $result = $this->execute($sql, $arg1, $arg2);
        if (!$result) return array();

        $moneyFields = array();
        for ($i = 0, $i_max = $result->columnCount(); $i < $i_max; $i++) {
            $f = $result->getColumnMeta($i);
            if (!empty($f['pgsql:oid']) && $f['pgsql:oid'] == Horde_Db_Adapter_Postgresql_Column::MONEY_COLUMN_TYPE_OID) {
                $moneyFields[] = $i;
                $moneyFields[] = $f['name'];
            }
        }

        foreach ($result as $row) {
            // If this is a money type column and there are any currency
            // symbols, then strip them off. Indeed it would be prettier to do
            // this in Horde_Db_Adapter_Postgres_Column::stringToDecimal but
            // would break form input fields that call valueBeforeTypeCast.
            foreach ($moneyFields as $f) {
                // Because money output is formatted according to the locale, there are two
                // cases to consider (note the decimal separators):
                //  (1) $12,345,678.12
                //  (2) $12.345.678,12
                if (preg_match('/^-?\D+[\d,]+\.\d{2}$/', $row[$f])) { // #1
                    $row[$f] = preg_replace('/[^-\d\.]/', '', $row[$f]) . "\n";
                } elseif (preg_match('/^-?\D+[\d\.]+,\d{2}$/', $row[$f])) { // #2
                    $row[$f] = str_replace(',', '.', preg_replace('/[^-\d,]/', '', $row[$f])) . "\n";
                }
            }
            $rows[] = $row;
        }

        $result->closeCursor();
        return $rows;
    }

    /**
     * Returns the current ID of a table's sequence.
     */
    protected function _lastInsertId($table, $sequenceName)
    {
        return (int)$this->selectValue('SELECT currval('.$this->quoteSequenceName($sequenceName).')');
    }
}