~ubuntu-branches/ubuntu/trusty/fusionforge/trusty

« back to all changes in this revision

Viewing changes to plugins/wiki/www/lib/pear/DB/sqlite.php

  • Committer: Bazaar Package Importer
  • Author(s): Roland Mas
  • Date: 2011-04-15 14:55:34 UTC
  • mfrom: (4.1.10 sid)
  • Revision ID: james.westby@ubuntu.com-20110415145534-mvn1nochufjmw177
Tags: 5.0.3-1
New upstream bugfix release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
 
3
// +----------------------------------------------------------------------+
 
4
// | PHP Version 4                                                        |
 
5
// +----------------------------------------------------------------------+
 
6
// | Copyright (c) 1997-2004 The PHP Group                                |
 
7
// +----------------------------------------------------------------------+
 
8
// | This source file is subject to version 2.02 of the PHP license,      |
 
9
// | that is bundled with this package in the file LICENSE, and is        |
 
10
// | available at through the world-wide-web at                           |
 
11
// | http://www.php.net/license/2_02.txt.                                 |
 
12
// | If you did not receive a copy of the PHP license and are unable to   |
 
13
// | obtain it through the world-wide-web, please send a note to          |
 
14
// | license@php.net so we can mail you a copy immediately.               |
 
15
// +----------------------------------------------------------------------+
 
16
// | Authors: Urs Gehrig <urs@circle.ch>                                  |
 
17
// |          Mika Tuupola <tuupola@appelsiini.net>                       |
 
18
// | Maintainer: Daniel Convissor <danielc@php.net>                       |
 
19
// +----------------------------------------------------------------------+
 
20
//
 
21
// $Id: sqlite.php 6184 2008-08-22 10:33:41Z vargenau $
 
22
 
 
23
require_once 'DB/common.php';
 
24
 
 
25
/**
 
26
 * Database independent query interface definition for the SQLite
 
27
 * PECL extension.
 
28
 *
 
29
 * @package  DB
 
30
 * @version  $Id: sqlite.php 6184 2008-08-22 10:33:41Z vargenau $
 
31
 * @category Database
 
32
 * @author   Urs Gehrig <urs@circle.ch>
 
33
 * @author   Mika Tuupola <tuupola@appelsiini.net>
 
34
 */
 
35
class DB_sqlite extends DB_common
 
