You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							371 lines
						
					
					
						
							9.7 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							371 lines
						
					
					
						
							9.7 KiB
						
					
					
				| <?php | |
| /* | |
| V4.55 3 Jan 2005  (c) 2000-2005 John Lim (jlim@natsoft.com.my). All rights reserved. | |
|   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 http://adodb.sourceforge.net | |
|    | |
|   SQLite info: http://www.hwaci.com/sw/sqlite/ | |
|      | |
|   Install Instructions: | |
|   ==================== | |
|   1. Place this in adodb/drivers | |
|   2. Rename the file, remove the .txt prefix. | |
| */ | |
| 
 | |
| // security - hide paths | |
| if (!defined('ADODB_DIR')) die(); | |
| 
 | |
| class ADODB_sqlite extends ADOConnection { | |
| 	var $databaseType = "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 ADODB_sqlite()  | |
| 	{ | |
| 	} | |
| 	 | |
| /* | |
|   function __get($name)  | |
|   { | |
|   	switch($name) { | |
| 	case 'sysDate': return "'".date($this->fmtDate)."'"; | |
| 	case 'sysTimeStamp' : return "'".date($this->sysTimeStamp)."'"; | |
| 	} | |
|   }*/ | |
| 	 | |
| 	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); | |
| 	} | |
| 
 | |
| 	function _insertid() | |
| 	{ | |
| 		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 &MetaColumns($tab) | |
| 	{ | |
| 	global $ADODB_FETCH_MODE; | |
| 	 | |
| 		$rs = $this->Execute("select * from $tab limit 1"); | |
| 		if (!$rs) { | |
| 			$false = false; | |
| 			return $false; | |
| 		} | |
| 		$arr = array(); | |
| 		for ($i=0,$max=$rs->_numOfFields; $i < $max; $i++) { | |
| 			$fld =& $rs->FetchField($i); | |
| 			if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] =& $fld;	 | |
| 			else $arr[strtoupper($fld->name)] =& $fld; | |
| 		} | |
| 		$rs->Close(); | |
| 		return $arr; | |
| 	} | |
| 	 | |
| 	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; | |
| 		 | |
| 		$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; | |
| 		 | |
| 		$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); | |
| 		} | |
| 		 | |
| 		return $rez; | |
| 	} | |
| 	 | |
| 	function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)  | |
| 	{ | |
| 		$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) | |
| 	{ | |
| 		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; | |
| 	} | |
| 
 | |
| } | |
| 
 | |
| /*-------------------------------------------------------------------------------------- | |
| 		 Class Name: Recordset | |
| --------------------------------------------------------------------------------------*/ | |
| 
 | |
| class ADORecordset_sqlite extends ADORecordSet { | |
| 
 | |
| 	var $databaseType = "sqlite"; | |
| 	var $bind = false; | |
| 
 | |
| 	function ADORecordset_sqlite($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()  | |
| 	{ | |
| 	} | |
| 
 | |
| } | |
| ?>
 |