TYPO3 CMS  TYPO3_6-2
adodb-sqlite.inc.php
Go to the documentation of this file.
1 <?php
2 /*
3 V5.19 23-Apr-2014 (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
4  Released under both BSD license and Lesser GPL library license.
5  Whenever there is any discrepancy between the two licenses,
6  the BSD license will take precedence.
7 
8  Latest version is available at http://adodb.sourceforge.net
9 
10  SQLite info: http://www.hwaci.com/sw/sqlite/
11 
12  Install Instructions:
13  ====================
14  1. Place this in adodb/drivers
15  2. Rename the file, remove the .txt prefix.
16 */
17 
18 // security - hide paths
19 if (!defined('ADODB_DIR')) die();
20 
21 class ADODB_sqlite extends ADOConnection {
22  var $databaseType = "sqlite";
23  var $replaceQuote = "''"; // string to use to replace quotes
24  var $concat_operator='||';
25  var $_errorNo = 0;
26  var $hasLimit = true;
27  var $hasInsertID = true;
28  var $hasAffectedRows = true;
29  var $metaTablesSQL = "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name";
30  var $sysDate = "adodb_date('Y-m-d')";
31  var $sysTimeStamp = "adodb_date('Y-m-d H:i:s')";
32  var $fmtTimeStamp = "'Y-m-d H:i:s'";
33 
34  function ADODB_sqlite()
35  {
36  }
37 
38 /*
39  function __get($name)
40  {
41  switch($name) {
42  case 'sysDate': return "'".date($this->fmtDate)."'";
43  case 'sysTimeStamp' : return "'".date($this->sysTimeStamp)."'";
44  }
45  }*/
46 
47  function ServerInfo()
48  {
49  $arr['version'] = sqlite_libversion();
50  $arr['description'] = 'SQLite ';
51  $arr['encoding'] = sqlite_libencoding();
52  return $arr;
53  }
54 
55  function BeginTrans()
56  {
57  if ($this->transOff) return true;
58  $ret = $this->Execute("BEGIN TRANSACTION");
59  $this->transCnt += 1;
60  return true;
61  }
62 
63  function CommitTrans($ok=true)
64  {
65  if ($this->transOff) return true;
66  if (!$ok) return $this->RollbackTrans();
67  $ret = $this->Execute("COMMIT");
68  if ($this->transCnt>0)$this->transCnt -= 1;
69  return !empty($ret);
70  }
71 
72  function RollbackTrans()
73  {
74  if ($this->transOff) return true;
75  $ret = $this->Execute("ROLLBACK");
76  if ($this->transCnt>0)$this->transCnt -= 1;
77  return !empty($ret);
78  }
79 
80  // mark newnham
81  function MetaColumns($table, $normalize=true)
82  {
83  global $ADODB_FETCH_MODE;
84  $false = false;
85  $save = $ADODB_FETCH_MODE;
86  $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
87  if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
88  $rs = $this->Execute("PRAGMA table_info('$table')");
89  if (isset($savem)) $this->SetFetchMode($savem);
90  if (!$rs) {
91  $ADODB_FETCH_MODE = $save;
92  return $false;
93  }
94  $arr = array();
95  while ($r = $rs->FetchRow()) {
96  $type = explode('(',$r['type']);
97  $size = '';
98  if (sizeof($type)==2)
99  $size = trim($type[1],')');
100  $fn = strtoupper($r['name']);
101  $fld = new ADOFieldObject;
102  $fld->name = $r['name'];
103  $fld->type = $type[0];
104  $fld->max_length = $size;
105  $fld->not_null = $r['notnull'];
106  $fld->default_value = $r['dflt_value'];
107  $fld->scale = 0;
108  if (isset($r['pk']) && $r['pk']) $fld->primary_key=1;
109  if ($save == ADODB_FETCH_NUM) $arr[] = $fld;
110  else $arr[strtoupper($fld->name)] = $fld;
111  }
112  $rs->Close();
113  $ADODB_FETCH_MODE = $save;
114  return $arr;
115  }
116 
117  function _init($parentDriver)
118  {
119 
120  $parentDriver->hasTransactions = false;
121  $parentDriver->hasInsertID = true;
122  }
123 
124  function _insertid()
125  {
126  return sqlite_last_insert_rowid($this->_connectionID);
127  }
128 
129  function _affectedrows()
130  {
131  return sqlite_changes($this->_connectionID);
132  }
133 
134  function ErrorMsg()
135  {
136  if ($this->_logsql) return $this->_errorMsg;
137  return ($this->_errorNo) ? sqlite_error_string($this->_errorNo) : '';
138  }
139 
140  function ErrorNo()
141  {
142  return $this->_errorNo;
143  }
144 
145  function SQLDate($fmt, $col=false)
146  {
147  $fmt = $this->qstr($fmt);
148  return ($col) ? "adodb_date2($fmt,$col)" : "adodb_date($fmt)";
149  }
150 
151 
152  function _createFunctions()
153  {
154  @sqlite_create_function($this->_connectionID, 'adodb_date', 'adodb_date', 1);
155  @sqlite_create_function($this->_connectionID, 'adodb_date2', 'adodb_date2', 2);
156  }
157 
158 
159  // returns true or false
160  function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
161  {
162  if (!function_exists('sqlite_open')) return null;
163  if (empty($argHostname) && $argDatabasename) $argHostname = $argDatabasename;
164 
165  $this->_connectionID = sqlite_open($argHostname);
166  if ($this->_connectionID === false) return false;
167  $this->_createFunctions();
168  return true;
169  }
170 
171  // returns true or false
172  function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
173  {
174  if (!function_exists('sqlite_open')) return null;
175  if (empty($argHostname) && $argDatabasename) $argHostname = $argDatabasename;
176 
177  $this->_connectionID = sqlite_popen($argHostname);
178  if ($this->_connectionID === false) return false;
179  $this->_createFunctions();
180  return true;
181  }
182 
183  // returns query ID if successful, otherwise false
184  function _query($sql,$inputarr=false)
185  {
186  $rez = sqlite_query($sql,$this->_connectionID);
187  if (!$rez) {
188  $this->_errorNo = sqlite_last_error($this->_connectionID);
189  }
190 
191  return $rez;
192  }
193 
194  function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
195  {
196  $offsetStr = ($offset >= 0) ? " OFFSET $offset" : '';
197  $limitStr = ($nrows >= 0) ? " LIMIT $nrows" : ($offset >= 0 ? ' LIMIT 999999999' : '');
198  if ($secs2cache)
199  $rs = $this->CacheExecute($secs2cache,$sql."$limitStr$offsetStr",$inputarr);
200  else
201  $rs = $this->Execute($sql."$limitStr$offsetStr",$inputarr);
202 
203  return $rs;
204  }
205 
206  /*
207  This algorithm is not very efficient, but works even if table locking
208  is not available.
209 
210  Will return false if unable to generate an ID after $MAXLOOPS attempts.
211  */
212  var $_genSeqSQL = "create table %s (id integer)";
213 
214  function GenID($seq='adodbseq',$start=1)
215  {
216  // if you have to modify the parameter below, your database is overloaded,
217  // or you need to implement generation of id's yourself!
218  $MAXLOOPS = 100;
219  //$this->debug=1;
220  while (--$MAXLOOPS>=0) {
221  @($num = $this->GetOne("select id from $seq"));
222  if ($num === false) {
223  $this->Execute(sprintf($this->_genSeqSQL ,$seq));
224  $start -= 1;
225  $num = '0';
226  $ok = $this->Execute("insert into $seq values($start)");
227  if (!$ok) return false;
228  }
229  $this->Execute("update $seq set id=id+1 where id=$num");
230 
231  if ($this->affected_rows() > 0) {
232  $num += 1;
233  $this->genID = $num;
234  return $num;
235  }
236  }
237  if ($fn = $this->raiseErrorFn) {
238  $fn($this->databaseType,'GENID',-32000,"Unable to generate unique id after $MAXLOOPS attempts",$seq,$num);
239  }
240  return false;
241  }
242 
243  function CreateSequence($seqname='adodbseq',$start=1)
244  {
245  if (empty($this->_genSeqSQL)) return false;
246  $ok = $this->Execute(sprintf($this->_genSeqSQL,$seqname));
247  if (!$ok) return false;
248  $start -= 1;
249  return $this->Execute("insert into $seqname values($start)");
250  }
251 
252  var $_dropSeqSQL = 'drop table %s';
253  function DropSequence($seqname)
254  {
255  if (empty($this->_dropSeqSQL)) return false;
256  return $this->Execute(sprintf($this->_dropSeqSQL,$seqname));
257  }
258 
259  // returns true or false
260  function _close()
261  {
262  return @sqlite_close($this->_connectionID);
263  }
264 
265  function MetaIndexes($table, $primary = FALSE, $owner=false, $owner = false)
266  {
267  $false = false;
268  // save old fetch mode
269  global $ADODB_FETCH_MODE;
270  $save = $ADODB_FETCH_MODE;
271  $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
272  if ($this->fetchMode !== FALSE) {
273  $savem = $this->SetFetchMode(FALSE);
274  }
275  $SQL=sprintf("SELECT name,sql FROM sqlite_master WHERE type='index' AND tbl_name='%s'", strtolower($table));
276  $rs = $this->Execute($SQL);
277  if (!is_object($rs)) {
278  if (isset($savem))
279  $this->SetFetchMode($savem);
280  $ADODB_FETCH_MODE = $save;
281  return $false;
282  }
283 
284  $indexes = array ();
285  while ($row = $rs->FetchRow()) {
286  if ($primary && preg_match("/primary/i",$row[1]) == 0) continue;
287  if (!isset($indexes[$row[0]])) {
288 
289  $indexes[$row[0]] = array(
290  'unique' => preg_match("/unique/i",$row[1]),
291  'columns' => array());
292  }
299  $cols = explode("(",$row[1]);
300  $cols = explode(")",$cols[1]);
301  array_pop($cols);
302  $indexes[$row[0]]['columns'] = $cols;
303  }
304  if (isset($savem)) {
305  $this->SetFetchMode($savem);
306  $ADODB_FETCH_MODE = $save;
307  }
308  return $indexes;
309  }
310 
311 }
312 
313 /*--------------------------------------------------------------------------------------
314  Class Name: Recordset
315 --------------------------------------------------------------------------------------*/
316 
317 class ADORecordset_sqlite extends ADORecordSet {
318 
319  var $databaseType = "sqlite";
320  var $bind = false;
321 
322  function ADORecordset_sqlite($queryID,$mode=false)
323  {
324 
325  if ($mode === false) {
326  global $ADODB_FETCH_MODE;
327  $mode = $ADODB_FETCH_MODE;
328  }
329  switch($mode) {
330  case ADODB_FETCH_NUM: $this->fetchMode = SQLITE_NUM; break;
331  case ADODB_FETCH_ASSOC: $this->fetchMode = SQLITE_ASSOC; break;
332  default: $this->fetchMode = SQLITE_BOTH; break;
333  }
334  $this->adodbFetchMode = $mode;
335 
336  $this->_queryID = $queryID;
337 
338  $this->_inited = true;
339  $this->fields = array();
340  if ($queryID) {
341  $this->_currentRow = 0;
342  $this->EOF = !$this->_fetch();
343  @$this->_initrs();
344  } else {
345  $this->_numOfRows = 0;
346  $this->_numOfFields = 0;
347  $this->EOF = true;
348  }
349 
350  return $this->_queryID;
351  }
352 
353 
354  function FetchField($fieldOffset = -1)
355  {
356  $fld = new ADOFieldObject;
357  $fld->name = sqlite_field_name($this->_queryID, $fieldOffset);
358  $fld->type = 'VARCHAR';
359  $fld->max_length = -1;
360  return $fld;
361  }
362 
363  function _initrs()
364  {
365  $this->_numOfRows = @sqlite_num_rows($this->_queryID);
366  $this->_numOfFields = @sqlite_num_fields($this->_queryID);
367  }
368 
369  function Fields($colname)
370  {
371  if ($this->fetchMode != SQLITE_NUM) return $this->fields[$colname];
372  if (!$this->bind) {
373  $this->bind = array();
374  for ($i=0; $i < $this->_numOfFields; $i++) {
375  $o = $this->FetchField($i);
376  $this->bind[strtoupper($o->name)] = $i;
377  }
378  }
379 
380  return $this->fields[$this->bind[strtoupper($colname)]];
381  }
382 
383  function _seek($row)
384  {
385  return sqlite_seek($this->_queryID, $row);
386  }
387 
388  function _fetch($ignore_fields=false)
389  {
390  $this->fields = @sqlite_fetch_array($this->_queryID,$this->fetchMode);
391  return !empty($this->fields);
392  }
393 
394  function _close()
395  {
396  }
397 
398 }
_init($parentDriver)
DropSequence($seqname)
_fetch($ignore_fields=false)
$hasAffectedRows
supports autoincrement ID?
_connect($argHostname, $argUsername, $argPassword, $argDatabasename)
CommitTrans($ok=true)
SelectLimit($sql, $nrows=-1, $offset=-1, $inputarr=false, $secs2cache=0)
$sql
Definition: server.php:82
if(isset($_REQUEST['nrows'])) else $rs
Definition: server.php:92
die
Definition: index.php:6
CreateSequence($seqname='adodbseq', $start=1)
FetchField($fieldOffset=-1)
$metaTablesSQL
supports affected rows for update/delete?
_query($sql, $inputarr=false)
MetaIndexes($table, $primary=FALSE, $owner=false, $owner=false)
SQLDate($fmt, $col=false)
ADORecordset_sqlite($queryID, $mode=false)
MetaColumns($table, $normalize=true)
GenID($seq='adodbseq', $start=1)
_pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)