36
{
 
37
    // {{{ properties
 
38
 
 
39
    var $connection;
 
40
    var $phptype, $dbsyntax;
 
41
    var $prepare_tokens = array();
 
42
    var $prepare_types = array();
 
43
    var $_lasterror = '';
 
44
 
 
45
    // }}}
 
46
    // {{{ constructor
 
47
 
 
48
    /**
 
49
     * Constructor for this class.
 
50
     *
 
51
     * Error codes according to sqlite_exec.  Error Codes specification is
 
52
     * in the {@link http://sqlite.org/c_interface.html online manual}.
 
53
     *
 
54
     * This errorhandling based on sqlite_exec is not yet implemented.
 
55
     *
 
56
     * @access public
 
57
     */
 
58
    function DB_sqlite()
 
59
    {
 
60
 
 
61
        $this->DB_common();
 
62
        $this->phptype = 'sqlite';
 
63
        $this->dbsyntax = 'sqlite';
 
64
        $this->features = array (
 
65
            'prepare' => false,
 
66
            'pconnect' => true,
 
67
            'transactions' => false,
 
68
            'limit' => 'alter'
 
69
        );
 
70
 
 
71
        // SQLite data types, http://www.sqlite.org/datatypes.html
 
72
        $this->keywords = array (
 
73
            'BLOB'      => '',
 
74
            'BOOLEAN'   => '',
 
75
            'CHARACTER' => '',
 
76
            'CLOB'      => '',
 
77
            'FLOAT'     => '',
 
78
            'INTEGER'   => '',
 
79
            'KEY'       => '',
 
80
            'NATIONAL'  => '',
 
81
            'NUMERIC'   => '',
 
82
            'NVARCHAR'  => '',
 
83
            'PRIMARY'   => '',
 
84
            'TEXT'      => '',
 
85
            'TIMESTAMP' => '',
 
86
            'UNIQUE'    => '',
 
87
            'VARCHAR'   => '',
 
88
            'VARYING'   => ''
 
89
        );
 
90
        $this->errorcode_map = array(
 
91
        );
 
92
    }
 
93
 
 
94
    // }}}
 
95
    // {{{ connect()
 
96
 
 
97
    /**
 
98
     * Connect to a database represented by a file.
 
99
     *
 
100
     * @param $dsn the data source name; the file is taken as
 
101
     *        database; "sqlite://root:@host/test.db?mode=0644"
 
102
     * @param $persistent (optional) whether the connection should
 
103
     *        be persistent
 
104
     * @access public
 
105
     * @return int DB_OK on success, a DB error on failure
 
106
     */
 
107
    function connect($dsninfo, $persistent = false)
 
108
    {
 
109
        if (!DB::assertExtension('sqlite')) {
 
110
            return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
 
111
        }
 
112
 
 
113
        $this->dsn = $dsninfo;
 
114
 
 
115
        if ($dsninfo['database']) {
 
116
            if (!file_exists($dsninfo['database'])) {
 
117
                if (!touch($dsninfo['database'])) {
 
118
                    return $this->sqliteRaiseError(DB_ERROR_NOT_FOUND);
 
119
                }
 
120
                if (!isset($dsninfo['mode']) ||
 
121
                    !is_numeric($dsninfo['mode']))
 
122
                {
 
123
                    $mode = 0644;
 
124
                } else {
 
125
                    $mode = octdec($dsninfo['mode']);
 
126
                }
 
127
                if (!chmod($dsninfo['database'], $mode)) {
 
128
                    return $this->sqliteRaiseError(DB_ERROR_NOT_FOUND);
 
129
                }
 
130
                if (!file_exists($dsninfo['database'])) {
 
131
                    return $this->sqliteRaiseError(DB_ERROR_NOT_FOUND);
 
132
                }
 
133
            }
 
134
            if (!is_file($dsninfo['database'])) {
 
135
                return $this->sqliteRaiseError(DB_ERROR_INVALID);
 
136
            }
 
137
            if (!is_readable($dsninfo['database'])) {
 
138
                return $this->sqliteRaiseError(DB_ERROR_ACCESS_VIOLATION);
 
139
            }
 
140
        } else {
 
141
            return $this->sqliteRaiseError(DB_ERROR_ACCESS_VIOLATION);
 
142
        }
 
143
 
 
144
        $connect_function = $persistent ? 'sqlite_popen' : 'sqlite_open';
 
145
        if (!($conn = @$connect_function($dsninfo['database']))) {
 
146
            return $this->sqliteRaiseError(DB_ERROR_NODBSELECTED);
 
147
        }
 
148
        $this->connection = $conn;
 
149
 
 
150
        return DB_OK;
 
151
    }
 
152
 
 
153
    // }}}
 
154
    // {{{ disconnect()
 
155
 
 
156
    /**
 
157
     * Log out and disconnect from the database.
 
158
     *
 
159
     * @access public
 
160
     * @return bool true on success, false if not connected.
 
161
     * @todo fix return values
 
162
     */
 
163
    function disconnect()
 
164
    {
 
165
        $ret = @sqlite_close($this->connection);
 
166
        $this->connection = null;
 
167
        return $ret;
 
168
    }
 
169
 
 
170
    // }}}
 
171
    // {{{ simpleQuery()
 
172
 
 
173
    /**
 
174
     * Send a query to SQLite and returns the results as a SQLite resource
 
175
     * identifier.
 
176
     *
 
177
     * @param the SQL query
 
178
     * @access public
 
179
     * @return mixed returns a valid SQLite result for successful SELECT
 
180
     * queries, DB_OK for other successful queries. A DB error is
 
181
     * returned on failure.
 
182
     */
 
183
    function simpleQuery($query)
 
184
    {
 
185
        $ismanip = DB::isManip($query);
 
186
        $this->last_query = $query;
 
187
        $query = $this->_modifyQuery($query);
 
188
        @ini_set('track_errors', true);
 
189
        $result = @sqlite_query($query, $this->connection);
 
190
        ini_restore('track_errors');
 
191
        $this->_lasterror = isset($php_errormsg) ? $php_errormsg : '';
 
192
        $this->result = $result;
 
193
        if (!$this->result) {
 
194
            return $this->sqliteRaiseError(null);
 
195
        }
 
196
 
 
197
        /* sqlite_query() seems to allways return a resource */
 
198
        /* so cant use that. Using $ismanip instead          */
 
199
        if (!$ismanip) {
 
200
            $numRows = $this->numRows($result);
 
201
 
 
202
            /* if numRows() returned PEAR_Error */
 
203
            if (is_object($numRows)) {
 
204
                return $numRows;
 
205
            }
 
206
            return $result;
 
207
        }
 
208
        return DB_OK;
 
209
    }
 
210
 
 
211
    // }}}
 
212
    // {{{ nextResult()
 
213
 
 
214
    /**
 
215
     * Move the internal sqlite result pointer to the next available result.
 
216
     *
 
217
     * @param a valid sqlite result resource
 
218
     * @access public
 
219
     * @return true if a result is available otherwise return false
 
220
     */
 
221
    function nextResult($result)
 
222
    {
 
223
        return false;
 
224
    }
 
225
 
 
226
    // }}}
 
227
    // {{{ fetchInto()
 
228
 
 
229
    /**
 
230
     * Fetch a row and insert the data into an existing array.
 
231
     *
 
232
     * Formating of the array and the data therein are configurable.
 
233
     * See DB_result::fetchInto() for more information.
 
234
     *
 
235
     * @param resource $result    query result identifier
 
236
     * @param array    $arr       (reference) array where data from the row
 
237
     *                            should be placed
 
238
     * @param int      $fetchmode how the resulting array should be indexed
 
239
     * @param int      $rownum    the row number to fetch
 
240
     *
 
241
     * @return mixed DB_OK on success, null when end of result set is
 
242
     *               reached or on failure
 
243
     *
 
244
     * @see DB_result::fetchInto()
 
245
     * @access private
 
246
     */
 
247
    function fetchInto($result, &$arr, $fetchmode, $rownum=null)
 
248
    {
 
249
        if ($rownum !== null) {
 
250
            if (!@sqlite_seek($this->result, $rownum)) {
 
251
                return null;
 
252
            }
 
253
        }
 
254
        if ($fetchmode & DB_FETCHMODE_ASSOC) {
 
255
            $arr = @sqlite_fetch_array($result, SQLITE_ASSOC);
 
256
            if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
 
257
                $arr = array_change_key_case($arr, CASE_LOWER);
 
258
            }
 
259
        } else {
 
260
            $arr = @sqlite_fetch_array($result, SQLITE_NUM);
 
261
        }
 
262
        if (!$arr) {
 
263
            /* See: http://bugs.php.net/bug.php?id=22328 */
 
264
            return null;
 
265
        }
 
266
        if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
 
267
            /*
 
268
             * Even though this DBMS already trims output, we do this because
 
269
             * a field might have intentional whitespace at the end that
 
270
             * gets removed by DB_PORTABILITY_RTRIM under another driver.
 
271
             */
 
272
            $this->_rtrimArrayValues($arr);
 
273
        }
 
