|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 /* 00003 V5.14 8 Sept 2011 (c) 2000-2011 John Lim (jlim#natsoft.com). All rights reserved. 00004 Released under both BSD license and Lesser GPL library license. 00005 Whenever there is any discrepancy between the two licenses, 00006 the BSD license will take precedence. 00007 00008 Latest version is available at http://adodb.sourceforge.net 00009 00010 SQLite info: http://www.hwaci.com/sw/sqlite/ 00011 00012 Install Instructions: 00013 ==================== 00014 1. Place this in adodb/drivers 00015 2. Rename the file, remove the .txt prefix. 00016 */ 00017 00018 // security - hide paths 00019 if (!defined('ADODB_DIR')) die(); 00020 00021 // class ADODB_sqlite extends ADOConnection { **change 00022 class ADODB_sqlite3 extends ADOConnection { 00023 //var $databaseType = "sqlite"; **change 00024 var $databaseType = "sqlite3"; 00025 var $replaceQuote = "''"; // string to use to replace quotes 00026 var $concat_operator='||'; 00027 var $_errorNo = 0; 00028 var $hasLimit = true; 00029 var $hasInsertID = true; 00030 var $hasAffectedRows = true; 00031 var $metaTablesSQL = "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name"; 00032 var $sysDate = "adodb_date('Y-m-d')"; 00033 var $sysTimeStamp = "adodb_date('Y-m-d H:i:s')"; 00034 var $fmtTimeStamp = "'Y-m-d H:i:s'"; 00035 00036 //function ADODB_sqlite3() **change 00037 function ADODB_sqlite3() 00038 { 00039 } 00040 00041 /* 00042 function __get($name) 00043 { 00044 switch($name) { 00045 case 'sysDate': return "'".date($this->fmtDate)."'"; 00046 case 'sysTimeStamp' : return "'".date($this->sysTimeStamp)."'"; 00047 } 00048 }*/ 00049 00050 function ServerInfo() 00051 { 00052 $arr['version'] = sqlite_libversion(); //**tochange 00053 $arr['description'] = 'SQLite '; //**tochange 00054 $arr['encoding'] = sqlite_libencoding();//**tochange 00055 return $arr; 00056 } 00057 00058 function BeginTrans() 00059 { 00060 if ($this->transOff) return true; 00061 $ret = $this->Execute("BEGIN TRANSACTION"); 00062 $this->transCnt += 1; 00063 return true; 00064 } 00065 00066 function CommitTrans($ok=true) 00067 { 00068 if ($this->transOff) return true; 00069 if (!$ok) return $this->RollbackTrans(); 00070 $ret = $this->Execute("COMMIT"); 00071 if ($this->transCnt>0)$this->transCnt -= 1; 00072 return !empty($ret); 00073 } 00074 00075 function RollbackTrans() 00076 { 00077 if ($this->transOff) return true; 00078 $ret = $this->Execute("ROLLBACK"); 00079 if ($this->transCnt>0)$this->transCnt -= 1; 00080 return !empty($ret); 00081 } 00082 00083 // mark newnham 00084 function MetaColumns($table, $normalize=true) 00085 { 00086 global $ADODB_FETCH_MODE; 00087 $false = false; 00088 $save = $ADODB_FETCH_MODE; 00089 $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC; 00090 if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false); 00091 $rs = $this->Execute("PRAGMA table_info('$table')"); 00092 if (isset($savem)) $this->SetFetchMode($savem); 00093 if (!$rs) { 00094 $ADODB_FETCH_MODE = $save; 00095 return $false; 00096 } 00097 $arr = array(); 00098 while ($r = $rs->FetchRow()) { 00099 00100 $type = explode('(',$r['type']); 00101 $size = ''; 00102 if (sizeof($type)==2) 00103 $size = trim($type[1],')'); 00104 $fn = strtoupper($r['name']); 00105 $fld = new ADOFieldObject; 00106 $fld->name = $r['name']; 00107 $fld->type = $type[0]; 00108 $fld->max_length = $size; 00109 $fld->not_null = $r['notnull']; 00110 $fld->default_value = $r['dflt_value']; 00111 $fld->scale = 0; 00112 if (isset($r['pk']) && $r['pk']) $fld->primary_key=1; 00113 if ($save == ADODB_FETCH_NUM) $arr[] = $fld; 00114 else $arr[strtoupper($fld->name)] = $fld; 00115 } 00116 $rs->Close(); 00117 $ADODB_FETCH_MODE = $save; 00118 return $arr; 00119 } 00120 00121 function _init($parentDriver) 00122 { 00123 00124 $parentDriver->hasTransactions = false; 00125 $parentDriver->hasInsertID = true; 00126 } 00127 00128 function _insertid() 00129 { 00130 //return sqlite_last_insert_rowid($this->_connectionID)->; //**change 00131 $temp = $this->_connectionID; 00132 return $temp->lastInsertRowID(); 00133 } 00134 00135 function _affectedrows() 00136 { 00137 return sqlite3_changes($this->_connectionID); //**tochange 00138 } 00139 00140 function ErrorMsg() 00141 { 00142 if ($this->_logsql) return $this->_errorMsg; 00143 00144 return ($this->_errorNo) ? sqlite_error_string($this->_errorNo) : ''; //**tochange? 00145 } 00146 00147 function ErrorNo() 00148 { 00149 return $this->_errorNo; //**tochange?? 00150 } 00151 00152 function SQLDate($fmt, $col=false) 00153 { 00154 $fmt = $this->qstr($fmt); 00155 return ($col) ? "adodb_date2($fmt,$col)" : "adodb_date($fmt)"; 00156 } 00157 00158 00159 function _createFunctions() 00160 { 00161 //@sqlite3_create_function($this->_connectionID, 'adodb_date', 'adodb_date', 1); *change 00162 $this->_connectionID->createFunction('adodb_date', 'adodb_date', 1); 00163 00164 //@sqlite3_create_function($this->_connectionID, 'adodb_date2', 'adodb_date2', 2);**change 00165 $this->_connectionID->createFunction('adodb_date2', 'adodb_date2', 2); 00166 } 00167 00168 00169 // returns true or false 00170 function _connect($argHostname, $argUsername, $argPassword, $argDatabasename) //**tochange: all the function need to be changed, just hacks for the moment 00171 { 00172 $this->_connectionID = new SQLite3('/path/mydb'); // hack 00173 if (empty($argHostname) && $argDatabasename) $argHostname = $argDatabasename; // hack 00174 $this->_createFunctions(); 00175 00176 return true; // hack 00177 00178 if (!function_exists('sqlite_open')) return null; 00179 if (empty($argHostname) && $argDatabasename) $argHostname = $argDatabasename; 00180 00181 $this->_connectionID = sqlite_open($argHostname); 00182 if ($this->_connectionID === false) return false; 00183 $this->_createFunctions(); 00184 return true; 00185 } 00186 00187 // returns true or false 00188 function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename) //**tochange 00189 { 00190 if (!function_exists('sqlite_open')) return null; 00191 if (empty($argHostname) && $argDatabasename) $argHostname = $argDatabasename; 00192 00193 $this->_connectionID = sqlite_popen($argHostname); 00194 if ($this->_connectionID === false) return false; 00195 $this->_createFunctions(); 00196 return true; 00197 } 00198 00199 // returns query ID if successful, otherwise false 00200 function _query($sql,$inputarr=false) 00201 { 00202 //$rez = sqlite_query($sql,$this->_connectionID);//**change 00203 $rez = $this->_connectionID->query($sql); 00204 if (!$rez) { 00205 //$this->_errorNo = sqlite3_last_error($this->_connectionID);**change 00206 $this->_connectionID->lastErrorCode(); 00207 } 00208 00209 return $rez; 00210 } 00211 00212 function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0) 00213 { 00214 $offsetStr = ($offset >= 0) ? " OFFSET $offset" : ''; 00215 $limitStr = ($nrows >= 0) ? " LIMIT $nrows" : ($offset >= 0 ? ' LIMIT 999999999' : ''); 00216 if ($secs2cache) 00217 $rs = $this->CacheExecute($secs2cache,$sql."$limitStr$offsetStr",$inputarr); 00218 else 00219 $rs = $this->Execute($sql."$limitStr$offsetStr",$inputarr); 00220 00221 return $rs; 00222 } 00223 00224 /* 00225 This algorithm is not very efficient, but works even if table locking 00226 is not available. 00227 00228 Will return false if unable to generate an ID after $MAXLOOPS attempts. 00229 */ 00230 var $_genSeqSQL = "create table %s (id integer)"; 00231 00232 function GenID($seq='adodbseq',$start=1) 00233 { 00234 // if you have to modify the parameter below, your database is overloaded, 00235 // or you need to implement generation of id's yourself! 00236 $MAXLOOPS = 100; 00237 //$this->debug=1; 00238 while (--$MAXLOOPS>=0) { 00239 @($num = $this->GetOne("select id from $seq")); 00240 if ($num === false) { 00241 $this->Execute(sprintf($this->_genSeqSQL ,$seq)); 00242 $start -= 1; 00243 $num = '0'; 00244 $ok = $this->Execute("insert into $seq values($start)"); 00245 if (!$ok) return false; 00246 } 00247 $this->Execute("update $seq set id=id+1 where id=$num"); 00248 00249 if ($this->affected_rows() > 0) { 00250 $num += 1; 00251 $this->genID = $num; 00252 return $num; 00253 } 00254 } 00255 if ($fn = $this->raiseErrorFn) { 00256 $fn($this->databaseType,'GENID',-32000,"Unable to generate unique id after $MAXLOOPS attempts",$seq,$num); 00257 } 00258 return false; 00259 } 00260 00261 function CreateSequence($seqname='adodbseq',$start=1) 00262 { 00263 if (empty($this->_genSeqSQL)) return false; 00264 $ok = $this->Execute(sprintf($this->_genSeqSQL,$seqname)); 00265 if (!$ok) return false; 00266 $start -= 1; 00267 return $this->Execute("insert into $seqname values($start)"); 00268 } 00269 00270 var $_dropSeqSQL = 'drop table %s'; 00271 function DropSequence($seqname) 00272 { 00273 if (empty($this->_dropSeqSQL)) return false; 00274 return $this->Execute(sprintf($this->_dropSeqSQL,$seqname)); 00275 } 00276 00277 // returns true or false 00278 function _close() 00279 { 00280 //return @sqlite3_close($this->_connectionID);**change 00281 return $this->_connectionID->close(); 00282 } 00283 00284 function MetaIndexes($table, $primary = FALSE, $owner=false, $owner = false) 00285 { 00286 $false = false; 00287 // save old fetch mode 00288 global $ADODB_FETCH_MODE; 00289 $save = $ADODB_FETCH_MODE; 00290 $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 00291 if ($this->fetchMode !== FALSE) { 00292 $savem = $this->SetFetchMode(FALSE); 00293 } 00294 $SQL=sprintf("SELECT name,sql FROM sqlite_master WHERE type='index' AND tbl_name='%s'", strtolower($table)); 00295 $rs = $this->Execute($SQL); 00296 if (!is_object($rs)) { 00297 if (isset($savem)) 00298 $this->SetFetchMode($savem); 00299 $ADODB_FETCH_MODE = $save; 00300 return $false; 00301 } 00302 00303 $indexes = array (); 00304 while ($row = $rs->FetchRow()) { 00305 if ($primary && preg_match("/primary/i",$row[1]) == 0) continue; 00306 if (!isset($indexes[$row[0]])) { 00307 00308 $indexes[$row[0]] = array( 00309 'unique' => preg_match("/unique/i",$row[1]), 00310 'columns' => array()); 00311 } 00318 $cols = explode("(",$row[1]); 00319 $cols = explode(")",$cols[1]); 00320 array_pop($cols); 00321 $indexes[$row[0]]['columns'] = $cols; 00322 } 00323 if (isset($savem)) { 00324 $this->SetFetchMode($savem); 00325 $ADODB_FETCH_MODE = $save; 00326 } 00327 return $indexes; 00328 } 00329 00330 } 00331 00332 /*-------------------------------------------------------------------------------------- 00333 Class Name: Recordset 00334 --------------------------------------------------------------------------------------*/ 00335 00336 //class ADORecordset_sqlite extends ADORecordSet {**change 00337 class ADORecordset_sqlite3 extends ADORecordSet { 00338 00339 //var $databaseType = "sqlite";**change 00340 var $databaseType = "sqlite3"; 00341 var $bind = false; 00342 00343 //function ADORecordset_sqlite($queryID,$mode=false)**change 00344 function ADORecordset_sqlite3($queryID,$mode=false) 00345 { 00346 00347 if ($mode === false) { 00348 global $ADODB_FETCH_MODE; 00349 $mode = $ADODB_FETCH_MODE; 00350 } 00351 switch($mode) { 00352 //case ADODB_FETCH_NUM: $this->fetchMode = SQLITE_NUM; break;**change 00353 case ADODB_FETCH_NUM: $this->fetchMode = SQLITE3_NUM; break; 00354 //case ADODB_FETCH_ASSOC: $this->fetchMode = SQLITE_ASSOC; break;**change 00355 case ADODB_FETCH_ASSOC: $this->fetchMode = SQLITE3_ASSOC; break; 00356 //default: $this->fetchMode = SQLITE_BOTH; break;**change 00357 default: $this->fetchMode = SQLITE3_BOTH; break; 00358 } 00359 $this->adodbFetchMode = $mode; 00360 00361 $this->_queryID = $queryID; 00362 00363 $this->_inited = true; 00364 $this->fields = array(); 00365 if ($queryID) { 00366 $this->_currentRow = 0; 00367 $this->EOF = !$this->_fetch(); 00368 @$this->_initrs(); 00369 } else { 00370 $this->_numOfRows = 0; 00371 $this->_numOfFields = 0; 00372 $this->EOF = true; 00373 } 00374 00375 return $this->_queryID; 00376 } 00377 00378 00379 function FetchField($fieldOffset = -1) 00380 { 00381 $fld = new ADOFieldObject; 00382 //$fld->name = sqlite3_field_name($this->_queryID, $fieldOffset);**change 00383 $fld->name->columnName($this->_queryID, $fieldOffset); 00384 $fld->type = 'VARCHAR'; 00385 $fld->max_length = -1; 00386 return $fld; 00387 } 00388 00389 function _initrs() 00390 { 00391 //$this->_numOfRows = @sqlite_num_rows($this->_queryID); **tochange but sqlite3 doesn't implement this! 00392 $this->_numOfRows = 1; 00393 //$this->_numOfFields = @sqlite3_num_fields($this->_queryID);**change 00394 $this->_numOfFields = $this->_queryID->numColumns(); 00395 00396 } 00397 00398 function Fields($colname) 00399 { 00400 //if ($this->fetchMode != SQLITE_NUM) return $this->fields[$colname];**change 00401 if ($this->fetchMode != SQLITE3_NUM) return $this->fields[$colname]; 00402 if (!$this->bind) { 00403 $this->bind = array(); 00404 for ($i=0; $i < $this->_numOfFields; $i++) { 00405 $o = $this->FetchField($i); 00406 $this->bind[strtoupper($o->name)] = $i; 00407 } 00408 } 00409 00410 return $this->fields[$this->bind[strtoupper($colname)]]; 00411 } 00412 00413 function _seek($row) 00414 { 00415 return sqlite3_seek($this->_queryID, $row);//**tochange but sqlite3 seems not to implement seek! 00416 } 00417 00418 function _fetch($ignore_fields=false) 00419 { 00420 //$this->fields = @sqlite3_fetch_array($this->_queryID,$this->fetchMode);**change 00421 $this->fields = $this->_queryID->fetchArray($this->fetchMode); 00422 return !empty($this->fields); 00423 } 00424 00425 function _close() 00426 { 00427 } 00428 00429 } 00430 ?>