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