274
        if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
 
275
            $this->_convertNullArrayValuesToEmpty($arr);
 
276
        }
 
277
        return DB_OK;
 
278
    }
 
279
 
 
280
    // }}}
 
281
    // {{{ freeResult()
 
282
 
 
283
    /**
 
284
     * Free the internal resources associated with $result.
 
285
     *
 
286
     * @param $result SQLite result identifier
 
287
     * @access public
 
288
     * @return bool true on success, false if $result is invalid
 
289
     */
 
290
    function freeResult(&$result)
 
291
    {
 
292
        // XXX No native free?
 
293
        if (!is_resource($result)) {
 
294
            return false;
 
295
        }
 
296
        $result = null;
 
297
        return true;
 
298
    }
 
299
 
 
300
    // }}}
 
301
    // {{{ numCols()
 
302
 
 
303
    /**
 
304
     * Gets the number of columns in a result set.
 
305
     *
 
306
     * @return number of columns in a result set
 
307
     */
 
308
    function numCols($result)
 
309
    {
 
310
        $cols = @sqlite_num_fields($result);
 
311
        if (!$cols) {
 
312
            return $this->sqliteRaiseError();
 
313
        }
 
314
        return $cols;
 
315
    }
 
316
 
 
317
    // }}}
 
318
    // {{{ numRows()
 
