xref: /plugin/sqlite/helper.php (revision b122d121ac9604bc3e513ddbbd2c62082e8f752e)
1a1e6784eSAndreas Gohr<?php
2a1e6784eSAndreas Gohr/**
3a1e6784eSAndreas Gohr * DokuWiki Plugin sqlite (Helper Component)
4a1e6784eSAndreas Gohr *
5a1e6784eSAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6a1e6784eSAndreas Gohr * @author  Andreas Gohr <gohr@cosmocode.de>
7a1e6784eSAndreas Gohr */
8a1e6784eSAndreas Gohr
9a1e6784eSAndreas Gohr// must be run within Dokuwiki
10a1e6784eSAndreas Gohrif(!defined('DOKU_INC')) die();
11a1e6784eSAndreas Gohr
1287fa2c18Sstretchyboyif(!defined('DOKU_EXT_SQLITE')) define('DOKU_EXT_SQLITE', 'sqlite');
1387fa2c18Sstretchyboyif(!defined('DOKU_EXT_PDO')) define('DOKU_EXT_PDO', 'pdo');
14c137e95fSAndreas Gohrif(!defined('DOKU_EXT_NULL')) define('DOKU_EXT_NULL', 'null');
1587fa2c18Sstretchyboy
16aa81d781SKlap-inrequire_once(DOKU_PLUGIN.'sqlite/classes/adapter.php');
1787fa2c18Sstretchyboy
18a1e6784eSAndreas Gohrclass helper_plugin_sqlite extends DokuWiki_Plugin {
19aa81d781SKlap-in    var $adapter = null;
20aa81d781SKlap-in
21ca2f2adaSKlap-in    public function getAdapter() {
22ca2f2adaSKlap-in        return $this->adapter;
23ca2f2adaSKlap-in    }
24ca2f2adaSKlap-in
25a1e6784eSAndreas Gohr    /**
26aa81d781SKlap-in     * Keep separate instances for every call to keep database connections
27aa81d781SKlap-in     */
28aa81d781SKlap-in    public function isSingleton() {
29aa81d781SKlap-in        return false;
30aa81d781SKlap-in    }
31aa81d781SKlap-in
32aa81d781SKlap-in    /**
33a1e6784eSAndreas Gohr     * constructor
34a1e6784eSAndreas Gohr     */
35aa81d781SKlap-in    public function helper_plugin_sqlite() {
3687fa2c18Sstretchyboy
3713896259SKlap-in        if(!$this->adapter) {
38b0653a7eSAndreas Gohr            if($this->existsPDOSqlite() && empty($_ENV['SQLITE_SKIP_PDO'])) {
39aa81d781SKlap-in                require_once(DOKU_PLUGIN.'sqlite/classes/adapter_pdosqlite.php');
40aa81d781SKlap-in                $this->adapter = new helper_plugin_sqlite_adapter_pdosqlite();
41aa81d781SKlap-in            }
42aa81d781SKlap-in        }
43aa81d781SKlap-in
4413896259SKlap-in        if(!$this->adapter) {
45aa81d781SKlap-in            if($this->existsSqlite2()) {
46aa81d781SKlap-in                require_once(DOKU_PLUGIN.'sqlite/classes/adapter_sqlite2.php');
47aa81d781SKlap-in                $this->adapter = new helper_plugin_sqlite_adapter_sqlite2();
48aa81d781SKlap-in            }
49aa81d781SKlap-in        }
50aa81d781SKlap-in
5113896259SKlap-in        if(!$this->adapter) {
52aa81d781SKlap-in            msg('SQLite & PDO SQLite support missing in this PHP install - plugin will not work', -1);
53aa81d781SKlap-in        }
54aa81d781SKlap-in    }
55aa81d781SKlap-in
56aa81d781SKlap-in    /**
57aa81d781SKlap-in     * check availabilty of PHPs sqlite extension (for sqlite2 support)
58aa81d781SKlap-in     */
59aa81d781SKlap-in    public function existsSqlite2() {
60aa81d781SKlap-in        if(!extension_loaded('sqlite')) {
61aa81d781SKlap-in            $prefix = (PHP_SHLIB_SUFFIX === 'dll') ? 'php_' : '';
62aa81d781SKlap-in            if(function_exists('dl')) @dl($prefix.'sqlite.'.PHP_SHLIB_SUFFIX);
63aa81d781SKlap-in        }
64aa81d781SKlap-in
65aa81d781SKlap-in        return function_exists('sqlite_open');
66aa81d781SKlap-in    }
67aa81d781SKlap-in
68aa81d781SKlap-in    /**
69aa81d781SKlap-in     * check availabilty of PHP PDO sqlite3
70aa81d781SKlap-in     */
71aa81d781SKlap-in    public function existsPDOSqlite() {
7287fa2c18Sstretchyboy        if(!extension_loaded('pdo_sqlite')) {
7387fa2c18Sstretchyboy            $prefix = (PHP_SHLIB_SUFFIX === 'dll') ? 'php_' : '';
7487fa2c18Sstretchyboy            if(function_exists('dl')) @dl($prefix.'pdo_sqlite.'.PHP_SHLIB_SUFFIX);
7587fa2c18Sstretchyboy        }
7687fa2c18Sstretchyboy
7787fa2c18Sstretchyboy        if(class_exists('pdo')) {
78aa81d781SKlap-in            foreach(PDO::getAvailableDrivers() as $driver) {
79aa81d781SKlap-in                if($driver == 'sqlite') {
80aa81d781SKlap-in                    return true;
8187fa2c18Sstretchyboy                }
8287fa2c18Sstretchyboy            }
837ed6069fSAdrian Lang        }
84aa81d781SKlap-in        return false;
85a1e6784eSAndreas Gohr    }
86a1e6784eSAndreas Gohr
87a1e6784eSAndreas Gohr    /**
88a1e6784eSAndreas Gohr     * Initializes and opens the database
89a1e6784eSAndreas Gohr     *
90a1e6784eSAndreas Gohr     * Needs to be called right after loading this helper plugin
91aa81d781SKlap-in     *
92aa81d781SKlap-in     * @param string $dbname
93aa81d781SKlap-in     * @param string $updatedir - Database update infos
94aa81d781SKlap-in     * @return bool
95a1e6784eSAndreas Gohr     */
96aa81d781SKlap-in    public function init($dbname, $updatedir) {
97aa81d781SKlap-in        $init = null; // set by initdb()
98c137e95fSAndreas Gohr        if( !$this->adapter or !$this->adapter->initdb($dbname, $init) ){
99c137e95fSAndreas Gohr            require_once(DOKU_PLUGIN.'sqlite/classes/adapter_null.php');
100c137e95fSAndreas Gohr            $this->adapter = new helper_plugin_sqlite_adapter_null();
101c137e95fSAndreas Gohr            return false;
102c137e95fSAndreas Gohr        }
103a1e6784eSAndreas Gohr
104aa81d781SKlap-in        return $this->_updatedb($init, $updatedir);
105a1e6784eSAndreas Gohr    }
106a1e6784eSAndreas Gohr
107a1e6784eSAndreas Gohr    /**
108a1e6784eSAndreas Gohr     * Return the current Database Version
109a1e6784eSAndreas Gohr     */
110aa81d781SKlap-in    private function _currentDBversion() {
111a1e6784eSAndreas Gohr        $sql = "SELECT val FROM opts WHERE opt = 'dbversion';";
112a1e6784eSAndreas Gohr        $res = $this->query($sql);
113a1e6784eSAndreas Gohr        if(!$res) return false;
114a1e6784eSAndreas Gohr        $row = $this->res2row($res, 0);
115a1e6784eSAndreas Gohr        return (int) $row['val'];
116a1e6784eSAndreas Gohr    }
117aa81d781SKlap-in
118a1e6784eSAndreas Gohr    /**
119a1e6784eSAndreas Gohr     * Update the database if needed
120a1e6784eSAndreas Gohr     *
121a1e6784eSAndreas Gohr     * @param bool   $init      - true if this is a new database to initialize
122a1e6784eSAndreas Gohr     * @param string $updatedir - Database update infos
123aa81d781SKlap-in     * @return bool
124a1e6784eSAndreas Gohr     */
12513896259SKlap-in    private function _updatedb($init, $updatedir) {
126a1e6784eSAndreas Gohr        if($init) {
1274d9093b4Sstretchyboy
128a1e6784eSAndreas Gohr            $current = 0;
129a1e6784eSAndreas Gohr        } else {
130a1e6784eSAndreas Gohr            $current = $this->_currentDBversion();
131a1e6784eSAndreas Gohr            if(!$current) {
132aa81d781SKlap-in                msg("SQLite: no DB version found. '".$this->adapter->getDbname()."' DB probably broken.", -1);
133a1e6784eSAndreas Gohr                return false;
134a1e6784eSAndreas Gohr            }
135a1e6784eSAndreas Gohr        }
136a1e6784eSAndreas Gohr
137a1e6784eSAndreas Gohr        // in case of init, add versioning table
138a1e6784eSAndreas Gohr        if($init) {
139a1e6784eSAndreas Gohr            if(!$this->_runupdatefile(dirname(__FILE__).'/db.sql', 0)) {
140aa81d781SKlap-in                msg("SQLite: '".$this->adapter->getDbname()."' database upgrade failed for version ", -1);
141a1e6784eSAndreas Gohr                return false;
142a1e6784eSAndreas Gohr            }
143a1e6784eSAndreas Gohr        }
144a1e6784eSAndreas Gohr
145a1e6784eSAndreas Gohr        $latest = (int) trim(io_readFile($updatedir.'/latest.version'));
146a1e6784eSAndreas Gohr
147a1e6784eSAndreas Gohr        // all up to date?
148a1e6784eSAndreas Gohr        if($current >= $latest) return true;
149a1e6784eSAndreas Gohr        for($i = $current + 1; $i <= $latest; $i++) {
150a1e6784eSAndreas Gohr            $file = sprintf($updatedir.'/update%04d.sql', $i);
151a1e6784eSAndreas Gohr            if(file_exists($file)) {
152a1e6784eSAndreas Gohr                if(!$this->_runupdatefile($file, $i)) {
153aa81d781SKlap-in                    msg("SQLite: '".$this->adapter->getDbname()."' database upgrade failed for version ".$i, -1);
154a1e6784eSAndreas Gohr                    return false;
155a1e6784eSAndreas Gohr                }
156a1e6784eSAndreas Gohr            }
157a1e6784eSAndreas Gohr        }
158a1e6784eSAndreas Gohr        return true;
159a1e6784eSAndreas Gohr    }
160a1e6784eSAndreas Gohr
161a1e6784eSAndreas Gohr    /**
162a1e6784eSAndreas Gohr     * Updates the database structure using the given file to
163a1e6784eSAndreas Gohr     * the given version.
164a1e6784eSAndreas Gohr     */
165aa81d781SKlap-in    private function _runupdatefile($file, $version) {
166a1e6784eSAndreas Gohr        $sql = io_readFile($file, false);
167a1e6784eSAndreas Gohr
168f10ea6c1SKlap-in        $sql = $this->SQLstring2array($sql);
169a1e6784eSAndreas Gohr        array_unshift($sql, 'BEGIN TRANSACTION');
170a1e6784eSAndreas Gohr        array_push($sql, "INSERT OR REPLACE INTO opts (val,opt) VALUES ($version,'dbversion')");
171a1e6784eSAndreas Gohr        array_push($sql, "COMMIT TRANSACTION");
172a1e6784eSAndreas Gohr
173f10ea6c1SKlap-in        if(!$this->doTransaction($sql)) {
174f10ea6c1SKlap-in            return false;
175f10ea6c1SKlap-in        }
176f10ea6c1SKlap-in        return ($version == $this->_currentDBversion());
177f10ea6c1SKlap-in    }
178f10ea6c1SKlap-in
179f10ea6c1SKlap-in    /**
180f10ea6c1SKlap-in     * Split sql queries on semicolons, unless when semicolons are quoted
181f10ea6c1SKlap-in     *
182f10ea6c1SKlap-in     * @param string $sql
183f10ea6c1SKlap-in     * @return array sql queries
184f10ea6c1SKlap-in     */
185f10ea6c1SKlap-in    public function SQLstring2array($sql) {
1863fb592daSAndreas Gohr        $statements = array();
1873fb592daSAndreas Gohr        $len = strlen($sql);
1883fb592daSAndreas Gohr
1893fb592daSAndreas Gohr        // Simple state machine to "parse" sql into single statements
1903fb592daSAndreas Gohr        $in_str = false;
1913fb592daSAndreas Gohr        $in_com = false;
1923fb592daSAndreas Gohr        $statement = '';
1933fb592daSAndreas Gohr        for($i=0; $i<$len; $i++){
1943fb592daSAndreas Gohr            $prev = $i ? $sql{$i-1} : "\n";
1953fb592daSAndreas Gohr            $char = $sql{$i};
1963fb592daSAndreas Gohr            $next = $sql{$i+1};
1973fb592daSAndreas Gohr
1983fb592daSAndreas Gohr            // in comment? ignore everything until line end
1993fb592daSAndreas Gohr            if($in_com){
2003fb592daSAndreas Gohr                if($char == "\n"){
2013fb592daSAndreas Gohr                    $in_com = false;
2023fb592daSAndreas Gohr                }
2033fb592daSAndreas Gohr                continue;
2043fb592daSAndreas Gohr            }
2053fb592daSAndreas Gohr
2063fb592daSAndreas Gohr            // handle strings
2073fb592daSAndreas Gohr            if($in_str){
2085922cb27SAndreas Gohr                if($char == "'"){
2095922cb27SAndreas Gohr                    if($next == "'"){
2105922cb27SAndreas Gohr                        // current char is an escape for the next
2113fb592daSAndreas Gohr                        $statement .= $char . $next;
2123fb592daSAndreas Gohr                        $i++;
2133fb592daSAndreas Gohr                        continue;
2145922cb27SAndreas Gohr                    }else{
2155922cb27SAndreas Gohr                        // end of string
2163fb592daSAndreas Gohr                        $statement .= $char;
2173fb592daSAndreas Gohr                        $in_str = false;
2183fb592daSAndreas Gohr                        continue;
2193fb592daSAndreas Gohr                    }
2205922cb27SAndreas Gohr                }
2213fb592daSAndreas Gohr                // still in string
2223fb592daSAndreas Gohr                $statement .= $char;
2233fb592daSAndreas Gohr                continue;
2243fb592daSAndreas Gohr            }
2253fb592daSAndreas Gohr
2263fb592daSAndreas Gohr            // new comment?
2273fb592daSAndreas Gohr            if($char == '-' && $next == '-' && $prev == "\n"){
2283fb592daSAndreas Gohr                $in_com = true;
2293fb592daSAndreas Gohr                continue;
2303fb592daSAndreas Gohr            }
2313fb592daSAndreas Gohr
2323fb592daSAndreas Gohr            // new string?
2335922cb27SAndreas Gohr            if($char == "'"){
2345922cb27SAndreas Gohr                $in_str = true;
2353fb592daSAndreas Gohr                $statement .= $char;
2363fb592daSAndreas Gohr                continue;
2373fb592daSAndreas Gohr            }
2383fb592daSAndreas Gohr
2393fb592daSAndreas Gohr            // the real delimiter
2403fb592daSAndreas Gohr            if($char == ';'){
2413fb592daSAndreas Gohr                $statements[] = trim($statement);
2423fb592daSAndreas Gohr                $statement = '';
2433fb592daSAndreas Gohr                continue;
2443fb592daSAndreas Gohr            }
2453fb592daSAndreas Gohr
2463fb592daSAndreas Gohr            // some standard query stuff
2473fb592daSAndreas Gohr            $statement .= $char;
2483fb592daSAndreas Gohr        }
2493fb592daSAndreas Gohr        if($statement) $statements[] = trim($statement);
2503fb592daSAndreas Gohr
2513fb592daSAndreas Gohr        return $statements;
252f10ea6c1SKlap-in    }
253f10ea6c1SKlap-in
254f10ea6c1SKlap-in    /**
255f10ea6c1SKlap-in     * @param array $sql queries without terminating semicolon
256f10ea6c1SKlap-in     * @param bool  $sqlpreparing
257f10ea6c1SKlap-in     * @return bool
258f10ea6c1SKlap-in     */
259f10ea6c1SKlap-in    public function doTransaction($sql, $sqlpreparing = true) {
260a1e6784eSAndreas Gohr        foreach($sql as $s) {
261a1e6784eSAndreas Gohr            $s = preg_replace('!^\s*--.*$!m', '', $s);
262a1e6784eSAndreas Gohr            $s = trim($s);
263a1e6784eSAndreas Gohr            if(!$s) continue;
264fd69a32cSAndreas Gohr
265f10ea6c1SKlap-in            if($sqlpreparing) {
266a1e6784eSAndreas Gohr                $res = $this->query("$s;");
267f10ea6c1SKlap-in            } else {
268f10ea6c1SKlap-in                $res = $this->adapter->executeQuery("$s;");
269f10ea6c1SKlap-in            }
270a1e6784eSAndreas Gohr            if($res === false) {
271f10ea6c1SKlap-in                //TODO check rollback for sqlite PDO
27213896259SKlap-in                if($this->adapter->getName() == DOKU_EXT_SQLITE) {
2731dc19626SKlap-in                    $this->query('ROLLBACK TRANSACTION');
274a1e6784eSAndreas Gohr                }
27505f176edSstretchyboy                return false;
27605f176edSstretchyboy            }
277a1e6784eSAndreas Gohr        }
278f10ea6c1SKlap-in        return true;
279a1e6784eSAndreas Gohr    }
280a1e6784eSAndreas Gohr
281a34ef333SKlap-in    /**
282a34ef333SKlap-in     * Dump db into a file in meta directory
283a34ef333SKlap-in     *
284a34ef333SKlap-in     */
285a34ef333SKlap-in    public function dumpDatabase($dbname, $from = DOKU_EXT_SQLITE) {
286a34ef333SKlap-in        global $conf;
287a34ef333SKlap-in        $adapterDumpDb = null;
288a34ef333SKlap-in        //connect to desired database
289a34ef333SKlap-in        if($this->adapter->getName() == $from) {
290a34ef333SKlap-in            $adapterDumpDb =& $this->adapter;
291a34ef333SKlap-in        } else {
292a34ef333SKlap-in            if($from == DOKU_EXT_SQLITE) {
293a34ef333SKlap-in                //TODO test connecting to sqlite2 database
294a34ef333SKlap-in                if($this->existsSqlite2()) {
295a34ef333SKlap-in                    require_once(DOKU_PLUGIN.'sqlite/classes/adapter_sqlite2.php');
296a34ef333SKlap-in                    $adapterDumpDb = new helper_plugin_sqlite_adapter_sqlite2();
297a34ef333SKlap-in                } else {
298a34ef333SKlap-in                    msg('PHP Sqlite Extension(needed for sqlite2) not available, database "'.hsc($dbname).'" is not dumped to file.');
299a34ef333SKlap-in                    return false;
300a34ef333SKlap-in                }
301a34ef333SKlap-in            }
302a34ef333SKlap-in        }
303a34ef333SKlap-in        if($adapterDumpDb === null) {
304a34ef333SKlap-in            msg('No adapter loaded');
305a34ef333SKlap-in            return false;
306a34ef333SKlap-in        }
307a34ef333SKlap-in        $init = false;
308a34ef333SKlap-in        if(!$adapterDumpDb->initdb($dbname, $init)) {
309a34ef333SKlap-in            msg('Opening database fails.', -1);
310a34ef333SKlap-in            return false;
311a34ef333SKlap-in        }
312f10ea6c1SKlap-in
313a34ef333SKlap-in        $res    = $adapterDumpDb->query(array("SELECT name,sql FROM sqlite_master WHERE type='table'"));
314a34ef333SKlap-in        $tables = $adapterDumpDb->res2arr($res);
315a34ef333SKlap-in
316a34ef333SKlap-in        $filename = $conf['metadir'].'/dumpfile_'.$dbname.'.sql';
317a34ef333SKlap-in        if($fp = fopen($filename, 'w')) {
318a34ef333SKlap-in
319a34ef333SKlap-in            fwrite($fp, 'BEGIN TRANSACTION;'."\n");
320a34ef333SKlap-in
321a34ef333SKlap-in            foreach($tables as $table) {
322a34ef333SKlap-in
323a34ef333SKlap-in                fwrite($fp, $table['sql'].";\n");
324a34ef333SKlap-in
325a34ef333SKlap-in                $sql = "SELECT * FROM ".$table['name'];
326a34ef333SKlap-in                $res = $adapterDumpDb->query(array($sql));
327a34ef333SKlap-in
328a34ef333SKlap-in                while($row = $adapterDumpDb->res_fetch_array($res)) {
329a34ef333SKlap-in
330a34ef333SKlap-in                    $line = 'INSERT INTO '.$table['name'].' VALUES(';
331a34ef333SKlap-in                    foreach($row as $no_entry => $entry) {
332a34ef333SKlap-in                        if($no_entry !== 0) {
333a34ef333SKlap-in                            $line .= ',';
334a34ef333SKlap-in                        }
335a34ef333SKlap-in
336a34ef333SKlap-in                        if(is_null($entry)) {
337a34ef333SKlap-in                            $line .= 'NULL';
338a34ef333SKlap-in                        } elseif(!is_numeric($entry)) {
339a34ef333SKlap-in                            $line .= $adapterDumpDb->quote_string($entry);
340a34ef333SKlap-in                        } else {
341a34ef333SKlap-in                            //TODO depending on locale extra leading zeros are truncated e.g 1.300 (thousand three hunderd)-> 1.3
342a34ef333SKlap-in                            $line .= $entry;
343a34ef333SKlap-in                        }
344a34ef333SKlap-in                    }
345a34ef333SKlap-in                    $line .= ');'."\n";
346a34ef333SKlap-in
347a34ef333SKlap-in                    fwrite($fp, $line);
348a34ef333SKlap-in                }
349a34ef333SKlap-in            }
350a34ef333SKlap-in
351a34ef333SKlap-in            $res     = $adapterDumpDb->query(array("SELECT name,sql FROM sqlite_master WHERE type='index'"));
352a34ef333SKlap-in            $indexes = $adapterDumpDb->res2arr($res);
353a34ef333SKlap-in            foreach($indexes as $index) {
354a34ef333SKlap-in                fwrite($fp, $index['sql'].";\n");
355a34ef333SKlap-in            }
356a34ef333SKlap-in
357a34ef333SKlap-in            fwrite($fp, 'COMMIT;'."\n");
358a34ef333SKlap-in
359a34ef333SKlap-in            fclose($fp);
360a34ef333SKlap-in            return $filename;
361a34ef333SKlap-in        } else {
362a34ef333SKlap-in            msg('Dumping "'.hsc($dbname).'" has failed. Could not open '.$filename);
363a34ef333SKlap-in            return false;
364a34ef333SKlap-in        }
365a34ef333SKlap-in    }
366a34ef333SKlap-in
367a34ef333SKlap-in    /**
368a34ef333SKlap-in     * Read $dumpfile and try to add it to database.
369a34ef333SKlap-in     * A existing database is backuped first as e.g. dbname.copy2.sqlite3
370a34ef333SKlap-in     *
371a34ef333SKlap-in     * @param string $dbname
372a34ef333SKlap-in     * @param string $dumpfile
373a34ef333SKlap-in     * @return bool true on succes
374a34ef333SKlap-in     */
375a34ef333SKlap-in    public function fillDatabaseFromDump($dbname, $dumpfile) {
376a34ef333SKlap-in        global $conf;
377a34ef333SKlap-in        //backup existing stuff
378a34ef333SKlap-in        $dbf    = $conf['metadir'].'/'.$dbname;
379a34ef333SKlap-in        $dbext  = $this->adapter->getFileextension();
380a34ef333SKlap-in        $dbfile = $dbf.$dbext;
381a34ef333SKlap-in        if(@file_exists($dbfile)) {
382a34ef333SKlap-in
383a34ef333SKlap-in            $i            = 0;
384a34ef333SKlap-in            $backupdbfile = $dbfile;
385a34ef333SKlap-in            do {
386a34ef333SKlap-in                $i++;
387a34ef333SKlap-in                $backupdbfile = $dbf.".copy$i".$dbext;
388a34ef333SKlap-in            } while(@file_exists($backupdbfile));
389a34ef333SKlap-in
390a34ef333SKlap-in            io_rename($dbfile, $backupdbfile);
391a34ef333SKlap-in        }
392a34ef333SKlap-in
393a34ef333SKlap-in        $init = false;
394a34ef333SKlap-in        if(!$this->adapter->initdb($dbname, $init, $sqliteupgrade = true)) {
395a34ef333SKlap-in            msg('Initialize db fails');
396a34ef333SKlap-in            return false;
397a34ef333SKlap-in        }
398a34ef333SKlap-in
399a34ef333SKlap-in        $sql = io_readFile($dumpfile, false);
400a34ef333SKlap-in        $sql = $this->SQLstring2array($sql);
401a34ef333SKlap-in
402a34ef333SKlap-in        //skip preparing, because it interprets question marks as placeholders.
403a34ef333SKlap-in        return $this->doTransaction($sql, $sqlpreparing = false);
404a34ef333SKlap-in    }
405f10ea6c1SKlap-in
406a1e6784eSAndreas Gohr    /**
4073ae3f79eSKlap-in     * Registers a User Defined Function for use in SQL statements
4083ae3f79eSKlap-in     */
409aa81d781SKlap-in    public function create_function($function_name, $callback, $num_args) {
410aa81d781SKlap-in        $this->adapter->create_function($function_name, $callback, $num_args);
4113ae3f79eSKlap-in    }
4123ae3f79eSKlap-in
4133ae3f79eSKlap-in    /**
414a1e6784eSAndreas Gohr     * Execute a query with the given parameters.
415a1e6784eSAndreas Gohr     *
416a1e6784eSAndreas Gohr     * Takes care of escaping
417a1e6784eSAndreas Gohr     *
418aa81d781SKlap-in     * @internal param string $sql - the statement
419aa81d781SKlap-in     * @internal param $arguments ...
420aa81d781SKlap-in     * @return bool|\SQLiteResult
421a1e6784eSAndreas Gohr     */
422aa81d781SKlap-in    public function query() {
423a1e6784eSAndreas Gohr        // get function arguments
424a1e6784eSAndreas Gohr        $args = func_get_args();
425a1e6784eSAndreas Gohr
426aa81d781SKlap-in        return $this->adapter->query($args);
42787fa2c18Sstretchyboy    }
428a1e6784eSAndreas Gohr
429a1e6784eSAndreas Gohr    /**
430a1e6784eSAndreas Gohr     * Join the given values and quote them for SQL insertion
431a1e6784eSAndreas Gohr     */
432aa81d781SKlap-in    public function quote_and_join($vals, $sep = ',') {
433aa81d781SKlap-in        return $this->adapter->quote_and_join($vals, $sep);
434a1e6784eSAndreas Gohr    }
435a1e6784eSAndreas Gohr
436a1e6784eSAndreas Gohr    /**
437a1e6784eSAndreas Gohr     * Run sqlite_escape_string() on the given string and surround it
438a1e6784eSAndreas Gohr     * with quotes
439a1e6784eSAndreas Gohr     */
440aa81d781SKlap-in    public function quote_string($string) {
441aa81d781SKlap-in        return $this->adapter->quote_string($string);
442a1e6784eSAndreas Gohr    }
443a1e6784eSAndreas Gohr
444b5b947d7SAndreas Gohr    /**
445fee3b689Sstretchyboy     * Escape string for sql
446fee3b689Sstretchyboy     */
447aa81d781SKlap-in    public function escape_string($str) {
448aa81d781SKlap-in        return $this->adapter->escape_string($str);
449ff97cc8fSstretchyboy    }
450ff97cc8fSstretchyboy
451ff97cc8fSstretchyboy    /**
452*b122d121SAndreas Gohr     * Closes the result set (and it's cursors)
453*b122d121SAndreas Gohr     *
454*b122d121SAndreas Gohr     * If you're doing SELECT queries inside a TRANSACTION, be sure to call this
455*b122d121SAndreas Gohr     * function on all your results sets, before COMMITing the transaction.
456*b122d121SAndreas Gohr     *
457*b122d121SAndreas Gohr     * @param $res
458*b122d121SAndreas Gohr     * @return bool
459*b122d121SAndreas Gohr     */
460*b122d121SAndreas Gohr    public function res_close($res){
461*b122d121SAndreas Gohr        return $this->adapter->res_close($res);
462*b122d121SAndreas Gohr    }
463*b122d121SAndreas Gohr
464*b122d121SAndreas Gohr    /**
465aa81d781SKlap-in     * Returns a complete result set as array
466ff97cc8fSstretchyboy     */
467ef383ac5SKlap-in    public function res2arr($res, $assoc = true) {
468ef383ac5SKlap-in        return $this->adapter->res2arr($res, $assoc);
469b5b947d7SAndreas Gohr    }
470b5b947d7SAndreas Gohr
471b5b947d7SAndreas Gohr    /**
472aa81d781SKlap-in     * Return the wanted row from a given result set as
473aa81d781SKlap-in     * associative array
474b5b947d7SAndreas Gohr     */
475aa81d781SKlap-in    public function res2row($res, $rownum = 0) {
476aa81d781SKlap-in        return $this->adapter->res2row($res, $rownum);
477b5b947d7SAndreas Gohr    }
478b5b947d7SAndreas Gohr
479e7112ccbSAdrian Lang    /**
48044685fc6SKlap-in     * Return the first value from the next row.
481e7112ccbSAdrian Lang     */
482aa81d781SKlap-in    public function res2single($res) {
483aa81d781SKlap-in        return $this->adapter->res2single($res);
484e7112ccbSAdrian Lang    }
485fee3b689Sstretchyboy
486fee3b689Sstretchyboy    /**
487fee3b689Sstretchyboy     * fetch the next row as zero indexed array
488fee3b689Sstretchyboy     */
489aa81d781SKlap-in    public function res_fetch_array($res) {
490aa81d781SKlap-in        return $this->adapter->res_fetch_array($res);
49187fa2c18Sstretchyboy    }
492fee3b689Sstretchyboy
493fee3b689Sstretchyboy    /**
494fee3b689Sstretchyboy     * fetch the next row as assocative array
495fee3b689Sstretchyboy     */
496aa81d781SKlap-in    public function res_fetch_assoc($res) {
497aa81d781SKlap-in        return $this->adapter->res_fetch_assoc($res);
498fee3b689Sstretchyboy    }
499fee3b689Sstretchyboy
500fee3b689Sstretchyboy    /**
50178977d74SKlap-in     * Count the number of records in result
5023157674bSAndreas Gohr     *
503db58e525SKlap-in     * This function is really inperformant in PDO and should be avoided!
504fee3b689Sstretchyboy     */
505aa81d781SKlap-in    public function res2count($res) {
506aa81d781SKlap-in        return $this->adapter->res2count($res);
507fee3b689Sstretchyboy    }
50824a03f6cSstretchyboy
50924a03f6cSstretchyboy    /**
51024a03f6cSstretchyboy     * Count the number of records changed last time
51124a03f6cSstretchyboy     */
51244685fc6SKlap-in    public function countChanges($res) {
51344685fc6SKlap-in        return $this->adapter->countChanges($res);
514a1e6784eSAndreas Gohr    }
515a1e6784eSAndreas Gohr
516aa81d781SKlap-in}
517