<?php
< /*
< @version v5.21.0 2021-02-27
< @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
< @copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
< Released under both BSD license and Lesser GPL library license.
< Whenever there is any discrepancy between the two licenses,
< the BSD license will take precedence.
<
< Latest version is available at https://adodb.org/
<
< SQLite info: http://www.hwaci.com/sw/sqlite/
<
< Install Instructions:
< ====================
< 1. Place this in adodb/drivers
< 2. Rename the file, remove the .txt prefix.
> /**
> * SQLite driver
> *
> * @link https://www.sqlite.org/
> *
> * @deprecated Use SQLite3 driver instead
> *
> * This file is part of ADOdb, a Database Abstraction Layer library for PHP.
> *
> * @package ADOdb
> * @link https://adodb.org Project's web site and documentation
> * @link https://github.com/ADOdb/ADOdb Source code and issue tracker
> *
> * The ADOdb Library is dual-licensed, released under both the BSD 3-Clause
> * and the GNU Lesser General Public Licence (LGPL) v2.1 or, at your option,
> * any later version. This means you can use it in proprietary products.
> * See the LICENSE.md file distributed with this source code for details.
> * @license BSD-3-Clause
> * @license LGPL-2.1-or-later
> *
> * @copyright 2000-2013 John Lim
> * @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
class ADODB_sqlite extends ADOConnection {
var $databaseType = "sqlite";
var $dataProvider = "sqlite";
var $replaceQuote = "''"; // string to use to replace quotes
var $concat_operator='||';
var $_errorNo = 0;
var $hasLimit = true;
var $hasInsertID = true; /// supports autoincrement ID?
var $hasAffectedRows = true; /// supports affected rows for update/delete?
var $metaTablesSQL = "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name";
var $sysDate = "adodb_date('Y-m-d')";
var $sysTimeStamp = "adodb_date('Y-m-d H:i:s')";
var $fmtTimeStamp = "'Y-m-d H:i:s'";
function ServerInfo()
{
$arr['version'] = sqlite_libversion();
$arr['description'] = 'SQLite ';
$arr['encoding'] = sqlite_libencoding();
return $arr;
}
function BeginTrans()
{
if ($this->transOff) {
return true;
}
$ret = $this->Execute("BEGIN TRANSACTION");
$this->transCnt += 1;
return true;
}
function CommitTrans($ok=true)
{
if ($this->transOff) {
return true;
}
if (!$ok) {
return $this->RollbackTrans();
}
$ret = $this->Execute("COMMIT");
if ($this->transCnt > 0) {
$this->transCnt -= 1;
}
return !empty($ret);
}
function RollbackTrans()
{
if ($this->transOff) {
return true;
}
$ret = $this->Execute("ROLLBACK");
if ($this->transCnt > 0) {
$this->transCnt -= 1;
}
return !empty($ret);
}
// mark newnham
function MetaColumns($table, $normalize=true)
{
global $ADODB_FETCH_MODE;
$false = false;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
if ($this->fetchMode !== false) {
$savem = $this->SetFetchMode(false);
}
$rs = $this->Execute("PRAGMA table_info('$table')");
if (isset($savem)) {
$this->SetFetchMode($savem);
}
if (!$rs) {
$ADODB_FETCH_MODE = $save;
return $false;
}
$arr = array();
while ($r = $rs->FetchRow()) {
$type = explode('(',$r['type']);
$size = '';
if (sizeof($type)==2) {
$size = trim($type[1],')');
}
$fn = strtoupper($r['name']);
$fld = new ADOFieldObject;
$fld->name = $r['name'];
$fld->type = $type[0];
$fld->max_length = $size;
$fld->not_null = $r['notnull'];
$fld->default_value = $r['dflt_value'];
$fld->scale = 0;
if (isset($r['pk']) && $r['pk']) {
$fld->primary_key=1;
}
if ($save == ADODB_FETCH_NUM) {
$arr[] = $fld;
} else {
$arr[strtoupper($fld->name)] = $fld;
}
}
$rs->Close();
$ADODB_FETCH_MODE = $save;
return $arr;
}
function _init($parentDriver)
{
$parentDriver->hasTransactions = false;
$parentDriver->hasInsertID = true;
}
< function _insertid()
> protected function _insertID($table = '', $column = '')
{
return sqlite_last_insert_rowid($this->_connectionID);
}
function _affectedrows()
{
return sqlite_changes($this->_connectionID);
}
function ErrorMsg()
{
if ($this->_logsql) {
return $this->_errorMsg;
}
return ($this->_errorNo) ? sqlite_error_string($this->_errorNo) : '';
}
function ErrorNo()
{
return $this->_errorNo;
}
function SQLDate($fmt, $col=false)
{
$fmt = $this->qstr($fmt);
return ($col) ? "adodb_date2($fmt,$col)" : "adodb_date($fmt)";
}
function _createFunctions()
{
@sqlite_create_function($this->_connectionID, 'adodb_date', 'adodb_date', 1);
@sqlite_create_function($this->_connectionID, 'adodb_date2', 'adodb_date2', 2);
}
// returns true or false
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
if (!function_exists('sqlite_open')) {
return null;
}
if (empty($argHostname) && $argDatabasename) {
$argHostname = $argDatabasename;
}
$this->_connectionID = sqlite_open($argHostname);
if ($this->_connectionID === false) {
return false;
}
$this->_createFunctions();
return true;
}
// returns true or false
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
if (!function_exists('sqlite_open')) {
return null;
}
if (empty($argHostname) && $argDatabasename) {
$argHostname = $argDatabasename;
}
$this->_connectionID = sqlite_popen($argHostname);
if ($this->_connectionID === false) {
return false;
}
$this->_createFunctions();
return true;
}
// returns query ID if successful, otherwise false
function _query($sql,$inputarr=false)
{
$rez = sqlite_query($sql,$this->_connectionID);
if (!$rez) {
$this->_errorNo = sqlite_last_error($this->_connectionID);
}
// If no data was returned, we don't need to create a real recordset
// Note: this code is untested, as I don't have a sqlite2 setup available
elseif (sqlite_num_fields($rez) == 0) {
$rez = true;
}
return $rez;
}
function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
{
$nrows = (int) $nrows;
$offset = (int) $offset;
$offsetStr = ($offset >= 0) ? " OFFSET $offset" : '';
$limitStr = ($nrows >= 0) ? " LIMIT $nrows" : ($offset >= 0 ? ' LIMIT 999999999' : '');
if ($secs2cache) {
$rs = $this->CacheExecute($secs2cache,$sql."$limitStr$offsetStr",$inputarr);
} else {
$rs = $this->Execute($sql."$limitStr$offsetStr",$inputarr);
}
return $rs;
}
/*
This algorithm is not very efficient, but works even if table locking
is not available.
Will return false if unable to generate an ID after $MAXLOOPS attempts.
*/
var $_genSeqSQL = "create table %s (id integer)";
function GenID($seq='adodbseq',$start=1)
{
// if you have to modify the parameter below, your database is overloaded,
// or you need to implement generation of id's yourself!
$MAXLOOPS = 100;
//$this->debug=1;
while (--$MAXLOOPS>=0) {
@($num = $this->GetOne("select id from $seq"));
if ($num === false) {
$this->Execute(sprintf($this->_genSeqSQL ,$seq));
$start -= 1;
$num = '0';
$ok = $this->Execute("insert into $seq values($start)");
if (!$ok) {
return false;
}
}
$this->Execute("update $seq set id=id+1 where id=$num");
if ($this->affected_rows() > 0) {
$num += 1;
$this->genID = $num;
return $num;
}
}
if ($fn = $this->raiseErrorFn) {
$fn($this->databaseType,'GENID',-32000,"Unable to generate unique id after $MAXLOOPS attempts",$seq,$num);
}
return false;
}
function CreateSequence($seqname='adodbseq',$start=1)
{
if (empty($this->_genSeqSQL)) {
return false;
}
$ok = $this->Execute(sprintf($this->_genSeqSQL,$seqname));
if (!$ok) {
return false;
}
$start -= 1;
return $this->Execute("insert into $seqname values($start)");
}
var $_dropSeqSQL = 'drop table %s';
function DropSequence($seqname = 'adodbseq')
{
if (empty($this->_dropSeqSQL)) {
return false;
}
return $this->Execute(sprintf($this->_dropSeqSQL,$seqname));
}
// returns true or false
function _close()
{
return @sqlite_close($this->_connectionID);
}
function MetaIndexes($table, $primary = FALSE, $owner = false)
{
$false = false;
// save old fetch mode
global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== FALSE) {
$savem = $this->SetFetchMode(FALSE);
}
$SQL=sprintf("SELECT name,sql FROM sqlite_master WHERE type='index' AND tbl_name='%s'", strtolower($table));
$rs = $this->Execute($SQL);
if (!is_object($rs)) {
if (isset($savem)) {
$this->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
return $false;
}
$indexes = array ();
while ($row = $rs->FetchRow()) {
if ($primary && preg_match("/primary/i",$row[1]) == 0) {
continue;
}
if (!isset($indexes[$row[0]])) {
$indexes[$row[0]] = array(
'unique' => preg_match("/unique/i",$row[1]),
'columns' => array()
);
}
/**
* There must be a more elegant way of doing this,
* the index elements appear in the SQL statement
* in cols[1] between parentheses
* e.g CREATE UNIQUE INDEX ware_0 ON warehouse (org,warehouse)
*/
$cols = explode("(",$row[1]);
$cols = explode(")",$cols[1]);
array_pop($cols);
$indexes[$row[0]]['columns'] = $cols;
}
if (isset($savem)) {
$this->SetFetchMode($savem);
$ADODB_FETCH_MODE = $save;
}
return $indexes;
}
/**
* Returns the maximum size of a MetaType C field. Because of the
* database design, sqlite places no limits on the size of data inserted
*
* @return int
*/
function charMax()
{
return ADODB_STRINGMAX_NOLIMIT;
}
/**
* Returns the maximum size of a MetaType X field. Because of the
* database design, sqlite places no limits on the size of data inserted
*
* @return int
*/
function textMax()
{
return ADODB_STRINGMAX_NOLIMIT;
}
/*
* Converts a date to a month only field and pads it to 2 characters
*
* @param str $fld The name of the field to process
* @return str The SQL Statement
*/
function month($fld)
{
$x = "strftime('%m',$fld)";
return $x;
}
/*
* Converts a date to a day only field and pads it to 2 characters
*
* @param str $fld The name of the field to process
* @return str The SQL Statement
*/
function day($fld) {
$x = "strftime('%d',$fld)";
return $x;
}
/*
* Converts a date to a year only field
*
* @param str $fld The name of the field to process
* @return str The SQL Statement
*/
function year($fld) {
$x = "strftime('%Y',$fld)";
return $x;
}
}
/*--------------------------------------------------------------------------------------
Class Name: Recordset
--------------------------------------------------------------------------------------*/
class ADORecordset_sqlite extends ADORecordSet {
var $databaseType = "sqlite";
var $bind = false;
function __construct($queryID,$mode=false)
{
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
switch($mode) {
case ADODB_FETCH_NUM:
$this->fetchMode = SQLITE_NUM;
break;
case ADODB_FETCH_ASSOC:
$this->fetchMode = SQLITE_ASSOC;
break;
default:
$this->fetchMode = SQLITE_BOTH;
break;
}
$this->adodbFetchMode = $mode;
$this->_queryID = $queryID;
$this->_inited = true;
$this->fields = array();
if ($queryID) {
$this->_currentRow = 0;
$this->EOF = !$this->_fetch();
@$this->_initrs();
} else {
$this->_numOfRows = 0;
$this->_numOfFields = 0;
$this->EOF = true;
}
return $this->_queryID;
}
function FetchField($fieldOffset = -1)
{
$fld = new ADOFieldObject;
$fld->name = sqlite_field_name($this->_queryID, $fieldOffset);
$fld->type = 'VARCHAR';
$fld->max_length = -1;
return $fld;
}
function _initrs()
{
$this->_numOfRows = @sqlite_num_rows($this->_queryID);
$this->_numOfFields = @sqlite_num_fields($this->_queryID);
}
function Fields($colname)
{
if ($this->fetchMode != SQLITE_NUM) {
return $this->fields[$colname];
}
if (!$this->bind) {
$this->bind = array();
for ($i=0; $i < $this->_numOfFields; $i++) {
$o = $this->FetchField($i);
$this->bind[strtoupper($o->name)] = $i;
}
}
return $this->fields[$this->bind[strtoupper($colname)]];
}
function _seek($row)
{
return sqlite_seek($this->_queryID, $row);
}
function _fetch($ignore_fields=false)
{
$this->fields = @sqlite_fetch_array($this->_queryID,$this->fetchMode);
return !empty($this->fields);
}
function _close()
{
}
}