319
 
 
320
    /**
 
321
     * Gets the number of rows affected by a query.
 
322
     *
 
323
     * @return number of rows affected by the last query
 
324
     */
 
325
    function numRows($result)
 
326
    {
 
327
        $rows = @sqlite_num_rows($result);
 
328
        if (!is_integer($rows)) {
 
329
            return $this->raiseError();
 
330
        }
 
331
        return $rows;
 
332
    }
 
333
 
 
334
    // }}}
 
335
    // {{{ affected()
 
336
 
 
337
    /**
 
338
     * Gets the number of rows affected by a query.
 
339
     *
 
340
     * @return number of rows affected by the last query
 
341
     */
 
342
    function affectedRows()
 
343
    {
 
344
        return @sqlite_changes($this->connection);
 
345
    }
 
346
 
 
347
    // }}}
 
348
    // {{{ errorNative()
 
349
 
 
350
    /**
 
351
     * Get the native error string of the last error (if any) that
 
352
     * occured on the current connection.
 
353
     *
 
354
     * This is used to retrieve more meaningfull error messages DB_pgsql
 
355
     * way since sqlite_last_error() does not provide adequate info.
 
356
     *
 
357
     * @return string native SQLite error message
 
358
     */
 
359
    function errorNative()
 
360
    {
 
361
        return($this->_lasterror);
 
362
    }
 
363
 
 
364
    // }}}
 
365
    // {{{ errorCode()
 
366
 
 
367
    /**
 
368
     * Determine PEAR::DB error code from the database's text error message.
 
369
     *
 
370
     * @param  string  $errormsg  error message returned from the database
 
371
     * @return integer  an error number from a DB error constant
 
372
     */
 
373
    function errorCode($errormsg)
 
374
    {
 
375
        static $error_regexps;
 
376
        if (!isset($error_regexps)) {
 
377
            $error_regexps = array(
 
378
                '/^no such table:/' => DB_ERROR_NOSUCHTABLE,
 
379
                '/^table .* already exists$/' => DB_ERROR_ALREADY_EXISTS,
 
380
                '/PRIMARY KEY must be unique/i' => DB_ERROR_CONSTRAINT,
 
381
                '/is not unique/' => DB_ERROR_CONSTRAINT,
 
382
                '/uniqueness constraint failed/' => DB_ERROR_CONSTRAINT,
 
383
                '/may not be NULL/' => DB_ERROR_CONSTRAINT_NOT_NULL,
 
384
                '/^no such column:/' => DB_ERROR_NOSUCHFIELD,
 
385
                '/^near ".*": syntax error$/' => DB_ERROR_SYNTAX
 
386
            );
 
387
        }
 
388
        foreach ($error_regexps as $regexp => $code) {
 
389
            if (preg_match($regexp, $errormsg)) {
 
390
                return $code;
 
391
            }
 
392
        }
 
393
        // Fall back to DB_ERROR if there was no mapping.
 
394
        return DB_ERROR;
 
395
    }
 
396
 
 
397
    // }}}
 
398
    // {{{ dropSequence()
 
399
 
 
400
    /**
 
401
     * Deletes a sequence
 
402
     *
 
403
     * @param string $seq_name  name of the sequence to be deleted
 
404
     *
 
405
     * @return int  DB_OK on success.  DB_Error if problems.
 
406
     *
 
407
     * @internal
 
408
     * @see DB_common::dropSequence()
 
409
     * @access public
 
410
     */
 
411
    function dropSequence($seq_name)
 
412
    {
 
413
        $seqname = $this->getSequenceName($seq_name);
 
414
        return $this->query("DROP TABLE $seqname");
 
415
    }
 
416
 
 
417
    /**
 
418
     * Creates a new sequence
 
419
     *
 
420
     * @param string $seq_name  name of the new sequence
 
421
     *
 
422
     * @return int  DB_OK on success.  A DB_Error object is returned if
 
423
     *              problems arise.
 
424
     *
 
425
     * @internal
 
426
     * @see DB_common::createSequence()
 
427
     * @access public
 
428
     */
 
429
    function createSequence($seq_name)
 
430
    {
 
431
        $seqname = $this->getSequenceName($seq_name);
 
432
        $query   = 'CREATE TABLE ' . $seqname .
 
433
                   ' (id INTEGER UNSIGNED PRIMARY KEY) ';
 
434
        $result  = $this->query($query);
 
435
        if (DB::isError($result)) {
 
436
            return($result);
 
437
        }
 
438
        $query   = "CREATE TRIGGER ${seqname}_cleanup AFTER INSERT ON $seqname
 
439
                    BEGIN
 
440
                        DELETE FROM $seqname WHERE id<LAST_INSERT_ROWID();
 
441
                    END ";
 
442
        $result  = $this->query($query);
 
443
        if (DB::isError($result)) {
 
444
            return($result);
 
445
        }
 
446
    }
 
447
 
 
448
    // }}}
 
449
    // {{{ nextId()
 
450
 
 
451
    /**
 
452
     * Returns the next free id in a sequence
 
453
     *
 
454
     * @param string  $seq_name  name of the sequence
 
455
     * @param boolean $ondemand  when true, the seqence is automatically
 
456
     *                           created if it does not exist
 
457
     *
 
458
     * @return int  the next id number in the sequence.  DB_Error if problem.
 
459
     *
 
460
     * @internal
 
461
     * @see DB_common::nextID()
 
462
     * @access public
 
463
     */
 
464
    function nextId($seq_name, $ondemand = true)
 
465
    {
 
466
        $seqname = $this->getSequenceName($seq_name);
 
467
 
 
468
        do {
 
469
            $repeat = 0;
 
470
            $this->pushErrorHandling(PEAR_ERROR_RETURN);
 
471
            $result = $this->query("INSERT INTO $seqname VALUES (NULL)");
 
472
            $this->popErrorHandling();
 
473
            if ($result == DB_OK) {
 
474
                $id = @sqlite_last_insert_rowid($this->connection);
 
475
                if ($id != 0) {
 
476
                    return $id;
 
477
                }
 
478
            } elseif ($ondemand && DB::isError($result) &&
 
479
                      $result->getCode() == DB_ERROR_NOSUCHTABLE)
 
480
            {
 
481
                $result = $this->createSequence($seq_name);
 
482
                if (DB::isError($result)) {
 
483
                    return $this->raiseError($result);
 
484
                } else {
 
485
                    $repeat = 1;
 
486
                }
 
487
            }
 
488
        } while ($repeat);
 
489
 
 
490
        return $this->raiseError($result);
 
491
    }
 
492
 
 
493
    // }}}
 
494
    // {{{ getSpecialQuery()
 
495
 
 
496
    /**
 
497
     * Returns the query needed to get some backend info.
 
498
     *
 
499
     * Refer to the online manual at http://sqlite.org/sqlite.html.
 
500
     *
 
501
     * @param string $type What kind of info you want to retrieve
 
502
     * @return string The SQL query string
 
503
     */
 
504
    function getSpecialQuery($type, $args=array())
 
505
    {
 
506
        if (!is_array($args))
 
507
            return $this->raiseError('no key specified', null, null, null,
 
508
                                     'Argument has to be an array.');
 
509
        switch (strtolower($type)) {
 
510
            case 'master':
 
511
                return 'SELECT * FROM sqlite_master;';
 
512
            case 'tables':
 
513
                return "SELECT name FROM sqlite_master WHERE type='table' "
 
514
                       . 'UNION ALL SELECT name FROM sqlite_temp_master '
 
515
                       . "WHERE type='table' ORDER BY name;";
 
516
            case 'schema':
 
517
                return 'SELECT sql FROM (SELECT * FROM sqlite_master UNION ALL '
 
518
                       . 'SELECT * FROM sqlite_temp_master) '
 
519
                       . "WHERE type!='meta' ORDER BY tbl_name, type DESC, name;";
 
520
            case 'schemax':
 
521
            case 'schema_x':
 
522
                /*
 
523
                 * Use like:
 
524
                 * $res = $db->query($db->getSpecialQuery('schema_x', array('table' => 'table3')));
 
525
                 */
 
526
                return 'SELECT sql FROM (SELECT * FROM sqlite_master UNION ALL '
 
527
                       . 'SELECT * FROM sqlite_temp_master) '
 
528
                       . "WHERE tbl_name LIKE '{$args['table']}' AND type!='meta' "
 
529
                       . 'ORDER BY type DESC, name;';
 
530
            case 'alter':
 
531
                /*
 
532
                 * SQLite does not support ALTER TABLE; this is a helper query
 
533
                 * to handle this. 'table' represents the table name, 'rows'
 
534
                 * the news rows to create, 'save' the row(s) to keep _with_
 
535
                 * the data.
 
536
                 *
 
537
                 * Use like:
 
538
                 * $args = array(
 
539
                 *     'table' => $table,
 
540
                 *     'rows'  => "id INTEGER PRIMARY KEY, firstname TEXT, surname TEXT, datetime TEXT",
 
541
                 *     'save'  => "NULL, titel, content, datetime"
 
542
                 * );
 
543
                 * $res = $db->query( $db->getSpecialQuery('alter', $args));
 
544
                 */
 
545
                $rows = strtr($args['rows'], $this->keywords);
 
546
 
 
547
                $q = array(
 
548
                    'BEGIN TRANSACTION',
 
549
                    "CREATE TEMPORARY TABLE {$args['table']}_backup ({$args['rows']})",
 
550
                    "INSERT INTO {$args['table']}_backup SELECT {$args['save']} FROM {$args['table']}",
 
551
                    "DROP TABLE {$args['table']}",
 
552
                    "CREATE TABLE {$args['table']} ({$args['rows']})",
 
553
                    "INSERT INTO {$args['table']} SELECT {$rows} FROM {$args['table']}_backup",
 
554
                    "DROP TABLE {$args['table']}_backup",
 
555
                    'COMMIT',
 
556
                );
 
557
 
 
558
                // This is a dirty hack, since the above query will no get executed with a single
 
559
                // query call; so here the query method will be called directly and return a select instead.
 
560
                foreach ($q as $query) {
 
561
                    $this->query($query);
 
562
                }
 
563
                return "SELECT * FROM {$args['table']};";
 
564
            default:
 
565
                return null;
 
566
        }
 
567
    }
 
568
 
 
569
    // }}}
 
570
    // {{{ getDbFileStats()
 
571
 
 
572
    /**
 
573
     * Get the file stats for the current database.
 
574
     *
 
575
     * Possible arguments are dev, ino, mode, nlink, uid, gid, rdev, size,
 
576
     * atime, mtime, ctime, blksize, blocks or a numeric key between
 
577
     * 0 and 12.
 
578
     *
 
579
     * @param string $arg Array key for stats()
 
580
     * @return mixed array on an unspecified key, integer on a passed arg and
 
581
     * false at a stats error.
 
582
     */
 
583
    function getDbFileStats($arg = '')
 
584
    {
 
585
        $stats = stat($this->dsn['database']);
 
586
        if ($stats == false) {
 
587
            return false;
 
588
        }
 
589
        if (is_array($stats)) {
 
590
            if (is_numeric($arg)) {
 
591
                if (((int)$arg <= 12) & ((int)$arg >= 0)) {
 
592
                    return false;
 
593
                }
 
594
                return $stats[$arg ];
 
595
            }
 
596
            if (array_key_exists(trim($arg), $stats)) {
 
597
                return $stats[$arg ];
 
598
            }
 
599
        }
 
600
        return $stats;
 
601
    }
 
602
 
 
603
    // }}}
 
604
    // {{{ escapeSimple()
 
605
 
 
606
    /**
 
607
     * Escape a string according to the current DBMS's standards
 
608
     *
 
609
     * In SQLite, this makes things safe for inserts/updates, but may
 
610
     * cause problems when performing text comparisons against columns
 
611
     * containing binary data. See the
 
612
     * {@link http://php.net/sqlite_escape_string PHP manual} for more info.
 
613
     *
 
614
     * @param string $str  the string to be escaped
 
615
     *
 
616
     * @return string  the escaped string
 
617
     *
 
618
     * @since 1.6.1
 
619
     * @see DB_common::escapeSimple()
 
620
     * @internal
 
621
     */
 
622
    function escapeSimple($str) {
 
623
        return @sqlite_escape_string($str);
 
624
    }
 
625
 
 
626
    // }}}
 
627
    // {{{ modifyLimitQuery()
 
628
 
 
629
    function modifyLimitQuery($query, $from, $count)
 
630
    {
 
631
        $query = $query . " LIMIT $count OFFSET $from";
 
632
        return $query;
 
633
    }
 
634
 
 
635
    // }}}
 
636
    // {{{ modifyQuery()
 
637
 
 
638
    /**
 
639
     * "DELETE FROM table" gives 0 affected rows in SQLite.
 
640
     *
 
641
     * This little hack lets you know how many rows were deleted.
 
642
     *
 
643
     * @param string $query The SQL query string
 
644
     * @return string The SQL query string
 
645
     */
 
646
    function _modifyQuery($query)
 
647
    {
 
648
        if ($this->options['portability'] & DB_PORTABILITY_DELETE_COUNT) {
 
649
            if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $query)) {
 
650
                $query = preg_replace('/^\s*DELETE\s+FROM\s+(\S+)\s*$/',
 
651
                                      'DELETE FROM \1 WHERE 1=1', $query);
 
652
            }
 
653
        }
 
654
        return $query;
 
655
    }
 
656
 
 
657
    // }}}
 
658
    // {{{ sqliteRaiseError()
 
659
 
 
660
    /**
 
661
     * Gather information about an error, then use that info to create a
 
662
     * DB error object and finally return that object.
 
663
     *
 
664
     * @param  integer  $errno  PEAR error number (usually a DB constant) if
 
665
     *                          manually raising an error
 
666
     * @return object  DB error object
 
667
     * @see errorNative()
 
668
     * @see errorCode()
 
669
     * @see DB_common::raiseError()
 
670
     */
 
671
    function sqliteRaiseError($errno = null)
 
672
    {
 
673
 
 
674
        $native = $this->errorNative();
 
675
        if ($errno === null) {
 
676
            $errno = $this->errorCode($native);
 
677
        }
 
678
 
 
679
        $errorcode = @sqlite_last_error($this->connection);
 
680
        $userinfo = "$errorcode ** $this->last_query";
 
681
 
 
682
        return $this->raiseError($errno, null, null, $userinfo, $native);
 
683
    }
 
684
 
 
685
    // }}}
 
686
}
 
687
 
 
688
/*
 
689
 * Local variables:
 
690
 * tab-width: 4
 
691
 * c-basic-offset: 4
 
692
 * End:
 
693
 */
 
694
 
 
695
?>