adodb 최신버전으로 변경

<? 를 <?php 로 변경
This commit is contained in:
2018-01-11 19:28:35 +09:00
parent feff33715f
commit 7b3b674dee
450 changed files with 19425 additions and 32248 deletions
+30 -29
View File
@@ -1,24 +1,26 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). 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. See License.txt.
/*
@version v5.20.9 21-Dec-2016
@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. See License.txt.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
Microsoft Access data driver. Requires ODBC. Works only on MS Windows.
*/
if (!defined('_ADODB_ODBC_LAYER')) {
if (!defined('ADODB_DIR')) die();
include(ADODB_DIR."/drivers/adodb-odbc.inc.php");
}
if (!defined('_ADODB_ACCESS')) {
define('_ADODB_ACCESS',1);
class ADODB_access extends ADODB_odbc {
class ADODB_access extends ADODB_odbc {
var $databaseType = 'access';
var $hasTop = 'top'; // support mssql SELECT TOP 10 * FROM TABLE
var $fmtDate = "#Y-m-d#";
@@ -28,23 +30,23 @@ class ADODB_access extends ADODB_odbc {
var $sysTimeStamp = 'NOW';
var $hasTransactions = false;
var $upperCase = 'ucase';
function ADODB_access()
function __construct()
{
global $ADODB_EXTENSION;
$ADODB_EXTENSION = false;
$this->ADODB_odbc();
parent::__construct();
}
function Time()
{
return time();
}
function BeginTrans() { return false;}
function IfNull( $field, $ifNull )
function IfNull( $field, $ifNull )
{
return " IIF(IsNull($field), $ifNull, $field) "; // if Access
}
@@ -52,16 +54,16 @@ class ADODB_access extends ADODB_odbc {
function MetaTables()
{
global $ADODB_FETCH_MODE;
$savem = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$qid = odbc_tables($this->_connectionID);
$rs = new ADORecordSet_odbc($qid);
$ADODB_FETCH_MODE = $savem;
if (!$rs) return false;
$rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
$arr = $rs->GetArray();
//print_pre($arr);
$arr2 = array();
@@ -73,15 +75,14 @@ class ADODB_access extends ADODB_odbc {
}*/
}
class ADORecordSet_access extends ADORecordSet_odbc {
var $databaseType = "access";
function ADORecordSet_access($id,$mode=false)
class ADORecordSet_access extends ADORecordSet_odbc {
var $databaseType = "access";
function __construct($id,$mode=false)
{
return $this->ADORecordSet_odbc($id,$mode);
return parent::__construct($id,$mode);
}
}// class
}
?>
}
+116 -116
View File
@@ -1,31 +1,33 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). 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.
/*
@version v5.20.9 21-Dec-2016
@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.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
Microsoft ADO data driver. Requires ADO. Works only on MS Windows.
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
define("_ADODB_ADO_LAYER", 1 );
/*--------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------*/
class ADODB_ado extends ADOConnection {
var $databaseType = "ado";
var $databaseType = "ado";
var $_bindInputArray = false;
var $fmtDate = "'Y-m-d'";
var $fmtTimeStamp = "'Y-m-d, h:i:sA'";
var $replaceQuote = "''"; // string to use to replace quotes
var $dataProvider = "ado";
var $dataProvider = "ado";
var $hasAffectedRows = true;
var $adoParameterType = 201; // 201 = long varchar, 203=long wide varchar, 205 = long varbinary
var $_affectedRows = false;
@@ -34,11 +36,11 @@ class ADODB_ado extends ADOConnection {
var $_cursor_location = 3; // 2=adUseServer, 3 = adUseClient;
var $_lock_type = -1;
var $_execute_option = -1;
var $poorAffectedRows = true;
var $poorAffectedRows = true;
var $charPage;
function ADODB_ado()
{
function __construct()
{
$this->_affectedRows = new VARIANT;
}
@@ -47,14 +49,14 @@ class ADODB_ado extends ADOConnection {
if (!empty($this->_connectionID)) $desc = $this->_connectionID->provider;
return array('description' => $desc, 'version' => '');
}
function _affectedrows()
{
if (PHP_VERSION >= 5) return $this->_affectedRows;
return $this->_affectedRows->value;
}
// you can also pass a connection string like this:
//
// $DB->Connect('USER ID=sa;PASSWORD=pwd;SERVER=mangrove;DATABASE=ai',false,false,'SQLOLEDB');
@@ -62,49 +64,49 @@ class ADODB_ado extends ADOConnection {
{
$u = 'UID';
$p = 'PWD';
if (!empty($this->charPage))
$dbc = new COM('ADODB.Connection',null,$this->charPage);
else
$dbc = new COM('ADODB.Connection');
if (! $dbc) return false;
/* special support if provider is mssql or access */
if ($argProvider=='mssql') {
$u = 'User Id'; //User parameter name for OLEDB
$p = 'Password';
$p = 'Password';
$argProvider = "SQLOLEDB"; // SQL Server Provider
// not yet
//if ($argDatabasename) $argHostname .= ";Initial Catalog=$argDatabasename";
//use trusted conection for SQL if username not specified
if (!$argUsername) $argHostname .= ";Trusted_Connection=Yes";
} else if ($argProvider=='access')
$argProvider = "Microsoft.Jet.OLEDB.4.0"; // Microsoft Jet Provider
if ($argProvider) $dbc->Provider = $argProvider;
if ($argProvider) $dbc->Provider = $argProvider;
if ($argUsername) $argHostname .= ";$u=$argUsername";
if ($argPassword)$argHostname .= ";$p=$argPassword";
if ($this->debug) ADOConnection::outp( "Host=".$argHostname."<BR>\n version=$dbc->version");
// @ added below for php 4.0.1 and earlier
@$dbc->Open((string) $argHostname);
$this->_connectionID = $dbc;
$dbc->CursorLocation = $this->_cursor_location;
return $dbc->State > 0;
}
// returns true or false
function _pconnect($argHostname, $argUsername, $argPassword, $argProvider='MSDASQL')
{
return $this->_connect($argHostname,$argUsername,$argPassword,$argProvider);
}
}
/*
adSchemaCatalogs = 1,
adSchemaCharacterSets = 2,
@@ -146,12 +148,12 @@ class ADODB_ado extends ADOConnection {
adSchemaMembers = 38
*/
function MetaTables()
function MetaTables($ttype = false, $showSchema = false, $mask = false)
{
$arr= array();
$dbc = $this->_connectionID;
$adors=@$dbc->OpenSchema(20);//tables
if ($adors){
$f = $adors->Fields(2);//table/view name
@@ -165,25 +167,25 @@ class ADODB_ado extends ADOConnection {
}
$adors->Close();
}
return $arr;
}
function MetaColumns($table, $normalize=true)
{
$table = strtoupper($table);
$arr = array();
$dbc = $this->_connectionID;
$adors=@$dbc->OpenSchema(4);//tables
if ($adors){
$t = $adors->Fields(2);//table/view name
while (!$adors->EOF){
if (strtoupper($t->Value) == $table) {
$fld = new ADOFieldObject();
$c = $adors->Fields(3);
$fld->name = $c->Value;
@@ -191,7 +193,7 @@ class ADODB_ado extends ADOConnection {
$fld->max_length = -1;
$arr[strtoupper($fld->name)]=$fld;
}
$adors->MoveNext();
}
$adors->Close();
@@ -199,20 +201,20 @@ class ADODB_ado extends ADOConnection {
$false = false;
return empty($arr) ? $false : $arr;
}
/* returns queryID or false */
function _query($sql,$inputarr=false)
function _query($sql,$inputarr=false)
{
$dbc = $this->_connectionID;
$false = false;
// return rs
// return rs
if ($inputarr) {
if (!empty($this->charPage))
$oCmd = new COM('ADODB.Command',null,$this->charPage);
else
@@ -238,7 +240,7 @@ class ADODB_ado extends ADOConnection {
$len=1;
else
$this->adoParameterType = 130;
// name, type, direction 1 = input, len,
$p = $oCmd->CreateParameter('name',$this->adoParameterType,1,$len,$val);
@@ -250,12 +252,12 @@ class ADODB_ado extends ADOConnection {
if ($dbc->Errors->Count > 0) return $false;
return $rs;
}
$rs = @$dbc->Execute($sql,$this->_affectedRows, $this->_execute_option);
if ($dbc->Errors->Count > 0) return $false;
if (! $rs) return $false;
if ($rs->State == 0) {
$true = true;
return $true; // 0 = adStateClosed means no records returned
@@ -263,11 +265,11 @@ class ADODB_ado extends ADOConnection {
return $rs;
}
function BeginTrans()
{
function BeginTrans()
{
if ($this->transOff) return true;
if (isset($this->_thisTransactions))
if (!$this->_thisTransactions) return false;
else {
@@ -279,12 +281,12 @@ class ADODB_ado extends ADOConnection {
$this->transCnt += 1;
return true;
}
function CommitTrans($ok=true)
{
function CommitTrans($ok=true)
{
if (!$ok) return $this->RollbackTrans();
if ($this->transOff) return true;
@$this->_connectionID->CommitTrans();
if ($this->transCnt) @$this->transCnt -= 1;
return true;
@@ -295,10 +297,10 @@ class ADODB_ado extends ADOConnection {
if ($this->transCnt) @$this->transCnt -= 1;
return true;
}
/* Returns: the last error message from previous database operation */
function ErrorMsg()
/* Returns: the last error message from previous database operation */
function ErrorMsg()
{
if (!$this->_connectionID) return "No connection established";
$errc = $this->_connectionID->Errors;
@@ -307,8 +309,8 @@ class ADODB_ado extends ADOConnection {
$err = $errc->Item($errc->Count-1);
return $err->Description;
}
function ErrorNo()
function ErrorNo()
{
$errc = $this->_connectionID->Errors;
if ($errc->Count == 0) return 0;
@@ -323,39 +325,39 @@ class ADODB_ado extends ADOConnection {
$this->_connectionID = false;
return true;
}
}
/*--------------------------------------------------------------------------------------
Class Name: Recordset
--------------------------------------------------------------------------------------*/
class ADORecordSet_ado extends ADORecordSet {
class ADORecordSet_ado extends ADORecordSet {
var $bind = false;
var $databaseType = "ado";
var $dataProvider = "ado";
var $databaseType = "ado";
var $dataProvider = "ado";
var $_tarr = false; // caches the types
var $_flds; // and field objects
var $canSeek = true;
var $hideErrors = true;
function ADORecordSet_ado($id,$mode=false)
function __construct($id,$mode=false)
{
if ($mode === false) {
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
$this->fetchMode = $mode;
return $this->ADORecordSet($id,$mode);
return parent::__construct($id,$mode);
}
// returns the field object
function FetchField($fieldOffset = -1) {
$off=$fieldOffset+1; // offsets begin at 1
$o= new ADOFieldObject();
$rs = $this->_queryID;
$f = $rs->Fields($fieldOffset);
@@ -363,12 +365,12 @@ class ADORecordSet_ado extends ADORecordSet {
$t = $f->Type;
$o->type = $this->MetaType($t);
$o->max_length = $f->DefinedSize;
$o->ado_type = $t;
$o->ado_type = $t;
//print "off=$off name=$o->name type=$o->type len=$o->max_length<br>";
return $o;
}
/* Use associative array to get fields array */
function Fields($colname)
{
@@ -380,25 +382,25 @@ class ADORecordSet_ado extends ADORecordSet {
$this->bind[strtoupper($o->name)] = $i;
}
}
return $this->fields[$this->bind[strtoupper($colname)]];
}
function _initrs()
{
$rs = $this->_queryID;
$this->_numOfRows = $rs->RecordCount;
$f = $rs->Fields;
$this->_numOfFields = $f->Count;
}
// should only be used to move forward as we normally use forward-only cursors
function _seek($row)
{
$rs = $this->_queryID;
$rs = $this->_queryID;
// absoluteposition doesn't work -- my maths is wrong ?
// $rs->AbsolutePosition->$row-2;
// return true;
@@ -406,10 +408,10 @@ class ADORecordSet_ado extends ADORecordSet {
@$rs->Move((integer)$row - $this->_currentRow-1); //adBookmarkFirst
return true;
}
/*
OLEDB types
enum DBTYPEENUM
{ DBTYPE_EMPTY = 0,
DBTYPE_NULL = 1,
@@ -445,9 +447,9 @@ class ADORecordSet_ado extends ADORecordSet {
DBTYPE_DBDATE = 133,
DBTYPE_DBTIME = 134,
DBTYPE_DBTIMESTAMP = 135
ADO Types
adEmpty = 0,
adTinyInt = 16,
adSmallInt = 2,
@@ -467,7 +469,7 @@ class ADORecordSet_ado extends ADORecordSet {
adUserDefined = 132,
adVariant = 12,
adIDispatch = 9,
adIUnknown = 13,
adIUnknown = 13,
adGUID = 72,
adDate = 7,
adDBDate = 133,
@@ -496,9 +498,9 @@ class ADORecordSet_ado extends ADORecordSet {
$t = $fieldobj->type;
$len = $fieldobj->max_length;
}
if (!is_numeric($t)) return $t;
switch ($t) {
case 0:
case 12: // variant
@@ -511,7 +513,7 @@ class ADORecordSet_ado extends ADORecordSet {
case 204: // varBin
case 72: // guid
if ($len <= $this->blobSize) return 'C';
case 201:
case 203:
return 'X';
@@ -521,12 +523,12 @@ class ADORecordSet_ado extends ADORecordSet {
return 'B';
case 7:
case 133: return 'D';
case 134:
case 135: return 'T';
case 11: return 'L';
case 16:// adTinyInt = 16,
case 2://adSmallInt = 2,
case 3://adInteger = 3,
@@ -539,17 +541,17 @@ class ADORecordSet_ado extends ADORecordSet {
default: return 'N';
}
}
// time stamp not supported yet
function _fetch()
{
{
$rs = $this->_queryID;
if (!$rs or $rs->EOF) {
$this->fields = false;
return false;
}
$this->fields = array();
if (!$this->_tarr) {
$tarr = array();
$flds = array();
@@ -559,12 +561,12 @@ class ADORecordSet_ado extends ADORecordSet {
$tarr[] = $f->Type;
}
// bind types and flds only once
$this->_tarr = $tarr;
$this->_tarr = $tarr;
$this->_flds = $flds;
}
$t = reset($this->_tarr);
$f = reset($this->_flds);
if ($this->hideErrors) $olde = error_reporting(E_ERROR|E_CORE_ERROR);// sometimes $f->value be null
for ($i=0,$max = $this->_numOfFields; $i < $max; $i++) {
//echo "<p>",$t,' ';var_dump($f->value); echo '</p>';
@@ -575,12 +577,12 @@ class ADORecordSet_ado extends ADORecordSet {
if (!is_numeric($f->value)) # $val = variant_date_to_timestamp($f->value);
// VT_DATE stores dates as (float) fractional days since 1899/12/30 00:00:00
$val=(float) variant_cast($f->value,VT_R8)*3600*24-2209161600;
else
else
$val = $f->value;
$this->fields[] = adodb_date('Y-m-d H:i:s',$val);
}
break;
case 133:// A date value (yyyymmdd)
break;
case 133:// A date value (yyyymmdd)
if ($val = $f->value) {
$this->fields[] = substr($val,0,4).'-'.substr($val,4,2).'-'.substr($val,6,2);
} else
@@ -591,7 +593,7 @@ class ADORecordSet_ado extends ADORecordSet {
else {
if (!is_numeric($f->value)) $val = variant_date_to_timestamp($f->value);
else $val = $f->value;
if (($val % 86400) == 0) $this->fields[] = adodb_date('Y-m-d',$val);
else $this->fields[] = adodb_date('Y-m-d H:i:s',$val);
}
@@ -610,11 +612,11 @@ class ADORecordSet_ado extends ADORecordSet {
else $val = 0;
}
if(is_null($f->value)) $val = null;
$this->fields[] = $val;
break;
default:
$this->fields[] = $f->value;
$this->fields[] = $f->value;
break;
}
//print " $f->value $t, ";
@@ -623,27 +625,27 @@ class ADORecordSet_ado extends ADORecordSet {
} // for
if ($this->hideErrors) error_reporting($olde);
@$rs->MoveNext(); // @ needed for some versions of PHP!
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
$this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
$this->fields = $this->GetRowAssoc();
}
return true;
}
function NextRecordSet()
{
$rs = $this->_queryID;
$this->_queryID = $rs->NextRecordSet();
//$this->_queryID = $this->_QueryId->NextRecordSet();
if ($this->_queryID == null) return false;
$this->_currentRow = -1;
$this->_currentPage = -1;
$this->bind = false;
$this->fields = false;
$this->_flds = false;
$this->_tarr = false;
$this->_inited = false;
$this->Init();
return true;
@@ -652,9 +654,7 @@ class ADORecordSet_ado extends ADORecordSet {
function _close() {
$this->_flds = false;
@$this->_queryID->Close();// by Pete Dishman (peterd@telephonetics.co.uk)
$this->_queryID = false;
$this->_queryID = false;
}
}
?>
+136 -132
View File
@@ -1,31 +1,33 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). 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.
/*
@version v5.20.9 21-Dec-2016
@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.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
Microsoft ADO data driver. Requires ADO. Works only on MS Windows. PHP5 compat version.
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
define("_ADODB_ADO_LAYER", 1 );
/*--------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------*/
class ADODB_ado extends ADOConnection {
var $databaseType = "ado";
var $databaseType = "ado";
var $_bindInputArray = false;
var $fmtDate = "'Y-m-d'";
var $fmtTimeStamp = "'Y-m-d, h:i:sA'";
var $replaceQuote = "''"; // string to use to replace quotes
var $dataProvider = "ado";
var $dataProvider = "ado";
var $hasAffectedRows = true;
var $adoParameterType = 201; // 201 = long varchar, 203=long wide varchar, 205 = long varbinary
var $_affectedRows = false;
@@ -34,11 +36,11 @@ class ADODB_ado extends ADOConnection {
var $_cursor_location = 3; // 2=adUseServer, 3 = adUseClient;
var $_lock_type = -1;
var $_execute_option = -1;
var $poorAffectedRows = true;
var $poorAffectedRows = true;
var $charPage;
function ADODB_ado()
{
function __construct()
{
$this->_affectedRows = new VARIANT;
}
@@ -47,14 +49,14 @@ class ADODB_ado extends ADOConnection {
if (!empty($this->_connectionID)) $desc = $this->_connectionID->provider;
return array('description' => $desc, 'version' => '');
}
function _affectedrows()
{
if (PHP_VERSION >= 5) return $this->_affectedRows;
return $this->_affectedRows->value;
}
// you can also pass a connection string like this:
//
// $DB->Connect('USER ID=sa;PASSWORD=pwd;SERVER=mangrove;DATABASE=ai',false,false,'SQLOLEDB');
@@ -63,73 +65,73 @@ class ADODB_ado extends ADOConnection {
// two modes
// - if $argProvider is empty, we assume that $argDBorProvider holds provider -- this is for backward compat
// - if $argProvider is not empty, then $argDBorProvider holds db
if ($argProvider) {
$argDatabasename = $argDBorProvider;
} else {
$argDatabasename = '';
if ($argDBorProvider) $argProvider = $argDBorProvider;
else if (stripos($argHostname,'PROVIDER') === false) /* full conn string is not in $argHostname */
else if (stripos($argHostname,'PROVIDER') === false) /* full conn string is not in $argHostname */
$argProvider = 'MSDASQL';
}
try {
$u = 'UID';
$p = 'PWD';
if (!empty($this->charPage))
$dbc = new COM('ADODB.Connection',null,$this->charPage);
else
$dbc = new COM('ADODB.Connection');
if (! $dbc) return false;
/* special support if provider is mssql or access */
if ($argProvider=='mssql') {
$u = 'User Id'; //User parameter name for OLEDB
$p = 'Password';
$p = 'Password';
$argProvider = "SQLOLEDB"; // SQL Server Provider
// not yet
//if ($argDatabasename) $argHostname .= ";Initial Catalog=$argDatabasename";
//use trusted conection for SQL if username not specified
if (!$argUsername) $argHostname .= ";Trusted_Connection=Yes";
} else if ($argProvider=='access')
$argProvider = "Microsoft.Jet.OLEDB.4.0"; // Microsoft Jet Provider
if ($argProvider) $dbc->Provider = $argProvider;
if ($argProvider) $argHostname = "PROVIDER=$argProvider;DRIVER={SQL Server};SERVER=$argHostname";
if ($argProvider) $dbc->Provider = $argProvider;
if ($argDatabasename) $argHostname .= ";DATABASE=$argDatabasename";
if ($argProvider) $argHostname = "PROVIDER=$argProvider;DRIVER={SQL Server};SERVER=$argHostname";
if ($argDatabasename) $argHostname .= ";DATABASE=$argDatabasename";
if ($argUsername) $argHostname .= ";$u=$argUsername";
if ($argPassword)$argHostname .= ";$p=$argPassword";
if ($this->debug) ADOConnection::outp( "Host=".$argHostname."<BR>\n version=$dbc->version");
// @ added below for php 4.0.1 and earlier
@$dbc->Open((string) $argHostname);
$this->_connectionID = $dbc;
$dbc->CursorLocation = $this->_cursor_location;
return $dbc->State > 0;
} catch (exception $e) {
if ($this->debug);echo "<pre>",$argHostname,"\n",$e,"</pre>\n";
if ($this->debug) echo "<pre>",$argHostname,"\n",$e,"</pre>\n";
}
return false;
}
// returns true or false
function _pconnect($argHostname, $argUsername, $argPassword, $argProvider='MSDASQL')
{
return $this->_connect($argHostname,$argUsername,$argPassword,$argProvider);
}
}
/*
adSchemaCatalogs = 1,
adSchemaCharacterSets = 2,
@@ -171,12 +173,12 @@ class ADODB_ado extends ADOConnection {
adSchemaMembers = 38
*/
function MetaTables()
function MetaTables($ttype = false, $showSchema = false, $mask = false)
{
$arr= array();
$dbc = $this->_connectionID;
$adors=@$dbc->OpenSchema(20);//tables
if ($adors){
$f = $adors->Fields(2);//table/view name
@@ -190,25 +192,25 @@ class ADODB_ado extends ADOConnection {
}
$adors->Close();
}
return $arr;
}
function MetaColumns($table, $normalize=true)
{
$table = strtoupper($table);
$arr= array();
$dbc = $this->_connectionID;
$adors=@$dbc->OpenSchema(4);//tables
if ($adors){
$t = $adors->Fields(2);//table/view name
while (!$adors->EOF){
if (strtoupper($t->Value) == $table) {
$fld = new ADOFieldObject();
$c = $adors->Fields(3);
$fld->name = $c->Value;
@@ -216,28 +218,28 @@ class ADODB_ado extends ADOConnection {
$fld->max_length = -1;
$arr[strtoupper($fld->name)]=$fld;
}
$adors->MoveNext();
}
$adors->Close();
}
return $arr;
}
/* returns queryID or false */
function _query($sql,$inputarr=false)
function _query($sql,$inputarr=false)
{
try { // In PHP5, all COM errors are exceptions, so to maintain old behaviour...
$dbc = $this->_connectionID;
// return rs
// return rs
$false = false;
if ($inputarr) {
if (!empty($this->charPage))
$oCmd = new COM('ADODB.Command',null,$this->charPage);
else
@@ -261,42 +263,42 @@ class ADODB_ado extends ADOConnection {
$len=1;
else
$this->adoParameterType = 130;
// name, type, direction 1 = input, len,
$p = $oCmd->CreateParameter('name',$this->adoParameterType,1,$len,$val);
$oCmd->Parameters->Append($p);
}
$p = false;
$rs = $oCmd->Execute();
$e = $dbc->Errors;
if ($dbc->Errors->Count > 0) return $false;
return $rs;
}
$rs = @$dbc->Execute($sql,$this->_affectedRows, $this->_execute_option);
if ($dbc->Errors->Count > 0) return $false;
if (! $rs) return $false;
if ($rs->State == 0) {
$true = true;
return $true; // 0 = adStateClosed means no records returned
}
return $rs;
} catch (exception $e) {
}
return $false;
}
function BeginTrans()
{
function BeginTrans()
{
if ($this->transOff) return true;
if (isset($this->_thisTransactions))
if (!$this->_thisTransactions) return false;
else {
@@ -308,11 +310,11 @@ class ADODB_ado extends ADOConnection {
$this->transCnt += 1;
return true;
}
function CommitTrans($ok=true)
{
function CommitTrans($ok=true)
{
if (!$ok) return $this->RollbackTrans();
if ($this->transOff) return true;
@$this->_connectionID->CommitTrans();
if ($this->transCnt) @$this->transCnt -= 1;
return true;
@@ -323,14 +325,14 @@ class ADODB_ado extends ADOConnection {
if ($this->transCnt) @$this->transCnt -= 1;
return true;
}
/* Returns: the last error message from previous database operation */
function ErrorMsg()
/* Returns: the last error message from previous database operation */
function ErrorMsg()
{
if (!$this->_connectionID) return "No connection established";
$errmsg = '';
try {
$errc = $this->_connectionID->Errors;
if (!$errc) return "No Errors object found";
@@ -341,8 +343,8 @@ class ADODB_ado extends ADOConnection {
}
return $errmsg;
}
function ErrorNo()
function ErrorNo()
{
$errc = $this->_connectionID->Errors;
if ($errc->Count == 0) return 0;
@@ -357,55 +359,55 @@ class ADODB_ado extends ADOConnection {
$this->_connectionID = false;
return true;
}
}
/*--------------------------------------------------------------------------------------
Class Name: Recordset
--------------------------------------------------------------------------------------*/
class ADORecordSet_ado extends ADORecordSet {
class ADORecordSet_ado extends ADORecordSet {
var $bind = false;
var $databaseType = "ado";
var $dataProvider = "ado";
var $databaseType = "ado";
var $dataProvider = "ado";
var $_tarr = false; // caches the types
var $_flds; // and field objects
var $canSeek = true;
var $hideErrors = true;
function ADORecordSet_ado($id,$mode=false)
function __construct($id,$mode=false)
{
if ($mode === false) {
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
$this->fetchMode = $mode;
return $this->ADORecordSet($id,$mode);
return parent::__construct($id,$mode);
}
// returns the field object
function FetchField($fieldOffset = -1) {
$off=$fieldOffset+1; // offsets begin at 1
$o= new ADOFieldObject();
$rs = $this->_queryID;
if (!$rs) return false;
$f = $rs->Fields($fieldOffset);
$o->name = $f->Name;
$t = $f->Type;
$o->type = $this->MetaType($t);
$o->max_length = $f->DefinedSize;
$o->ado_type = $t;
//print "off=$off name=$o->name type=$o->type len=$o->max_length<br>";
return $o;
}
/* Use associative array to get fields array */
function Fields($colname)
{
@@ -417,15 +419,15 @@ class ADORecordSet_ado extends ADORecordSet {
$this->bind[strtoupper($o->name)] = $i;
}
}
return $this->fields[$this->bind[strtoupper($colname)]];
}
function _initrs()
{
$rs = $this->_queryID;
try {
$this->_numOfRows = $rs->RecordCount;
} catch (Exception $e) {
@@ -434,12 +436,12 @@ class ADORecordSet_ado extends ADORecordSet {
$f = $rs->Fields;
$this->_numOfFields = $f->Count;
}
// should only be used to move forward as we normally use forward-only cursors
function _seek($row)
{
$rs = $this->_queryID;
$rs = $this->_queryID;
// absoluteposition doesn't work -- my maths is wrong ?
// $rs->AbsolutePosition->$row-2;
// return true;
@@ -447,10 +449,10 @@ class ADORecordSet_ado extends ADORecordSet {
@$rs->Move((integer)$row - $this->_currentRow-1); //adBookmarkFirst
return true;
}
/*
OLEDB types
enum DBTYPEENUM
{ DBTYPE_EMPTY = 0,
DBTYPE_NULL = 1,
@@ -486,9 +488,9 @@ class ADORecordSet_ado extends ADORecordSet {
DBTYPE_DBDATE = 133,
DBTYPE_DBTIME = 134,
DBTYPE_DBTIMESTAMP = 135
ADO Types
adEmpty = 0,
adTinyInt = 16,
adSmallInt = 2,
@@ -508,7 +510,7 @@ class ADORecordSet_ado extends ADORecordSet {
adUserDefined = 132,
adVariant = 12,
adIDispatch = 9,
adIUnknown = 13,
adIUnknown = 13,
adGUID = 72,
adDate = 7,
adDBDate = 133,
@@ -537,9 +539,9 @@ class ADORecordSet_ado extends ADORecordSet {
$t = $fieldobj->type;
$len = $fieldobj->max_length;
}
if (!is_numeric($t)) return $t;
switch ($t) {
case 0:
case 12: // variant
@@ -552,7 +554,7 @@ class ADORecordSet_ado extends ADORecordSet {
case 204: // varBin
case 72: // guid
if ($len <= $this->blobSize) return 'C';
case 201:
case 203:
return 'X';
@@ -562,12 +564,12 @@ class ADORecordSet_ado extends ADORecordSet {
return 'B';
case 7:
case 133: return 'D';
case 134:
case 135: return 'T';
case 11: return 'L';
case 16:// adTinyInt = 16,
case 2://adSmallInt = 2,
case 3://adInteger = 3,
@@ -580,17 +582,17 @@ class ADORecordSet_ado extends ADORecordSet {
default: return 'N';
}
}
// time stamp not supported yet
function _fetch()
{
{
$rs = $this->_queryID;
if (!$rs or $rs->EOF) {
$this->fields = false;
return false;
}
$this->fields = array();
if (!$this->_tarr) {
$tarr = array();
$flds = array();
@@ -600,12 +602,12 @@ class ADORecordSet_ado extends ADORecordSet {
$tarr[] = $f->Type;
}
// bind types and flds only once
$this->_tarr = $tarr;
$this->_tarr = $tarr;
$this->_flds = $flds;
}
$t = reset($this->_tarr);
$f = reset($this->_flds);
if ($this->hideErrors) $olde = error_reporting(E_ERROR|E_CORE_ERROR);// sometimes $f->value be null
for ($i=0,$max = $this->_numOfFields; $i < $max; $i++) {
//echo "<p>",$t,' ';var_dump($f->value); echo '</p>';
@@ -616,12 +618,12 @@ class ADORecordSet_ado extends ADORecordSet {
if (!is_numeric($f->value)) # $val = variant_date_to_timestamp($f->value);
// VT_DATE stores dates as (float) fractional days since 1899/12/30 00:00:00
$val= (float) variant_cast($f->value,VT_R8)*3600*24-2209161600;
else
else
$val = $f->value;
$this->fields[] = adodb_date('Y-m-d H:i:s',$val);
}
break;
case 133:// A date value (yyyymmdd)
break;
case 133:// A date value (yyyymmdd)
if ($val = $f->value) {
$this->fields[] = substr($val,0,4).'-'.substr($val,4,2).'-'.substr($val,6,2);
} else
@@ -632,7 +634,7 @@ class ADORecordSet_ado extends ADORecordSet {
else {
if (!is_numeric($f->value)) $val = variant_date_to_timestamp($f->value);
else $val = $f->value;
if (($val % 86400) == 0) $this->fields[] = adodb_date('Y-m-d',$val);
else $this->fields[] = adodb_date('Y-m-d H:i:s',$val);
}
@@ -640,6 +642,10 @@ class ADORecordSet_ado extends ADORecordSet {
case 1: // null
$this->fields[] = false;
break;
case 20:
case 21: // bigint (64 bit)
$this->fields[] = (float) $f->value; // if 64 bit PHP, could use (int)
break;
case 6: // currency is not supported properly;
ADOConnection::outp( '<b>'.$f->Name.': currency type not supported by PHP</b>');
$this->fields[] = (float) $f->value;
@@ -651,11 +657,11 @@ class ADORecordSet_ado extends ADORecordSet {
else $val = 0;
}
if(is_null($f->value)) $val = null;
$this->fields[] = $val;
break;
default:
$this->fields[] = $f->value;
$this->fields[] = $f->value;
break;
}
//print " $f->value $t, ";
@@ -664,27 +670,27 @@ class ADORecordSet_ado extends ADORecordSet {
} // for
if ($this->hideErrors) error_reporting($olde);
@$rs->MoveNext(); // @ needed for some versions of PHP!
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
$this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
$this->fields = $this->GetRowAssoc();
}
return true;
}
function NextRecordSet()
{
$rs = $this->_queryID;
$this->_queryID = $rs->NextRecordSet();
//$this->_queryID = $this->_QueryId->NextRecordSet();
if ($this->_queryID == null) return false;
$this->_currentRow = -1;
$this->_currentPage = -1;
$this->bind = false;
$this->fields = false;
$this->_flds = false;
$this->_tarr = false;
$this->_inited = false;
$this->Init();
return true;
@@ -696,9 +702,7 @@ class ADORecordSet_ado extends ADORecordSet {
@$this->_queryID->Close();// by Pete Dishman (peterd@telephonetics.co.uk)
} catch (Exception $e) {
}
$this->_queryID = false;
$this->_queryID = false;
}
}
?>
+20 -24
View File
@@ -1,13 +1,15 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). 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. See License.txt.
/*
@version v5.20.9 21-Dec-2016
@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. See License.txt.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
Microsoft Access ADO data driver. Requires ADO and ODBC. Works only on MS Windows.
*/
@@ -19,7 +21,7 @@ if (!defined('_ADODB_ADO_LAYER')) {
else include(ADODB_DIR."/drivers/adodb-ado.inc.php");
}
class ADODB_ado_access extends ADODB_ado {
class ADODB_ado_access extends ADODB_ado {
var $databaseType = 'ado_access';
var $hasTop = 'top'; // support mssql SELECT TOP 10 * FROM TABLE
var $fmtDate = "#Y-m-d#";
@@ -27,28 +29,22 @@ class ADODB_ado_access extends ADODB_ado {
var $sysDate = "FORMAT(NOW,'yyyy-mm-dd')";
var $sysTimeStamp = 'NOW';
var $upperCase = 'ucase';
function ADODB_ado_access()
{
$this->ADODB_ado();
}
/*function BeginTrans() { return false;}
function CommitTrans() { return false;}
function RollbackTrans() { return false;}*/
}
class ADORecordSet_ado_access extends ADORecordSet_ado {
var $databaseType = "ado_access";
function ADORecordSet_ado_access($id,$mode=false)
class ADORecordSet_ado_access extends ADORecordSet_ado {
var $databaseType = "ado_access";
function __construct($id,$mode=false)
{
return $this->ADORecordSet_ado($id,$mode);
return parent::__construct($id,$mode);
}
}
?>
+37 -41
View File
@@ -1,17 +1,19 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). 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.
/*
@version v5.20.9 21-Dec-2016
@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.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
Microsoft SQL Server ADO data driver. Requires ADO and MSSQL client.
Microsoft SQL Server ADO data driver. Requires ADO and MSSQL client.
Works only on MS Windows.
Warning: Some versions of PHP (esp PHP4) leak memory when ADO/COM is used.
Warning: Some versions of PHP (esp PHP4) leak memory when ADO/COM is used.
Please check http://bugs.php.net/ for more info.
*/
@@ -24,7 +26,7 @@ if (!defined('_ADODB_ADO_LAYER')) {
}
class ADODB_ado_mssql extends ADODB_ado {
class ADODB_ado_mssql extends ADODB_ado {
var $databaseType = 'ado_mssql';
var $hasTop = 'top';
var $hasInsertID = true;
@@ -36,25 +38,20 @@ class ADODB_ado_mssql extends ADODB_ado {
var $substr = "substring";
var $length = 'len';
var $_dropSeqSQL = "drop table %s";
//var $_inTransaction = 1; // always open recordsets, so no transaction problems.
function ADODB_ado_mssql()
{
$this->ADODB_ado();
}
function _insertid()
{
return $this->GetOne('select SCOPE_IDENTITY()');
}
function _affectedrows()
{
return $this->GetOne('select @@rowcount');
}
function SetTransactionMode( $transaction_mode )
function SetTransactionMode( $transaction_mode )
{
$this->_transmode = $transaction_mode;
if (empty($transaction_mode)) {
@@ -64,25 +61,25 @@ class ADODB_ado_mssql extends ADODB_ado {
if (!stristr($transaction_mode,'isolation')) $transaction_mode = 'ISOLATION LEVEL '.$transaction_mode;
$this->Execute("SET TRANSACTION ".$transaction_mode);
}
function qstr($s,$magic_quotes=false)
{
$s = ADOConnection::qstr($s, $magic_quotes);
return str_replace("\0", "\\\\000", $s);
}
function MetaColumns($table, $normalize=true)
{
$table = strtoupper($table);
$arr= array();
$dbc = $this->_connectionID;
$osoptions = array();
$osoptions[0] = null;
$osoptions[1] = null;
$osoptions[2] = $table;
$osoptions[3] = null;
$adors=@$dbc->OpenSchema(4, $osoptions);//tables
if ($adors){
@@ -93,7 +90,7 @@ class ADODB_ado_mssql extends ADODB_ado {
$fld->type = 'CHAR'; // cannot discover type in ADO!
$fld->max_length = -1;
$arr[strtoupper($fld->name)]=$fld;
$adors->MoveNext();
}
$adors->Close();
@@ -101,10 +98,10 @@ class ADODB_ado_mssql extends ADODB_ado {
$false = false;
return empty($arr) ? $false : $arr;
}
function CreateSequence($seq='adodbseq',$start=1)
{
$this->Execute('BEGIN TRANSACTION adodbseq');
$start -= 1;
$this->Execute("create table $seq (id float(53))");
@@ -113,7 +110,7 @@ class ADODB_ado_mssql extends ADODB_ado {
$this->Execute('ROLLBACK TRANSACTION adodbseq');
return false;
}
$this->Execute('COMMIT TRANSACTION adodbseq');
$this->Execute('COMMIT TRANSACTION adodbseq');
return true;
}
@@ -129,26 +126,25 @@ class ADODB_ado_mssql extends ADODB_ado {
$this->Execute('ROLLBACK TRANSACTION adodbseq');
return false;
}
$this->Execute('COMMIT TRANSACTION adodbseq');
$this->Execute('COMMIT TRANSACTION adodbseq');
return $start;
}
$num = $this->GetOne("select id from $seq");
$this->Execute('COMMIT TRANSACTION adodbseq');
$this->Execute('COMMIT TRANSACTION adodbseq');
return $num;
// in old implementation, pre 1.90, we returned GUID...
//return $this->GetOne("SELECT CONVERT(varchar(255), NEWID()) AS 'Char'");
}
} // end class
class ADORecordSet_ado_mssql extends ADORecordSet_ado {
} // end class
class ADORecordSet_ado_mssql extends ADORecordSet_ado {
var $databaseType = 'ado_mssql';
function ADORecordSet_ado_mssql($id,$mode=false)
function __construct($id,$mode=false)
{
return $this->ADORecordSet_ado($id,$mode);
return parent::__construct($id,$mode);
}
}
?>
+16 -28
View File
@@ -1,6 +1,6 @@
<?php
/*
(c) 2000-2007 John Lim (jlim#natsoft.com.my). All rights reserved.
(c) 2000-2014 John Lim (jlim#natsoft.com.my). All rights reserved.
Portions Copyright (c) 2007-2009, iAnywhere Solutions, Inc.
All rights reserved. All unpublished rights reserved.
@@ -66,7 +66,7 @@ class ADODB_ads extends ADOConnection {
var $uCaseTables = true; // for meta* functions, uppercase table names
function ADODB_ads()
function __construct()
{
$this->_haserrorfunctions = ADODB_PHPVER >= 0x4050;
$this->_has_stupid_odbc_fetch_api_change = ADODB_PHPVER >= 0x4200;
@@ -136,7 +136,7 @@ class ADODB_ads extends ADOConnection {
// returns true or false
function CreateSequence( $seqname,$start=1)
function CreateSequence($seqname = 'adodbseq', $start = 1)
{
$res = $this->Execute("CREATE TABLE $seqname ( ID autoinc( 1 ) ) IN DATABASE");
if(!$res){
@@ -149,7 +149,7 @@ class ADODB_ads extends ADOConnection {
}
// returns true or false
function DropSequence($seqname)
function DropSequence($seqname = 'adodbseq')
{
$res = $this->Execute("DROP TABLE $seqname");
if(!$res){
@@ -164,7 +164,7 @@ class ADODB_ads extends ADOConnection {
// returns the generated ID or false
// checks if the table already exists, else creates the table and inserts a record into the table
// and gets the ID number of the last inserted record.
function GenID($seqname,$start=1)
function GenID($seqname = 'adodbseq', $start = 1)
{
$go = $this->Execute("select * from $seqname");
if (!$go){
@@ -254,7 +254,7 @@ class ADODB_ads extends ADOConnection {
// Returns tables,Views or both on succesfull execution. Returns
// tables by default on succesfull execustion.
function &MetaTables($ttype)
function &MetaTables($ttype = false, $showSchema = false, $mask = false)
{
$recordSet1 = $this->Execute("select * from system.tables");
if(!$recordSet1){
@@ -294,7 +294,7 @@ class ADODB_ads extends ADOConnection {
}
function &MetaPrimaryKeys($table)
function &MetaPrimaryKeys($table, $owner = false)
{
$recordSet = $this->Execute("select table_primary_key from system.tables where name='$table'");
if(!$recordSet){
@@ -378,7 +378,7 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/od
}
}
function &MetaColumns($table)
function &MetaColumns($table, $normalize = true)
{
global $ADODB_FETCH_MODE;
@@ -486,7 +486,7 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/od
}
// Returns an array of columns names for a given table
function &MetaColumnNames($table)
function &MetaColumnNames($table, $numIndexes = false, $useattnum = false)
{
$recordSet = $this->Execute("select name from system.columns where parent='$table'");
if(!$recordSet){
@@ -654,7 +654,7 @@ class ADORecordSet_ads extends ADORecordSet {
var $useFetchArray;
var $_has_stupid_odbc_fetch_api_change;
function ADORecordSet_ads($id,$mode=false)
function __construct($id,$mode=false)
{
if ($mode === false) {
global $ADODB_FETCH_MODE;
@@ -667,7 +667,7 @@ class ADORecordSet_ads extends ADORecordSet {
// the following is required for mysql odbc driver in 4.3.1 -- why?
$this->EOF = false;
$this->_currentRow = -1;
//$this->ADORecordSet($id);
//parent::__construct($id);
}
@@ -731,7 +731,7 @@ class ADORecordSet_ads extends ADORecordSet {
$this->fetchMode = $savem;
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
$this->fields =& $this->GetRowAssoc(ADODB_ASSOC_CASE);
$this->fields =& $this->GetRowAssoc();
}
$results = array();
@@ -749,18 +749,8 @@ class ADORecordSet_ads extends ADORecordSet {
{
if ($this->_numOfRows != 0 && !$this->EOF) {
$this->_currentRow++;
if ($this->_has_stupid_odbc_fetch_api_change)
$rez = @ads_fetch_into($this->_queryID,$this->fields);
else {
$row = 0;
$rez = @ads_fetch_into($this->_queryID,$row,$this->fields);
}
if ($rez) {
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
$this->fields =& $this->GetRowAssoc(ADODB_ASSOC_CASE);
}
return true;
if( $this->_fetch() ) {
return true;
}
}
$this->fields = false;
@@ -770,7 +760,7 @@ class ADORecordSet_ads extends ADORecordSet {
function _fetch()
{
$this->fields = false;
if ($this->_has_stupid_odbc_fetch_api_change)
$rez = @ads_fetch_into($this->_queryID,$this->fields);
else {
@@ -779,11 +769,10 @@ class ADORecordSet_ads extends ADORecordSet {
}
if ($rez) {
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
$this->fields =& $this->GetRowAssoc(ADODB_ASSOC_CASE);
$this->fields =& $this->GetRowAssoc();
}
return true;
}
$this->fields = false;
return false;
}
@@ -793,4 +782,3 @@ class ADORecordSet_ads extends ADORecordSet {
}
}
?>
@@ -1,13 +1,15 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). 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.
/*
@version v5.20.9 21-Dec-2016
@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.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
Support Borland Interbase 6.5 and later
*/
@@ -18,28 +20,22 @@ if (!defined('ADODB_DIR')) die();
include_once(ADODB_DIR."/drivers/adodb-ibase.inc.php");
class ADODB_borland_ibase extends ADODB_ibase {
var $databaseType = "borland_ibase";
function ADODB_borland_ibase()
{
$this->ADODB_ibase();
}
var $databaseType = "borland_ibase";
function BeginTrans()
{
{
if ($this->transOff) return true;
$this->transCnt += 1;
$this->autoCommit = false;
$this->_transactionID = ibase_trans($this->ibasetrans, $this->_connectionID);
return $this->_transactionID;
}
function ServerInfo()
{
$arr['dialect'] = $this->dialect;
switch($arr['dialect']) {
case '':
case '':
case '1': $s = 'Interbase 6.5, Dialect 1'; break;
case '2': $s = 'Interbase 6.5, Dialect 2'; break;
default:
@@ -49,44 +45,43 @@ class ADODB_borland_ibase extends ADODB_ibase {
$arr['description'] = $s;
return $arr;
}
// Note that Interbase 6.5 uses ROWS instead - don't you love forking wars!
// SELECT col1, col2 FROM table ROWS 5 -- get 5 rows
// SELECT col1, col2 FROM table ROWS 5 -- get 5 rows
// SELECT col1, col2 FROM TABLE ORDER BY col1 ROWS 3 TO 7 -- first 5 skip 2
// Firebird uses
// SELECT FIRST 5 SKIP 2 col1, col2 FROM TABLE
function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
{
if ($nrows > 0) {
if ($offset <= 0) $str = " ROWS $nrows ";
if ($offset <= 0) $str = " ROWS $nrows ";
else {
$a = $offset+1;
$b = $offset+$nrows;
$str = " ROWS $a TO $b";
}
} else {
// ok, skip
// ok, skip
$a = $offset + 1;
$str = " ROWS $a TO 999999999"; // 999 million
}
$sql .= $str;
return ($secs2cache) ?
return ($secs2cache) ?
$this->CacheExecute($secs2cache,$sql,$inputarr)
:
$this->Execute($sql,$inputarr);
}
};
class ADORecordSet_borland_ibase extends ADORecordSet_ibase {
var $databaseType = "borland_ibase";
function ADORecordSet_borland_ibase($id,$mode=false)
};
class ADORecordSet_borland_ibase extends ADORecordSet_ibase {
var $databaseType = "borland_ibase";
function __construct($id,$mode=false)
{
$this->ADORecordSet_ibase($id,$mode);
parent::__construct($id,$mode);
}
}
?>
+52 -52
View File
@@ -1,19 +1,21 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
@version v5.20.9 21-Dec-2016
@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.
Set tabs to 4.
Currently unsupported: MetaDatabases, MetaTables and MetaColumns, and also inputarr in Execute.
Native types have been converted to MetaTypes.
Transactions not supported yet.
Limitation of url length. For IIS, see MaxClientRequestBuffer registry value.
http://support.microsoft.com/default.aspx?scid=kb;en-us;260694
*/
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
@@ -22,12 +24,12 @@ if (! defined("_ADODB_CSV_LAYER")) {
define("_ADODB_CSV_LAYER", 1 );
include_once(ADODB_DIR.'/adodb-csvlib.inc.php');
class ADODB_csv extends ADOConnection {
var $databaseType = 'csv';
var $databaseProvider = 'csv';
var $hasInsertID = true;
var $hasAffectedRows = true;
var $hasAffectedRows = true;
var $fmtTimeStamp = "'Y-m-d H:i:s'";
var $_affectedrows=0;
var $_insertid=0;
@@ -35,35 +37,35 @@ class ADODB_csv extends ADOConnection {
var $replaceQuote = "''"; // string to use to replace quotes
var $hasTransactions = false;
var $_errorNo = false;
function ADODB_csv()
{
function __construct()
{
}
function _insertid()
{
return $this->_insertid;
}
function _affectedrows()
{
return $this->_affectedrows;
}
function MetaDatabases()
{
return false;
}
// returns true or false
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
if (strtolower(substr($argHostname,0,7)) !== 'http://') return false;
$this->_url = $argHostname;
return true;
return true;
}
// returns true or false
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
@@ -71,24 +73,24 @@ class ADODB_csv extends ADOConnection {
$this->_url = $argHostname;
return true;
}
function MetaColumns($table, $normalize=true)
function MetaColumns($table, $normalize=true)
{
return false;
}
// parameters use PostgreSQL convention, not MySQL
function SelectLimit($sql,$nrows=-1,$offset=-1)
function SelectLimit($sql, $nrows = -1, $offset = -1, $inputarr = false, $secs2cache = 0)
{
global $ADODB_FETCH_MODE;
$url = $this->_url.'?sql='.urlencode($sql)."&nrows=$nrows&fetch=".
(($this->fetchMode !== false)?$this->fetchMode : $ADODB_FETCH_MODE).
"&offset=$offset";
$err = false;
$rs = csv2rs($url,$err,false);
if ($this->debug) print "$url<br><i>$err</i><br>";
$at = strpos($err,'::::');
@@ -99,25 +101,25 @@ class ADODB_csv extends ADOConnection {
$this->_errorMsg = substr($err,$at+4,1024);
$this->_errorNo = -9999;
}
if ($this->_errorNo)
if ($this->_errorNo)
if ($fn = $this->raiseErrorFn) {
$fn($this->databaseType,'EXECUTE',$this->ErrorNo(),$this->ErrorMsg(),$sql,'');
}
if (is_object($rs)) {
$rs->databaseType='csv';
if (is_object($rs)) {
$rs->databaseType='csv';
$rs->fetchMode = ($this->fetchMode !== false) ? $this->fetchMode : $ADODB_FETCH_MODE;
$rs->connection = $this;
}
return $rs;
}
// returns queryID or false
function _Execute($sql,$inputarr=false)
{
global $ADODB_FETCH_MODE;
if (!$this->_bindInputArray && $inputarr) {
$sqlarr = explode('?',$sql);
$sql = '';
@@ -132,37 +134,37 @@ class ADODB_csv extends ADOConnection {
else
$sql .= $v;
$i += 1;
}
$sql .= $sqlarr[$i];
if ($i+1 != sizeof($sqlarr))
if ($i+1 != sizeof($sqlarr))
print "Input Array does not match ?: ".htmlspecialchars($sql);
$inputarr = false;
}
$url = $this->_url.'?sql='.urlencode($sql)."&fetch=".
(($this->fetchMode !== false)?$this->fetchMode : $ADODB_FETCH_MODE);
$err = false;
$rs = csv2rs($url,$err,false);
if ($this->debug) print urldecode($url)."<br><i>$err</i><br>";
$at = strpos($err,'::::');
if ($at === false) {
if ($at === false) {
$this->_errorMsg = $err;
$this->_errorNo = (integer)$err;
} else {
$this->_errorMsg = substr($err,$at+4,1024);
$this->_errorNo = -9999;
}
if ($this->_errorNo)
if ($this->_errorNo)
if ($fn = $this->raiseErrorFn) {
$fn($this->databaseType,'EXECUTE',$this->ErrorNo(),$this->ErrorMsg(),$sql,$inputarr);
}
if (is_object($rs)) {
$rs->fetchMode = ($this->fetchMode !== false) ? $this->fetchMode : $ADODB_FETCH_MODE;
$this->_affectedrows = $rs->affectedrows;
$this->_insertid = $rs->insertid;
$rs->databaseType='csv';
@@ -171,18 +173,18 @@ class ADODB_csv extends ADOConnection {
return $rs;
}
/* Returns: the last error message from previous database operation */
function ErrorMsg()
/* Returns: the last error message from previous database operation */
function ErrorMsg()
{
return $this->_errorMsg;
}
/* Returns: the last error number from previous database operation */
function ErrorNo()
/* Returns: the last error number from previous database operation */
function ErrorNo()
{
return $this->_errorNo;
}
// returns true or false
function _close()
{
@@ -191,11 +193,11 @@ class ADODB_csv extends ADOConnection {
} // class
class ADORecordset_csv extends ADORecordset {
function ADORecordset_csv($id,$mode=false)
function __construct($id,$mode=false)
{
$this->ADORecordset($id,$mode);
parent::__construct($id,$mode);
}
function _close()
{
return true;
@@ -203,5 +205,3 @@ class ADORecordset_csv extends ADORecordset {
}
} // define
?>
+191 -170
View File
@@ -1,6 +1,8 @@
<?php
/*
V5.06 16 Oct 2008 (c) 2006 John Lim (jlim#natsoft.com). All rights reserved.
/**
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
This is a version of the ADODB driver for DB2. It uses the 'ibm_db2' PECL extension
for PHP (http://pecl.php.net/package/ibm_db2), which in turn requires DB2 V8.2.2 or
@@ -19,20 +21,23 @@
if (!defined('ADODB_DIR')) die();
define("_ADODB_DB2_LAYER", 2 );
/*--------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------*/
class ADODB_db2 extends ADOConnection {
var $databaseType = "db2";
var $databaseType = "db2";
var $fmtDate = "'Y-m-d'";
var $concat_operator = '||';
var $sysTime = 'CURRENT TIME';
var $sysDate = 'CURRENT DATE';
var $sysTimeStamp = 'CURRENT TIMESTAMP';
var $fmtTimeStamp = "'Y-m-d H:i:s'";
var $replaceQuote = "''"; // string to use to replace quotes
var $dataProvider = "db2";
@@ -42,7 +47,7 @@ class ADODB_db2 extends ADOConnection {
var $useFetchArray = false; // setting this to true will make array elements in FETCH_ASSOC mode case-sensitive
// breaking backward-compat
var $_bindInputArray = false;
var $_bindInputArray = false;
var $_genIDSQL = "VALUES NEXTVAL FOR %s";
var $_genSeqSQL = "CREATE SEQUENCE %s START WITH %s NO MAXVALUE NO CYCLE";
var $_dropSeqSQL = "DROP SEQUENCE %s";
@@ -51,22 +56,23 @@ class ADODB_db2 extends ADOConnection {
var $_lastAffectedRows = 0;
var $uCaseTables = true; // for meta* functions, uppercase table names
var $hasInsertID = true;
function _insertid()
{
return ADOConnection::GetOne('VALUES IDENTITY_VAL_LOCAL()');
}
function ADODB_db2()
{
function __construct()
{
$this->_haserrorfunctions = ADODB_PHPVER >= 0x4050;
}
// returns true or false
function _connect($argDSN, $argUsername, $argPassword, $argDatabasename)
{
global $php_errormsg;
if (!function_exists('db2_connect')) {
ADOConnection::outp("Warning: The old ODBC based DB2 driver has been renamed 'odbc_db2'. This ADOdb driver calls PHP's native db2 extension which is not installed.");
return null;
@@ -75,10 +81,14 @@ class ADODB_db2 extends ADOConnection {
// Replaces the odbc_binmode() call that was in Execute()
ini_set('ibm_db2.binmode', $this->binmode);
if ($argDatabasename) {
$this->_connectionID = db2_connect($argDatabasename,$argUsername,$argPassword);
if ($argDatabasename && empty($argDSN)) {
if (stripos($argDatabasename,'UID=') && stripos($argDatabasename,'PWD=')) $this->_connectionID = db2_connect($argDatabasename,null,null);
else $this->_connectionID = db2_connect($argDatabasename,$argUsername,$argPassword);
} else {
$this->_connectionID = db2_connect($argDSN,$argUsername,$argPassword);
if ($argDatabasename) $schema = $argDatabasename;
if (stripos($argDSN,'UID=') && stripos($argDSN,'PWD=')) $this->_connectionID = db2_connect($argDSN,null,null);
else $this->_connectionID = db2_connect($argDSN,$argUsername,$argPassword);
}
if (isset($php_errormsg)) $php_errormsg = '';
@@ -86,51 +96,56 @@ class ADODB_db2 extends ADOConnection {
// an array of valid options. So far, we don't use them.
$this->_errorMsg = @db2_conn_errormsg();
if (isset($this->connectStmt)) $this->Execute($this->connectStmt);
if ($this->_connectionID && isset($schema)) $this->Execute("SET SCHEMA=$schema");
return $this->_connectionID != false;
}
// returns true or false
function _pconnect($argDSN, $argUsername, $argPassword, $argDatabasename)
{
global $php_errormsg;
if (!function_exists('db2_connect')) return null;
// This needs to be set before the connect().
// Replaces the odbc_binmode() call that was in Execute()
ini_set('ibm_db2.binmode', $this->binmode);
if (isset($php_errormsg)) $php_errormsg = '';
$this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
if ($argDatabasename) {
$this->_connectionID = db2_pconnect($argDatabasename,$argUsername,$argPassword);
if ($argDatabasename && empty($argDSN)) {
if (stripos($argDatabasename,'UID=') && stripos($argDatabasename,'PWD=')) $this->_connectionID = db2_pconnect($argDatabasename,null,null);
else $this->_connectionID = db2_pconnect($argDatabasename,$argUsername,$argPassword);
} else {
$this->_connectionID = db2_pconnect($argDSN,$argUsername,$argPassword);
if ($argDatabasename) $schema = $argDatabasename;
if (stripos($argDSN,'UID=') && stripos($argDSN,'PWD=')) $this->_connectionID = db2_pconnect($argDSN,null,null);
else $this->_connectionID = db2_pconnect($argDSN,$argUsername,$argPassword);
}
if (isset($php_errormsg)) $php_errormsg = '';
$this->_errorMsg = @db2_conn_errormsg();
if ($this->_connectionID && $this->autoRollback) @db2_rollback($this->_connectionID);
if (isset($this->connectStmt)) $this->Execute($this->connectStmt);
if ($this->_connectionID && isset($schema)) $this->Execute("SET SCHEMA=$schema");
return $this->_connectionID != false;
}
// format and return date string in database timestamp format
function DBTimeStamp($ts)
function DBTimeStamp($ts, $isfld = false)
{
if (empty($ts) && $ts !== 0) return 'null';
if (is_string($ts)) $ts = ADORecordSet::UnixTimeStamp($ts);
return 'TO_DATE('.adodb_date($this->fmtTimeStamp,$ts).",'YYYY-MM-DD HH24:MI:SS')";
}
// Format date column in sql string given an input format that understands Y M D
function SQLDate($fmt, $col=false)
{
{
// use right() and replace() ?
if (!$col) $col = $this->sysDate;
@@ -139,7 +154,7 @@ class ADODB_db2 extends ADOConnection {
return 'TO_CHAR('.$col.", 'YYYY-MM-DD HH24:MI:SS')";
$s = '';
$len = strlen($fmt);
for ($i=0; $i < $len; $i++) {
if ($s) $s .= $this->concat_operator;
@@ -166,7 +181,7 @@ class ADODB_db2 extends ADOConnection {
case 'H':
case 'h':
if ($len==1) return "hour($col)";
if ($col != $this->sysDate) $s .= "right(digits(hour($col)),2)";
if ($col != $this->sysDate) $s .= "right(digits(hour($col)),2)";
else $s .= "''";
break;
case 'i':
@@ -192,39 +207,26 @@ class ADODB_db2 extends ADOConnection {
}
}
return $s;
}
}
function ServerInfo()
{
if (!empty($this->host) && ADODB_PHPVER >= 0x4300) {
$dsn = strtoupper($this->host);
$first = true;
$found = false;
if (!function_exists('db2_data_source')) return false;
while(true) {
$rez = @db2_data_source($this->_connectionID,
$first ? SQL_FETCH_FIRST : SQL_FETCH_NEXT);
$first = false;
if (!is_array($rez)) break;
if (strtoupper($rez['server']) == $dsn) {
$found = true;
break;
}
}
if (!$found) return ADOConnection::ServerInfo();
if (!isset($rez['version'])) $rez['version'] = '';
return $rez;
$row = $this->GetRow("SELECT service_level, fixpack_num FROM TABLE(sysproc.env_get_inst_info())
as INSTANCEINFO");
if ($row) {
$info['version'] = $row[0].':'.$row[1];
$info['fixpack'] = $row[1];
$info['description'] = '';
} else {
return ADOConnection::ServerInfo();
}
return $info;
}
function CreateSequence($seqname='adodbseq',$start=1)
{
if (empty($this->_genSeqSQL)) return false;
@@ -232,21 +234,40 @@ class ADODB_db2 extends ADOConnection {
if (!$ok) return false;
return true;
}
function DropSequence($seqname)
function DropSequence($seqname = 'adodbseq')
{
if (empty($this->_dropSeqSQL)) return false;
return $this->Execute(sprintf($this->_dropSeqSQL,$seqname));
}
function SelectLimit($sql, $nrows = -1, $offset = -1, $inputArr = false, $secs2cache = 0)
{
$nrows = (integer) $nrows;
if ($offset <= 0) {
// could also use " OPTIMIZE FOR $nrows ROWS "
if ($nrows >= 0) $sql .= " FETCH FIRST $nrows ROWS ONLY ";
$rs = $this->Execute($sql,$inputArr);
} else {
if ($offset > 0 && $nrows < 0);
else {
$nrows += $offset;
$sql .= " FETCH FIRST $nrows ROWS ONLY ";
}
$rs = ADOConnection::SelectLimit($sql,-1,$offset,$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.
*/
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!
$num = $this->GetOne("VALUES NEXTVAL FOR $seq");
@@ -262,40 +283,40 @@ class ADODB_db2 extends ADOConnection {
return @db2_conn_errormsg($this->_connectionID);
} else return ADOConnection::ErrorMsg();
}
function ErrorNo()
{
if ($this->_haserrorfunctions) {
if ($this->_errorCode !== false) {
// bug in 4.0.6, error number can be corrupted string (should be 6 digits)
return (strlen($this->_errorCode)<=2) ? 0 : $this->_errorCode;
}
if (empty($this->_connectionID)) $e = @db2_conn_error();
if (empty($this->_connectionID)) $e = @db2_conn_error();
else $e = @db2_conn_error($this->_connectionID);
// bug in 4.0.6, error number can be corrupted string (should be 6 digits)
// so we check and patch
if (strlen($e)<=2) return 0;
return $e;
} else return ADOConnection::ErrorNo();
}
function BeginTrans()
{
{
if (!$this->hasTransactions) return false;
if ($this->transOff) return true;
if ($this->transOff) return true;
$this->transCnt += 1;
$this->_autocommit = false;
return db2_autocommit($this->_connectionID,false);
}
function CommitTrans($ok=true)
{
if ($this->transOff) return true;
function CommitTrans($ok=true)
{
if ($this->transOff) return true;
if (!$ok) return $this->RollbackTrans();
if ($this->transCnt) $this->transCnt -= 1;
$this->_autocommit = true;
@@ -303,21 +324,21 @@ class ADODB_db2 extends ADOConnection {
db2_autocommit($this->_connectionID,true);
return $ret;
}
function RollbackTrans()
{
if ($this->transOff) return true;
if ($this->transOff) return true;
if ($this->transCnt) $this->transCnt -= 1;
$this->_autocommit = true;
$ret = db2_rollback($this->_connectionID);
db2_autocommit($this->_connectionID,true);
return $ret;
}
function MetaPrimaryKeys($table)
function MetaPrimaryKeys($table, $owner = false)
{
global $ADODB_FETCH_MODE;
if ($this->uCaseTables) $table = strtoupper($table);
$schema = '';
$this->_findschema($table,$schema);
@@ -325,16 +346,16 @@ class ADODB_db2 extends ADOConnection {
$savem = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$qid = @db2_primarykeys($this->_connectionID,'',$schema,$table);
if (!$qid) {
$ADODB_FETCH_MODE = $savem;
return false;
}
$rs = new ADORecordSet_db2($qid);
$ADODB_FETCH_MODE = $savem;
if (!$rs) return false;
$arr = $rs->GetArray();
$rs->Close();
$arr2 = array();
@@ -343,11 +364,11 @@ class ADODB_db2 extends ADOConnection {
}
return $arr2;
}
function MetaForeignKeys($table, $owner = FALSE, $upper = FALSE, $asociative = FALSE )
{
global $ADODB_FETCH_MODE;
if ($this->uCaseTables) $table = strtoupper($table);
$schema = '';
$this->_findschema($table,$schema);
@@ -372,15 +393,15 @@ class ADODB_db2 extends ADOConnection {
5 FKTABLE_SCHEM
6 FKTABLE_NAME
7 FKCOLUMN_NAME
*/
*/
if (!$rs) return false;
$foreign_keys = array();
$foreign_keys = array();
while (!$rs->EOF) {
if (strtoupper(trim($rs->fields[2])) == $table && (!$schema || strtoupper($rs->fields[1]) == $schema)) {
if (!is_array($foreign_keys[$rs->fields[5].'.'.$rs->fields[6]]))
if (!is_array($foreign_keys[$rs->fields[5].'.'.$rs->fields[6]]))
$foreign_keys[$rs->fields[5].'.'.$rs->fields[6]] = array();
$foreign_keys[$rs->fields[5].'.'.$rs->fields[6]][$rs->fields[7]] = $rs->fields[3];
$foreign_keys[$rs->fields[5].'.'.$rs->fields[6]][$rs->fields[7]] = $rs->fields[3];
}
$rs->MoveNext();
}
@@ -388,45 +409,45 @@ class ADODB_db2 extends ADOConnection {
$rs->Close();
return $foreign_key;
}
function MetaTables($ttype=false,$schema=false)
function MetaTables($ttype = false, $schema = false, $mask = false)
{
global $ADODB_FETCH_MODE;
$savem = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$qid = db2_tables($this->_connectionID);
$rs = new ADORecordSet_db2($qid);
$ADODB_FETCH_MODE = $savem;
if (!$rs) {
$false = false;
return $false;
}
$arr = $rs->GetArray();
$rs->Close();
$arr2 = array();
if ($ttype) {
$isview = strncmp($ttype,'V',1) === 0;
}
for ($i=0; $i < sizeof($arr); $i++) {
if (!$arr[$i][2]) continue;
$type = $arr[$i][3];
$owner = $arr[$i][1];
$schemaval = ($schema) ? $arr[$i][1].'.' : '';
if ($ttype) {
if ($ttype) {
if ($isview) {
if (strncmp($type,'V',1) === 0) $arr2[] = $schemaval.$arr[$i][2];
} else if (strncmp($type,'SYS',3) !== 0) $arr2[] = $schemaval.$arr[$i][2];
} else if (strncmp($type,'SYS',3) !== 0) $arr2[] = $schemaval.$arr[$i][2];
} else if (strncmp($owner,'SYS',3) !== 0) $arr2[] = $schemaval.$arr[$i][2];
} else if (strncmp($owner,'SYS',3) !== 0) $arr2[] = $schemaval.$arr[$i][2];
}
return $arr2;
}
/*
See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2datetime_data_type_changes.asp
/ SQL data type codes /
@@ -458,7 +479,7 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2
function DB2Types($t)
{
switch ((integer)$t) {
case 1:
case 1:
case 12:
case 0:
case -95:
@@ -469,56 +490,56 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2
return 'X';
case -4: //image
return 'B';
case 9:
case 9:
case 91:
return 'D';
case 10:
case 11:
case 92:
case 93:
return 'T';
case 4:
case 5:
case -6:
return 'I';
case -11: // uniqidentifier
return 'R';
case -7: //bit
return 'L';
default:
return 'N';
}
}
function MetaColumns($table, $normalize=true)
{
global $ADODB_FETCH_MODE;
$false = false;
if ($this->uCaseTables) $table = strtoupper($table);
$schema = '';
$this->_findschema($table,$schema);
$savem = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$colname = "%";
$qid = db2_columns($this->_connectionID, "", $schema, $table, $colname);
if (empty($qid)) return $false;
$rs = new ADORecordSet_db2($qid);
$ADODB_FETCH_MODE = $savem;
if (!$rs) return $false;
$rs->_fetch();
$retarr = array();
/*
$rs->fields indices
0 TABLE_QUALIFIER
@@ -539,7 +560,7 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2
$fld = new ADOFieldObject();
$fld->name = $rs->fields[3];
$fld->type = $this->DB2Types($rs->fields[4]);
// ref: http://msdn.microsoft.com/library/default.asp?url=/archive/en-us/dnaraccgen/html/msdn_odk.asp
// access uses precision to store length for char/varchar
if ($fld->type == 'C' or $fld->type == 'X') {
@@ -547,28 +568,28 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2
$fld->max_length = $rs->fields[7]/2;
else
$fld->max_length = $rs->fields[7];
} else
} else
$fld->max_length = $rs->fields[7];
$fld->not_null = !empty($rs->fields[10]);
$fld->scale = $rs->fields[8];
$fld->primary_key = false;
$retarr[strtoupper($fld->name)] = $fld;
$retarr[strtoupper($fld->name)] = $fld;
} else if (sizeof($retarr)>0)
break;
$rs->MoveNext();
}
$rs->Close();
$rs->Close();
if (empty($retarr)) $retarr = false;
$qid = db2_primary_keys($this->_connectionID, "", $schema, $table);
if (empty($qid)) return $false;
$rs = new ADORecordSet_db2($qid);
$ADODB_FETCH_MODE = $savem;
if (!$rs) return $retarr;
$rs->_fetch();
/*
$rs->fields indices
0 TABLE_CAT
@@ -585,12 +606,13 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2
break;
$rs->MoveNext();
}
$rs->Close();
$rs->Close();
if (empty($retarr)) $retarr = false;
return $retarr;
}
function Prepare($sql)
{
if (! $this->_bindInputArray) return $sql; // no binding
@@ -603,24 +625,24 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2
}
/* returns queryID or false */
function _query($sql,$inputarr=false)
function _query($sql,$inputarr=false)
{
GLOBAL $php_errormsg;
if (isset($php_errormsg)) $php_errormsg = '';
$this->_error = '';
if ($inputarr) {
if (is_array($sql)) {
$stmtid = $sql[1];
} else {
$stmtid = db2_prepare($this->_connectionID,$sql);
if ($stmtid == false) {
$this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
return false;
}
}
if (! db2_execute($stmtid,$inputarr)) {
if ($this->_haserrorfunctions) {
$this->_errorMsg = db2_stmt_errormsg();
@@ -628,7 +650,7 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2
}
return false;
}
} else if (is_array($sql)) {
$stmtid = $sql[1];
if (!db2_execute($stmtid)) {
@@ -640,7 +662,7 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2
}
} else
$stmtid = @db2_exec($this->_connectionID,$sql);
$this->_lastAffectedRows = 0;
if ($stmtid) {
if (@db2_num_fields($stmtid) == 0) {
@@ -649,7 +671,7 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2
} else {
$this->_lastAffectedRows = 0;
}
if ($this->_haserrorfunctions) {
$this->_errorMsg = '';
$this->_errorCode = 0;
@@ -669,9 +691,9 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2
/*
Insert a null into the blob field of the table first.
Then use UpdateBlob to store the blob.
Usage:
$conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, null)');
$conn->UpdateBlob('blobtable','blobcol',$blob,'id=1');
*/
@@ -679,7 +701,7 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2
{
return $this->Execute("UPDATE $table SET $column=? WHERE $where",array($val)) != false;
}
// returns true or false
function _close()
{
@@ -692,34 +714,34 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2
{
return $this->_lastAffectedRows;
}
}
/*--------------------------------------------------------------------------------------
Class Name: Recordset
--------------------------------------------------------------------------------------*/
class ADORecordSet_db2 extends ADORecordSet {
class ADORecordSet_db2 extends ADORecordSet {
var $bind = false;
var $databaseType = "db2";
var $databaseType = "db2";
var $dataProvider = "db2";
var $useFetchArray;
function ADORecordSet_db2($id,$mode=false)
function __construct($id,$mode=false)
{
if ($mode === false) {
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
$this->fetchMode = $mode;
$this->_queryID = $id;
}
// returns the field object
function FetchField($offset = -1)
function FetchField($offset = -1)
{
$o= new ADOFieldObject();
$o->name = @db2_field_name($this->_queryID,$offset);
@@ -729,7 +751,7 @@ class ADORecordSet_db2 extends ADORecordSet {
else if (ADODB_ASSOC_CASE == 1) $o->name = strtoupper($o->name);
return $o;
}
/* Use associative array to get fields array */
function Fields($colname)
{
@@ -744,8 +766,8 @@ class ADORecordSet_db2 extends ADORecordSet {
return $this->fields[$this->bind[strtoupper($colname)]];
}
function _initrs()
{
global $ADODB_COUNTRECS;
@@ -753,15 +775,15 @@ class ADORecordSet_db2 extends ADORecordSet {
$this->_numOfFields = @db2_num_fields($this->_queryID);
// some silly drivers such as db2 as/400 and intersystems cache return _numOfRows = 0
if ($this->_numOfRows == 0) $this->_numOfRows = -1;
}
}
function _seek($row)
{
return false;
}
// speed up SelectLimit() by switching to ADODB_FETCH_NUM as ADODB_FETCH_ASSOC is emulated
function GetArrayLimit($nrows,$offset=-1)
function GetArrayLimit($nrows,$offset=-1)
{
if ($offset <= 0) {
$rs = $this->GetArray($nrows);
@@ -771,31 +793,31 @@ class ADORecordSet_db2 extends ADORecordSet {
$this->fetchMode = ADODB_FETCH_NUM;
$this->Move($offset);
$this->fetchMode = $savem;
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
$this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
$this->fields = $this->GetRowAssoc();
}
$results = array();
$cnt = 0;
while (!$this->EOF && $nrows != $cnt) {
$results[$cnt++] = $this->fields;
$this->MoveNext();
}
return $results;
}
function MoveNext()
function MoveNext()
{
if ($this->_numOfRows != 0 && !$this->EOF) {
if ($this->_numOfRows != 0 && !$this->EOF) {
$this->_currentRow++;
$this->fields = @db2_fetch_array($this->_queryID);
if ($this->fields) {
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
$this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
$this->fields = $this->GetRowAssoc();
}
return true;
}
@@ -803,26 +825,25 @@ class ADORecordSet_db2 extends ADORecordSet {
$this->fields = false;
$this->EOF = true;
return false;
}
}
function _fetch()
{
$this->fields = db2_fetch_array($this->_queryID);
if ($this->fields) {
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
$this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
$this->fields = $this->GetRowAssoc();
}
return true;
}
$this->fields = false;
return false;
}
function _close()
function _close()
{
return @db2_free_result($this->_queryID);
return @db2_free_result($this->_queryID);
}
}
?>
+226
View File
@@ -0,0 +1,226 @@
<?php
/*
@version v5.20.9 21-Dec-2016
@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.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
Microsoft Visual FoxPro data driver. Requires ODBC. Works only on MS Windows.
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
include(ADODB_DIR."/drivers/adodb-db2.inc.php");
if (!defined('ADODB_DB2OCI')){
define('ADODB_DB2OCI',1);
/*
// regex code for smart remapping of :0, :1 bind vars to ? ?
function _colontrack($p)
{
global $_COLONARR,$_COLONSZ;
$v = (integer) substr($p,1);
if ($v > $_COLONSZ) return $p;
$_COLONARR[] = $v;
return '?';
}
// smart remapping of :0, :1 bind vars to ? ?
function _colonscope($sql,$arr)
{
global $_COLONARR,$_COLONSZ;
$_COLONARR = array();
$_COLONSZ = sizeof($arr);
$sql2 = preg_replace("/(:[0-9]+)/e","_colontrack('\\1')",$sql);
if (empty($_COLONARR)) return array($sql,$arr);
foreach($_COLONARR as $k => $v) {
$arr2[] = $arr[$v];
}
return array($sql2,$arr2);
}
*/
/*
Smart remapping of :0, :1 bind vars to ? ?
Handles colons in comments -- and / * * / and in quoted strings.
*/
function _colonparser($sql,$arr)
{
$lensql = strlen($sql);
$arrsize = sizeof($arr);
$state = 'NORM';
$at = 1;
$ch = $sql[0];
$ch2 = @$sql[1];
$sql2 = '';
$arr2 = array();
$nprev = 0;
while (strlen($ch)) {
switch($ch) {
case '/':
if ($state == 'NORM' && $ch2 == '*') {
$state = 'COMMENT';
$at += 1;
$ch = $ch2;
$ch2 = $at < $lensql ? $sql[$at] : '';
}
break;
case '*':
if ($state == 'COMMENT' && $ch2 == '/') {
$state = 'NORM';
$at += 1;
$ch = $ch2;
$ch2 = $at < $lensql ? $sql[$at] : '';
}
break;
case "\n":
case "\r":
if ($state == 'COMMENT2') $state = 'NORM';
break;
case "'":
do {
$at += 1;
$ch = $ch2;
$ch2 = $at < $lensql ? $sql[$at] : '';
} while ($ch !== "'");
break;
case ':':
if ($state == 'COMMENT' || $state == 'COMMENT2') break;
//echo "$at=$ch $ch2, ";
if ('0' <= $ch2 && $ch2 <= '9') {
$n = '';
$nat = $at;
do {
$at += 1;
$ch = $ch2;
$n .= $ch;
$ch2 = $at < $lensql ? $sql[$at] : '';
} while ('0' <= $ch && $ch <= '9');
#echo "$n $arrsize ] ";
$n = (integer) $n;
if ($n < $arrsize) {
$sql2 .= substr($sql,$nprev,$nat-$nprev-1).'?';
$nprev = $at-1;
$arr2[] = $arr[$n];
}
}
break;
case '-':
if ($state == 'NORM') {
if ($ch2 == '-') $state = 'COMMENT2';
$at += 1;
$ch = $ch2;
$ch2 = $at < $lensql ? $sql[$at] : '';
}
break;
}
$at += 1;
$ch = $ch2;
$ch2 = $at < $lensql ? $sql[$at] : '';
}
if ($nprev == 0) {
$sql2 = $sql;
} else {
$sql2 .= substr($sql,$nprev);
}
return array($sql2,$arr2);
}
class ADODB_db2oci extends ADODB_db2 {
var $databaseType = "db2oci";
var $sysTimeStamp = 'sysdate';
var $sysDate = 'trunc(sysdate)';
var $_bindInputArray = true;
function Param($name,$type='C')
{
return ':'.$name;
}
function MetaTables($ttype = false, $schema = false, $mask = false)
{
global $ADODB_FETCH_MODE;
$savem = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$qid = db2_tables($this->_connectionID);
$rs = new ADORecordSet_db2($qid);
$ADODB_FETCH_MODE = $savem;
if (!$rs) {
$false = false;
return $false;
}
$arr = $rs->GetArray();
$rs->Close();
$arr2 = array();
// adodb_pr($arr);
if ($ttype) {
$isview = strncmp($ttype,'V',1) === 0;
}
for ($i=0; $i < sizeof($arr); $i++) {
if (!$arr[$i][2]) continue;
$type = $arr[$i][3];
$schemaval = ($schema) ? $arr[$i][1].'.' : '';
$name = $schemaval.$arr[$i][2];
$owner = $arr[$i][1];
if (substr($name,0,8) == 'EXPLAIN_') continue;
if ($ttype) {
if ($isview) {
if (strncmp($type,'V',1) === 0) $arr2[] = $name;
} else if (strncmp($type,'T',1) === 0 && strncmp($owner,'SYS',3) !== 0) $arr2[] = $name;
} else if (strncmp($type,'T',1) === 0 && strncmp($owner,'SYS',3) !== 0) $arr2[] = $name;
}
return $arr2;
}
function _Execute($sql, $inputarr=false )
{
if ($inputarr) list($sql,$inputarr) = _colonparser($sql, $inputarr);
return parent::_Execute($sql, $inputarr);
}
};
class ADORecordSet_db2oci extends ADORecordSet_db2 {
var $databaseType = "db2oci";
function __construct($id,$mode=false)
{
return parent::__construct($id,$mode);
}
}
} //define
+86
View File
@@ -0,0 +1,86 @@
<?php
/*
@version v5.20.9 21-Dec-2016
@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.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
Microsoft Visual FoxPro data driver. Requires ODBC. Works only on MS Windows.
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
include(ADODB_DIR."/drivers/adodb-db2.inc.php");
if (!defined('ADODB_DB2OCI')){
define('ADODB_DB2OCI',1);
/**
* Callback function for preg_replace in _colonscope()
* @param array $p matched patterns
* return string '?' if parameter replaced, :N if not
*/
function _colontrack($p)
{
global $_COLONARR, $_COLONSZ;
$v = (integer) substr($p[1], 1);
if ($v > $_COLONSZ) return $p[1];
$_COLONARR[] = $v;
return '?';
}
/**
* smart remapping of :0, :1 bind vars to ? ?
* @param string $sql SQL statement
* @param array $arr parameters
* @return array
*/
function _colonscope($sql,$arr)
{
global $_COLONARR,$_COLONSZ;
$_COLONARR = array();
$_COLONSZ = sizeof($arr);
$sql2 = preg_replace_callback('/(:[0-9]+)/', '_colontrack', $sql);
if (empty($_COLONARR)) return array($sql,$arr);
foreach($_COLONARR as $k => $v) {
$arr2[] = $arr[$v];
}
return array($sql2,$arr2);
}
class ADODB_db2oci extends ADODB_db2 {
var $databaseType = "db2oci";
var $sysTimeStamp = 'sysdate';
var $sysDate = 'trunc(sysdate)';
function _Execute($sql, $inputarr = false)
{
if ($inputarr) list($sql,$inputarr) = _colonscope($sql, $inputarr);
return parent::_Execute($sql, $inputarr);
}
};
class ADORecordSet_db2oci extends ADORecordSet_odbc {
var $databaseType = "db2oci";
function __construct($id,$mode=false)
{
return parent::__construct($id,$mode);
}
}
} //define
+72 -71
View File
@@ -1,12 +1,14 @@
<?php
/*
@version V5.06 16 Oct 2008 (c) 2000-2009 John Lim (jlim#natsoft.com). 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.
Contribution by Frank M. Kromann <frank@frontbase.com>.
@version v5.20.9 21-Dec-2016
@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.
Contribution by Frank M. Kromann <frank@frontbase.com>.
Set tabs to 8.
*/
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
@@ -17,26 +19,26 @@ if (! defined("_ADODB_FBSQL_LAYER")) {
class ADODB_fbsql extends ADOConnection {
var $databaseType = 'fbsql';
var $hasInsertID = true;
var $hasAffectedRows = true;
var $metaTablesSQL = "SHOW TABLES";
var $hasAffectedRows = true;
var $metaTablesSQL = "SHOW TABLES";
var $metaColumnsSQL = "SHOW COLUMNS FROM %s";
var $fmtTimeStamp = "'Y-m-d H:i:s'";
var $hasLimit = false;
function ADODB_fbsql()
{
function __construct()
{
}
function _insertid()
{
return fbsql_insert_id($this->_connectionID);
}
function _affectedrows()
{
return fbsql_affected_rows($this->_connectionID);
}
function MetaDatabases()
{
$qid = fbsql_list_dbs($this->_connectionID);
@@ -61,39 +63,39 @@ class ADODB_fbsql extends ADOConnection {
if (sizeof($arr) > 0) return "CONCAT($s)";
else return '';
}
// returns true or false
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
$this->_connectionID = fbsql_connect($argHostname,$argUsername,$argPassword);
if ($this->_connectionID === false) return false;
if ($argDatabasename) return $this->SelectDB($argDatabasename);
return true;
return true;
}
// returns true or false
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
$this->_connectionID = fbsql_pconnect($argHostname,$argUsername,$argPassword);
if ($this->_connectionID === false) return false;
if ($argDatabasename) return $this->SelectDB($argDatabasename);
return true;
return true;
}
function MetaColumns($table, $normalize=true)
function MetaColumns($table, $normalize=true)
{
if ($this->metaColumnsSQL) {
$rs = $this->Execute(sprintf($this->metaColumnsSQL,$table));
if ($rs === false) return false;
$retarr = array();
while (!$rs->EOF){
$fld = new ADOFieldObject();
$fld->name = $rs->fields[0];
$fld->type = $rs->fields[1];
// split type into type(length):
if (preg_match("/^(.+)\((\d+)\)$/", $fld->type, $query_array)) {
$fld->type = $query_array[1];
@@ -105,86 +107,86 @@ class ADODB_fbsql extends ADOConnection {
$fld->primary_key = ($rs->fields[3] == 'PRI');
$fld->auto_increment = (strpos($rs->fields[5], 'auto_increment') !== false);
$fld->binary = (strpos($fld->type,'blob') !== false);
$retarr[strtoupper($fld->name)] = $fld;
$retarr[strtoupper($fld->name)] = $fld;
$rs->MoveNext();
}
$rs->Close();
return $retarr;
return $retarr;
}
return false;
}
// returns true or false
function SelectDB($dbName)
function SelectDB($dbName)
{
$this->database = $dbName;
if ($this->_connectionID) {
return @fbsql_select_db($dbName,$this->_connectionID);
return @fbsql_select_db($dbName,$this->_connectionID);
}
else return false;
else return false;
}
// returns queryID or false
function _query($sql,$inputarr=false)
{
return fbsql_query("$sql;",$this->_connectionID);
}
/* Returns: the last error message from previous database operation */
function ErrorMsg()
/* Returns: the last error message from previous database operation */
function ErrorMsg()
{
$this->_errorMsg = @fbsql_error($this->_connectionID);
return $this->_errorMsg;
}
/* Returns: the last error number from previous database operation */
function ErrorNo()
/* Returns: the last error number from previous database operation */
function ErrorNo()
{
return @fbsql_errno($this->_connectionID);
}
// returns true or false
function _close()
{
return @fbsql_close($this->_connectionID);
}
}
/*--------------------------------------------------------------------------------------
Class Name: Recordset
--------------------------------------------------------------------------------------*/
class ADORecordSet_fbsql extends ADORecordSet{
class ADORecordSet_fbsql extends ADORecordSet{
var $databaseType = "fbsql";
var $canSeek = true;
function ADORecordSet_fbsql($queryID,$mode=false)
function __construct($queryID,$mode=false)
{
if (!$mode) {
if (!$mode) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
switch ($mode) {
case ADODB_FETCH_NUM: $this->fetchMode = FBSQL_NUM; break;
case ADODB_FETCH_ASSOC: $this->fetchMode = FBSQL_ASSOC; break;
case ADODB_FETCH_BOTH:
case ADODB_FETCH_BOTH:
default:
$this->fetchMode = FBSQL_BOTH; break;
}
return $this->ADORecordSet($queryID);
return parent::__construct($queryID);
}
function _initrs()
{
GLOBAL $ADODB_COUNTRECS;
$this->_numOfRows = ($ADODB_COUNTRECS) ? @fbsql_num_rows($this->_queryID):-1;
$this->_numOfFields = @fbsql_num_fields($this->_queryID);
}
function FetchField($fieldOffset = -1) {
@@ -198,25 +200,25 @@ class ADORecordSet_fbsql extends ADORecordSet{
$o = @fbsql_fetch_field($this->_queryID);// fbsql returns the max length less spaces -- so it is unrealiable
//$o->max_length = -1;
}
return $o;
}
function _seek($row)
{
return @fbsql_data_seek($this->_queryID,$row);
}
function _fetch($ignore_fields=false)
{
$this->fields = @fbsql_fetch_array($this->_queryID,$this->fetchMode);
return ($this->fields == true);
}
function _close() {
return @fbsql_free_result($this->_queryID);
return @fbsql_free_result($this->_queryID);
}
function MetaType($t,$len=-1,$fieldobj=false)
{
if (is_object($t)) {
@@ -227,40 +229,39 @@ class ADORecordSet_fbsql extends ADORecordSet{
$len = -1; // fbsql max_length is not accurate
switch (strtoupper($t)) {
case 'CHARACTER':
case 'CHARACTER VARYING':
case 'BLOB':
case 'CLOB':
case 'BIT':
case 'BIT VARYING':
case 'CHARACTER VARYING':
case 'BLOB':
case 'CLOB':
case 'BIT':
case 'BIT VARYING':
if ($len <= $this->blobSize) return 'C';
// so we have to check whether binary...
case 'IMAGE':
case 'LONGBLOB':
case 'LONGBLOB':
case 'BLOB':
case 'MEDIUMBLOB':
return !empty($fieldobj->binary) ? 'B' : 'X';
case 'DATE': return 'D';
case 'TIME':
case 'TIME WITH TIME ZONE':
case 'TIMESTAMP':
case 'TIMESTAMP':
case 'TIMESTAMP WITH TIME ZONE': return 'T';
case 'PRIMARY_KEY':
return 'R';
case 'INTEGER':
case 'SMALLINT':
case 'SMALLINT':
case 'BOOLEAN':
if (!empty($fieldobj->primary_key)) return 'R';
else return 'I';
default: return 'N';
}
}
} //class
} // defined
?>
+28 -32
View File
@@ -1,11 +1,13 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). 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.
/*
@version v5.20.9 21-Dec-2016
@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.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
*/
@@ -16,21 +18,16 @@ if (!defined('ADODB_DIR')) die();
include_once(ADODB_DIR."/drivers/adodb-ibase.inc.php");
class ADODB_firebird extends ADODB_ibase {
var $databaseType = "firebird";
var $databaseType = "firebird";
var $dialect = 3;
var $sysTimeStamp = "CURRENT_TIMESTAMP"; //"cast('NOW' as timestamp)";
function ADODB_firebird()
{
$this->ADODB_ibase();
}
function ServerInfo()
{
$arr['dialect'] = $this->dialect;
switch($arr['dialect']) {
case '':
case '':
case '1': $s = 'Firebird Dialect 1'; break;
case '2': $s = 'Firebird Dialect 2'; break;
default:
@@ -40,38 +37,37 @@ class ADODB_firebird extends ADODB_ibase {
$arr['description'] = $s;
return $arr;
}
// Note that Interbase 6.5 uses this ROWS instead - don't you love forking wars!
// SELECT col1, col2 FROM table ROWS 5 -- get 5 rows
// SELECT col1, col2 FROM table ROWS 5 -- get 5 rows
// SELECT col1, col2 FROM TABLE ORDER BY col1 ROWS 3 TO 7 -- first 5 skip 2
function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false, $secs=0)
{
$nrows = (integer) $nrows;
$offset = (integer) $offset;
$str = 'SELECT ';
if ($nrows >= 0) $str .= "FIRST $nrows ";
if ($nrows >= 0) $str .= "FIRST $nrows ";
$str .=($offset>=0) ? "SKIP $offset " : '';
$sql = preg_replace('/^[ \t]*select/i',$str,$sql);
$sql = preg_replace('/^[ \t]*select/i',$str,$sql);
if ($secs)
$rs = $this->CacheExecute($secs,$sql,$inputarr);
else
$rs = $this->Execute($sql,$inputarr);
return $rs;
}
};
class ADORecordSet_firebird extends ADORecordSet_ibase {
var $databaseType = "firebird";
function ADORecordSet_firebird($id,$mode=false)
};
class ADORecordSet_firebird extends ADORecordSet_ibase {
var $databaseType = "firebird";
function __construct($id,$mode=false)
{
$this->ADORecordSet_ibase($id,$mode);
parent::__construct($id,$mode);
}
}
?>
+361 -330
View File
@@ -1,23 +1,25 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
@version v5.20.9 21-Dec-2016
@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 http://adodb.sourceforge.net
Interbase data driver. Requires interbase client. Works on Windows and Unix.
3 Jan 2002 -- suggestions by Hans-Peter Oeri <kampfcaspar75@oeri.ch>
changed transaction handling and added experimental blob stuff
Docs to interbase at the website
http://www.synectics.co.za/php3/tutorial/IB_PHP3_API.html
To use gen_id(), see
http://www.volny.cz/iprenosil/interbase/ip_ib_code.htm#_code_creategen
$rs = $conn->Execute('select gen_id(adodb,1) from rdb$database');
$id = $rs->fields[0];
$conn->Execute("insert into table (id, col1,...) values ($id, $val1,...)");
@@ -53,26 +55,26 @@ class ADODB_ibase extends ADOConnection {
var $poorAffectedRows = true;
var $blobEncodeType = 'C';
var $role = false;
function ADODB_ibase()
function __construct()
{
if (defined('IBASE_DEFAULT')) $this->ibasetrans = IBASE_DEFAULT;
}
// returns true or false
if (defined('IBASE_DEFAULT')) $this->ibasetrans = IBASE_DEFAULT;
}
// returns true or false
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename,$persist=false)
{
{
if (!function_exists('ibase_pconnect')) return null;
if ($argDatabasename) $argHostname .= ':'.$argDatabasename;
$fn = ($persist) ? 'ibase_pconnect':'ibase_connect';
if ($this->role)
$this->_connectionID = $fn($argHostname,$argUsername,$argPassword,
$this->charSet,$this->buffers,$this->dialect,$this->role);
else
else
$this->_connectionID = $fn($argHostname,$argUsername,$argPassword,
$this->charSet,$this->buffers,$this->dialect);
if ($this->dialect != 1) { // http://www.ibphoenix.com/ibp_60_del_id_ds.html
$this->replaceQuote = "''";
}
@@ -80,14 +82,18 @@ class ADODB_ibase extends ADOConnection {
$this->_handleerror();
return false;
}
// PHP5 change.
if (function_exists('ibase_timefmt')) {
ibase_timefmt($this->ibase_datefmt,IBASE_DATE );
if ($this->dialect == 1) ibase_timefmt($this->ibase_datefmt,IBASE_TIMESTAMP );
else ibase_timefmt($this->ibase_timestampfmt,IBASE_TIMESTAMP );
if ($this->dialect == 1) {
ibase_timefmt($this->ibase_datefmt,IBASE_TIMESTAMP );
}
else {
ibase_timefmt($this->ibase_timestampfmt,IBASE_TIMESTAMP );
}
ibase_timefmt($this->ibase_timefmt,IBASE_TIME );
} else {
ini_set("ibase.timestampformat", $this->ibase_timestampfmt);
ini_set("ibase.dateformat", $this->ibase_datefmt);
@@ -95,34 +101,37 @@ class ADODB_ibase extends ADOConnection {
}
return true;
}
// returns true or false
// returns true or false
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename,true);
}
}
function MetaPrimaryKeys($table,$owner_notused=false,$internalKey=false)
{
if ($internalKey) return array('RDB$DB_KEY');
{
if ($internalKey) {
return array('RDB$DB_KEY');
}
$table = strtoupper($table);
$sql = 'SELECT S.RDB$FIELD_NAME AFIELDNAME
FROM RDB$INDICES I JOIN RDB$INDEX_SEGMENTS S ON I.RDB$INDEX_NAME=S.RDB$INDEX_NAME
FROM RDB$INDICES I JOIN RDB$INDEX_SEGMENTS S ON I.RDB$INDEX_NAME=S.RDB$INDEX_NAME
WHERE I.RDB$RELATION_NAME=\''.$table.'\' and I.RDB$INDEX_NAME like \'RDB$PRIMARY%\'
ORDER BY I.RDB$INDEX_NAME,S.RDB$FIELD_POSITION';
$a = $this->GetCol($sql,false,true);
if ($a && sizeof($a)>0) return $a;
return false;
return false;
}
function ServerInfo()
{
$arr['dialect'] = $this->dialect;
switch($arr['dialect']) {
case '':
case '':
case '1': $s = 'Interbase 5.5 or earlier'; break;
case '2': $s = 'Interbase 5.6'; break;
default:
@@ -134,35 +143,41 @@ class ADODB_ibase extends ADOConnection {
}
function BeginTrans()
{
{
if ($this->transOff) return true;
$this->transCnt += 1;
$this->autoCommit = false;
$this->_transactionID = $this->_connectionID;//ibase_trans($this->ibasetrans, $this->_connectionID);
$this->_transactionID = $this->_connectionID;//ibase_trans($this->ibasetrans, $this->_connectionID);
return $this->_transactionID;
}
function CommitTrans($ok=true)
{
if (!$ok) return $this->RollbackTrans();
if ($this->transOff) return true;
if ($this->transCnt) $this->transCnt -= 1;
function CommitTrans($ok=true)
{
if (!$ok) {
return $this->RollbackTrans();
}
if ($this->transOff) {
return true;
}
if ($this->transCnt) {
$this->transCnt -= 1;
}
$ret = false;
$this->autoCommit = true;
if ($this->_transactionID) {
//print ' commit ';
//print ' commit ';
$ret = ibase_commit($this->_transactionID);
}
$this->_transactionID = false;
return $ret;
}
// there are some compat problems with ADODB_COUNTRECS=false and $this->_logsql currently.
// it appears that ibase extension cannot support multiple concurrent queryid's
function _Execute($sql,$inputarr=false)
function _Execute($sql,$inputarr=false)
{
global $ADODB_COUNTRECS;
if ($this->_logsql) {
$savecrecs = $ADODB_COUNTRECS;
$ADODB_COUNTRECS = true; // force countrecs
@@ -173,96 +188,101 @@ class ADODB_ibase extends ADOConnection {
}
return $ret;
}
function RollbackTrans()
{
if ($this->transOff) return true;
if ($this->transCnt) $this->transCnt -= 1;
$ret = false;
$this->autoCommit = true;
if ($this->_transactionID)
$ret = ibase_rollback($this->_transactionID);
$this->_transactionID = false;
if ($this->_transactionID) {
$ret = ibase_rollback($this->_transactionID);
}
$this->_transactionID = false;
return $ret;
}
function MetaIndexes ($table, $primary = FALSE, $owner=false)
{
// save old fetch mode
global $ADODB_FETCH_MODE;
$false = false;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== FALSE) {
$savem = $this->SetFetchMode(FALSE);
}
$table = strtoupper($table);
$sql = "SELECT * FROM RDB\$INDICES WHERE RDB\$RELATION_NAME = '".$table."'";
if (!$primary) {
$sql .= " AND RDB\$INDEX_NAME NOT LIKE 'RDB\$%'";
} else {
$sql .= " AND RDB\$INDEX_NAME NOT LIKE 'RDB\$FOREIGN%'";
}
// get index details
$rs = $this->Execute($sql);
if (!is_object($rs)) {
// restore fetchmode
if (isset($savem)) {
$this->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
return $false;
}
$indexes = array();
// save old fetch mode
global $ADODB_FETCH_MODE;
$false = false;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== FALSE) {
$savem = $this->SetFetchMode(FALSE);
}
$table = strtoupper($table);
$sql = "SELECT * FROM RDB\$INDICES WHERE RDB\$RELATION_NAME = '".$table."'";
if (!$primary) {
$sql .= " AND RDB\$INDEX_NAME NOT LIKE 'RDB\$%'";
} else {
$sql .= " AND RDB\$INDEX_NAME NOT LIKE 'RDB\$FOREIGN%'";
}
// get index details
$rs = $this->Execute($sql);
if (!is_object($rs)) {
// restore fetchmode
if (isset($savem)) {
$this->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
return $false;
}
$indexes = array();
while ($row = $rs->FetchRow()) {
$index = $row[0];
if (!isset($indexes[$index])) {
if (is_null($row[3])) {$row[3] = 0;}
$indexes[$index] = array(
'unique' => ($row[3] == 1),
'columns' => array()
);
}
if (!isset($indexes[$index])) {
if (is_null($row[3])) {
$row[3] = 0;
}
$indexes[$index] = array(
'unique' => ($row[3] == 1),
'columns' => array()
);
}
$sql = "SELECT * FROM RDB\$INDEX_SEGMENTS WHERE RDB\$INDEX_NAME = '".$index."' ORDER BY RDB\$FIELD_POSITION ASC";
$rs1 = $this->Execute($sql);
while ($row1 = $rs1->FetchRow()) {
$indexes[$index]['columns'][$row1[2]] = $row1[1];
}
while ($row1 = $rs1->FetchRow()) {
$indexes[$index]['columns'][$row1[2]] = $row1[1];
}
}
// restore fetchmode
if (isset($savem)) {
$this->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
return $indexes;
// restore fetchmode
if (isset($savem)) {
$this->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
return $indexes;
}
// See http://community.borland.com/article/0,1410,25844,00.html
function RowLock($tables,$where,$col)
function RowLock($tables,$where,$col=false)
{
if ($this->autoCommit) $this->BeginTrans();
if ($this->autoCommit) {
$this->BeginTrans();
}
$this->Execute("UPDATE $table SET $col=$col WHERE $where "); // is this correct - jlim?
return 1;
}
function CreateSequence($seqname,$startID=1)
function CreateSequence($seqname = 'adodbseq', $startID = 1)
{
$ok = $this->Execute(("INSERT INTO RDB\$GENERATORS (RDB\$GENERATOR_NAME) VALUES (UPPER('$seqname'))" ));
if (!$ok) return false;
return $this->Execute("SET GENERATOR $seqname TO ".($startID-1).';');
}
function DropSequence($seqname)
function DropSequence($seqname = 'adodbseq')
{
$seqname = strtoupper($seqname);
$this->Execute("delete from RDB\$GENERATORS where RDB\$GENERATOR_NAME='$seqname'");
}
function GenID($seqname='adodbseq',$startID=1)
{
$getnext = ("SELECT Gen_ID($seqname,1) FROM RDB\$DATABASE");
@@ -272,17 +292,23 @@ class ADODB_ibase extends ADOConnection {
$this->Execute("SET GENERATOR $seqname TO ".($startID-1).';');
$rs = $this->Execute($getnext);
}
if ($rs && !$rs->EOF) $this->genID = (integer) reset($rs->fields);
else $this->genID = 0; // false
if ($rs) $rs->Close();
if ($rs && !$rs->EOF) {
$this->genID = (integer) reset($rs->fields);
}
else {
$this->genID = 0; // false
}
if ($rs) {
$rs->Close();
}
return $this->genID;
}
function SelectDB($dbName)
function SelectDB($dbName)
{
return false;
return false;
}
function _handleerror()
@@ -290,13 +316,13 @@ class ADODB_ibase extends ADOConnection {
$this->_errorMsg = ibase_errmsg();
}
function ErrorNo()
function ErrorNo()
{
if (preg_match('/error code = ([\-0-9]*)/i', $this->_errorMsg,$arr)) return (integer) $arr[1];
else return 0;
}
function ErrorMsg()
function ErrorMsg()
{
return $this->_errorMsg;
}
@@ -308,10 +334,10 @@ class ADODB_ibase extends ADOConnection {
return array($sql,$stmt);
}
// returns query ID if successful, otherwise false
// there have been reports of problems with nested queries - the code is probably not re-entrant?
// returns query ID if successful, otherwise false
// there have been reports of problems with nested queries - the code is probably not re-entrant?
function _query($sql,$iarr=false)
{
{
if (!$this->autoCommit && $this->_transactionID) {
$conn = $this->_transactionID;
@@ -341,11 +367,11 @@ class ADODB_ibase extends ADOConnection {
case 8: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5],$iarr[6],$iarr[7]); break;
}
}
} else $ret = $fn($sql);
} else $ret = $fn($sql);
} else {
$fn = 'ibase_query';
if (is_array($iarr)) {
if (is_array($iarr)) {
if (ADODB_PHPVER >= 0x4050) { // actually 4.0.4
if (sizeof($iarr) == 0) $iarr[0] = ''; // PHP5 compat hack
$fnarr = array_merge( array($conn,$sql) , $iarr);
@@ -363,21 +389,25 @@ class ADODB_ibase extends ADOConnection {
case 8: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5],$iarr[6],$iarr[7]); break;
}
}
} else $ret = $fn($conn,$sql);
} else $ret = $fn($conn,$sql);
}
if ($docommit && $ret === true) {
ibase_commit($this->_connectionID);
}
if ($docommit && $ret === true) ibase_commit($this->_connectionID);
$this->_handleerror();
return $ret;
}
// returns true or false
function _close()
{
if (!$this->autoCommit) @ibase_rollback($this->_connectionID);
// returns true or false
function _close()
{
if (!$this->autoCommit) {
@ibase_rollback($this->_connectionID);
}
return @ibase_close($this->_connectionID);
}
}
//OPN STUFF start
function _ConvertFieldType(&$fld, $ftype, $flen, $fscale, $fsubtype, $fprecision, $dialect3)
{
@@ -385,27 +415,27 @@ class ADODB_ibase extends ADOConnection {
$fld->max_length = $flen;
$fld->scale = null;
switch($ftype){
case 7:
case 7:
case 8:
if ($dialect3) {
switch($fsubtype){
case 0:
$fld->type = ($ftype == 7 ? 'smallint' : 'integer');
break;
case 1:
$fld->type = 'numeric';
switch($fsubtype){
case 0:
$fld->type = ($ftype == 7 ? 'smallint' : 'integer');
break;
case 1:
$fld->type = 'numeric';
$fld->max_length = $fprecision;
$fld->scale = $fscale;
break;
case 2:
$fld->type = 'decimal';
break;
case 2:
$fld->type = 'decimal';
$fld->max_length = $fprecision;
$fld->scale = $fscale;
break;
} // switch
break;
} // switch
} else {
if ($fscale !=0) {
$fld->type = 'decimal';
$fld->type = 'decimal';
$fld->scale = $fscale;
$fld->max_length = ($ftype == 7 ? 4 : 9);
} else {
@@ -413,25 +443,25 @@ class ADODB_ibase extends ADOConnection {
}
}
break;
case 16:
case 16:
if ($dialect3) {
switch($fsubtype){
case 0:
$fld->type = 'decimal';
switch($fsubtype){
case 0:
$fld->type = 'decimal';
$fld->max_length = 18;
$fld->scale = 0;
break;
case 1:
$fld->type = 'numeric';
break;
case 1:
$fld->type = 'numeric';
$fld->max_length = $fprecision;
$fld->scale = $fscale;
break;
case 2:
$fld->type = 'decimal';
break;
case 2:
$fld->type = 'decimal';
$fld->max_length = $fprecision;
$fld->scale = $fscale;
break;
} // switch
break;
} // switch
}
break;
case 10:
@@ -442,7 +472,7 @@ class ADODB_ibase extends ADOConnection {
break;
case 27:
if ($fscale !=0) {
$fld->type = 'decimal';
$fld->type = 'decimal';
$fld->max_length = 15;
$fld->scale = 5;
} else {
@@ -451,7 +481,7 @@ class ADODB_ibase extends ADOConnection {
break;
case 35:
if ($dialect3) {
$fld->type = 'timestamp';
$fld->type = 'timestamp';
} else {
$fld->type = 'date';
}
@@ -475,22 +505,23 @@ class ADODB_ibase extends ADOConnection {
} // switch
}
//OPN STUFF end
// returns array of ADOFieldObjects for current table
function MetaColumns($table, $normalize=true)
// returns array of ADOFieldObjects for current table
function MetaColumns($table, $normalize=true)
{
global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$rs = $this->Execute(sprintf($this->metaColumnsSQL,strtoupper($table)));
$ADODB_FETCH_MODE = $save;
$false = false;
if ($rs === false) {
return $false;
}
$retarr = array();
//OPN STUFF start
$dialect3 = ($this->dialect==3 ? true : false);
@@ -502,16 +533,16 @@ class ADODB_ibase extends ADOConnection {
$this->_ConvertFieldType($fld, $rs->fields[7], $rs->fields[3], $rs->fields[4], $rs->fields[5], $rs->fields[6], $dialect3);
if (isset($rs->fields[1]) && $rs->fields[1]) {
$fld->not_null = true;
}
}
if (isset($rs->fields[2])) {
$fld->has_default = true;
$d = substr($rs->fields[2],strlen('default '));
switch ($fld->type)
{
case 'smallint':
case 'integer': $fld->default_value = (int) $d; break;
case 'char':
case 'char':
case 'blob':
case 'text':
case 'varchar': $fld->default_value = (string) substr($d,1,strlen($d)-2); break;
@@ -527,135 +558,135 @@ class ADODB_ibase extends ADOConnection {
$fld->sub_type = null;
}
//OPN STUFF end
if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;
if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;
else $retarr[strtoupper($fld->name)] = $fld;
$rs->MoveNext();
}
$rs->Close();
if ( empty($retarr)) return $false;
else return $retarr;
else return $retarr;
}
function BlobEncode( $blob )
function BlobEncode( $blob )
{
$blobid = ibase_blob_create( $this->_connectionID);
ibase_blob_add( $blobid, $blob );
return ibase_blob_close( $blobid );
}
// since we auto-decode all blob's since 2.42,
// since we auto-decode all blob's since 2.42,
// BlobDecode should not do any transforms
function BlobDecode($blob)
{
return $blob;
return $blob;
}
// old blobdecode function
// still used to auto-decode all blob's
function _BlobDecode_old( $blob )
function _BlobDecode_old( $blob )
{
$blobid = ibase_blob_open($this->_connectionID, $blob );
$realblob = ibase_blob_get( $blobid,$this->maxblobsize); // 2nd param is max size of blob -- Kevin Boillet <kevinboillet@yahoo.fr>
while($string = ibase_blob_get($blobid, 8192)){
$realblob .= $string;
while($string = ibase_blob_get($blobid, 8192)){
$realblob .= $string;
}
ibase_blob_close( $blobid );
return( $realblob );
}
function _BlobDecode( $blob )
{
if (ADODB_PHPVER >= 0x5000) {
$blob_data = ibase_blob_info($this->_connectionID, $blob );
$blobid = ibase_blob_open($this->_connectionID, $blob );
} else {
$blob_data = ibase_blob_info( $blob );
$blobid = ibase_blob_open( $blob );
}
if( $blob_data[0] > $this->maxblobsize ) {
$realblob = ibase_blob_get($blobid, $this->maxblobsize);
while($string = ibase_blob_get($blobid, 8192)){
$realblob .= $string;
}
} else {
$realblob = ibase_blob_get($blobid, $blob_data[0]);
}
ibase_blob_close( $blobid );
return( $realblob );
}
function UpdateBlobFile($table,$column,$path,$where,$blobtype='BLOB')
{
$fd = fopen($path,'rb');
if ($fd === false) return false;
$blob_id = ibase_blob_create($this->_connectionID);
/* fill with data */
while ($val = fread($fd,32768)){
ibase_blob_add($blob_id, $val);
}
/* close and get $blob_id_str for inserting into table */
$blob_id_str = ibase_blob_close($blob_id);
fclose($fd);
return $this->Execute("UPDATE $table SET $column=(?) WHERE $where",array($blob_id_str)) != false;
}
function _BlobDecode( $blob )
{
if (ADODB_PHPVER >= 0x5000) {
$blob_data = ibase_blob_info($this->_connectionID, $blob );
$blobid = ibase_blob_open($this->_connectionID, $blob );
} else {
$blob_data = ibase_blob_info( $blob );
$blobid = ibase_blob_open( $blob );
}
if( $blob_data[0] > $this->maxblobsize ) {
$realblob = ibase_blob_get($blobid, $this->maxblobsize);
while($string = ibase_blob_get($blobid, 8192)){
$realblob .= $string;
}
} else {
$realblob = ibase_blob_get($blobid, $blob_data[0]);
}
ibase_blob_close( $blobid );
return( $realblob );
}
function UpdateBlobFile($table,$column,$path,$where,$blobtype='BLOB')
{
$fd = fopen($path,'rb');
if ($fd === false) return false;
$blob_id = ibase_blob_create($this->_connectionID);
/* fill with data */
while ($val = fread($fd,32768)){
ibase_blob_add($blob_id, $val);
}
/* close and get $blob_id_str for inserting into table */
$blob_id_str = ibase_blob_close($blob_id);
fclose($fd);
return $this->Execute("UPDATE $table SET $column=(?) WHERE $where",array($blob_id_str)) != false;
}
/*
Insert a null into the blob field of the table first.
Then use UpdateBlob to store the blob.
Usage:
$conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, null)');
$conn->UpdateBlob('blobtable','blobcol',$blob,'id=1');
*/
function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
{
$blob_id = ibase_blob_create($this->_connectionID);
// ibase_blob_add($blob_id, $val);
// replacement that solves the problem by which only the first modulus 64K /
// of $val are stored at the blob field ////////////////////////////////////
function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
{
$blob_id = ibase_blob_create($this->_connectionID);
// ibase_blob_add($blob_id, $val);
// replacement that solves the problem by which only the first modulus 64K /
// of $val are stored at the blob field ////////////////////////////////////
// Thx Abel Berenstein aberenstein#afip.gov.ar
$len = strlen($val);
$chunk_size = 32768;
$tail_size = $len % $chunk_size;
$n_chunks = ($len - $tail_size) / $chunk_size;
for ($n = 0; $n < $n_chunks; $n++) {
$start = $n * $chunk_size;
$data = substr($val, $start, $chunk_size);
ibase_blob_add($blob_id, $data);
}
if ($tail_size) {
$start = $n_chunks * $chunk_size;
$data = substr($val, $start, $tail_size);
ibase_blob_add($blob_id, $data);
$len = strlen($val);
$chunk_size = 32768;
$tail_size = $len % $chunk_size;
$n_chunks = ($len - $tail_size) / $chunk_size;
for ($n = 0; $n < $n_chunks; $n++) {
$start = $n * $chunk_size;
$data = substr($val, $start, $chunk_size);
ibase_blob_add($blob_id, $data);
}
// end replacement /////////////////////////////////////////////////////////
$blob_id_str = ibase_blob_close($blob_id);
return $this->Execute("UPDATE $table SET $column=(?) WHERE $where",array($blob_id_str)) != false;
}
if ($tail_size) {
$start = $n_chunks * $chunk_size;
$data = substr($val, $start, $tail_size);
ibase_blob_add($blob_id, $data);
}
// end replacement /////////////////////////////////////////////////////////
$blob_id_str = ibase_blob_close($blob_id);
return $this->Execute("UPDATE $table SET $column=(?) WHERE $where",array($blob_id_str)) != false;
}
function OldUpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
{
$blob_id = ibase_blob_create($this->_connectionID);
@@ -663,15 +694,15 @@ class ADODB_ibase extends ADOConnection {
$blob_id_str = ibase_blob_close($blob_id);
return $this->Execute("UPDATE $table SET $column=(?) WHERE $where",array($blob_id_str)) != false;
}
// Format date column in sql string given an input format that understands Y M D
// Only since Interbase 6.0 - uses EXTRACT
// problem - does not zero-fill the day and month yet
function SQLDate($fmt, $col=false)
{
{
if (!$col) $col = $this->sysDate;
$s = '';
$len = strlen($fmt);
for ($i=0; $i < $len; $i++) {
if ($s) $s .= '||';
@@ -695,16 +726,16 @@ class ADODB_ibase extends ADOConnection {
break;
case 'H':
case 'h':
$s .= "(extract(hour from $col))";
break;
$s .= "(extract(hour from $col))";
break;
case 'I':
case 'i':
$s .= "(extract(minute from $col))";
break;
$s .= "(extract(minute from $col))";
break;
case 'S':
case 's':
$s .= "CAST((extract(second from $col)) AS INTEGER)";
break;
$s .= "CAST((extract(second from $col)) AS INTEGER)";
break;
default:
if ($ch == '\\') {
@@ -720,7 +751,7 @@ class ADODB_ibase extends ADOConnection {
}
/*--------------------------------------------------------------------------------------
Class Name: Recordset
Class Name: Recordset
--------------------------------------------------------------------------------------*/
class ADORecordset_ibase extends ADORecordSet
@@ -729,13 +760,13 @@ class ADORecordset_ibase extends ADORecordSet
var $databaseType = "ibase";
var $bind=false;
var $_cacheType;
function ADORecordset_ibase($id,$mode=false)
function __construct($id,$mode=false)
{
global $ADODB_FETCH_MODE;
$this->fetchMode = ($mode === false) ? $ADODB_FETCH_MODE : $mode;
$this->ADORecordSet($id);
parent::__construct($id);
}
/* Returns: an object containing field information.
@@ -745,31 +776,32 @@ class ADORecordset_ibase extends ADORecordSet
function FetchField($fieldOffset = -1)
{
$fld = new ADOFieldObject;
$ibf = ibase_field_info($this->_queryID,$fieldOffset);
switch (ADODB_ASSOC_CASE) {
case 2: // the default
$fld->name = ($ibf['alias']);
if (empty($fld->name)) $fld->name = ($ibf['name']);
break;
case 0:
$fld->name = strtoupper($ibf['alias']);
if (empty($fld->name)) $fld->name = strtoupper($ibf['name']);
break;
case 1:
$fld->name = strtolower($ibf['alias']);
if (empty($fld->name)) $fld->name = strtolower($ibf['name']);
break;
}
$fld->type = $ibf['type'];
$fld->max_length = $ibf['length'];
/* This needs to be populated from the metadata */
$fld->not_null = false;
$fld->has_default = false;
$fld->default_value = 'null';
return $fld;
$fld = new ADOFieldObject;
$ibf = ibase_field_info($this->_queryID,$fieldOffset);
$name = empty($ibf['alias']) ? $ibf['name'] : $ibf['alias'];
switch (ADODB_ASSOC_CASE) {
case ADODB_ASSOC_CASE_UPPER:
$fld->name = strtoupper($name);
break;
case ADODB_ASSOC_CASE_LOWER:
$fld->name = strtolower($name);
break;
case ADODB_ASSOC_CASE_NATIVE:
default:
$fld->name = $name;
break;
}
$fld->type = $ibf['type'];
$fld->max_length = $ibf['length'];
/* This needs to be populated from the metadata */
$fld->not_null = false;
$fld->has_default = false;
$fld->default_value = 'null';
return $fld;
}
function _initrs()
@@ -778,53 +810,53 @@ class ADORecordset_ibase extends ADORecordSet
$this->_numOfFields = @ibase_num_fields($this->_queryID);
// cache types for blob decode check
for ($i=0, $max = $this->_numOfFields; $i < $max; $i++) {
$f1 = $this->FetchField($i);
for ($i=0, $max = $this->_numOfFields; $i < $max; $i++) {
$f1 = $this->FetchField($i);
$this->_cacheType[] = $f1->type;
}
}
}
function _seek($row)
{
return false;
}
function _fetch()
function _fetch()
{
$f = @ibase_fetch_row($this->_queryID);
$f = @ibase_fetch_row($this->_queryID);
if ($f === false) {
$this->fields = false;
return false;
}
// OPN stuff start - optimized
// fix missing nulls and decode blobs automatically
global $ADODB_ANSI_PADDING_OFF;
//$ADODB_ANSI_PADDING_OFF=1;
$rtrim = !empty($ADODB_ANSI_PADDING_OFF);
for ($i=0, $max = $this->_numOfFields; $i < $max; $i++) {
for ($i=0, $max = $this->_numOfFields; $i < $max; $i++) {
if ($this->_cacheType[$i]=="BLOB") {
if (isset($f[$i])) {
$f[$i] = $this->connection->_BlobDecode($f[$i]);
} else {
$f[$i] = null;
}
} else {
if (!isset($f[$i])) {
$f[$i] = null;
if (isset($f[$i])) {
$f[$i] = $this->connection->_BlobDecode($f[$i]);
} else {
$f[$i] = null;
}
} else {
if (!isset($f[$i])) {
$f[$i] = null;
} else if ($rtrim && is_string($f[$i])) {
$f[$i] = rtrim($f[$i]);
}
}
}
// OPN stuff end
}
}
// OPN stuff end
$this->fields = $f;
if ($this->fetchMode == ADODB_FETCH_ASSOC) {
$this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
$this->fields = $this->GetRowAssoc();
} else if ($this->fetchMode == ADODB_FETCH_BOTH) {
$this->fields = array_merge($this->fields,$this->GetRowAssoc(ADODB_ASSOC_CASE));
$this->fields = array_merge($this->fields,$this->GetRowAssoc());
}
return true;
}
@@ -840,13 +872,13 @@ class ADORecordset_ibase extends ADORecordSet
$this->bind[strtoupper($o->name)] = $i;
}
}
return $this->fields[$this->bind[strtoupper($colname)]];
}
function _close()
return $this->fields[$this->bind[strtoupper($colname)]];
}
function _close()
{
return @ibase_free_result($this->_queryID);
}
@@ -861,7 +893,7 @@ class ADORecordset_ibase extends ADORecordSet
switch (strtoupper($t)) {
case 'CHAR':
return 'C';
case 'TEXT':
case 'VARCHAR':
case 'VARYING':
@@ -869,14 +901,14 @@ class ADORecordset_ibase extends ADORecordSet
return 'X';
case 'BLOB':
return 'B';
case 'TIMESTAMP':
case 'DATE': return 'D';
case 'TIME': return 'T';
//case 'T': return 'T';
//case 'L': return 'L';
case 'INT':
case 'INT':
case 'SHORT':
case 'INTEGER': return 'I';
default: return 'N';
@@ -884,4 +916,3 @@ class ADORecordset_ibase extends ADORecordSet
}
}
?>
+7 -6
View File
@@ -1,6 +1,8 @@
<?php
/**
* @version V5.06 16 Oct 2008 (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved.
* @version v5.20.9 21-Dec-2016
* @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.
@@ -22,7 +24,7 @@ class ADODB_informix extends ADODB_informix72 {
var $databaseType = "informix";
var $hasTop = 'FIRST';
var $ansiOuter = true;
function IfNull( $field, $ifNull )
{
return " NVL($field, $ifNull) "; // if Informix 9.X or 10.X
@@ -31,10 +33,9 @@ class ADODB_informix extends ADODB_informix72 {
class ADORecordset_informix extends ADORecordset_informix72 {
var $databaseType = "informix";
function ADORecordset_informix($id,$mode=false)
function __construct($id,$mode=false)
{
$this->ADORecordset_informix72($id,$mode);
parent::__construct($id,$mode);
}
}
?>
+87 -37
View File
@@ -1,6 +1,8 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim. All rights reserved.
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim. 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.
@@ -31,7 +33,7 @@ class ADODB_informix72 extends ADOConnection {
var $metaTablesSQL="select tabname,tabtype from systables where tabtype in ('T','V') and owner!='informix'"; //Don't get informix tables and pseudo-tables
var $metaColumnsSQL =
var $metaColumnsSQL =
"select c.colname, c.coltype, c.collength, d.default,c.colno
from syscolumns c, systables t,outer sysdefaults d
where c.tabid=t.tabid and d.tabid=t.tabid and d.colno=c.colno
@@ -53,26 +55,26 @@ class ADODB_informix72 extends ADOConnection {
var $sysDate = 'TODAY';
var $sysTimeStamp = 'CURRENT';
var $cursorType = IFX_SCROLL; // IFX_SCROLL or IFX_HOLD or 0
function ADODB_informix72()
function __construct()
{
// alternatively, use older method:
//putenv("DBDATE=Y4MD-");
// force ISO date format
putenv('GL_DATE=%Y-%m-%d');
if (function_exists('ifx_byteasvarchar')) {
ifx_byteasvarchar(1); // Mode "0" will return a blob id, and mode "1" will return a varchar with text content.
ifx_textasvarchar(1); // Mode "0" will return a blob id, and mode "1" will return a varchar with text content.
ifx_byteasvarchar(1); // Mode "0" will return a blob id, and mode "1" will return a varchar with text content.
ifx_textasvarchar(1); // Mode "0" will return a blob id, and mode "1" will return a varchar with text content.
ifx_blobinfile_mode(0); // Mode "0" means save Byte-Blobs in memory, and mode "1" means save Byte-Blobs in a file.
}
}
function ServerInfo()
{
if (isset($this->version)) return $this->version;
$arr['description'] = $this->GetOne("select DBINFO('version','full') from systables where tabid = 1");
$arr['version'] = $this->GetOne("select DBINFO('version','major') || DBINFO('version','minor') from systables where tabid = 1");
$this->version = $arr;
@@ -104,8 +106,8 @@ class ADODB_informix72 extends ADOConnection {
return true;
}
function CommitTrans($ok=true)
{
function CommitTrans($ok=true)
{
if (!$ok) return $this->RollbackTrans();
if ($this->transOff) return true;
if ($this->transCnt) $this->transCnt -= 1;
@@ -123,16 +125,16 @@ class ADODB_informix72 extends ADOConnection {
return true;
}
function RowLock($tables,$where,$flds='1 as ignore')
function RowLock($tables,$where,$col='1 as adodbignore')
{
if ($this->_autocommit) $this->BeginTrans();
return $this->GetOne("select $flds from $tables where $where for update");
return $this->GetOne("select $col from $tables where $where for update");
}
/* Returns: the last error message from previous database operation
Note: This function is NOT available for Microsoft SQL Server. */
function ErrorMsg()
function ErrorMsg()
{
if (!empty($this->_logsql)) return $this->_errorMsg;
$this->_errorMsg = ifx_errormsg();
@@ -142,15 +144,60 @@ class ADODB_informix72 extends ADOConnection {
function ErrorNo()
{
preg_match("/.*SQLCODE=([^\]]*)/",ifx_error(),$parse);
if (is_array($parse) && isset($parse[1])) return (int)$parse[1];
if (is_array($parse) && isset($parse[1])) return (int)$parse[1];
return 0;
}
function MetaProcedures($NamePattern = false, $catalog = null, $schemaPattern = null)
{
// save old fetch mode
global $ADODB_FETCH_MODE;
$false = false;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== FALSE) {
$savem = $this->SetFetchMode(FALSE);
}
$procedures = array ();
// get index details
$likepattern = '';
if ($NamePattern) {
$likepattern = " WHERE procname LIKE '".$NamePattern."'";
}
$rs = $this->Execute('SELECT procname, isproc FROM sysprocedures'.$likepattern);
if (is_object($rs)) {
// parse index data into array
while ($row = $rs->FetchRow()) {
$procedures[$row[0]] = array(
'type' => ($row[1] == 'f' ? 'FUNCTION' : 'PROCEDURE'),
'catalog' => '',
'schema' => '',
'remarks' => ''
);
}
}
// restore fetchmode
if (isset($savem)) {
$this->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
return $procedures;
}
function MetaColumns($table, $normalize=true)
{
global $ADODB_FETCH_MODE;
$false = false;
if (!empty($this->metaColumnsSQL)) {
$save = $ADODB_FETCH_MODE;
@@ -187,18 +234,18 @@ class ADODB_informix72 extends ADOConnection {
$fld->has_default = 0;
}
$retarr[strtolower($fld->name)] = $fld;
$retarr[strtolower($fld->name)] = $fld;
$rs->MoveNext();
}
$rs->Close();
$rspkey->Close(); //!eos
return $retarr;
return $retarr;
}
return $false;
}
function xMetaColumns($table)
{
return ADOConnection::MetaColumns($table,false);
@@ -247,15 +294,15 @@ class ADODB_informix72 extends ADOConnection {
{
return function_exists('ifx_byteasvarchar') ? $blobid : @ifx_get_blob($blobid);
}
// returns true or false
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
if (!function_exists('ifx_connect')) return null;
$dbs = $argDatabasename . "@" . $argHostname;
if ($argHostname) putenv("INFORMIXSERVER=$argHostname");
putenv("INFORMIXSERVER=".trim($argHostname));
if ($argHostname) putenv("INFORMIXSERVER=$argHostname");
putenv("INFORMIXSERVER=".trim($argHostname));
$this->_connectionID = ifx_connect($dbs,$argUsername,$argPassword);
if ($this->_connectionID === false) return false;
#if ($argDatabasename) return $this->SelectDB($argDatabasename);
@@ -266,9 +313,9 @@ class ADODB_informix72 extends ADOConnection {
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
if (!function_exists('ifx_connect')) return null;
$dbs = $argDatabasename . "@" . $argHostname;
putenv("INFORMIXSERVER=".trim($argHostname));
putenv("INFORMIXSERVER=".trim($argHostname));
$this->_connectionID = ifx_pconnect($dbs,$argUsername,$argPassword);
if ($this->_connectionID === false) return false;
#if ($argDatabasename) return $this->SelectDB($argDatabasename);
@@ -287,7 +334,7 @@ class ADODB_informix72 extends ADOConnection {
function _query($sql,$inputarr=false)
{
global $ADODB_COUNTRECS;
// String parameters have to be converted using ifx_create_char
if ($inputarr) {
foreach($inputarr as $v) {
@@ -331,7 +378,10 @@ class ADODB_informix72 extends ADOConnection {
function _close()
{
$this->lastQuery = false;
return ifx_close($this->_connectionID);
if($this->_connectionID) {
return ifx_close($this->_connectionID);
}
return true;
}
}
@@ -346,14 +396,14 @@ class ADORecordset_informix72 extends ADORecordSet {
var $canSeek = true;
var $_fieldprops = false;
function ADORecordset_informix72($id,$mode=false)
function __construct($id,$mode=false)
{
if ($mode === false) {
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
$this->fetchMode = $mode;
return $this->ADORecordSet($id);
return parent::__construct($id);
}
@@ -369,7 +419,7 @@ class ADORecordset_informix72 extends ADORecordSet {
foreach($fp as $k => $v) {
$o = new ADOFieldObject;
$o->name = $k;
$arr = split(';',$v); //"SQLTYPE;length;precision;scale;ISNULLABLE"
$arr = explode(';',$v); //"SQLTYPE;length;precision;scale;ISNULLABLE"
$o->type = $arr[0];
$o->max_length = $arr[1];
$this->_fieldprops[] = $o;
@@ -443,7 +493,10 @@ class ADORecordset_informix72 extends ADORecordSet {
is running. All associated result memory for the specified result identifier will automatically be freed. */
function _close()
{
return ifx_free_result($this->_queryID);
if($this->_queryID) {
return ifx_free_result($this->_queryID);
}
return true;
}
}
@@ -470,6 +523,3 @@ function ifx_props($coltype,$collength){
}
return array($mtype,$length,$precision,$nullable);
}
?>
+251 -246
View File
@@ -1,39 +1,41 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
@version v5.20.9 21-Dec-2016
@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.
Set tabs to 8.
Revision 1: (02/25/2005) Updated codebase to include the _inject_bind_options function. This allows
users to access the options in the ldap_set_option function appropriately. Most importantly
LDAP Version 3 is now supported. See the examples for more information. Also fixed some minor
bugs that surfaced when PHP error levels were set high.
Joshua Eldridge (joshuae74#hotmail.com)
*/
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
if (!defined('LDAP_ASSOC')) {
define('LDAP_ASSOC',ADODB_FETCH_ASSOC);
define('LDAP_NUM',ADODB_FETCH_NUM);
define('LDAP_BOTH',ADODB_FETCH_BOTH);
define('LDAP_ASSOC',ADODB_FETCH_ASSOC);
define('LDAP_NUM',ADODB_FETCH_NUM);
define('LDAP_BOTH',ADODB_FETCH_BOTH);
}
class ADODB_ldap extends ADOConnection {
var $databaseType = 'ldap';
var $databaseType = 'ldap';
var $dataProvider = 'ldap';
# Connection information
var $username = false;
var $password = false;
# Used during searches
var $filter;
var $dn;
var $username = false;
var $password = false;
# Used during searches
var $filter;
var $dn;
var $version;
var $port = 389;
@@ -42,28 +44,28 @@ class ADODB_ldap extends ADOConnection {
# error on binding, eg. "Binding: invalid credentials"
var $_bind_errmsg = "Binding: %s";
function ADODB_ldap()
{
function __construct()
{
}
// returns true or false
function _connect( $host, $username, $password, $ldapbase)
{
global $LDAP_CONNECT_OPTIONS;
global $LDAP_CONNECT_OPTIONS;
if ( !function_exists( 'ldap_connect' ) ) return null;
if (strpos('ldap://',$host) === 0 || strpos('ldaps://',$host) === 0) {
if (strpos($host,'ldap://') === 0 || strpos($host,'ldaps://') === 0) {
$this->_connectionID = @ldap_connect($host);
} else {
$conn_info = array( $host,$this->port);
if ( strstr( $host, ':' ) ) {
$conn_info = split( ':', $host );
}
$conn_info = explode( ':', $host );
}
$this->_connectionID = @ldap_connect( $conn_info[0], $conn_info[1] );
}
if (!$this->_connectionID) {
@@ -75,14 +77,14 @@ class ADODB_ldap extends ADOConnection {
if( count( $LDAP_CONNECT_OPTIONS ) > 0 ) {
$this->_inject_bind_options( $LDAP_CONNECT_OPTIONS );
}
if ($username) {
$bind = @ldap_bind( $this->_connectionID, $username, $password );
$bind = @ldap_bind( $this->_connectionID, $username, $password );
} else {
$username = 'anonymous';
$bind = @ldap_bind( $this->_connectionID );
$bind = @ldap_bind( $this->_connectionID );
}
if (!$bind) {
$e = sprintf($this->_bind_errmsg,ldap_error($this->_connectionID));
$this->_errorMsg = $e;
@@ -93,7 +95,7 @@ class ADODB_ldap extends ADOConnection {
$this->database = $ldapbase;
return $this->_connectionID;
}
/*
Valid Domain Values for LDAP Options:
@@ -152,272 +154,275 @@ class ADODB_ldap extends ADOConnection {
or die( "Unable to set server option: " . $option["OPTION_NAME"] );
}
}
/* returns _queryID or false */
function _query($sql,$inputarr=false)
{
$rs = @ldap_search( $this->_connectionID, $this->database, $sql );
$this->_errorMsg = ($rs) ? '' : 'Search error on '.$sql.': '.ldap_error($this->_connectionID);
return $rs;
return $rs;
}
function ErrorMsg()
{
return $this->_errorMsg;
}
function ErrorNo()
{
return @ldap_errno($this->_connectionID);
}
/* closes the LDAP connection */
/* closes the LDAP connection */
function _close()
{
@ldap_close( $this->_connectionID );
$this->_connectionID = false;
}
function SelectDB($db) {
$this->database = $db;
return true;
} // SelectDB
function ServerInfo()
{
if( !empty( $this->version ) ) return $this->version;
$version = array();
/*
Determines how aliases are handled during search.
LDAP_DEREF_NEVER (0x00)
LDAP_DEREF_SEARCHING (0x01)
LDAP_DEREF_FINDING (0x02)
LDAP_DEREF_ALWAYS (0x03)
The LDAP_DEREF_SEARCHING value means aliases are dereferenced during the search but
not when locating the base object of the search. The LDAP_DEREF_FINDING value means
aliases are dereferenced when locating the base object but not during the search.
Default: LDAP_DEREF_NEVER
*/
ldap_get_option( $this->_connectionID, LDAP_OPT_DEREF, $version['LDAP_OPT_DEREF'] ) ;
switch ( $version['LDAP_OPT_DEREF'] ) {
case 0:
$version['LDAP_OPT_DEREF'] = 'LDAP_DEREF_NEVER';
case 1:
$version['LDAP_OPT_DEREF'] = 'LDAP_DEREF_SEARCHING';
case 2:
$version['LDAP_OPT_DEREF'] = 'LDAP_DEREF_FINDING';
case 3:
$version['LDAP_OPT_DEREF'] = 'LDAP_DEREF_ALWAYS';
}
/*
A limit on the number of entries to return from a search.
LDAP_NO_LIMIT (0) means no limit.
Default: LDAP_NO_LIMIT
*/
ldap_get_option( $this->_connectionID, LDAP_OPT_SIZELIMIT, $version['LDAP_OPT_SIZELIMIT'] );
if ( $version['LDAP_OPT_SIZELIMIT'] == 0 ) {
$version['LDAP_OPT_SIZELIMIT'] = 'LDAP_NO_LIMIT';
}
/*
A limit on the number of seconds to spend on a search.
LDAP_NO_LIMIT (0) means no limit.
Default: LDAP_NO_LIMIT
*/
ldap_get_option( $this->_connectionID, LDAP_OPT_TIMELIMIT, $version['LDAP_OPT_TIMELIMIT'] );
if ( $version['LDAP_OPT_TIMELIMIT'] == 0 ) {
$version['LDAP_OPT_TIMELIMIT'] = 'LDAP_NO_LIMIT';
}
/*
Determines whether the LDAP library automatically follows referrals returned by LDAP servers or not.
LDAP_OPT_ON
LDAP_OPT_OFF
Default: ON
*/
ldap_get_option( $this->_connectionID, LDAP_OPT_REFERRALS, $version['LDAP_OPT_REFERRALS'] );
if ( $version['LDAP_OPT_REFERRALS'] == 0 ) {
$version['LDAP_OPT_REFERRALS'] = 'LDAP_OPT_OFF';
} else {
$version['LDAP_OPT_REFERRALS'] = 'LDAP_OPT_ON';
}
/*
Determines whether LDAP I/O operations are automatically restarted if they abort prematurely.
LDAP_OPT_ON
LDAP_OPT_OFF
Default: OFF
*/
ldap_get_option( $this->_connectionID, LDAP_OPT_RESTART, $version['LDAP_OPT_RESTART'] );
if ( $version['LDAP_OPT_RESTART'] == 0 ) {
$version['LDAP_OPT_RESTART'] = 'LDAP_OPT_OFF';
} else {
$version['LDAP_OPT_RESTART'] = 'LDAP_OPT_ON';
}
/*
This option indicates the version of the LDAP protocol used when communicating with the primary LDAP server.
LDAP_VERSION2 (2)
LDAP_VERSION3 (3)
Default: LDAP_VERSION2 (2)
*/
ldap_get_option( $this->_connectionID, LDAP_OPT_PROTOCOL_VERSION, $version['LDAP_OPT_PROTOCOL_VERSION'] );
if ( $version['LDAP_OPT_PROTOCOL_VERSION'] == 2 ) {
$version['LDAP_OPT_PROTOCOL_VERSION'] = 'LDAP_VERSION2';
} else {
$version['LDAP_OPT_PROTOCOL_VERSION'] = 'LDAP_VERSION3';
}
/* The host name (or list of hosts) for the primary LDAP server. */
ldap_get_option( $this->_connectionID, LDAP_OPT_HOST_NAME, $version['LDAP_OPT_HOST_NAME'] );
ldap_get_option( $this->_connectionID, LDAP_OPT_ERROR_NUMBER, $version['LDAP_OPT_ERROR_NUMBER'] );
ldap_get_option( $this->_connectionID, LDAP_OPT_ERROR_STRING, $version['LDAP_OPT_ERROR_STRING'] );
ldap_get_option( $this->_connectionID, LDAP_OPT_MATCHED_DN, $version['LDAP_OPT_MATCHED_DN'] );
return $this->version = $version;
}
function ServerInfo()
{
if( !empty( $this->version ) ) {
return $this->version;
}
$version = array();
/*
Determines how aliases are handled during search.
LDAP_DEREF_NEVER (0x00)
LDAP_DEREF_SEARCHING (0x01)
LDAP_DEREF_FINDING (0x02)
LDAP_DEREF_ALWAYS (0x03)
The LDAP_DEREF_SEARCHING value means aliases are dereferenced during the search but
not when locating the base object of the search. The LDAP_DEREF_FINDING value means
aliases are dereferenced when locating the base object but not during the search.
Default: LDAP_DEREF_NEVER
*/
ldap_get_option( $this->_connectionID, LDAP_OPT_DEREF, $version['LDAP_OPT_DEREF'] ) ;
switch ( $version['LDAP_OPT_DEREF'] ) {
case 0:
$version['LDAP_OPT_DEREF'] = 'LDAP_DEREF_NEVER';
case 1:
$version['LDAP_OPT_DEREF'] = 'LDAP_DEREF_SEARCHING';
case 2:
$version['LDAP_OPT_DEREF'] = 'LDAP_DEREF_FINDING';
case 3:
$version['LDAP_OPT_DEREF'] = 'LDAP_DEREF_ALWAYS';
}
/*
A limit on the number of entries to return from a search.
LDAP_NO_LIMIT (0) means no limit.
Default: LDAP_NO_LIMIT
*/
ldap_get_option( $this->_connectionID, LDAP_OPT_SIZELIMIT, $version['LDAP_OPT_SIZELIMIT'] );
if ( $version['LDAP_OPT_SIZELIMIT'] == 0 ) {
$version['LDAP_OPT_SIZELIMIT'] = 'LDAP_NO_LIMIT';
}
/*
A limit on the number of seconds to spend on a search.
LDAP_NO_LIMIT (0) means no limit.
Default: LDAP_NO_LIMIT
*/
ldap_get_option( $this->_connectionID, LDAP_OPT_TIMELIMIT, $version['LDAP_OPT_TIMELIMIT'] );
if ( $version['LDAP_OPT_TIMELIMIT'] == 0 ) {
$version['LDAP_OPT_TIMELIMIT'] = 'LDAP_NO_LIMIT';
}
/*
Determines whether the LDAP library automatically follows referrals returned by LDAP servers or not.
LDAP_OPT_ON
LDAP_OPT_OFF
Default: ON
*/
ldap_get_option( $this->_connectionID, LDAP_OPT_REFERRALS, $version['LDAP_OPT_REFERRALS'] );
if ( $version['LDAP_OPT_REFERRALS'] == 0 ) {
$version['LDAP_OPT_REFERRALS'] = 'LDAP_OPT_OFF';
} else {
$version['LDAP_OPT_REFERRALS'] = 'LDAP_OPT_ON';
}
/*
Determines whether LDAP I/O operations are automatically restarted if they abort prematurely.
LDAP_OPT_ON
LDAP_OPT_OFF
Default: OFF
*/
ldap_get_option( $this->_connectionID, LDAP_OPT_RESTART, $version['LDAP_OPT_RESTART'] );
if ( $version['LDAP_OPT_RESTART'] == 0 ) {
$version['LDAP_OPT_RESTART'] = 'LDAP_OPT_OFF';
} else {
$version['LDAP_OPT_RESTART'] = 'LDAP_OPT_ON';
}
/*
This option indicates the version of the LDAP protocol used when communicating with the primary LDAP server.
LDAP_VERSION2 (2)
LDAP_VERSION3 (3)
Default: LDAP_VERSION2 (2)
*/
ldap_get_option( $this->_connectionID, LDAP_OPT_PROTOCOL_VERSION, $version['LDAP_OPT_PROTOCOL_VERSION'] );
if ( $version['LDAP_OPT_PROTOCOL_VERSION'] == 2 ) {
$version['LDAP_OPT_PROTOCOL_VERSION'] = 'LDAP_VERSION2';
} else {
$version['LDAP_OPT_PROTOCOL_VERSION'] = 'LDAP_VERSION3';
}
/* The host name (or list of hosts) for the primary LDAP server. */
ldap_get_option( $this->_connectionID, LDAP_OPT_HOST_NAME, $version['LDAP_OPT_HOST_NAME'] );
ldap_get_option( $this->_connectionID, LDAP_OPT_ERROR_NUMBER, $version['LDAP_OPT_ERROR_NUMBER'] );
ldap_get_option( $this->_connectionID, LDAP_OPT_ERROR_STRING, $version['LDAP_OPT_ERROR_STRING'] );
ldap_get_option( $this->_connectionID, LDAP_OPT_MATCHED_DN, $version['LDAP_OPT_MATCHED_DN'] );
return $this->version = $version;
}
}
/*--------------------------------------------------------------------------------------
Class Name: Recordset
Class Name: Recordset
--------------------------------------------------------------------------------------*/
class ADORecordSet_ldap extends ADORecordSet{
class ADORecordSet_ldap extends ADORecordSet{
var $databaseType = "ldap";
var $canSeek = false;
var $_entryID; /* keeps track of the entry resource identifier */
function ADORecordSet_ldap($queryID,$mode=false)
function __construct($queryID,$mode=false)
{
if ($mode === false) {
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
switch ($mode)
{
case ADODB_FETCH_NUM:
$this->fetchMode = LDAP_NUM;
break;
case ADODB_FETCH_ASSOC:
$this->fetchMode = LDAP_ASSOC;
break;
case ADODB_FETCH_NUM:
$this->fetchMode = LDAP_NUM;
break;
case ADODB_FETCH_ASSOC:
$this->fetchMode = LDAP_ASSOC;
break;
case ADODB_FETCH_DEFAULT:
case ADODB_FETCH_BOTH:
case ADODB_FETCH_BOTH:
default:
$this->fetchMode = LDAP_BOTH;
break;
$this->fetchMode = LDAP_BOTH;
break;
}
$this->ADORecordSet($queryID);
parent::__construct($queryID);
}
function _initrs()
{
/*
This could be teaked to respect the $COUNTRECS directive from ADODB
It's currently being used in the _fetch() function and the
GetAssoc() function
*/
$this->_numOfRows = ldap_count_entries( $this->connection->_connectionID, $this->_queryID );
/*
This could be teaked to respect the $COUNTRECS directive from ADODB
It's currently being used in the _fetch() function and the
GetAssoc() function
*/
$this->_numOfRows = ldap_count_entries( $this->connection->_connectionID, $this->_queryID );
}
/*
Return whole recordset as a multi-dimensional associative array
/*
Return whole recordset as a multi-dimensional associative array
*/
function GetAssoc($force_array = false, $first2cols = false)
function GetAssoc($force_array = false, $first2cols = false)
{
$records = $this->_numOfRows;
$results = array();
for ( $i=0; $i < $records; $i++ ) {
foreach ( $this->fields as $k=>$v ) {
if ( is_array( $v ) ) {
if ( $v['count'] == 1 ) {
$results[$i][$k] = $v[0];
} else {
array_shift( $v );
$results[$i][$k] = $v;
}
}
}
}
return $results;
$results = array();
for ( $i=0; $i < $records; $i++ ) {
foreach ( $this->fields as $k=>$v ) {
if ( is_array( $v ) ) {
if ( $v['count'] == 1 ) {
$results[$i][$k] = $v[0];
} else {
array_shift( $v );
$results[$i][$k] = $v;
}
}
}
}
return $results;
}
function GetRowAssoc()
function GetRowAssoc($upper = ADODB_ASSOC_CASE)
{
$results = array();
foreach ( $this->fields as $k=>$v ) {
if ( is_array( $v ) ) {
if ( $v['count'] == 1 ) {
$results[$k] = $v[0];
} else {
array_shift( $v );
$results[$k] = $v;
}
}
}
return $results;
$results = array();
foreach ( $this->fields as $k=>$v ) {
if ( is_array( $v ) ) {
if ( $v['count'] == 1 ) {
$results[$k] = $v[0];
} else {
array_shift( $v );
$results[$k] = $v;
}
}
}
return $results;
}
function GetRowNums()
{
$results = array();
foreach ( $this->fields as $k=>$v ) {
static $i = 0;
if (is_array( $v )) {
if ( $v['count'] == 1 ) {
$results[$i] = $v[0];
} else {
array_shift( $v );
$results[$i] = $v;
}
$i++;
}
}
return $results;
}
function GetRowNums()
{
$results = array();
foreach ( $this->fields as $k=>$v ) {
static $i = 0;
if (is_array( $v )) {
if ( $v['count'] == 1 ) {
$results[$i] = $v[0];
} else {
array_shift( $v );
$results[$i] = $v;
}
$i++;
}
}
return $results;
}
function _fetch()
{
if ( $this->_currentRow >= $this->_numOfRows && $this->_numOfRows >= 0 )
return false;
if ( $this->_currentRow == 0 ) {
$this->_entryID = ldap_first_entry( $this->connection->_connectionID, $this->_queryID );
} else {
$this->_entryID = ldap_next_entry( $this->connection->_connectionID, $this->_entryID );
}
$this->fields = ldap_get_attributes( $this->connection->_connectionID, $this->_entryID );
$this->_numOfFields = $this->fields['count'];
switch ( $this->fetchMode ) {
case LDAP_ASSOC:
$this->fields = $this->GetRowAssoc();
break;
case LDAP_NUM:
$this->fields = array_merge($this->GetRowNums(),$this->GetRowAssoc());
break;
case LDAP_BOTH:
default:
$this->fields = $this->GetRowNums();
break;
}
return ( is_array( $this->fields ) );
{
if ( $this->_currentRow >= $this->_numOfRows && $this->_numOfRows >= 0 ) {
return false;
}
if ( $this->_currentRow == 0 ) {
$this->_entryID = ldap_first_entry( $this->connection->_connectionID, $this->_queryID );
} else {
$this->_entryID = ldap_next_entry( $this->connection->_connectionID, $this->_entryID );
}
$this->fields = ldap_get_attributes( $this->connection->_connectionID, $this->_entryID );
$this->_numOfFields = $this->fields['count'];
switch ( $this->fetchMode ) {
case LDAP_ASSOC:
$this->fields = $this->GetRowAssoc();
break;
case LDAP_NUM:
$this->fields = array_merge($this->GetRowNums(),$this->GetRowAssoc());
break;
case LDAP_BOTH:
default:
$this->fields = $this->GetRowNums();
break;
}
return is_array( $this->fields );
}
function _close() {
@ldap_free_result( $this->_queryID );
@ldap_free_result( $this->_queryID );
$this->_queryID = false;
}
}
?>
+308 -229
View File
@@ -1,17 +1,19 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). 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.
/*
@version v5.20.9 21-Dec-2016
@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.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
Native mssql driver. Requires mssql client. Works on Windows.
To configure for Unix, see
Native mssql driver. Requires mssql client. Works on Windows.
To configure for Unix, see
http://phpbuilder.com/columns/alberto20000919.php3
*/
@@ -20,15 +22,15 @@ if (!defined('ADODB_DIR')) die();
//----------------------------------------------------------------
// MSSQL returns dates with the format Oct 13 2002 or 13 Oct 2002
// and this causes tons of problems because localized versions of
// MSSQL will return the dates in dmy or mdy order; and also the
// month strings depends on what language has been configured. The
// and this causes tons of problems because localized versions of
// MSSQL will return the dates in dmy or mdy order; and also the
// month strings depends on what language has been configured. The
// following two variables allow you to control the localization
// settings - Ugh.
//
// MORE LOCALIZATION INFO
// ----------------------
// To configure datetime, look for and modify sqlcommn.loc,
// To configure datetime, look for and modify sqlcommn.loc,
// typically found in c:\mssql\install
// Also read :
// http://support.microsoft.com/default.aspx?scid=kb;EN-US;q220918
@@ -40,12 +42,12 @@ if (!defined('ADODB_DIR')) die();
// has datetime converstion to YYYY-MM-DD format, and also mssql_fetch_assoc
if (ADODB_PHPVER >= 0x4300) {
// docs say 4.2.0, but testing shows only since 4.3.0 does it work!
ini_set('mssql.datetimeconvert',0);
ini_set('mssql.datetimeconvert',0);
} else {
global $ADODB_mssql_mths; // array, months must be upper-case
$ADODB_mssql_date_order = 'mdy';
$ADODB_mssql_date_order = 'mdy';
$ADODB_mssql_mths = array(
'JAN'=>1,'FEB'=>2,'MAR'=>3,'APR'=>4,'MAY'=>5,'JUN'=>6,
'JUL'=>7,'AUG'=>8,'SEP'=>9,'OCT'=>10,'NOV'=>11,'DEC'=>12);
@@ -72,11 +74,11 @@ global $ADODB_mssql_date_order;
}
class ADODB_mssql extends ADOConnection {
var $databaseType = "mssql";
var $databaseType = "mssql";
var $dataProvider = "mssql";
var $replaceQuote = "''"; // string to use to replace quotes
var $fmtDate = "'Y-m-d'";
var $fmtTimeStamp = "'Y-m-d H:i:s'";
var $fmtTimeStamp = "'Y-m-d\TH:i:s'";
var $hasInsertID = true;
var $substr = "substring";
var $length = 'len';
@@ -84,9 +86,9 @@ class ADODB_mssql extends ADOConnection {
var $metaDatabasesSQL = "select name from sysdatabases where name <> 'master'";
var $metaTablesSQL="select name,case when type='U' then 'T' else 'V' end from sysobjects where (type='U' or type='V') and (name not in ('sysallocations','syscolumns','syscomments','sysdepends','sysfilegroups','sysfiles','sysfiles1','sysforeignkeys','sysfulltextcatalogs','sysindexes','sysindexkeys','sysmembers','sysobjects','syspermissions','sysprotects','sysreferences','systypes','sysusers','sysalternates','sysconstraints','syssegments','REFERENTIAL_CONSTRAINTS','CHECK_CONSTRAINTS','CONSTRAINT_TABLE_USAGE','CONSTRAINT_COLUMN_USAGE','VIEWS','VIEW_TABLE_USAGE','VIEW_COLUMN_USAGE','SCHEMATA','TABLES','TABLE_CONSTRAINTS','TABLE_PRIVILEGES','COLUMNS','COLUMN_DOMAIN_USAGE','COLUMN_PRIVILEGES','DOMAINS','DOMAIN_CONSTRAINTS','KEY_COLUMN_USAGE','dtproperties'))";
var $metaColumnsSQL = # xtype==61 is datetime
"select c.name,t.name,c.length,
(case when c.xusertype=61 then 0 else c.xprec end),
(case when c.xusertype=61 then 0 else c.xscale end)
"select c.name,t.name,c.length,c.isnullable, c.status,
(case when c.xusertype=61 then 0 else c.xprec end),
(case when c.xusertype=61 then 0 else c.xscale end)
from syscolumns c join systypes t on t.xusertype=c.xusertype join sysobjects o on o.id=c.id where o.name='%s'";
var $hasTop = 'top'; // support mssql SELECT TOP 10 * FROM TABLE
var $hasGenID = true;
@@ -104,54 +106,54 @@ class ADODB_mssql extends ADOConnection {
var $uniqueOrderBy = true;
var $_bindInputArray = true;
var $forceNewConnect = false;
function ADODB_mssql()
{
function __construct()
{
$this->_has_mssql_init = (strnatcmp(PHP_VERSION,'4.1.0')>=0);
}
function ServerInfo()
{
global $ADODB_FETCH_MODE;
if ($this->fetchMode === false) {
$savem = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
} else
} else
$savem = $this->SetFetchMode(ADODB_FETCH_NUM);
if (0) {
$stmt = $this->PrepareSP('sp_server_info');
$val = 2;
$this->Parameter($stmt,$val,'attribute_id');
$row = $this->GetRow($stmt);
}
$row = $this->GetRow("execute sp_server_info 2");
if ($this->fetchMode === false) {
$ADODB_FETCH_MODE = $savem;
} else
$this->SetFetchMode($savem);
$arr['description'] = $row[2];
$arr['version'] = ADOConnection::_findvers($arr['description']);
return $arr;
}
function IfNull( $field, $ifNull )
function IfNull( $field, $ifNull )
{
return " ISNULL($field, $ifNull) "; // if MS SQL Server
}
function _insertid()
{
// SCOPE_IDENTITY()
// Returns the last IDENTITY value inserted into an IDENTITY column in
// the same scope. A scope is a module -- a stored procedure, trigger,
// function, or batch. Thus, two statements are in the same scope if
// Returns the last IDENTITY value inserted into an IDENTITY column in
// the same scope. A scope is a module -- a stored procedure, trigger,
// function, or batch. Thus, two statements are in the same scope if
// they are in the same stored procedure, function, or batch.
if ($this->lastInsID !== false) {
return $this->lastInsID; // InsID from sp_executesql call
@@ -166,7 +168,7 @@ class ADODB_mssql extends ADOConnection {
* Correctly quotes a string so that all strings are escaped. We prefix and append
* to the string single-quotes.
* An example is $db->qstr("Don't bother",magic_quotes_runtime());
*
*
* @param s the string to quote
* @param [magic_quotes] if $s is GET/POST var, set to get_magic_quotes_gpc().
* This undoes the stupidity of magic quotes for GPC.
@@ -201,10 +203,10 @@ class ADODB_mssql extends ADOConnection {
}
var $_dropSeqSQL = "drop table %s";
function CreateSequence($seq='adodbseq',$start=1)
{
$this->Execute('BEGIN TRANSACTION adodbseq');
$start -= 1;
$this->Execute("create table $seq (id float(53))");
@@ -213,7 +215,7 @@ class ADODB_mssql extends ADOConnection {
$this->Execute('ROLLBACK TRANSACTION adodbseq');
return false;
}
$this->Execute('COMMIT TRANSACTION adodbseq');
$this->Execute('COMMIT TRANSACTION adodbseq');
return true;
}
@@ -229,41 +231,41 @@ class ADODB_mssql extends ADOConnection {
$this->Execute('ROLLBACK TRANSACTION adodbseq');
return false;
}
$this->Execute('COMMIT TRANSACTION adodbseq');
$this->Execute('COMMIT TRANSACTION adodbseq');
return $start;
}
$num = $this->GetOne("select id from $seq");
$this->Execute('COMMIT TRANSACTION adodbseq');
$this->Execute('COMMIT TRANSACTION adodbseq');
return $num;
// in old implementation, pre 1.90, we returned GUID...
//return $this->GetOne("SELECT CONVERT(varchar(255), NEWID()) AS 'Char'");
}
function SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
{
if ($nrows > 0 && $offset <= 0) {
$sql = preg_replace(
'/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop." $nrows ",$sql);
if ($secs2cache)
$rs = $this->CacheExecute($secs2cache, $sql, $inputarr);
else
$rs = $this->Execute($sql,$inputarr);
} else
$rs = ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
return $rs;
}
// Format date column in sql string given an input format that understands Y M D
function SQLDate($fmt, $col=false)
{
{
if (!$col) $col = $this->sysTimeStamp;
$s = '';
$len = strlen($fmt);
for ($i=0; $i < $len; $i++) {
if ($s) $s .= '+';
@@ -290,11 +292,11 @@ class ADODB_mssql extends ADOConnection {
case 'h':
$s .= "substring(convert(char(14),$col,0),13,2)";
break;
case 'H':
$s .= "replace(str(datepart(hh,$col),2),' ','0')";
break;
case 'i':
$s .= "replace(str(datepart(mi,$col),2),' ','0')";
break;
@@ -305,7 +307,7 @@ class ADODB_mssql extends ADOConnection {
case 'A':
$s .= "substring(convert(char(19),$col,0),18,2)";
break;
default:
if ($ch == '\\') {
$i++;
@@ -318,18 +320,18 @@ class ADODB_mssql extends ADOConnection {
return $s;
}
function BeginTrans()
{
if ($this->transOff) return true;
if ($this->transOff) return true;
$this->transCnt += 1;
$ok = $this->Execute('BEGIN TRAN');
return $ok;
}
function CommitTrans($ok=true)
{
if ($this->transOff) return true;
function CommitTrans($ok=true)
{
if ($this->transOff) return true;
if (!$ok) return $this->RollbackTrans();
if ($this->transCnt) $this->transCnt -= 1;
$ok = $this->Execute('COMMIT TRAN');
@@ -337,13 +339,13 @@ class ADODB_mssql extends ADOConnection {
}
function RollbackTrans()
{
if ($this->transOff) return true;
if ($this->transOff) return true;
if ($this->transCnt) $this->transCnt -= 1;
$ok = $this->Execute('ROLLBACK TRAN');
return $ok;
}
function SetTransactionMode( $transaction_mode )
function SetTransactionMode( $transaction_mode )
{
$this->_transmode = $transaction_mode;
if (empty($transaction_mode)) {
@@ -353,35 +355,94 @@ class ADODB_mssql extends ADOConnection {
if (!stristr($transaction_mode,'isolation')) $transaction_mode = 'ISOLATION LEVEL '.$transaction_mode;
$this->Execute("SET TRANSACTION ".$transaction_mode);
}
/*
Usage:
$this->BeginTrans();
$this->RowLock('table1,table2','table1.id=33 and table2.id=table1.id'); # lock row 33 for both tables
# some operation on both tables table1 and table2
$this->CommitTrans();
See http://www.swynk.com/friends/achigrik/SQL70Locks.asp
*/
function RowLock($tables,$where,$flds='top 1 null as ignore')
function RowLock($tables,$where,$col='1 as adodbignore')
{
if ($col == '1 as adodbignore') $col = 'top 1 null as ignore';
if (!$this->transCnt) $this->BeginTrans();
return $this->GetOne("select $flds from $tables with (ROWLOCK,HOLDLOCK) where $where");
return $this->GetOne("select $col from $tables with (ROWLOCK,HOLDLOCK) where $where");
}
function MetaColumns($table, $normalize=true)
{
// $arr = ADOConnection::MetaColumns($table);
// return $arr;
$this->_findschema($table,$schema);
if ($schema) {
$dbName = $this->database;
$this->SelectDB($schema);
}
global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
$rs = $this->Execute(sprintf($this->metaColumnsSQL,$table));
if ($schema) {
$this->SelectDB($dbName);
}
if (isset($savem)) $this->SetFetchMode($savem);
$ADODB_FETCH_MODE = $save;
if (!is_object($rs)) {
$false = false;
return $false;
}
$retarr = array();
while (!$rs->EOF){
$fld = new ADOFieldObject();
$fld->name = $rs->fields[0];
$fld->type = $rs->fields[1];
$fld->not_null = (!$rs->fields[3]);
$fld->auto_increment = ($rs->fields[4] == 128); // sys.syscolumns status field. 0x80 = 128 ref: http://msdn.microsoft.com/en-us/library/ms186816.aspx
if (isset($rs->fields[5]) && $rs->fields[5]) {
if ($rs->fields[5]>0) $fld->max_length = $rs->fields[5];
$fld->scale = $rs->fields[6];
if ($fld->scale>0) $fld->max_length += 1;
} else
$fld->max_length = $rs->fields[2];
if ($save == ADODB_FETCH_NUM) {
$retarr[] = $fld;
} else {
$retarr[strtoupper($fld->name)] = $fld;
}
$rs->MoveNext();
}
$rs->Close();
return $retarr;
}
function MetaIndexes($table,$primary=false, $owner=false)
{
$table = $this->qstr($table);
$sql = "SELECT i.name AS ind_name, C.name AS col_name, USER_NAME(O.uid) AS Owner, c.colid, k.Keyno,
$sql = "SELECT i.name AS ind_name, C.name AS col_name, USER_NAME(O.uid) AS Owner, c.colid, k.Keyno,
CASE WHEN I.indid BETWEEN 1 AND 254 AND (I.status & 2048 = 2048 OR I.Status = 16402 AND O.XType = 'V') THEN 1 ELSE 0 END AS IsPK,
CASE WHEN I.status & 2 = 2 THEN 1 ELSE 0 END AS IsUnique
FROM dbo.sysobjects o INNER JOIN dbo.sysindexes I ON o.id = i.id
INNER JOIN dbo.sysindexkeys K ON I.id = K.id AND I.Indid = K.Indid
FROM dbo.sysobjects o INNER JOIN dbo.sysindexes I ON o.id = i.id
INNER JOIN dbo.sysindexkeys K ON I.id = K.id AND I.Indid = K.Indid
INNER JOIN dbo.syscolumns c ON K.id = C.id AND K.colid = C.Colid
WHERE LEFT(i.name, 8) <> '_WA_Sys_' AND o.status >= 0 AND O.Name LIKE $table
ORDER BY O.name, I.Name, K.keyno";
@@ -392,7 +453,7 @@ class ADODB_mssql extends ADOConnection {
if ($this->fetchMode !== FALSE) {
$savem = $this->SetFetchMode(FALSE);
}
$rs = $this->Execute($sql);
if (isset($savem)) {
$this->SetFetchMode($savem);
@@ -406,22 +467,22 @@ class ADODB_mssql extends ADOConnection {
$indexes = array();
while ($row = $rs->FetchRow()) {
if ($primary && !$row[5]) continue;
$indexes[$row[0]]['unique'] = $row[6];
$indexes[$row[0]]['columns'][] = $row[1];
}
return $indexes;
}
function MetaForeignKeys($table, $owner=false, $upper=false)
{
global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$table = $this->qstr(strtoupper($table));
$sql =
$sql =
"select object_name(constid) as constraint_name,
col_name(fkeyid, fkey) as column_name,
object_name(rkeyid) as referenced_table_name,
@@ -429,20 +490,20 @@ class ADODB_mssql extends ADOConnection {
from sysforeignkeys
where upper(object_name(fkeyid)) = $table
order by constraint_name, referenced_table_name, keyno";
$constraints = $this->GetArray($sql);
$ADODB_FETCH_MODE = $save;
$arr = false;
foreach($constraints as $constr) {
//print_r($constr);
$arr[$constr[0]][$constr[2]][] = $constr[1].'='.$constr[3];
$arr[$constr[0]][$constr[2]][] = $constr[1].'='.$constr[3];
}
if (!$arr) return false;
$arr2 = false;
foreach($arr as $k => $v) {
foreach($v as $a => $b) {
if ($upper) $a = strtoupper($a);
@@ -453,55 +514,55 @@ order by constraint_name, referenced_table_name, keyno";
}
//From: Fernando Moreira <FMoreira@imediata.pt>
function MetaDatabases()
{
if(@mssql_select_db("master")) {
$qry=$this->metaDatabasesSQL;
if($rs=@mssql_query($qry,$this->_connectionID)){
$tmpAr=$ar=array();
while($tmpAr=@mssql_fetch_row($rs))
$ar[]=$tmpAr[0];
@mssql_select_db($this->database);
if(sizeof($ar))
return($ar);
else
return(false);
} else {
@mssql_select_db($this->database);
return(false);
}
}
return(false);
}
function MetaDatabases()
{
if(@mssql_select_db("master")) {
$qry=$this->metaDatabasesSQL;
if($rs=@mssql_query($qry,$this->_connectionID)){
$tmpAr=$ar=array();
while($tmpAr=@mssql_fetch_row($rs))
$ar[]=$tmpAr[0];
@mssql_select_db($this->database);
if(sizeof($ar))
return($ar);
else
return(false);
} else {
@mssql_select_db($this->database);
return(false);
}
}
return(false);
}
// "Stein-Aksel Basma" <basma@accelero.no>
// tested with MSSQL 2000
function MetaPrimaryKeys($table)
function MetaPrimaryKeys($table, $owner=false)
{
global $ADODB_FETCH_MODE;
$schema = '';
$this->_findschema($table,$schema);
if (!$schema) $schema = $this->database;
if ($schema) $schema = "and k.table_catalog like '$schema%'";
if ($schema) $schema = "and k.table_catalog like '$schema%'";
$sql = "select distinct k.column_name,ordinal_position from information_schema.key_column_usage k,
information_schema.table_constraints tc
information_schema.table_constraints tc
where tc.constraint_name = k.constraint_name and tc.constraint_type =
'PRIMARY KEY' and k.table_name = '$table' $schema order by ordinal_position ";
$savem = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$a = $this->GetCol($sql);
$ADODB_FETCH_MODE = $savem;
if ($a && sizeof($a)>0) return $a;
$false = false;
return $false;
return $false;
}
function MetaTables($ttype=false,$showSchema=false,$mask=false)
function MetaTables($ttype=false,$showSchema=false,$mask=false)
{
if ($mask) {
$save = $this->metaTablesSQL;
@@ -509,32 +570,32 @@ order by constraint_name, referenced_table_name, keyno";
$this->metaTablesSQL .= " AND name like $mask";
}
$ret = ADOConnection::MetaTables($ttype,$showSchema);
if ($mask) {
$this->metaTablesSQL = $save;
}
return $ret;
}
function SelectDB($dbName)
function SelectDB($dbName)
{
$this->database = $dbName;
$this->databaseName = $dbName; # obsolete, retained for compat with older adodb versions
if ($this->_connectionID) {
return @mssql_select_db($dbName);
return @mssql_select_db($dbName);
}
else return false;
else return false;
}
function ErrorMsg()
function ErrorMsg()
{
if (empty($this->_errorMsg)){
$this->_errorMsg = mssql_get_last_message();
}
return $this->_errorMsg;
}
function ErrorNo()
function ErrorNo()
{
if ($this->_logsql && $this->_errorCode !== false) return $this->_errorCode;
if (empty($this->_errorMsg)) {
@@ -547,7 +608,7 @@ order by constraint_name, referenced_table_name, keyno";
if (is_array($arr)) return $arr[0];
else return -1;
}
// returns true or false, newconnect supported since php 5.1.0.
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename,$newconnect=false)
{
@@ -555,26 +616,26 @@ order by constraint_name, referenced_table_name, keyno";
$this->_connectionID = mssql_connect($argHostname,$argUsername,$argPassword,$newconnect);
if ($this->_connectionID === false) return false;
if ($argDatabasename) return $this->SelectDB($argDatabasename);
return true;
return true;
}
// returns true or false
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
if (!function_exists('mssql_pconnect')) return null;
$this->_connectionID = mssql_pconnect($argHostname,$argUsername,$argPassword);
if ($this->_connectionID === false) return false;
// persistent connections can forget to rollback on crash, so we do it here.
if ($this->autoRollback) {
$cnt = $this->GetOne('select @@TRANCOUNT');
while (--$cnt >= 0) $this->Execute('ROLLBACK TRAN');
while (--$cnt >= 0) $this->Execute('ROLLBACK TRAN');
}
if ($argDatabasename) return $this->SelectDB($argDatabasename);
return true;
return true;
}
function _nconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename, true);
@@ -587,11 +648,11 @@ order by constraint_name, referenced_table_name, keyno";
$sql2 = $sqlarr[0];
for ($i = 1, $max = sizeof($sqlarr); $i < $max; $i++) {
$sql2 .= '@P'.($i-1) . $sqlarr[$i];
}
}
return array($sql,$this->qstr($sql2),$max,$sql2);
}
function PrepareSP($sql)
function PrepareSP($sql,$param=true)
{
if (!$this->_has_mssql_init) {
ADOConnection::outp( "PrepareSP: mssql_init only available since PHP 4.1.0");
@@ -601,7 +662,7 @@ order by constraint_name, referenced_table_name, keyno";
if (!$stmt) return $sql;
return array($sql,$stmt);
}
// returns concatenated string
// MSSQL requires integers to be cast as strings
// automatically cast every datatype to VARCHAR(255)
@@ -622,26 +683,26 @@ order by constraint_name, referenced_table_name, keyno";
array_walk($arr, create_function('&$v', '$v = "CAST(" . $v . " AS VARCHAR(255))";'));
$s = implode('+',$arr);
if (sizeof($arr) > 0) return "$s";
return '';
}
/*
/*
Usage:
$stmt = $db->PrepareSP('SP_RUNSOMETHING'); -- takes 2 params, @myid and @group
# note that the parameter does not have @ in front!
$db->Parameter($stmt,$id,'myid');
$db->Parameter($stmt,$group,'group',false,64);
$db->Execute($stmt);
@param $stmt Statement returned by Prepare() or PrepareSP().
@param $var PHP variable to bind to. Can set to null (for isNull support).
@param $name Name of stored procedure variable name to bind to.
@param [$isOutput] Indicates direction of parameter 0/false=IN 1=OUT 2= IN/OUT. This is ignored in oci8.
@param [$maxLen] Holds an maximum length of the variable.
@param [$type] The data type of $var. Legal values depend on driver.
See mssql_bind documentation at php.net.
*/
function Parameter(&$stmt, &$var, $name, $isOutput=false, $maxLen=4000, $type=false)
@@ -652,8 +713,8 @@ order by constraint_name, referenced_table_name, keyno";
}
$isNull = is_null($var); // php 4.0.4 and above...
if ($type === false)
if ($type === false)
switch(gettype($var)) {
default:
case 'string': $type = SQLVARCHAR; break;
@@ -661,7 +722,7 @@ order by constraint_name, referenced_table_name, keyno";
case 'integer': $type = SQLINT4; break;
case 'boolean': $type = SQLINT1; break; # SQLBIT not supported in 4.1.0
}
if ($this->debug) {
$prefix = ($isOutput) ? 'Out' : 'In';
$ztype = (empty($type)) ? 'false' : $type;
@@ -669,32 +730,32 @@ order by constraint_name, referenced_table_name, keyno";
}
/*
See http://phplens.com/lens/lensforum/msgs.php?id=7231
RETVAL is HARD CODED into php_mssql extension:
The return value (a long integer value) is treated like a special OUTPUT parameter,
called "RETVAL" (without the @). See the example at mssql_execute to
see how it works. - type: one of this new supported PHP constants.
SQLTEXT, SQLVARCHAR,SQLCHAR, SQLINT1,SQLINT2, SQLINT4, SQLBIT,SQLFLT8
The return value (a long integer value) is treated like a special OUTPUT parameter,
called "RETVAL" (without the @). See the example at mssql_execute to
see how it works. - type: one of this new supported PHP constants.
SQLTEXT, SQLVARCHAR,SQLCHAR, SQLINT1,SQLINT2, SQLINT4, SQLBIT,SQLFLT8
*/
if ($name !== 'RETVAL') $name = '@'.$name;
return mssql_bind($stmt[1], $name, $var, $type, $isOutput, $isNull, $maxLen);
}
/*
/*
Unfortunately, it appears that mssql cannot handle varbinary > 255 chars
So all your blobs must be of type "image".
Remember to set in php.ini the following...
; Valid range 0 - 2147483647. Default = 4096.
mssql.textlimit = 0 ; zero to pass through
; Valid range 0 - 2147483647. Default = 4096.
mssql.textsize = 0 ; zero to pass through
Remember to set in php.ini the following...
; Valid range 0 - 2147483647. Default = 4096.
mssql.textlimit = 0 ; zero to pass through
; Valid range 0 - 2147483647. Default = 4096.
mssql.textsize = 0 ; zero to pass through
*/
function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
{
if (strtoupper($blobtype) == 'CLOB') {
$sql = "UPDATE $table SET $column='" . $val . "' WHERE $where";
return $this->Execute($sql) != false;
@@ -702,14 +763,14 @@ order by constraint_name, referenced_table_name, keyno";
$sql = "UPDATE $table SET $column=0x".bin2hex($val)." WHERE $where";
return $this->Execute($sql) != false;
}
// returns query ID if successful, otherwise false
function _query($sql,$inputarr=false)
{
$this->_errorMsg = false;
if (is_array($inputarr)) {
# bind input params with sp_executesql:
# bind input params with sp_executesql:
# see http://www.quest-pipelines.com/newsletter-v3/0402_F.htm
# works only with sql server 7 and newer
$getIdentity = false;
@@ -725,11 +786,11 @@ order by constraint_name, referenced_table_name, keyno";
if ($decl) {
$decl .= ', ';
$params .= ', ';
}
}
if (is_string($v)) {
$len = strlen($v);
if ($len == 0) $len = 1;
if ($len > 4000 ) {
// NVARCHAR is max 4000 chars. Let's use NTEXT
$decl .= "@P$i NTEXT";
@@ -761,73 +822,73 @@ order by constraint_name, referenced_table_name, keyno";
$this->lastInsID = isset($arr[0]) ? $arr[0] : false;
@mssql_data_seek($rez, 0);
}
} else if (is_array($sql)) {
# PrepareSP()
$rez = mssql_execute($sql[1]);
$this->lastInsID = false;
} else {
$rez = mssql_query($sql,$this->_connectionID);
$this->lastInsID = false;
}
return $rez;
}
// returns true or false
function _close()
{
{
if ($this->transCnt) $this->RollbackTrans();
$rez = @mssql_close($this->_connectionID);
$this->_connectionID = false;
return $rez;
}
// mssql uses a default date like Dec 30 2000 12:00AM
static function UnixDate($v)
{
return ADORecordSet_array_mssql::UnixDate($v);
}
static function UnixTimeStamp($v)
{
return ADORecordSet_array_mssql::UnixTimeStamp($v);
}
}
}
/*--------------------------------------------------------------------------------------
Class Name: Recordset
--------------------------------------------------------------------------------------*/
class ADORecordset_mssql extends ADORecordSet {
class ADORecordset_mssql extends ADORecordSet {
var $databaseType = "mssql";
var $canSeek = true;
var $hasFetchAssoc; // see http://phplens.com/lens/lensforum/msgs.php?id=6083
// _mths works only in non-localised system
function ADORecordset_mssql($id,$mode=false)
function __construct($id,$mode=false)
{
// freedts check...
$this->hasFetchAssoc = function_exists('mssql_fetch_assoc');
if ($mode === false) {
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
$this->fetchMode = $mode;
return $this->ADORecordSet($id,$mode);
return parent::__construct($id,$mode);
}
function _initrs()
{
GLOBAL $ADODB_COUNTRECS;
GLOBAL $ADODB_COUNTRECS;
$this->_numOfRows = ($ADODB_COUNTRECS)? @mssql_num_rows($this->_queryID):-1;
$this->_numOfFields = @mssql_num_fields($this->_queryID);
}
//Contributed by "Sven Axelsson" <sven.axelsson@bokochwebb.se>
// get next resultset - requires PHP 4.0.5 or later
@@ -852,16 +913,16 @@ class ADORecordset_mssql extends ADORecordSet {
$this->bind[strtoupper($o->name)] = $i;
}
}
return $this->fields[$this->bind[strtoupper($colname)]];
}
/* Returns: an object containing field information.
/* Returns: an object containing field information.
Get column information in the Recordset object. fetchField() can be used in order to obtain information about
fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
fetchField() is retrieved. */
function FetchField($fieldOffset = -1)
function FetchField($fieldOffset = -1)
{
if ($fieldOffset != -1) {
$f = @mssql_fetch_field($this->_queryID, $fieldOffset);
@@ -873,19 +934,19 @@ class ADORecordset_mssql extends ADORecordSet {
if (empty($f)) return $false;
return $f;
}
function _seek($row)
function _seek($row)
{
return @mssql_data_seek($this->_queryID, $row);
}
// speedup
function MoveNext()
function MoveNext()
{
if ($this->EOF) return false;
$this->_currentRow++;
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
if ($this->fetchMode & ADODB_FETCH_NUM) {
//ADODB_FETCH_BOTH mode
@@ -907,15 +968,23 @@ class ADORecordset_mssql extends ADORecordSet {
$this->fields = false;
}
}
if (is_array($this->fields)) {
if (ADODB_ASSOC_CASE == 0) {
foreach($this->fields as $k=>$v) {
$this->fields[strtolower($k)] = $v;
$kn = strtolower($k);
if ($kn <> $k) {
unset($this->fields[$k]);
$this->fields[$kn] = $v;
}
}
} else if (ADODB_ASSOC_CASE == 1) {
foreach($this->fields as $k=>$v) {
$this->fields[strtoupper($k)] = $v;
$kn = strtoupper($k);
if ($kn <> $k) {
unset($this->fields[$k]);
$this->fields[$kn] = $v;
}
}
}
}
@@ -924,14 +993,14 @@ class ADORecordset_mssql extends ADORecordSet {
}
if ($this->fields) return true;
$this->EOF = true;
return false;
}
// INSERT UPDATE DELETE returns false even if no error occurs in 4.0.4
// also the date format has been changed from YYYY-mm-dd to dd MMM YYYY in 4.0.4. Idiot!
function _fetch($ignore_fields=false)
function _fetch($ignore_fields=false)
{
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
if ($this->fetchMode & ADODB_FETCH_NUM) {
@@ -952,15 +1021,23 @@ class ADORecordset_mssql extends ADORecordSet {
}
}
}
if (!$this->fields) {
} else if (ADODB_ASSOC_CASE == 0) {
foreach($this->fields as $k=>$v) {
$this->fields[strtolower($k)] = $v;
$kn = strtolower($k);
if ($kn <> $k) {
unset($this->fields[$k]);
$this->fields[$kn] = $v;
}
}
} else if (ADODB_ASSOC_CASE == 1) {
foreach($this->fields as $k=>$v) {
$this->fields[strtoupper($k)] = $v;
$kn = strtoupper($k);
if ($kn <> $k) {
unset($this->fields[$k]);
$this->fields[$kn] = $v;
}
}
}
} else {
@@ -968,51 +1045,55 @@ class ADORecordset_mssql extends ADORecordSet {
}
return $this->fields;
}
/* close() only needs to be called if you are worried about using too much memory while your script
is running. All associated result memory for the specified result identifier will automatically be freed. */
function _close()
function _close()
{
$rez = mssql_free_result($this->_queryID);
$this->_queryID = false;
return $rez;
if($this->_queryID) {
$rez = mssql_free_result($this->_queryID);
$this->_queryID = false;
return $rez;
}
return true;
}
// mssql uses a default date like Dec 30 2000 12:00AM
static function UnixDate($v)
{
return ADORecordSet_array_mssql::UnixDate($v);
}
static function UnixTimeStamp($v)
{
return ADORecordSet_array_mssql::UnixTimeStamp($v);
}
}
class ADORecordSet_array_mssql extends ADORecordSet_array {
function ADORecordSet_array_mssql($id=-1,$mode=false)
function __construct($id=-1,$mode=false)
{
$this->ADORecordSet_array($id,$mode);
parent::__construct($id,$mode);
}
// mssql uses a default date like Dec 30 2000 12:00AM
static function UnixDate($v)
{
if (is_numeric(substr($v,0,1)) && ADODB_PHPVER >= 0x4200) return parent::UnixDate($v);
global $ADODB_mssql_mths,$ADODB_mssql_date_order;
//Dec 30 2000 12:00AM
//Dec 30 2000 12:00AM
if ($ADODB_mssql_date_order == 'dmy') {
if (!preg_match( "|^([0-9]{1,2})[-/\. ]+([A-Za-z]{3})[-/\. ]+([0-9]{4})|" ,$v, $rr)) {
return parent::UnixDate($v);
}
if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
$theday = $rr[1];
$themth = substr(strtoupper($rr[2]),0,3);
} else {
@@ -1020,7 +1101,7 @@ class ADORecordSet_array_mssql extends ADORecordSet_array {
return parent::UnixDate($v);
}
if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
$theday = $rr[2];
$themth = substr(strtoupper($rr[1]),0,3);
}
@@ -1029,34 +1110,34 @@ class ADORecordSet_array_mssql extends ADORecordSet_array {
// h-m-s-MM-DD-YY
return mktime(0,0,0,$themth,$theday,$rr[3]);
}
static function UnixTimeStamp($v)
{
if (is_numeric(substr($v,0,1)) && ADODB_PHPVER >= 0x4200) return parent::UnixTimeStamp($v);
global $ADODB_mssql_mths,$ADODB_mssql_date_order;
//Dec 30 2000 12:00AM
if ($ADODB_mssql_date_order == 'dmy') {
if (!preg_match( "|^([0-9]{1,2})[-/\. ]+([A-Za-z]{3})[-/\. ]+([0-9]{4}) +([0-9]{1,2}):([0-9]{1,2}) *([apAP]{0,1})|"
,$v, $rr)) return parent::UnixTimeStamp($v);
if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
$theday = $rr[1];
$themth = substr(strtoupper($rr[2]),0,3);
} else {
if (!preg_match( "|^([A-Za-z]{3})[-/\. ]+([0-9]{1,2})[-/\. ]+([0-9]{4}) +([0-9]{1,2}):([0-9]{1,2}) *([apAP]{0,1})|"
,$v, $rr)) return parent::UnixTimeStamp($v);
if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
$theday = $rr[2];
$themth = substr(strtoupper($rr[1]),0,3);
}
$themth = $ADODB_mssql_mths[$themth];
if ($themth <= 0) return false;
switch (strtoupper($rr[6])) {
case 'P':
if ($rr[4]<12) $rr[4] += 12;
@@ -1076,7 +1157,7 @@ class ADORecordSet_array_mssql extends ADORecordSet_array {
Code Example 1:
select object_name(constid) as constraint_name,
object_name(fkeyid) as table_name,
object_name(fkeyid) as table_name,
col_name(fkeyid, fkey) as column_name,
object_name(rkeyid) as referenced_table_name,
col_name(rkeyid, rkey) as referenced_column_name
@@ -1095,5 +1176,3 @@ order by constraint_name, ordinal_position
http://www.databasejournal.com/scripts/article.php/1440551
*/
?>
+161 -83
View File
@@ -9,7 +9,7 @@
// ADOdb - Database Abstraction Library for PHP //
// http://adodb.sourceforge.net/ //
// //
// Copyright (C) 2000-2009 John Lim (jlim\@natsoft.com.my) //
// Copyright (c) 2000-2014 John Lim (jlim\@natsoft.com.my) //
// All rights reserved. //
// Released under both BSD license and LGPL library license. //
// Whenever there is any discrepancy between the two licenses, //
@@ -52,11 +52,6 @@ include_once(ADODB_DIR.'/drivers/adodb-mssql.inc.php');
class ADODB_mssql_n extends ADODB_mssql {
var $databaseType = "mssql_n";
function ADODB_mssqlpo()
{
ADODB_mssql::ADODB_mssql();
}
function _query($sql,$inputarr=false)
{
@@ -64,108 +59,191 @@ class ADODB_mssql_n extends ADODB_mssql {
return ADODB_mssql::_query($sql,$inputarr);
}
/**
/**
* This function will intercept all the literals used in the SQL, prepending the "N" char to them
* in order to allow mssql to store properly data sent in the correct UCS-2 encoding (by freeTDS
* and ODBTP) keeping SQL compatibility at ADOdb level (instead of hacking every project to add
* the "N" notation when working against MSSQL.
*
* Note that this hack only must be used if ALL the char-based columns in your DB are of type nchar,
* nvarchar and ntext
* The orginal note indicated that this hack should only be used if ALL the char-based columns
* in your DB are of type nchar, nvarchar and ntext, but testing seems to indicate that SQL server
* doesn't seem to care if the statement is used against char etc fields.
*
* @todo This function should raise an ADOdb error if one of the transformations fail
*
* @param mixed $inboundData Either a string containing an SQL statement
* or an array with resources from prepared statements
*
* @return mixed
*/
function _appendN($sql) {
function _appendN($inboundData) {
$result = $sql;
$inboundIsArray = false;
if (is_array($inboundData))
{
$inboundIsArray = true;
$inboundArray = $inboundData;
} else
$inboundArray = (array)$inboundData;
/*
* All changes will be placed here
*/
$outboundArray = $inboundArray;
foreach($inboundArray as $inboundKey=>$inboundValue)
{
if (is_resource($inboundValue))
{
/*
* Prepared statement resource
*/
if ($this->debug)
ADOConnection::outp("{$this->databaseType} index $inboundKey value is resource, continue");
/// Check we have some single quote in the query. Exit ok.
if (strpos($sql, SINGLEQUOTE) === false) {
return $sql;
}
/// Check we haven't an odd number of single quotes (this can cause problems below
/// and should be considered one wrong SQL). Exit with debug info.
if ((substr_count($sql, SINGLEQUOTE) & 1)) {
if ($this->debug) {
ADOConnection::outp("{$this->databaseType} internal transformation: not converted. Wrong number of quotes (odd)");
continue;
}
return $sql;
}
/// Check we haven't any backslash + single quote combination. It should mean wrong
/// backslashes use (bad magic_quotes_sybase?). Exit with debug info.
$regexp = '/(\\\\' . SINGLEQUOTE . '[^' . SINGLEQUOTE . '])/';
if (preg_match($regexp, $sql)) {
if ($this->debug) {
ADOConnection::outp("{$this->databaseType} internal transformation: not converted. Found bad use of backslash + single quote");
if (strpos($inboundValue, SINGLEQUOTE) === false)
{
/*
* Check we have something to manipulate
*/
if ($this->debug)
ADOConnection::outp("{$this->databaseType} index $inboundKey value $inboundValue has no single quotes, continue");
continue;
}
return $sql;
}
/// Remove pairs of single-quotes
$pairs = array();
$regexp = '/(' . SINGLEQUOTE . SINGLEQUOTE . ')/';
preg_match_all($regexp, $result, $list_of_pairs);
if ($list_of_pairs) {
foreach (array_unique($list_of_pairs[0]) as $key=>$value) {
$pairs['<@#@#@PAIR-'.$key.'@#@#@>'] = $value;
/*
* Check we haven't an odd number of single quotes (this can cause problems below
* and should be considered one wrong SQL). Exit with debug info.
*/
if ((substr_count($inboundValue, SINGLEQUOTE) & 1))
{
if ($this->debug)
ADOConnection::outp("{$this->databaseType} internal transformation: not converted. Wrong number of quotes (odd)");
break;
}
if (!empty($pairs)) {
$result = str_replace($pairs, array_keys($pairs), $result);
}
}
/// Remove the rest of literals present in the query
$literals = array();
$regexp = '/(N?' . SINGLEQUOTE . '.*?' . SINGLEQUOTE . ')/is';
preg_match_all($regexp, $result, $list_of_literals);
if ($list_of_literals) {
foreach (array_unique($list_of_literals[0]) as $key=>$value) {
$literals['<#@#@#LITERAL-'.$key.'#@#@#>'] = $value;
/*
* Check we haven't any backslash + single quote combination. It should mean wrong
* backslashes use (bad magic_quotes_sybase?). Exit with debug info.
*/
$regexp = '/(\\\\' . SINGLEQUOTE . '[^' . SINGLEQUOTE . '])/';
if (preg_match($regexp, $inboundValue))
{
if ($this->debug)
ADOConnection::outp("{$this->databaseType} internal transformation: not converted. Found bad use of backslash + single quote");
break;
}
if (!empty($literals)) {
$result = str_replace($literals, array_keys($literals), $result);
/*
* Remove pairs of single-quotes
*/
$pairs = array();
$regexp = '/(' . SINGLEQUOTE . SINGLEQUOTE . ')/';
preg_match_all($regexp, $inboundValue, $list_of_pairs);
if ($list_of_pairs)
{
foreach (array_unique($list_of_pairs[0]) as $key=>$value)
$pairs['<@#@#@PAIR-'.$key.'@#@#@>'] = $value;
if (!empty($pairs))
$inboundValue = str_replace($pairs, array_keys($pairs), $inboundValue);
}
}
/*
* Remove the rest of literals present in the query
*/
$literals = array();
$regexp = '/(N?' . SINGLEQUOTE . '.*?' . SINGLEQUOTE . ')/is';
preg_match_all($regexp, $inboundValue, $list_of_literals);
if ($list_of_literals)
{
foreach (array_unique($list_of_literals[0]) as $key=>$value)
$literals['<#@#@#LITERAL-'.$key.'#@#@#>'] = $value;
if (!empty($literals))
$inboundValue = str_replace($literals, array_keys($literals), $inboundValue);
}
/// Analyse literals to prepend the N char to them if their contents aren't numeric
if (!empty($literals)) {
foreach ($literals as $key=>$value) {
if (!is_numeric(trim($value, SINGLEQUOTE))) {
/// Non numeric string, prepend our dear N
$literals[$key] = 'N' . trim($value, 'N'); //Trimming potentially existing previous "N"
/*
* Analyse literals to prepend the N char to them if their contents aren't numeric
*/
if (!empty($literals))
{
foreach ($literals as $key=>$value) {
if (!is_numeric(trim($value, SINGLEQUOTE)))
/*
* Non numeric string, prepend our dear N, whilst
* Trimming potentially existing previous "N"
*/
$literals[$key] = 'N' . trim($value, 'N');
}
}
/*
* Re-apply literals to the text
*/
if (!empty($literals))
$inboundValue = str_replace(array_keys($literals), $literals, $inboundValue);
/*
* Any pairs followed by N' must be switched to N' followed by those pairs
* (or strings beginning with single quotes will fail)
*/
$inboundValue = preg_replace("/((<@#@#@PAIR-(\d+)@#@#@>)+)N'/", "N'$1", $inboundValue);
/*
* Re-apply pairs of single-quotes to the text
*/
if (!empty($pairs))
$inboundValue = str_replace(array_keys($pairs), $pairs, $inboundValue);
/*
* Print transformation if debug = on
*/
if (strcmp($inboundValue,$inboundArray[$inboundKey]) <> 0 && $this->debug)
ADOConnection::outp("{$this->databaseType} internal transformation: {$inboundArray[$inboundKey]} to {$inboundValue}");
if (strcmp($inboundValue,$inboundArray[$inboundKey]) <> 0)
/*
* Place the transformed value into the outbound array
*/
$outboundArray[$inboundKey] = $inboundValue;
}
/// Re-apply literals to the text
if (!empty($literals)) {
$result = str_replace(array_keys($literals), $literals, $result);
}
/// Any pairs followed by N' must be switched to N' followed by those pairs
/// (or strings beginning with single quotes will fail)
$result = preg_replace("/((<@#@#@PAIR-(\d+)@#@#@>)+)N'/", "N'$1", $result);
/// Re-apply pairs of single-quotes to the text
if (!empty($pairs)) {
$result = str_replace(array_keys($pairs), $pairs, $result);
}
/// Print transformation if debug = on
if ($result != $sql && $this->debug) {
ADOConnection::outp("{$this->databaseType} internal transformation:<br>{$sql}<br>to<br>{$result}");
}
return $result;
/*
* Any transformations are in the $outboundArray
*/
if ($inboundIsArray)
return $outboundArray;
/*
* We passed a string in originally
*/
return $outboundArray[0];
}
}
class ADORecordset_mssql_n extends ADORecordset_mssql {
var $databaseType = "mssql_n";
function ADORecordset_mssql_n($id,$mode=false)
function __construct($id,$mode=false)
{
$this->ADORecordset_mssql($id,$mode);
parent::__construct($id,$mode);
}
}
?>
+641 -366
View File
@@ -1,16 +1,18 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). 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.
/*
@version v5.20.9 21-Dec-2016
@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.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
Native mssql driver. Requires mssql client. Works on Windows.
Native mssql driver. Requires mssql client. Works on Windows.
http://www.microsoft.com/sql/technologies/php/default.mspx
To configure for Unix, see
To configure for Unix, see
http://phpbuilder.com/columns/alberto20000919.php3
$stream = sqlsrv_get_field($stmt, $index, SQLSRV_SQLTYPE_STREAM(SQLSRV_ENC_BINARY));
@@ -44,22 +46,22 @@ if (!function_exists('sqlsrv_log_set_subsystems')) {
//----------------------------------------------------------------
// MSSQL returns dates with the format Oct 13 2002 or 13 Oct 2002
// and this causes tons of problems because localized versions of
// MSSQL will return the dates in dmy or mdy order; and also the
// month strings depends on what language has been configured. The
// and this causes tons of problems because localized versions of
// MSSQL will return the dates in dmy or mdy order; and also the
// month strings depends on what language has been configured. The
// following two variables allow you to control the localization
// settings - Ugh.
//
// MORE LOCALIZATION INFO
// ----------------------
// To configure datetime, look for and modify sqlcommn.loc,
// To configure datetime, look for and modify sqlcommn.loc,
// typically found in c:\mssql\install
// Also read :
// http://support.microsoft.com/default.aspx?scid=kb;EN-US;q220918
// Alternatively use:
// CONVERT(char(12),datecol,120)
//
// Also if your month is showing as month-1,
// Also if your month is showing as month-1,
// e.g. Jan 13, 2002 is showing as 13/0/2002, then see
// http://phplens.com/lens/lensforum/msgs.php?id=7048&x=1
// it's a localisation problem.
@@ -69,41 +71,21 @@ if (!function_exists('sqlsrv_log_set_subsystems')) {
// has datetime converstion to YYYY-MM-DD format, and also mssql_fetch_assoc
if (ADODB_PHPVER >= 0x4300) {
// docs say 4.2.0, but testing shows only since 4.3.0 does it work!
ini_set('mssql.datetimeconvert',0);
ini_set('mssql.datetimeconvert',0);
} else {
global $ADODB_mssql_mths; // array, months must be upper-case
$ADODB_mssql_date_order = 'mdy';
$ADODB_mssql_date_order = 'mdy';
$ADODB_mssql_mths = array(
'JAN'=>1,'FEB'=>2,'MAR'=>3,'APR'=>4,'MAY'=>5,'JUN'=>6,
'JUL'=>7,'AUG'=>8,'SEP'=>9,'OCT'=>10,'NOV'=>11,'DEC'=>12);
}
//---------------------------------------------------------------------------
// Call this to autoset $ADODB_mssql_date_order at the beginning of your code,
// just after you connect to the database. Supports mdy and dmy only.
// Not required for PHP 4.2.0 and above.
function AutoDetect_MSSQL_Date_Order($conn)
{
global $ADODB_mssql_date_order;
$adate = $conn->GetOne('select getdate()');
if ($adate) {
$anum = (int) $adate;
if ($anum > 0) {
if ($anum > 31) {
//ADOConnection::outp( "MSSQL: YYYY-MM-DD date format not supported currently");
} else
$ADODB_mssql_date_order = 'dmy';
} else
$ADODB_mssql_date_order = 'mdy';
}
}
class ADODB_mssqlnative extends ADOConnection {
var $databaseType = "mssqlnative";
var $databaseType = "mssqlnative";
var $dataProvider = "mssqlnative";
var $replaceQuote = "''"; // string to use to replace quotes
var $fmtDate = "'Y-m-d'";
var $fmtTimeStamp = "'Y-m-d H:i:s'";
var $fmtTimeStamp = "'Y-m-d\TH:i:s'";
var $hasInsertID = true;
var $substr = "substring";
var $length = 'len';
@@ -111,11 +93,23 @@ class ADODB_mssqlnative extends ADOConnection {
var $poorAffectedRows = false;
var $metaDatabasesSQL = "select name from sys.sysdatabases where name <> 'master'";
var $metaTablesSQL="select name,case when type='U' then 'T' else 'V' end from sysobjects where (type='U' or type='V') and (name not in ('sysallocations','syscolumns','syscomments','sysdepends','sysfilegroups','sysfiles','sysfiles1','sysforeignkeys','sysfulltextcatalogs','sysindexes','sysindexkeys','sysmembers','sysobjects','syspermissions','sysprotects','sysreferences','systypes','sysusers','sysalternates','sysconstraints','syssegments','REFERENTIAL_CONSTRAINTS','CHECK_CONSTRAINTS','CONSTRAINT_TABLE_USAGE','CONSTRAINT_COLUMN_USAGE','VIEWS','VIEW_TABLE_USAGE','VIEW_COLUMN_USAGE','SCHEMATA','TABLES','TABLE_CONSTRAINTS','TABLE_PRIVILEGES','COLUMNS','COLUMN_DOMAIN_USAGE','COLUMN_PRIVILEGES','DOMAINS','DOMAIN_CONSTRAINTS','KEY_COLUMN_USAGE','dtproperties'))";
var $metaColumnsSQL = # xtype==61 is datetime
"select c.name,t.name,c.length,
(case when c.xusertype=61 then 0 else c.xprec end),
(case when c.xusertype=61 then 0 else c.xscale end)
from syscolumns c join systypes t on t.xusertype=c.xusertype join sysobjects o on o.id=c.id where o.name='%s'";
var $metaColumnsSQL =
"select c.name,
t.name as type,
c.length,
c.xprec as precision,
c.xscale as scale,
c.isnullable as nullable,
c.cdefault as default_value,
c.xtype,
t.length as type_length,
sc.is_identity
from syscolumns c
join systypes t on t.xusertype=c.xusertype
join sysobjects o on o.id=c.id
join sys.tables st on st.name=o.name
join sys.columns sc on sc.object_id = st.object_id and sc.name=c.name
where o.name='%s'";
var $hasTop = 'top'; // support mssql SELECT TOP 10 * FROM TABLE
var $hasGenID = true;
var $sysDate = 'convert(datetime,convert(char,GetDate(),102),102)';
@@ -130,101 +124,206 @@ class ADODB_mssqlnative extends ADOConnection {
var $uniqueOrderBy = true;
var $_bindInputArray = true;
var $_dropSeqSQL = "drop table %s";
function ADODB_mssqlnative()
{
if ($this->debug) {
error_log("<pre>");
sqlsrv_set_error_handling( SQLSRV_ERRORS_LOG_ALL );
sqlsrv_log_set_severity( SQLSRV_LOG_SEVERITY_ALL );
sqlsrv_log_set_subsystems(SQLSRV_LOG_SYSTEM_ALL);
sqlsrv_configure('warnings_return_as_errors', 0);
} else {
sqlsrv_set_error_handling(0);
sqlsrv_log_set_severity(0);
sqlsrv_log_set_subsystems(SQLSRV_LOG_SYSTEM_ALL);
sqlsrv_configure('warnings_return_as_errors', 0);
}
var $connectionInfo = array();
var $cachedSchemaFlush = false;
var $sequences = false;
var $mssql_version = '';
function __construct()
{
if ($this->debug) {
ADOConnection::outp("<pre>");
sqlsrv_set_error_handling( SQLSRV_ERRORS_LOG_ALL );
sqlsrv_log_set_severity( SQLSRV_LOG_SEVERITY_ALL );
sqlsrv_log_set_subsystems(SQLSRV_LOG_SYSTEM_ALL);
sqlsrv_configure('WarningsReturnAsErrors', 0);
} else {
sqlsrv_set_error_handling(0);
sqlsrv_log_set_severity(0);
sqlsrv_log_set_subsystems(SQLSRV_LOG_SYSTEM_ALL);
sqlsrv_configure('WarningsReturnAsErrors', 0);
}
}
function ServerInfo()
{
/**
* Initializes the SQL Server version.
* Dies if connected to a non-supported version (2000 and older)
*/
function ServerVersion() {
$data = $this->ServerInfo();
preg_match('/^\d{2}/', $data['version'], $matches);
$version = (int)reset($matches);
// We only support SQL Server 2005 and up
if($version < 9) {
die("SQL SERVER VERSION {$data['version']} NOT SUPPORTED IN mssqlnative DRIVER");
}
$this->mssql_version = $version;
}
function ServerInfo() {
global $ADODB_FETCH_MODE;
static $arr = false;
if (is_array($arr))
return $arr;
if ($this->fetchMode === false) {
$savem = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
} else
} elseif ($this->fetchMode >=0 && $this->fetchMode <=2) {
$savem = $this->fetchMode;
} else
$savem = $this->SetFetchMode(ADODB_FETCH_NUM);
$arrServerInfo = sqlsrv_server_info($this->_connectionID);
$ADODB_FETCH_MODE = $savem;
$arr['description'] = $arrServerInfo['SQLServerName'].' connected to '.$arrServerInfo['CurrentDatabase'];
$arr['version'] = $arrServerInfo['SQLServerVersion'];//ADOConnection::_findvers($arr['description']);
return $arr;
}
function IfNull( $field, $ifNull )
function IfNull( $field, $ifNull )
{
return " ISNULL($field, $ifNull) "; // if MS SQL Server
}
function _insertid()
{
// SCOPE_IDENTITY()
// Returns the last IDENTITY value inserted into an IDENTITY column in
// the same scope. A scope is a module -- a stored procedure, trigger,
// function, or batch. Thus, two statements are in the same scope if
// Returns the last IDENTITY value inserted into an IDENTITY column in
// the same scope. A scope is a module -- a stored procedure, trigger,
// function, or batch. Thus, two statements are in the same scope if
// they are in the same stored procedure, function, or batch.
return $this->GetOne($this->identitySQL);
return $this->lastInsertID;
}
function _affectedrows()
{
return sqlsrv_rows_affected($this->_queryID);
if ($this->_queryID)
return sqlsrv_rows_affected($this->_queryID);
}
function GenID($seq='adodbseq',$start=1) {
if (!$this->mssql_version)
$this->ServerVersion();
switch($this->mssql_version){
case 9:
case 10:
return $this->GenID2008($seq, $start);
break;
default:
return $this->GenID2012($seq, $start);
break;
}
}
function CreateSequence($seq='adodbseq',$start=1)
{
if($this->debug) error_log("<hr>CreateSequence($seq,$start)");
sqlsrv_begin_transaction($this->_connectionID);
if (!$this->mssql_version)
$this->ServerVersion();
switch($this->mssql_version){
case 9:
case 10:
return $this->CreateSequence2008($seq, $start);
break;
default:
return $this->CreateSequence2012($seq, $start);
break;
}
}
/**
* For Server 2005,2008, duplicate a sequence with an identity table
*/
function CreateSequence2008($seq='adodbseq',$start=1)
{
if($this->debug) ADOConnection::outp("<hr>CreateSequence($seq,$start)");
sqlsrv_begin_transaction($this->_connectionID);
$start -= 1;
$this->Execute("create table $seq (id int)");//was float(53)
$ok = $this->Execute("insert into $seq with (tablock,holdlock) values($start)");
if (!$ok) {
if($this->debug) error_log("<hr>Error: ROLLBACK");
sqlsrv_rollback($this->_connectionID);
if($this->debug) ADOConnection::outp("<hr>Error: ROLLBACK");
sqlsrv_rollback($this->_connectionID);
return false;
}
sqlsrv_commit($this->_connectionID);
sqlsrv_commit($this->_connectionID);
return true;
}
function GenID($seq='adodbseq',$start=1)
/**
* Proper Sequences Only available to Server 2012 and up
*/
function CreateSequence2012($seq='adodbseq',$start=1){
if (!$this->sequences){
$sql = "SELECT name FROM sys.sequences";
$this->sequences = $this->GetCol($sql);
}
$ok = $this->Execute("CREATE SEQUENCE $seq START WITH $start INCREMENT BY 1");
if (!$ok)
die("CANNOT CREATE SEQUENCE" . print_r(sqlsrv_errors(),true));
$this->sequences[] = $seq;
}
/**
* For Server 2005,2008, duplicate a sequence with an identity table
*/
function GenID2008($seq='adodbseq',$start=1)
{
if($this->debug) error_log("<hr>GenID($seq,$start)");
sqlsrv_begin_transaction($this->_connectionID);
if($this->debug) ADOConnection::outp("<hr>CreateSequence($seq,$start)");
sqlsrv_begin_transaction($this->_connectionID);
$ok = $this->Execute("update $seq with (tablock,holdlock) set id = id + 1");
if (!$ok) {
$this->Execute("create table $seq (id int)");
$start -= 1;
$this->Execute("create table $seq (id int)");//was float(53)
$ok = $this->Execute("insert into $seq with (tablock,holdlock) values($start)");
if (!$ok) {
if($this->debug) error_log("<hr>Error: ROLLBACK");
sqlsrv_rollback($this->_connectionID);
if($this->debug) ADOConnection::outp("<hr>Error: ROLLBACK");
sqlsrv_rollback($this->_connectionID);
return false;
}
sqlsrv_commit($this->_connectionID);
return $start;
}
$num = $this->GetOne("select id from $seq");
sqlsrv_commit($this->_connectionID);
if($this->debug) error_log(" Returning: $num");
sqlsrv_commit($this->_connectionID);
return $num;
}
/**
* Only available to Server 2012 and up
* Cannot do this the normal adodb way by trapping an error if the
* sequence does not exist because sql server will auto create a
* sequence with the starting number of -9223372036854775808
*/
function GenID2012($seq='adodbseq',$start=1)
{
/*
* First time in create an array of sequence names that we
* can use in later requests to see if the sequence exists
* the overhead is creating a list of sequences every time
* we need access to at least 1. If we really care about
* performance, we could maybe flag a 'nocheck' class variable
*/
if (!$this->sequences){
$sql = "SELECT name FROM sys.sequences";
$this->sequences = $this->GetCol($sql);
}
if (!is_array($this->sequences)
|| is_array($this->sequences) && !in_array($seq,$this->sequences)){
$this->CreateSequence2012($seq, $start);
}
$num = $this->GetOne("SELECT NEXT VALUE FOR $seq");
return $num;
}
// Format date column in sql string given an input format that understands Y M D
function SQLDate($fmt, $col=false)
{
{
if (!$col) $col = $this->sysTimeStamp;
$s = '';
$len = strlen($fmt);
for ($i=0; $i < $len; $i++) {
if ($s) $s .= '+';
@@ -251,11 +350,11 @@ class ADODB_mssqlnative extends ADOConnection {
case 'h':
$s .= "substring(convert(char(14),$col,0),13,2)";
break;
case 'H':
$s .= "replace(str(datepart(hh,$col),2),' ','0')";
break;
case 'i':
$s .= "replace(str(datepart(mi,$col),2),' ','0')";
break;
@@ -266,7 +365,7 @@ class ADODB_mssqlnative extends ADOConnection {
case 'A':
$s .= "substring(convert(char(19),$col,0),18,2)";
break;
default:
if ($ch == '\\') {
$i++;
@@ -279,20 +378,20 @@ class ADODB_mssqlnative extends ADOConnection {
return $s;
}
function BeginTrans()
{
if ($this->transOff) return true;
if ($this->transOff) return true;
$this->transCnt += 1;
if ($this->debug) error_log('<hr>begin transaction');
if ($this->debug) ADOConnection::outp('<hr>begin transaction');
sqlsrv_begin_transaction($this->_connectionID);
return true;
return true;
}
function CommitTrans($ok=true)
{
if ($this->transOff) return true;
if ($this->debug) error_log('<hr>commit transaction');
function CommitTrans($ok=true)
{
if ($this->transOff) return true;
if ($this->debug) ADOConnection::outp('<hr>commit transaction');
if (!$ok) return $this->RollbackTrans();
if ($this->transCnt) $this->transCnt -= 1;
sqlsrv_commit($this->_connectionID);
@@ -300,14 +399,14 @@ class ADODB_mssqlnative extends ADOConnection {
}
function RollbackTrans()
{
if ($this->transOff) return true;
if ($this->debug) error_log('<hr>rollback transaction');
if ($this->transOff) return true;
if ($this->debug) ADOConnection::outp('<hr>rollback transaction');
if ($this->transCnt) $this->transCnt -= 1;
sqlsrv_rollback($this->_connectionID);
return true;
}
function SetTransactionMode( $transaction_mode )
function SetTransactionMode( $transaction_mode )
{
$this->_transmode = $transaction_mode;
if (empty($transaction_mode)) {
@@ -317,39 +416,40 @@ class ADODB_mssqlnative extends ADOConnection {
if (!stristr($transaction_mode,'isolation')) $transaction_mode = 'ISOLATION LEVEL '.$transaction_mode;
$this->Execute("SET TRANSACTION ".$transaction_mode);
}
/*
Usage:
$this->BeginTrans();
$this->RowLock('table1,table2','table1.id=33 and table2.id=table1.id'); # lock row 33 for both tables
# some operation on both tables table1 and table2
$this->CommitTrans();
See http://www.swynk.com/friends/achigrik/SQL70Locks.asp
*/
function RowLock($tables,$where,$flds='top 1 null as ignore')
function RowLock($tables,$where,$col='1 as adodbignore')
{
if ($col == '1 as adodbignore') $col = 'top 1 null as ignore';
if (!$this->transCnt) $this->BeginTrans();
return $this->GetOne("select $flds from $tables with (ROWLOCK,HOLDLOCK) where $where");
return $this->GetOne("select $col from $tables with (ROWLOCK,HOLDLOCK) where $where");
}
function SelectDB($dbName)
function SelectDB($dbName)
{
$this->database = $dbName;
$this->databaseName = $dbName; # obsolete, retained for compat with older adodb versions
if ($this->_connectionID) {
$rs = $this->Execute('USE '.$dbName);
if($rs) {
return true;
} else return false;
$rs = $this->Execute('USE '.$dbName);
if($rs) {
return true;
} else return false;
}
else return false;
else return false;
}
function ErrorMsg()
function ErrorMsg()
{
$retErrors = sqlsrv_errors(SQLSRV_ERR_ALL);
if($retErrors != null) {
@@ -363,84 +463,92 @@ class ADODB_mssqlnative extends ADOConnection {
}
return $this->_errorMsg;
}
function ErrorNo()
function ErrorNo()
{
if ($this->_logsql && $this->_errorCode !== false) return $this->_errorCode;
$err = sqlsrv_errors(SQLSRV_ERR_ALL);
if($err[0]) return $err[0]['code'];
else return -1;
if($err[0]) return $err[0]['code'];
else return 0;
}
// returns true or false
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
if (!function_exists('sqlsrv_connect')) return null;
$connectionInfo = array("Database"=>$argDatabasename,'UID'=>$argUsername,'PWD'=>$argPassword);
if ($this->debug) error_log("<hr>connecting... hostname: $argHostname params: ".var_export($connectionInfo,true));
//if ($this->debug) error_log("<hr>_connectionID before: ".serialize($this->_connectionID));
if(!($this->_connectionID = sqlsrv_connect($argHostname,$connectionInfo))) {
if ($this->debug) error_log( "<hr><b>errors</b>: ".print_r( sqlsrv_errors(), true));
return false;
}
//if ($this->debug) error_log(" _connectionID after: ".serialize($this->_connectionID));
//if ($this->debug) error_log("<hr>defined functions: <pre>".var_export(get_defined_functions(),true)."</pre>");
return true;
$connectionInfo = $this->connectionInfo;
$connectionInfo["Database"]=$argDatabasename;
$connectionInfo["UID"]=$argUsername;
$connectionInfo["PWD"]=$argPassword;
foreach ($this->connectionParameters as $parameter=>$value)
$connectionInfo[$parameter] = $value;
if ($this->debug) ADOConnection::outp("<hr>connecting... hostname: $argHostname params: ".var_export($connectionInfo,true));
//if ($this->debug) ADOConnection::outp("<hr>_connectionID before: ".serialize($this->_connectionID));
if(!($this->_connectionID = sqlsrv_connect($argHostname,$connectionInfo))) {
if ($this->debug) ADOConnection::outp( "<hr><b>errors</b>: ".print_r( sqlsrv_errors(), true));
return false;
}
//if ($this->debug) ADOConnection::outp(" _connectionID after: ".serialize($this->_connectionID));
//if ($this->debug) ADOConnection::outp("<hr>defined functions: <pre>".var_export(get_defined_functions(),true)."</pre>");
return true;
}
// returns true or false
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
//return null;//not implemented. NOTE: Persistent connections have no effect if PHP is used as a CGI program. (FastCGI!)
return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename);
return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename);
}
function Prepare($sql)
{
return $sql; // prepare does not work properly with bind parameters as bind parameters are managed by sqlsrv_prepare!
$stmt = sqlsrv_prepare( $this->_connectionID, $sql);
if (!$stmt) return $sql;
return array($sql,$stmt);
}
// returns concatenated string
// MSSQL requires integers to be cast as strings
// automatically cast every datatype to VARCHAR(255)
// @author David Rogers (introspectshun)
function Concat()
{
$s = "";
$arr = func_get_args();
// MSSQL requires integers to be cast as strings
// automatically cast every datatype to VARCHAR(255)
// @author David Rogers (introspectshun)
function Concat()
{
$s = "";
$arr = func_get_args();
// Split single record on commas, if possible
if (sizeof($arr) == 1) {
foreach ($arr as $arg) {
$args = explode(',', $arg);
}
$arr = $args;
}
// Split single record on commas, if possible
if (sizeof($arr) == 1) {
foreach ($arr as $arg) {
$args = explode(',', $arg);
}
$arr = $args;
}
array_walk($arr, create_function('&$v', '$v = "CAST(" . $v . " AS VARCHAR(255))";'));
$s = implode('+',$arr);
if (sizeof($arr) > 0) return "$s";
array_walk($arr, create_function('&$v', '$v = "CAST(" . $v . " AS VARCHAR(255))";'));
$s = implode('+',$arr);
if (sizeof($arr) > 0) return "$s";
return '';
}
/*
}
/*
Unfortunately, it appears that mssql cannot handle varbinary > 255 chars
So all your blobs must be of type "image".
Remember to set in php.ini the following...
; Valid range 0 - 2147483647. Default = 4096.
mssql.textlimit = 0 ; zero to pass through
; Valid range 0 - 2147483647. Default = 4096.
mssql.textsize = 0 ; zero to pass through
Remember to set in php.ini the following...
; Valid range 0 - 2147483647. Default = 4096.
mssql.textlimit = 0 ; zero to pass through
; Valid range 0 - 2147483647. Default = 4096.
mssql.textsize = 0 ; zero to pass through
*/
function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
{
if (strtoupper($blobtype) == 'CLOB') {
$sql = "UPDATE $table SET $column='" . $val . "' WHERE $where";
return $this->Execute($sql) != false;
@@ -448,121 +556,130 @@ class ADODB_mssqlnative extends ADOConnection {
$sql = "UPDATE $table SET $column=0x".bin2hex($val)." WHERE $where";
return $this->Execute($sql) != false;
}
// returns query ID if successful, otherwise false
function _query($sql,$inputarr=false)
{
$this->_errorMsg = false;
if (is_array($inputarr)) {
$rez = sqlsrv_query($this->_connectionID,$sql,$inputarr);
} else if (is_array($sql)) {
$rez = sqlsrv_query($this->_connectionID,$sql[1],$inputarr);
if (is_array($sql)) $sql = $sql[1];
$insert = false;
// handle native driver flaw for retrieving the last insert ID
if(preg_match('/^\W*insert[\s\w()",.]+values\s*\((?:[^;\']|\'\'|(?:(?:\'\')*\'[^\']+\'(?:\'\')*))*;?$/i', $sql)) {
$insert = true;
$sql .= '; '.$this->identitySQL; // select scope_identity()
}
if($inputarr) {
$rez = sqlsrv_query($this->_connectionID, $sql, $inputarr);
} else {
$rez = sqlsrv_query($this->_connectionID,$sql);
}
if ($this->debug) error_log("<hr>running query: ".var_export($sql,true)."<hr>input array: ".var_export($inputarr,true)."<hr>result: ".var_export($rez,true));//"<hr>connection: ".serialize($this->_connectionID)
//fix for returning true on anything besides select statements
if (is_array($sql)) $sql = $sql[1];
$sql = ltrim($sql);
if(stripos($sql, 'SELECT') !== 0 && $rez !== false) {
if ($this->debug) error_log(" isn't a select query, returning boolean true");
return true;
}
//end fix
if(!$rez) $rez = false;
if ($this->debug) ADOConnection::outp("<hr>running query: ".var_export($sql,true)."<hr>input array: ".var_export($inputarr,true)."<hr>result: ".var_export($rez,true));
if(!$rez) {
$rez = false;
} else if ($insert) {
// retrieve the last insert ID (where applicable)
while ( sqlsrv_next_result($rez) ) {
sqlsrv_fetch($rez);
$this->lastInsertID = sqlsrv_get_field($rez, 0);
}
}
return $rez;
}
// returns true or false
function _close()
{
{
if ($this->transCnt) $this->RollbackTrans();
$rez = @sqlsrv_close($this->_connectionID);
$this->_connectionID = false;
return $rez;
}
// mssql uses a default date like Dec 30 2000 12:00AM
static function UnixDate($v)
{
return ADORecordSet_array_mssql::UnixDate($v);
return ADORecordSet_array_mssqlnative::UnixDate($v);
}
static function UnixTimeStamp($v)
{
return ADORecordSet_array_mssql::UnixTimeStamp($v);
}
return ADORecordSet_array_mssqlnative::UnixTimeStamp($v);
}
function &MetaIndexes($table,$primary=false)
function MetaIndexes($table,$primary=false, $owner = false)
{
$table = $this->qstr($table);
$sql = "SELECT i.name AS ind_name, C.name AS col_name, USER_NAME(O.uid) AS Owner, c.colid, k.Keyno,
$sql = "SELECT i.name AS ind_name, C.name AS col_name, USER_NAME(O.uid) AS Owner, c.colid, k.Keyno,
CASE WHEN I.indid BETWEEN 1 AND 254 AND (I.status & 2048 = 2048 OR I.Status = 16402 AND O.XType = 'V') THEN 1 ELSE 0 END AS IsPK,
CASE WHEN I.status & 2 = 2 THEN 1 ELSE 0 END AS IsUnique
FROM dbo.sysobjects o INNER JOIN dbo.sysindexes I ON o.id = i.id
INNER JOIN dbo.sysindexkeys K ON I.id = K.id AND I.Indid = K.Indid
FROM dbo.sysobjects o INNER JOIN dbo.sysindexes I ON o.id = i.id
INNER JOIN dbo.sysindexkeys K ON I.id = K.id AND I.Indid = K.Indid
INNER JOIN dbo.syscolumns c ON K.id = C.id AND K.colid = C.Colid
WHERE LEFT(i.name, 8) <> '_WA_Sys_' AND o.status >= 0 AND O.Name LIKE $table
ORDER BY O.name, I.Name, K.keyno";
global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== FALSE) {
$savem = $this->SetFetchMode(FALSE);
}
$rs = $this->Execute($sql);
if (isset($savem)) {
$this->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== FALSE) {
$savem = $this->SetFetchMode(FALSE);
}
if (!is_object($rs)) {
return FALSE;
}
$rs = $this->Execute($sql);
if (isset($savem)) {
$this->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
if (!is_object($rs)) {
return FALSE;
}
$indexes = array();
while ($row = $rs->FetchRow()) {
if (!$primary && $row[5]) continue;
$indexes[$row[0]]['unique'] = $row[6];
$indexes[$row[0]]['columns'][] = $row[1];
}
return $indexes;
$indexes[$row[0]]['unique'] = $row[6];
$indexes[$row[0]]['columns'][] = $row[1];
}
return $indexes;
}
function MetaForeignKeys($table, $owner=false, $upper=false)
{
global $ADODB_FETCH_MODE;
global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$table = $this->qstr(strtoupper($table));
$sql =
"select object_name(constid) as constraint_name,
col_name(fkeyid, fkey) as column_name,
object_name(rkeyid) as referenced_table_name,
col_name(rkeyid, rkey) as referenced_column_name
from sysforeignkeys
where upper(object_name(fkeyid)) = $table
order by constraint_name, referenced_table_name, keyno";
$sql =
"select object_name(constid) as constraint_name,
col_name(fkeyid, fkey) as column_name,
object_name(rkeyid) as referenced_table_name,
col_name(rkeyid, rkey) as referenced_column_name
from sysforeignkeys
where upper(object_name(fkeyid)) = $table
order by constraint_name, referenced_table_name, keyno";
$constraints =& $this->GetArray($sql);
$ADODB_FETCH_MODE = $save;
$arr = false;
foreach($constraints as $constr) {
//print_r($constr);
$arr[$constr[0]][$constr[2]][] = $constr[1].'='.$constr[3];
$arr[$constr[0]][$constr[2]][] = $constr[1].'='.$constr[3];
}
if (!$arr) return false;
$arr2 = false;
foreach($arr as $k => $v) {
foreach($v as $a => $b) {
if ($upper) $a = strtoupper($a);
@@ -573,101 +690,191 @@ class ADODB_mssqlnative extends ADOConnection {
}
//From: Fernando Moreira <FMoreira@imediata.pt>
function MetaDatabases()
{
$this->SelectDB("master");
$rs =& $this->Execute($this->metaDatabasesSQL);
$rows = $rs->GetRows();
$ret = array();
for($i=0;$i<count($rows);$i++) {
$ret[] = $rows[$i][0];
}
$this->SelectDB($this->database);
if($ret)
return $ret;
else
return false;
}
function MetaDatabases()
{
$this->SelectDB("master");
$rs =& $this->Execute($this->metaDatabasesSQL);
$rows = $rs->GetRows();
$ret = array();
for($i=0;$i<count($rows);$i++) {
$ret[] = $rows[$i][0];
}
$this->SelectDB($this->database);
if($ret)
return $ret;
else
return false;
}
// "Stein-Aksel Basma" <basma@accelero.no>
// tested with MSSQL 2000
function &MetaPrimaryKeys($table)
function MetaPrimaryKeys($table, $owner=false)
{
global $ADODB_FETCH_MODE;
global $ADODB_FETCH_MODE;
$schema = '';
$this->_findschema($table,$schema);
if (!$schema) $schema = $this->database;
if ($schema) $schema = "and k.table_catalog like '$schema%'";
if ($schema) $schema = "and k.table_catalog like '$schema%'";
$sql = "select distinct k.column_name,ordinal_position from information_schema.key_column_usage k,
information_schema.table_constraints tc
information_schema.table_constraints tc
where tc.constraint_name = k.constraint_name and tc.constraint_type =
'PRIMARY KEY' and k.table_name = '$table' $schema order by ordinal_position ";
$savem = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$a = $this->GetCol($sql);
$ADODB_FETCH_MODE = $savem;
if ($a && sizeof($a)>0) return $a;
$false = false;
return $false;
return $false;
}
function &MetaTables($ttype=false,$showSchema=false,$mask=false)
function MetaTables($ttype=false,$showSchema=false,$mask=false)
{
if ($mask) {
if ($mask) {
$save = $this->metaTablesSQL;
$mask = $this->qstr(($mask));
$this->metaTablesSQL .= " AND name like $mask";
}
$ret =& ADOConnection::MetaTables($ttype,$showSchema);
$ret = ADOConnection::MetaTables($ttype,$showSchema);
if ($mask) {
$this->metaTablesSQL = $save;
}
return $ret;
}
function MetaColumns($table, $upper=true, $schema=false){
# start adg
static $cached_columns = array();
if ($this->cachedSchemaFlush)
$cached_columns = array();
if (array_key_exists($table,$cached_columns)){
return $cached_columns[$table];
}
# end adg
if (!$this->mssql_version)
$this->ServerVersion();
$this->_findschema($table,$schema);
if ($schema) {
$dbName = $this->database;
$this->SelectDB($schema);
}
global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
$rs = $this->Execute(sprintf($this->metaColumnsSQL,$table));
if ($schema) {
$this->SelectDB($dbName);
}
if (isset($savem)) $this->SetFetchMode($savem);
$ADODB_FETCH_MODE = $save;
if (!is_object($rs)) {
$false = false;
return $false;
}
$retarr = array();
while (!$rs->EOF){
$fld = new ADOFieldObject();
if (array_key_exists(0,$rs->fields)) {
$fld->name = $rs->fields[0];
$fld->type = $rs->fields[1];
$fld->max_length = $rs->fields[2];
$fld->precision = $rs->fields[3];
$fld->scale = $rs->fields[4];
$fld->not_null =!$rs->fields[5];
$fld->has_default = $rs->fields[6];
$fld->xtype = $rs->fields[7];
$fld->type_length = $rs->fields[8];
$fld->auto_increment= $rs->fields[9];
} else {
$fld->name = $rs->fields['name'];
$fld->type = $rs->fields['type'];
$fld->max_length = $rs->fields['length'];
$fld->precision = $rs->fields['precision'];
$fld->scale = $rs->fields['scale'];
$fld->not_null =!$rs->fields['nullable'];
$fld->has_default = $rs->fields['default_value'];
$fld->xtype = $rs->fields['xtype'];
$fld->type_length = $rs->fields['type_length'];
$fld->auto_increment= $rs->fields['is_identity'];
}
if ($save == ADODB_FETCH_NUM)
$retarr[] = $fld;
else
$retarr[strtoupper($fld->name)] = $fld;
$rs->MoveNext();
}
$rs->Close();
# start adg
$cached_columns[$table] = $retarr;
# end adg
return $retarr;
}
}
/*--------------------------------------------------------------------------------------
Class Name: Recordset
--------------------------------------------------------------------------------------*/
class ADORecordset_mssqlnative extends ADORecordSet {
class ADORecordset_mssqlnative extends ADORecordSet {
var $databaseType = "mssqlnative";
var $canSeek = false;
var $fieldOffset = 0;
// _mths works only in non-localised system
function ADORecordset_mssqlnative($id,$mode=false)
function __construct($id,$mode=false)
{
if ($mode === false) {
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
$this->fetchMode = $mode;
return $this->ADORecordSet($id,$mode);
return parent::__construct($id,$mode);
}
function _initrs()
{
global $ADODB_COUNTRECS;
if ($this->connection->debug) error_log("(before) ADODB_COUNTRECS: {$ADODB_COUNTRECS} _numOfRows: {$this->_numOfRows} _numOfFields: {$this->_numOfFields}");
/*$retRowsAff = sqlsrv_rows_affected($this->_queryID);//"If you need to determine the number of rows a query will return before retrieving the actual results, appending a SELECT COUNT ... query would let you get that information, and then a call to next_result would move you to the "real" results."
error_log("rowsaff: ".serialize($retRowsAff));
global $ADODB_COUNTRECS;
# KMN # if ($this->connection->debug) ADOConnection::outp("(before) ADODB_COUNTRECS: {$ADODB_COUNTRECS} _numOfRows: {$this->_numOfRows} _numOfFields: {$this->_numOfFields}");
/*$retRowsAff = sqlsrv_rows_affected($this->_queryID);//"If you need to determine the number of rows a query will return before retrieving the actual results, appending a SELECT COUNT ... query would let you get that information, and then a call to next_result would move you to the "real" results."
ADOConnection::outp("rowsaff: ".serialize($retRowsAff));
$this->_numOfRows = ($ADODB_COUNTRECS)? $retRowsAff:-1;*/
$this->_numOfRows = -1;//not supported
$fieldmeta = sqlsrv_field_metadata($this->_queryID);
$this->_numOfFields = ($fieldmeta)? count($fieldmeta):-1;
if ($this->connection->debug) error_log("(after) _numOfRows: {$this->_numOfRows} _numOfFields: {$this->_numOfFields}");
$this->_numOfRows = -1;//not supported
$fieldmeta = sqlsrv_field_metadata($this->_queryID);
$this->_numOfFields = ($fieldmeta)? count($fieldmeta):-1;
# KMN # if ($this->connection->debug) ADOConnection::outp("(after) _numOfRows: {$this->_numOfRows} _numOfFields: {$this->_numOfFields}");
/*
* Copy the oracle method and cache the metadata at init time
*/
if ($this->_numOfFields>0) {
$this->_fieldobjs = array();
$max = $this->_numOfFields;
for ($i=0;$i<$max; $i++) $this->_fieldobjs[] = $this->_FetchField($i);
}
}
//Contributed by "Sven Axelsson" <sven.axelsson@bokochwebb.se>
// get next resultset - requires PHP 4.0.5 or later
@@ -692,95 +899,162 @@ class ADORecordset_mssqlnative extends ADORecordSet {
$this->bind[strtoupper($o->name)] = $i;
}
}
return $this->fields[$this->bind[strtoupper($colname)]];
}
/* Returns: an object containing field information.
/* Returns: an object containing field information.
Get column information in the Recordset object. fetchField() can be used in order to obtain information about
fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
fetchField() is retrieved. */
function &FetchField($fieldOffset = -1)
fetchField() is retrieved.
Designed By jcortinap#jc.com.mx
*/
function _FetchField($fieldOffset = -1)
{
if ($this->connection->debug) error_log("<hr>fetchfield: $fieldOffset, fetch array: <pre>".print_r($this->fields,true)."</pre> backtrace: ".adodb_backtrace(false));
if ($fieldOffset != -1) $this->fieldOffset = $fieldOffset;
$arrKeys = array_keys($this->fields);
if(array_key_exists($this->fieldOffset,$arrKeys) && !array_key_exists($arrKeys[$this->fieldOffset],$this->fields)) {
$f = false;
} else {
$f = $this->fields[ $arrKeys[$this->fieldOffset] ];
if($fieldOffset == -1) $this->fieldOffset++;
}
$_typeConversion = array(
-155 => 'datetimeoffset',
-154 => 'time',
-152 => 'xml',
-151 => 'udt',
-11 => 'uniqueidentifier',
-10 => 'ntext',
-9 => 'nvarchar',
-8 => 'nchar',
-7 => 'bit',
-6 => 'tinyint',
-5 => 'bigint',
-4 => 'image',
-3 => 'varbinary',
-2 => 'timestamp',
-1 => 'text',
1 => 'char',
2 => 'numeric',
3 => 'decimal',
4 => 'int',
5 => 'smallint',
6 => 'float',
7 => 'real',
12 => 'varchar',
91 => 'date',
93 => 'datetime'
);
if (empty($f)) {
$f = false;//PHP Notice: Only variable references should be returned by reference
}
$fa = @sqlsrv_field_metadata($this->_queryID);
if ($fieldOffset != -1) {
$fa = $fa[$fieldOffset];
}
$false = false;
if (empty($fa)) {
$f = false;//PHP Notice: Only variable references should be returned by reference
}
else
{
// Convert to an object
$fa = array_change_key_case($fa, CASE_LOWER);
$fb = array();
if ($fieldOffset != -1)
{
$fb = array(
'name' => $fa['name'],
'max_length' => $fa['size'],
'column_source' => $fa['name'],
'type' => $_typeConversion[$fa['type']]
);
}
else
{
foreach ($fa as $key => $value)
{
$fb[] = array(
'name' => $value['name'],
'max_length' => $value['size'],
'column_source' => $value['name'],
'type' => $_typeConversion[$value['type']]
);
}
}
$f = (object) $fb;
}
return $f;
}
function _seek($row)
/*
* Fetchfield copies the oracle method, it loads the field information
* into the _fieldobjs array once, to save multiple calls to the
* sqlsrv_field_metadata function
*
* @author KM Newnham
* @date 02/20/2013
*/
function FetchField($fieldOffset = -1)
{
return $this->_fieldobjs[$fieldOffset];
}
function _seek($row)
{
return false;//There is no support for cursors in the driver at this time. All data is returned via forward-only streams.
}
// speedup
function MoveNext()
function MoveNext()
{
if ($this->connection->debug) error_log("movenext()");
//if ($this->connection->debug) error_log("eof (beginning): ".$this->EOF);
//# KMN # if ($this->connection->debug) ADOConnection::outp("movenext()");
//# KMN # if ($this->connection->debug) ADOConnection::outp("eof (beginning): ".$this->EOF);
if ($this->EOF) return false;
$this->_currentRow++;
if ($this->connection->debug) error_log("_currentRow: ".$this->_currentRow);
// # KMN # if ($this->connection->debug) ADOConnection::outp("_currentRow: ".$this->_currentRow);
if ($this->_fetch()) return true;
$this->EOF = true;
//if ($this->connection->debug) error_log("eof (end): ".$this->EOF);
//# KMN # if ($this->connection->debug) ADOConnection::outp("eof (end): ".$this->EOF);
return false;
}
// INSERT UPDATE DELETE returns false even if no error occurs in 4.0.4
// also the date format has been changed from YYYY-mm-dd to dd MMM YYYY in 4.0.4. Idiot!
function _fetch($ignore_fields=false)
function _fetch($ignore_fields=false)
{
if ($this->connection->debug) error_log("_fetch()");
# KMN # if ($this->connection->debug) ADOConnection::outp("_fetch()");
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
if ($this->fetchMode & ADODB_FETCH_NUM) {
if ($this->connection->debug) error_log("fetch mode: both");
//# KMN # if ($this->connection->debug) ADOConnection::outp("fetch mode: both");
$this->fields = @sqlsrv_fetch_array($this->_queryID,SQLSRV_FETCH_BOTH);
} else {
if ($this->connection->debug) error_log("fetch mode: assoc");
//# KMN # if ($this->connection->debug) ADOConnection::outp("fetch mode: assoc");
$this->fields = @sqlsrv_fetch_array($this->_queryID,SQLSRV_FETCH_ASSOC);
}
if (ADODB_ASSOC_CASE == 0) {
foreach($this->fields as $k=>$v) {
$this->fields[strtolower($k)] = $v;
}
} else if (ADODB_ASSOC_CASE == 1) {
foreach($this->fields as $k=>$v) {
$this->fields[strtoupper($k)] = $v;
if (is_array($this->fields)) {
if (ADODB_ASSOC_CASE == 0) {
foreach($this->fields as $k=>$v) {
$this->fields[strtolower($k)] = $v;
}
} else if (ADODB_ASSOC_CASE == 1) {
foreach($this->fields as $k=>$v) {
$this->fields[strtoupper($k)] = $v;
}
}
}
} else {
if ($this->connection->debug) error_log("fetch mode: num");
//# KMN # if ($this->connection->debug) ADOConnection::outp("fetch mode: num");
$this->fields = @sqlsrv_fetch_array($this->_queryID,SQLSRV_FETCH_NUMERIC);
}
if(is_array($this->fields) && array_key_exists(1,$this->fields) && !array_key_exists(0,$this->fields)) {//fix fetch numeric keys since they're not 0 based
$arrFixed = array();
foreach($this->fields as $key=>$value) {
if(is_numeric($key)) {
$arrFixed[$key-1] = $value;
} else {
$arrFixed[$key] = $value;
}
}
//if($this->connection->debug) error_log("<hr>fixing non 0 based return array, old: ".print_r($this->fields,true)." new: ".print_r($arrFixed,true));
$this->fields = $arrFixed;
}
if(is_array($this->fields) && array_key_exists(1,$this->fields) && !array_key_exists(0,$this->fields)) {//fix fetch numeric keys since they're not 0 based
$arrFixed = array();
foreach($this->fields as $key=>$value) {
if(is_numeric($key)) {
$arrFixed[$key-1] = $value;
} else {
$arrFixed[$key] = $value;
}
}
//if($this->connection->debug) ADOConnection::outp("<hr>fixing non 0 based return array, old: ".print_r($this->fields,true)." new: ".print_r($arrFixed,true));
$this->fields = $arrFixed;
}
if(is_array($this->fields)) {
foreach($this->fields as $key=>$value) {
if (is_object($value) && method_exists($value, 'format')) {//is DateTime object
@@ -788,18 +1062,21 @@ class ADORecordset_mssqlnative extends ADORecordSet {
}
}
}
if($this->fields === null) $this->fields = false;
if ($this->connection->debug) error_log("<hr>after _fetch, fields: <pre>".print_r($this->fields,true)." backtrace: ".adodb_backtrace(false));
if($this->fields === null) $this->fields = false;
# KMN # if ($this->connection->debug) ADOConnection::outp("<hr>after _fetch, fields: <pre>".print_r($this->fields,true)." backtrace: ".adodb_backtrace(false));
return $this->fields;
}
/* close() only needs to be called if you are worried about using too much memory while your script
/* close() only needs to be called if you are worried about using too much memory while your script
is running. All associated result memory for the specified result identifier will automatically be freed. */
function _close()
function _close()
{
$rez = sqlsrv_free_stmt($this->_queryID);
$this->_queryID = false;
return $rez;
if(is_object($this->_queryID)) {
$rez = sqlsrv_free_stmt($this->_queryID);
$this->_queryID = false;
return $rez;
}
return true;
}
// mssql uses a default date like Dec 30 2000 12:00AM
@@ -807,7 +1084,7 @@ class ADORecordset_mssqlnative extends ADORecordSet {
{
return ADORecordSet_array_mssqlnative::UnixDate($v);
}
static function UnixTimeStamp($v)
{
return ADORecordSet_array_mssqlnative::UnixTimeStamp($v);
@@ -816,26 +1093,26 @@ class ADORecordset_mssqlnative extends ADORecordSet {
class ADORecordSet_array_mssqlnative extends ADORecordSet_array {
function ADORecordSet_array_mssqlnative($id=-1,$mode=false)
function __construct($id=-1,$mode=false)
{
$this->ADORecordSet_array($id,$mode);
parent::__construct($id,$mode);
}
// mssql uses a default date like Dec 30 2000 12:00AM
static function UnixDate($v)
{
if (is_numeric(substr($v,0,1)) && ADODB_PHPVER >= 0x4200) return parent::UnixDate($v);
global $ADODB_mssql_mths,$ADODB_mssql_date_order;
//Dec 30 2000 12:00AM
global $ADODB_mssql_mths,$ADODB_mssql_date_order;
//Dec 30 2000 12:00AM
if ($ADODB_mssql_date_order == 'dmy') {
if (!preg_match( "|^([0-9]{1,2})[-/\. ]+([A-Za-z]{3})[-/\. ]+([0-9]{4})|" ,$v, $rr)) {
return parent::UnixDate($v);
}
if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
$theday = $rr[1];
$themth = substr(strtoupper($rr[2]),0,3);
} else {
@@ -843,43 +1120,43 @@ class ADORecordSet_array_mssqlnative extends ADORecordSet_array {
return parent::UnixDate($v);
}
if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
$theday = $rr[2];
$themth = substr(strtoupper($rr[1]),0,3);
}
$themth = $ADODB_mssql_mths[$themth];
if ($themth <= 0) return false;
// h-m-s-MM-DD-YY
return mktime(0,0,0,$themth,$theday,$rr[3]);
return adodb_mktime(0,0,0,$themth,$theday,$rr[3]);
}
static function UnixTimeStamp($v)
{
if (is_numeric(substr($v,0,1)) && ADODB_PHPVER >= 0x4200) return parent::UnixTimeStamp($v);
global $ADODB_mssql_mths,$ADODB_mssql_date_order;
global $ADODB_mssql_mths,$ADODB_mssql_date_order;
//Dec 30 2000 12:00AM
if ($ADODB_mssql_date_order == 'dmy') {
if (!preg_match( "|^([0-9]{1,2})[-/\. ]+([A-Za-z]{3})[-/\. ]+([0-9]{4}) +([0-9]{1,2}):([0-9]{1,2}) *([apAP]{0,1})|"
,$v, $rr)) return parent::UnixTimeStamp($v);
if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
$theday = $rr[1];
$themth = substr(strtoupper($rr[2]),0,3);
} else {
if (!preg_match( "|^([A-Za-z]{3})[-/\. ]+([0-9]{1,2})[-/\. ]+([0-9]{4}) +([0-9]{1,2}):([0-9]{1,2}) *([apAP]{0,1})|"
,$v, $rr)) return parent::UnixTimeStamp($v);
if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
$theday = $rr[2];
$themth = substr(strtoupper($rr[1]),0,3);
}
$themth = $ADODB_mssql_mths[$themth];
if ($themth <= 0) return false;
switch (strtoupper($rr[6])) {
case 'P':
if ($rr[4]<12) $rr[4] += 12;
@@ -891,24 +1168,24 @@ class ADORecordSet_array_mssqlnative extends ADORecordSet_array {
break;
}
// h-m-s-MM-DD-YY
return mktime($rr[4],$rr[5],0,$themth,$theday,$rr[3]);
return adodb_mktime($rr[4],$rr[5],0,$themth,$theday,$rr[3]);
}
}
/*
Code Example 1:
select object_name(constid) as constraint_name,
object_name(fkeyid) as table_name,
col_name(fkeyid, fkey) as column_name,
select object_name(constid) as constraint_name,
object_name(fkeyid) as table_name,
col_name(fkeyid, fkey) as column_name,
object_name(rkeyid) as referenced_table_name,
col_name(rkeyid, rkey) as referenced_column_name
col_name(rkeyid, rkey) as referenced_column_name
from sysforeignkeys
where object_name(fkeyid) = x
order by constraint_name, table_name, referenced_table_name, keyno
Code Example 2:
select constraint_name,
select constraint_name,
column_name,
ordinal_position
from information_schema.key_column_usage
@@ -918,5 +1195,3 @@ order by constraint_name, ordinal_position
http://www.databasejournal.com/scripts/article.php/1440551
*/
?>
+9 -13
View File
@@ -1,6 +1,8 @@
<?php
/**
* @version V5.06 16 Oct 2008 (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved.
* @version v5.20.9 21-Dec-2016
* @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.
@@ -21,19 +23,14 @@ if (!defined('ADODB_DIR')) die();
The big difference between mssqlpo and it's parent mssql is that mssqlpo supports
the more standard || string concatenation operator.
*/
include_once(ADODB_DIR.'/drivers/adodb-mssql.inc.php');
class ADODB_mssqlpo extends ADODB_mssql {
var $databaseType = "mssqlpo";
var $concat_operator = '||';
function ADODB_mssqlpo()
{
ADODB_mssql::ADODB_mssql();
}
var $concat_operator = '||';
function PrepareSP($sql)
function PrepareSP($sql, $param = true)
{
if (!$this->_has_mssql_init) {
ADOConnection::outp( "PrepareSP: mssql_init only available since PHP 4.1.0");
@@ -44,7 +41,7 @@ class ADODB_mssqlpo extends ADODB_mssql {
if (!$stmt) return $sql;
return array($sql,$stmt);
}
function _query($sql,$inputarr=false)
{
if (is_string($sql)) $sql = str_replace('||','+',$sql);
@@ -54,9 +51,8 @@ class ADODB_mssqlpo extends ADODB_mssql {
class ADORecordset_mssqlpo extends ADORecordset_mssql {
var $databaseType = "mssqlpo";
function ADORecordset_mssqlpo($id,$mode=false)
function __construct($id,$mode=false)
{
$this->ADORecordset_mssql($id,$mode);
parent::__construct($id,$mode);
}
}
?>
+358 -261
View File
@@ -1,29 +1,39 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
@version v5.20.9 21-Dec-2016
@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.
Set tabs to 8.
This driver only supports the original non-transactional MySQL driver. It
is deprected in PHP version 5.5 and removed in PHP version 7. It is deprecated
as of ADOdb version 5.20.0. Use the mysqli driver instead, which supports both
transactional and non-transactional updates
MySQL code that does not support transactions. Use mysqlt if you need transactions.
Requires mysql client. Works on Windows and Unix.
28 Feb 2001: MetaColumns bug fix - suggested by Freek Dijkstra (phpeverywhere@macfreek.com)
*/
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
if (! defined("_ADODB_MYSQL_LAYER")) {
define("_ADODB_MYSQL_LAYER", 1 );
define("_ADODB_MYSQL_LAYER", 1 );
class ADODB_mysql extends ADOConnection {
var $databaseType = 'mysql';
var $dataProvider = 'mysql';
var $hasInsertID = true;
var $hasAffectedRows = true;
var $metaTablesSQL = "SHOW TABLES";
var $hasAffectedRows = true;
var $metaTablesSQL = "SELECT
TABLE_NAME,
CASE WHEN TABLE_TYPE = 'VIEW' THEN 'V' ELSE 'T' END
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA=";
var $metaColumnsSQL = "SHOW COLUMNS FROM `%s`";
var $fmtTimeStamp = "'Y-m-d H:i:s'";
var $hasLimit = true;
@@ -36,105 +46,192 @@ class ADODB_mysql extends ADOConnection {
var $forceNewConnect = false;
var $poorAffectedRows = true;
var $clientFlags = 0;
var $charSet = '';
var $substr = "substring";
var $nameQuote = '`'; /// string to use to quote identifiers and names
var $compat323 = false; // true if compat with mysql 3.23
function ADODB_mysql()
{
function __construct()
{
if (defined('ADODB_EXTENSION')) $this->rsPrefix .= 'ext_';
}
// SetCharSet - switch the client encoding
function SetCharSet($charset_name)
{
if (!function_exists('mysql_set_charset')) {
return false;
}
if ($this->charSet !== $charset_name) {
$ok = @mysql_set_charset($charset_name,$this->_connectionID);
if ($ok) {
$this->charSet = $charset_name;
return true;
}
return false;
}
return true;
}
function ServerInfo()
{
$arr['description'] = ADOConnection::GetOne("select version()");
$arr['version'] = ADOConnection::_findvers($arr['description']);
return $arr;
}
function IfNull( $field, $ifNull )
function IfNull( $field, $ifNull )
{
return " IFNULL($field, $ifNull) "; // if MySQL
}
function MetaTables($ttype=false,$showSchema=false,$mask=false)
{
function MetaProcedures($NamePattern = false, $catalog = null, $schemaPattern = null)
{
// save old fetch mode
global $ADODB_FETCH_MODE;
$false = false;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== FALSE) {
$savem = $this->SetFetchMode(FALSE);
}
$procedures = array ();
// get index details
$likepattern = '';
if ($NamePattern) {
$likepattern = " LIKE '".$NamePattern."'";
}
$rs = $this->Execute('SHOW PROCEDURE STATUS'.$likepattern);
if (is_object($rs)) {
// parse index data into array
while ($row = $rs->FetchRow()) {
$procedures[$row[1]] = array(
'type' => 'PROCEDURE',
'catalog' => '',
'schema' => '',
'remarks' => $row[7],
);
}
}
$rs = $this->Execute('SHOW FUNCTION STATUS'.$likepattern);
if (is_object($rs)) {
// parse index data into array
while ($row = $rs->FetchRow()) {
$procedures[$row[1]] = array(
'type' => 'FUNCTION',
'catalog' => '',
'schema' => '',
'remarks' => $row[7]
);
}
}
// restore fetchmode
if (isset($savem)) {
$this->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
return $procedures;
}
/**
* Retrieves a list of tables based on given criteria
*
* @param string $ttype Table type = 'TABLE', 'VIEW' or false=both (default)
* @param string $showSchema schema name, false = current schema (default)
* @param string $mask filters the table by name
*
* @return array list of tables
*/
function MetaTables($ttype=false,$showSchema=false,$mask=false)
{
$save = $this->metaTablesSQL;
if ($showSchema && is_string($showSchema)) {
$this->metaTablesSQL .= " from $showSchema";
$this->metaTablesSQL .= $this->qstr($showSchema);
} else {
$this->metaTablesSQL .= "schema()";
}
if ($mask) {
$mask = $this->qstr($mask);
$this->metaTablesSQL .= " like $mask";
$this->metaTablesSQL .= " AND table_name LIKE $mask";
}
$ret = ADOConnection::MetaTables($ttype,$showSchema);
$this->metaTablesSQL = $save;
return $ret;
}
function MetaIndexes ($table, $primary = FALSE, $owner=false)
{
// save old fetch mode
global $ADODB_FETCH_MODE;
// save old fetch mode
global $ADODB_FETCH_MODE;
$false = false;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== FALSE) {
$savem = $this->SetFetchMode(FALSE);
}
// get index details
$rs = $this->Execute(sprintf('SHOW INDEX FROM %s',$table));
// restore fetchmode
if (isset($savem)) {
$this->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
if (!is_object($rs)) {
return $false;
}
$indexes = array ();
// parse index data into array
while ($row = $rs->FetchRow()) {
if ($primary == FALSE AND $row[2] == 'PRIMARY') {
continue;
}
if (!isset($indexes[$row[2]])) {
$indexes[$row[2]] = array(
'unique' => ($row[1] == 0),
'columns' => array()
);
}
$indexes[$row[2]]['columns'][$row[3] - 1] = $row[4];
}
// sort columns by order in the index
foreach ( array_keys ($indexes) as $index )
{
ksort ($indexes[$index]['columns']);
}
return $indexes;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== FALSE) {
$savem = $this->SetFetchMode(FALSE);
}
// get index details
$rs = $this->Execute(sprintf('SHOW INDEX FROM %s',$table));
// restore fetchmode
if (isset($savem)) {
$this->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
if (!is_object($rs)) {
return $false;
}
$indexes = array ();
// parse index data into array
while ($row = $rs->FetchRow()) {
if ($primary == FALSE AND $row[2] == 'PRIMARY') {
continue;
}
if (!isset($indexes[$row[2]])) {
$indexes[$row[2]] = array(
'unique' => ($row[1] == 0),
'columns' => array()
);
}
$indexes[$row[2]]['columns'][$row[3] - 1] = $row[4];
}
// sort columns by order in the index
foreach ( array_keys ($indexes) as $index )
{
ksort ($indexes[$index]['columns']);
}
return $indexes;
}
// if magic quotes disabled, use mysql_real_escape_string()
function qstr($s,$magic_quotes=false)
{
if (is_null($s)) return 'NULL';
if (!$magic_quotes) {
if (ADODB_PHPVER >= 0x4300) {
if (is_resource($this->_connectionID))
return "'".mysql_real_escape_string($s,$this->_connectionID)."'";
@@ -142,27 +239,28 @@ class ADODB_mysql extends ADOConnection {
if ($this->replaceQuote[0] == '\\'){
$s = adodb_str_replace(array('\\',"\0"),array('\\\\',"\\\0"),$s);
}
return "'".str_replace("'",$this->replaceQuote,$s)."'";
return "'".str_replace("'",$this->replaceQuote,$s)."'";
}
// undo magic quotes for "
$s = str_replace('\\"','"',$s);
return "'$s'";
}
function _insertid()
{
return ADOConnection::GetOne('SELECT LAST_INSERT_ID()');
//return mysql_insert_id($this->_connectionID);
}
function GetOne($sql,$inputarr=false)
{
global $ADODB_GETONE_EOF;
if ($this->compat323 == false && strncasecmp($sql,'sele',4) == 0) {
$rs = $this->SelectLimit($sql,1,-1,$inputarr);
if ($rs) {
$rs->Close();
if ($rs->EOF) return false;
if ($rs->EOF) return $ADODB_GETONE_EOF;
return reset($rs->fields);
}
} else {
@@ -170,41 +268,41 @@ class ADODB_mysql extends ADOConnection {
}
return false;
}
function BeginTrans()
{
if ($this->debug) ADOConnection::outp("Transactions not supported in 'mysql' driver. Use 'mysqlt' or 'mysqli' driver");
}
function _affectedrows()
{
return mysql_affected_rows($this->_connectionID);
}
// See http://www.mysql.com/doc/M/i/Miscellaneous_functions.html
// See http://www.mysql.com/doc/M/i/Miscellaneous_functions.html
// Reference on Last_Insert_ID on the recommended way to simulate sequences
var $_genIDSQL = "update %s set id=LAST_INSERT_ID(id+1);";
var $_genSeqSQL = "create table %s (id int not null)";
var $_genIDSQL = "update %s set id=LAST_INSERT_ID(id+1);";
var $_genSeqSQL = "create table if not exists %s (id int not null)";
var $_genSeqCountSQL = "select count(*) from %s";
var $_genSeq2SQL = "insert into %s values (%s)";
var $_dropSeqSQL = "drop table %s";
var $_dropSeqSQL = "drop table if exists %s";
function CreateSequence($seqname='adodbseq',$startID=1)
{
if (empty($this->_genSeqSQL)) return false;
$u = strtoupper($seqname);
$ok = $this->Execute(sprintf($this->_genSeqSQL,$seqname));
if (!$ok) return false;
return $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1));
}
function GenID($seqname='adodbseq',$startID=1)
{
// post-nuke sets hasGenID to false
if (!$this->hasGenID) return false;
$savelog = $this->_logsql;
$this->_logsql = false;
$getnext = sprintf($this->_genIDSQL,$seqname);
@@ -218,18 +316,18 @@ class ADODB_mysql extends ADOConnection {
if (!$cnt) $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1));
$rs = $this->Execute($getnext);
}
if ($rs) {
$this->genID = mysql_insert_id($this->_connectionID);
$rs->Close();
} else
$this->genID = 0;
$this->_logsql = $savelog;
return $this->genID;
}
function MetaDatabases()
function MetaDatabases()
{
$qid = mysql_list_dbs($this->_connectionID);
$arr = array();
@@ -242,11 +340,11 @@ class ADODB_mysql extends ADOConnection {
}
return $arr;
}
// Format date column in sql string given an input format that understands Y M D
function SQLDate($fmt, $col=false)
{
{
if (!$col) $col = $this->sysTimeStamp;
$s = 'DATE_FORMAT('.$col.",'";
$concat = false;
@@ -254,7 +352,7 @@ class ADODB_mysql extends ADOConnection {
for ($i=0; $i < $len; $i++) {
$ch = $fmt[$i];
switch($ch) {
default:
if ($ch == '\\') {
$i++;
@@ -265,7 +363,7 @@ class ADODB_mysql extends ADOConnection {
case '/':
$s .= $ch;
break;
case 'Y':
case 'y':
$s .= '%Y';
@@ -273,7 +371,7 @@ class ADODB_mysql extends ADOConnection {
case 'M':
$s .= '%b';
break;
case 'm':
$s .= '%m';
break;
@@ -281,45 +379,45 @@ class ADODB_mysql extends ADOConnection {
case 'd':
$s .= '%d';
break;
case 'Q':
case 'q':
$s .= "'),Quarter($col)";
if ($len > $i+1) $s .= ",DATE_FORMAT($col,'";
else $s .= ",('";
$concat = true;
break;
case 'H':
case 'H':
$s .= '%H';
break;
case 'h':
$s .= '%I';
break;
case 'i':
$s .= '%i';
break;
case 's':
$s .= '%s';
break;
case 'a':
case 'A':
$s .= '%p';
break;
case 'w':
$s .= '%w';
break;
case 'W':
$s .= '%U';
break;
case 'l':
$s .= '%W';
break;
@@ -329,7 +427,7 @@ class ADODB_mysql extends ADOConnection {
if ($concat) $s = "CONCAT($s)";
return $s;
}
// returns concatenated string
// much easier to run "mysqld --ansi" or "mysqld --sql-mode=PIPES_AS_CONCAT" and use || operator
@@ -337,28 +435,28 @@ class ADODB_mysql extends ADOConnection {
{
$s = "";
$arr = func_get_args();
// suggestion by andrew005@mnogo.ru
$s = implode(',',$arr);
$s = implode(',',$arr);
if (strlen($s) > 0) return "CONCAT($s)";
else return '';
}
function OffsetDate($dayFraction,$date=false)
{
{
if (!$date) $date = $this->sysDate;
$fraction = $dayFraction * 24 * 3600;
return '('. $date . ' + INTERVAL ' . $fraction.' SECOND)';
// return "from_unixtime(unix_timestamp($date)+$fraction)";
}
// returns true or false
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
if (!empty($this->port)) $argHostname .= ":".$this->port;
if (ADODB_PHPVER >= 0x4300)
$this->_connectionID = mysql_connect($argHostname,$argUsername,$argPassword,
$this->forceNewConnect,$this->clientFlags);
@@ -367,17 +465,17 @@ class ADODB_mysql extends ADOConnection {
$this->forceNewConnect);
else
$this->_connectionID = mysql_connect($argHostname,$argUsername,$argPassword);
if ($this->_connectionID === false) return false;
if ($argDatabasename) return $this->SelectDB($argDatabasename);
return true;
return true;
}
// returns true or false
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
if (!empty($this->port)) $argHostname .= ":".$this->port;
if (ADODB_PHPVER >= 0x4300)
$this->_connectionID = mysql_pconnect($argHostname,$argUsername,$argPassword,$this->clientFlags);
else
@@ -385,16 +483,16 @@ class ADODB_mysql extends ADOConnection {
if ($this->_connectionID === false) return false;
if ($this->autoRollback) $this->RollbackTrans();
if ($argDatabasename) return $this->SelectDB($argDatabasename);
return true;
return true;
}
function _nconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
$this->forceNewConnect = true;
return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename);
}
function MetaColumns($table, $normalize=true)
function MetaColumns($table, $normalize=true)
{
$this->_findschema($table,$schema);
if ($schema) {
@@ -404,27 +502,27 @@ class ADODB_mysql extends ADOConnection {
global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
$rs = $this->Execute(sprintf($this->metaColumnsSQL,$table));
if ($schema) {
$this->SelectDB($dbName);
}
if (isset($savem)) $this->SetFetchMode($savem);
$ADODB_FETCH_MODE = $save;
if (!is_object($rs)) {
$false = false;
return $false;
}
$retarr = array();
while (!$rs->EOF){
$fld = new ADOFieldObject();
$fld->name = $rs->fields[0];
$type = $rs->fields[1];
// split type into type(length):
$fld->scale = null;
if (preg_match("/^(.+)\((\d+),(\d+)/", $type, $query_array)) {
@@ -460,7 +558,7 @@ class ADODB_mysql extends ADOConnection {
$fld->has_default = false;
}
}
if ($save == ADODB_FETCH_NUM) {
$retarr[] = $fld;
} else {
@@ -468,148 +566,157 @@ class ADODB_mysql extends ADOConnection {
}
$rs->MoveNext();
}
$rs->Close();
return $retarr;
return $retarr;
}
// returns true or false
function SelectDB($dbName)
function SelectDB($dbName)
{
$this->database = $dbName;
$this->databaseName = $dbName; # obsolete, retained for compat with older adodb versions
if ($this->_connectionID) {
return @mysql_select_db($dbName,$this->_connectionID);
return @mysql_select_db($dbName,$this->_connectionID);
}
else return false;
else return false;
}
// parameters use PostgreSQL convention, not MySQL
function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs=0)
{
$offsetStr =($offset>=0) ? ((integer)$offset)."," : '';
// jason judge, see http://phplens.com/lens/lensforum/msgs.php?id=9220
if ($nrows < 0) $nrows = '18446744073709551615';
if ($nrows < 0) $nrows = '18446744073709551615';
if ($secs)
$rs = $this->CacheExecute($secs,$sql." LIMIT $offsetStr".((integer)$nrows),$inputarr);
else
$rs = $this->Execute($sql." LIMIT $offsetStr".((integer)$nrows),$inputarr);
return $rs;
}
// returns queryID or false
function _query($sql,$inputarr=false)
{
//global $ADODB_COUNTRECS;
//if($ADODB_COUNTRECS)
return mysql_query($sql,$this->_connectionID);
//else return @mysql_unbuffered_query($sql,$this->_connectionID); // requires PHP >= 4.0.6
return mysql_query($sql,$this->_connectionID);
/*
global $ADODB_COUNTRECS;
if($ADODB_COUNTRECS)
return mysql_query($sql,$this->_connectionID);
else
return @mysql_unbuffered_query($sql,$this->_connectionID); // requires PHP >= 4.0.6
*/
}
/* Returns: the last error message from previous database operation */
function ErrorMsg()
/* Returns: the last error message from previous database operation */
function ErrorMsg()
{
if ($this->_logsql) return $this->_errorMsg;
if (empty($this->_connectionID)) $this->_errorMsg = @mysql_error();
else $this->_errorMsg = @mysql_error($this->_connectionID);
return $this->_errorMsg;
}
/* Returns: the last error number from previous database operation */
function ErrorNo()
/* Returns: the last error number from previous database operation */
function ErrorNo()
{
if ($this->_logsql) return $this->_errorCode;
if (empty($this->_connectionID)) return @mysql_errno();
if (empty($this->_connectionID)) return @mysql_errno();
else return @mysql_errno($this->_connectionID);
}
// returns true or false
function _close()
{
@mysql_close($this->_connectionID);
$this->charSet = '';
$this->_connectionID = false;
}
/*
* Maximum size of C field
*/
function CharMax()
{
return 255;
return 255;
}
/*
* Maximum size of X field
*/
function TextMax()
{
return 4294967295;
return 4294967295;
}
// "Innox - Juan Carlos Gonzalez" <jgonzalez#innox.com.mx>
function MetaForeignKeys( $table, $owner = FALSE, $upper = FALSE, $associative = FALSE )
{
{
global $ADODB_FETCH_MODE;
if ($ADODB_FETCH_MODE == ADODB_FETCH_ASSOC || $this->fetchMode == ADODB_FETCH_ASSOC) $associative = true;
if ( !empty($owner) ) {
$table = "$owner.$table";
}
$a_create_table = $this->getRow(sprintf('SHOW CREATE TABLE %s', $table));
if ($associative) {
$create_sql = isset($a_create_table["Create Table"]) ? $a_create_table["Create Table"] : $a_create_table["Create View"];
} else $create_sql = $a_create_table[1];
if ( !empty($owner) ) {
$table = "$owner.$table";
}
$a_create_table = $this->getRow(sprintf('SHOW CREATE TABLE %s', $table));
if ($associative) {
$create_sql = isset($a_create_table["Create Table"]) ? $a_create_table["Create Table"] : $a_create_table["Create View"];
} else {
$create_sql = $a_create_table[1];
}
$matches = array();
$matches = array();
if (!preg_match_all("/FOREIGN KEY \(`(.*?)`\) REFERENCES `(.*?)` \(`(.*?)`\)/", $create_sql, $matches)) return false;
$foreign_keys = array();
$num_keys = count($matches[0]);
for ( $i = 0; $i < $num_keys; $i ++ ) {
$my_field = explode('`, `', $matches[1][$i]);
$ref_table = $matches[2][$i];
$ref_field = explode('`, `', $matches[3][$i]);
if (!preg_match_all("/FOREIGN KEY \(`(.*?)`\) REFERENCES `(.*?)` \(`(.*?)`\)/", $create_sql, $matches)) return false;
$foreign_keys = array();
$num_keys = count($matches[0]);
for ( $i = 0; $i < $num_keys; $i ++ ) {
$my_field = explode('`, `', $matches[1][$i]);
$ref_table = $matches[2][$i];
$ref_field = explode('`, `', $matches[3][$i]);
if ( $upper ) {
$ref_table = strtoupper($ref_table);
}
if ( $upper ) {
$ref_table = strtoupper($ref_table);
}
// see https://sourceforge.net/tracker/index.php?func=detail&aid=2287278&group_id=42718&atid=433976
if (!isset($foreign_keys[$ref_table])) {
$foreign_keys[$ref_table] = array();
}
$num_fields = count($my_field);
for ( $j = 0; $j < $num_fields; $j ++ ) {
if ( $associative ) {
$foreign_keys[$ref_table][$ref_field[$j]] = $my_field[$j];
} else {
$foreign_keys[$ref_table][] = "{$my_field[$j]}={$ref_field[$j]}";
}
}
}
return $foreign_keys;
}
$num_fields = count($my_field);
for ( $j = 0; $j < $num_fields; $j ++ ) {
if ( $associative ) {
$foreign_keys[$ref_table][$ref_field[$j]] = $my_field[$j];
} else {
$foreign_keys[$ref_table][] = "{$my_field[$j]}={$ref_field[$j]}";
}
}
}
return $foreign_keys;
}
}
/*--------------------------------------------------------------------------------------
Class Name: Recordset
--------------------------------------------------------------------------------------*/
class ADORecordSet_mysql extends ADORecordSet{
class ADORecordSet_mysql extends ADORecordSet{
var $databaseType = "mysql";
var $canSeek = true;
function ADORecordSet_mysql($queryID,$mode=false)
function __construct($queryID,$mode=false)
{
if ($mode === false) {
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
@@ -623,9 +730,9 @@ class ADORecordSet_mysql extends ADORecordSet{
$this->fetchMode = MYSQL_BOTH; break;
}
$this->adodbFetchMode = $mode;
$this->ADORecordSet($queryID);
parent::__construct($queryID);
}
function _initrs()
{
//GLOBAL $ADODB_COUNTRECS;
@@ -633,9 +740,9 @@ class ADORecordSet_mysql extends ADORecordSet{
$this->_numOfRows = @mysql_num_rows($this->_queryID);
$this->_numOfFields = @mysql_num_fields($this->_queryID);
}
function FetchField($fieldOffset = -1)
{
function FetchField($fieldOffset = -1)
{
if ($fieldOffset != -1) {
$o = @mysql_fetch_field($this->_queryID, $fieldOffset);
$f = @mysql_field_flags($this->_queryID,$fieldOffset);
@@ -643,28 +750,32 @@ class ADORecordSet_mysql extends ADORecordSet{
//$o->max_length = -1; // mysql returns the max length less spaces -- so it is unrealiable
if ($o) $o->binary = (strpos($f,'binary')!== false);
}
else if ($fieldOffset == -1) { /* The $fieldOffset argument is not provided thus its -1 */
else { /* The $fieldOffset argument is not provided thus its -1 */
$o = @mysql_fetch_field($this->_queryID);
if ($o) $o->max_length = @mysql_field_len($this->_queryID); // suggested by: Jim Nicholson (jnich#att.com)
//$o->max_length = -1; // mysql returns the max length less spaces -- so it is unrealiable
//if ($o) $o->max_length = @mysql_field_len($this->_queryID); // suggested by: Jim Nicholson (jnich#att.com)
$o->max_length = -1; // mysql returns the max length less spaces -- so it is unrealiable
}
return $o;
}
function GetRowAssoc($upper=true)
function GetRowAssoc($upper = ADODB_ASSOC_CASE)
{
if ($this->fetchMode == MYSQL_ASSOC && !$upper) $row = $this->fields;
else $row = ADORecordSet::GetRowAssoc($upper);
if ($this->fetchMode == MYSQL_ASSOC && $upper == ADODB_ASSOC_CASE_LOWER) {
$row = $this->fields;
}
else {
$row = ADORecordSet::GetRowAssoc($upper);
}
return $row;
}
/* Use associative array to get fields array */
function Fields($colname)
{
{
// added @ by "Michael William Miller" <mille562@pilot.msu.edu>
if ($this->fetchMode != MYSQL_NUM) return @$this->fields[$colname];
if (!$this->bind) {
$this->bind = array();
for ($i=0; $i < $this->_numOfFields; $i++) {
@@ -674,18 +785,19 @@ class ADORecordSet_mysql extends ADORecordSet{
}
return $this->fields[$this->bind[strtoupper($colname)]];
}
function _seek($row)
{
if ($this->_numOfRows == 0) return false;
return @mysql_data_seek($this->_queryID,$row);
}
function MoveNext()
{
//return adodb_movenext($this);
//if (defined('ADODB_EXTENSION')) return adodb_movenext($this);
if (@$this->fields = mysql_fetch_array($this->_queryID,$this->fetchMode)) {
$this->_updatefields();
$this->_currentRow += 1;
return true;
}
@@ -695,18 +807,19 @@ class ADORecordSet_mysql extends ADORecordSet{
}
return false;
}
function _fetch()
{
$this->fields = @mysql_fetch_array($this->_queryID,$this->fetchMode);
$this->fields = @mysql_fetch_array($this->_queryID,$this->fetchMode);
$this->_updatefields();
return is_array($this->fields);
}
function _close() {
@mysql_free_result($this->_queryID);
$this->_queryID = false;
@mysql_free_result($this->_queryID);
$this->_queryID = false;
}
function MetaType($t,$len=-1,$fieldobj=false)
{
if (is_object($t)) {
@@ -714,81 +827,65 @@ class ADORecordSet_mysql extends ADORecordSet{
$t = $fieldobj->type;
$len = $fieldobj->max_length;
}
$len = -1; // mysql max_length is not accurate
switch (strtoupper($t)) {
case 'STRING':
case 'STRING':
case 'CHAR':
case 'VARCHAR':
case 'TINYBLOB':
case 'TINYTEXT':
case 'ENUM':
case 'SET':
case 'VARCHAR':
case 'TINYBLOB':
case 'TINYTEXT':
case 'ENUM':
case 'SET':
if ($len <= $this->blobSize) return 'C';
case 'TEXT':
case 'LONGTEXT':
case 'LONGTEXT':
case 'MEDIUMTEXT':
return 'X';
// php_mysql extension always returns 'blob' even if 'text'
// so we have to check whether binary...
case 'IMAGE':
case 'LONGBLOB':
case 'LONGBLOB':
case 'BLOB':
case 'MEDIUMBLOB':
case 'BINARY':
return !empty($fieldobj->binary) ? 'B' : 'X';
case 'YEAR':
case 'DATE': return 'D';
case 'TIME':
case 'DATETIME':
case 'TIMESTAMP': return 'T';
case 'INT':
case 'INT':
case 'INTEGER':
case 'BIGINT':
case 'TINYINT':
case 'MEDIUMINT':
case 'SMALLINT':
case 'SMALLINT':
if (!empty($fieldobj->primary_key)) return 'R';
else return 'I';
default: return 'N';
}
}
}
class ADORecordSet_ext_mysql extends ADORecordSet_mysql {
function ADORecordSet_ext_mysql($queryID,$mode=false)
class ADORecordSet_ext_mysql extends ADORecordSet_mysql {
function __construct($queryID,$mode=false)
{
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
switch ($mode)
{
case ADODB_FETCH_NUM: $this->fetchMode = MYSQL_NUM; break;
case ADODB_FETCH_ASSOC:$this->fetchMode = MYSQL_ASSOC; break;
case ADODB_FETCH_DEFAULT:
case ADODB_FETCH_BOTH:
default:
$this->fetchMode = MYSQL_BOTH; break;
}
$this->adodbFetchMode = $mode;
$this->ADORecordSet($queryID);
parent::__construct($queryID,$mode);
}
function MoveNext()
{
return @adodb_movenext($this);
}
}
}
?>
+618 -512
View File
@@ -1,26 +1,32 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
@version v5.20.9 21-Dec-2016
@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.
Set tabs to 8.
This is the preferred driver for MySQL connections, and supports both transactional
and non-transactional table types. You can use this as a drop-in replacement for both
the mysql and mysqlt drivers. As of ADOdb Version 5.20.0, all other native MySQL drivers
are deprecated
MySQL code that does not support transactions. Use mysqlt if you need transactions.
Requires mysql client. Works on Windows and Unix.
21 October 2003: MySQLi extension implementation by Arjen de Rijke (a.de.rijke@xs4all.nl)
Based on adodb 3.40
*/
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
if (! defined("_ADODB_MYSQLI_LAYER")) {
define("_ADODB_MYSQLI_LAYER", 1 );
// PHP5 compat...
if (! defined("MYSQLI_BINARY_FLAG")) define("MYSQLI_BINARY_FLAG", 128);
if (! defined("MYSQLI_BINARY_FLAG")) define("MYSQLI_BINARY_FLAG", 128);
if (!defined('MYSQLI_READ_DEFAULT_GROUP')) define('MYSQLI_READ_DEFAULT_GROUP',1);
// disable adodb extension - currently incompatible.
@@ -28,10 +34,14 @@ if (! defined("_ADODB_MYSQLI_LAYER")) {
class ADODB_mysqli extends ADOConnection {
var $databaseType = 'mysqli';
var $dataProvider = 'native';
var $dataProvider = 'mysql';
var $hasInsertID = true;
var $hasAffectedRows = true;
var $metaTablesSQL = "SHOW TABLES";
var $hasAffectedRows = true;
var $metaTablesSQL = "SELECT
TABLE_NAME,
CASE WHEN TABLE_TYPE = 'VIEW' THEN 'V' ELSE 'T' END
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA=";
var $metaColumnsSQL = "SHOW COLUMNS FROM `%s`";
var $fmtTimeStamp = "'Y-m-d H:i:s'";
var $hasLimit = true;
@@ -45,23 +55,23 @@ class ADODB_mysqli extends ADOConnection {
var $poorAffectedRows = true;
var $clientFlags = 0;
var $substr = "substring";
var $port = false;
var $socket = false;
var $port = 3306; //Default to 3306 to fix HHVM bug
var $socket = ''; //Default to empty string to fix HHVM bug
var $_bindInputArray = false;
var $nameQuote = '`'; /// string to use to quote identifiers and names
var $optionFlags = array(array(MYSQLI_READ_DEFAULT_GROUP,0));
var $arrayClass = 'ADORecordSet_array_mysqli';
function ADODB_mysqli()
{
// if(!extension_loaded("mysqli"))
;//trigger_error("You must have the mysqli extension installed.", E_USER_ERROR);
}
function SetTransactionMode( $transaction_mode )
var $arrayClass = 'ADORecordSet_array_mysqli';
var $multiQuery = false;
function __construct()
{
$this->_transmode = $transaction_mode;
// if(!extension_loaded("mysqli"))
//trigger_error("You must have the mysqli extension installed.", E_USER_ERROR);
}
function SetTransactionMode( $transaction_mode )
{
$this->_transmode = $transaction_mode;
if (empty($transaction_mode)) {
$this->Execute('SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ');
return;
@@ -73,117 +83,125 @@ class ADODB_mysqli extends ADOConnection {
// returns true or false
// To add: parameter int $port,
// parameter string $socket
function _connect($argHostname = NULL,
$argUsername = NULL,
$argPassword = NULL,
$argDatabasename = NULL, $persist=false)
{
if(!extension_loaded("mysqli")) {
function _connect($argHostname = NULL,
$argUsername = NULL,
$argPassword = NULL,
$argDatabasename = NULL, $persist=false)
{
if(!extension_loaded("mysqli")) {
return null;
}
$this->_connectionID = @mysqli_init();
if (is_null($this->_connectionID)) {
// mysqli_init only fails if insufficient memory
if ($this->debug)
}
$this->_connectionID = @mysqli_init();
if (is_null($this->_connectionID)) {
// mysqli_init only fails if insufficient memory
if ($this->debug) {
ADOConnection::outp("mysqli_init() failed : " . $this->ErrorMsg());
return false;
}
}
return false;
}
/*
I suggest a simple fix which would enable adodb and mysqli driver to
read connection options from the standard mysql configuration file
/etc/my.cnf - "Bastien Duclaux" <bduclaux#yahoo.com>
*/
foreach($this->optionFlags as $arr) {
foreach($this->optionFlags as $arr) {
mysqli_options($this->_connectionID,$arr[0],$arr[1]);
}
//http ://php.net/manual/en/mysqli.persistconns.php
if ($persist && PHP_VERSION > 5.2 && strncmp($argHostname,'p:',2) != 0) $argHostname = 'p:'.$argHostname;
#if (!empty($this->port)) $argHostname .= ":".$this->port;
$ok = mysqli_real_connect($this->_connectionID,
$argHostname,
$argUsername,
$argPassword,
$argDatabasename,
$this->port,
$argHostname,
$argUsername,
$argPassword,
$argDatabasename,
# PHP7 compat: port must be int. Use default port if cast yields zero
(int)$this->port != 0 ? (int)$this->port : 3306,
$this->socket,
$this->clientFlags);
if ($ok) {
if ($argDatabasename) return $this->SelectDB($argDatabasename);
return true;
} else {
if ($this->debug)
ADOConnection::outp("Could't connect : " . $this->ErrorMsg());
if ($argDatabasename) return $this->SelectDB($argDatabasename);
return true;
} else {
if ($this->debug) {
ADOConnection::outp("Could't connect : " . $this->ErrorMsg());
}
$this->_connectionID = null;
return false;
}
}
}
// returns true or false
// How to force a persistent connection
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename, true);
}
// When is this used? Close old connection first?
// In _connect(), check $this->forceNewConnect?
// In _connect(), check $this->forceNewConnect?
function _nconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
$this->forceNewConnect = true;
return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename);
}
function IfNull( $field, $ifNull )
{
$this->forceNewConnect = true;
return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename);
}
function IfNull( $field, $ifNull )
{
return " IFNULL($field, $ifNull) "; // if MySQL
}
// do not use $ADODB_COUNTRECS
function GetOne($sql,$inputarr=false)
{
global $ADODB_GETONE_EOF;
$ret = false;
$rs = $this->Execute($sql,$inputarr);
if ($rs) {
if (!$rs->EOF) $ret = reset($rs->fields);
if ($rs) {
if ($rs->EOF) $ret = $ADODB_GETONE_EOF;
else $ret = reset($rs->fields);
$rs->Close();
}
return $ret;
}
function ServerInfo()
{
$arr['description'] = $this->GetOne("select version()");
$arr['version'] = ADOConnection::_findvers($arr['description']);
return $arr;
}
function BeginTrans()
{
{
if ($this->transOff) return true;
$this->transCnt += 1;
//$this->Execute('SET AUTOCOMMIT=0');
mysqli_autocommit($this->_connectionID, false);
$this->Execute('BEGIN');
return true;
}
function CommitTrans($ok=true)
function CommitTrans($ok=true)
{
if ($this->transOff) return true;
if ($this->transOff) return true;
if (!$ok) return $this->RollbackTrans();
if ($this->transCnt) $this->transCnt -= 1;
$this->Execute('COMMIT');
//$this->Execute('SET AUTOCOMMIT=1');
mysqli_autocommit($this->_connectionID, true);
return true;
}
function RollbackTrans()
{
if ($this->transOff) return true;
@@ -193,83 +211,89 @@ class ADODB_mysqli extends ADOConnection {
mysqli_autocommit($this->_connectionID, true);
return true;
}
function RowLock($tables,$where='',$flds='1 as adodb_ignore')
function RowLock($tables,$where='',$col='1 as adodbignore')
{
if ($this->transCnt==0) $this->BeginTrans();
if ($where) $where = ' where '.$where;
$rs = $this->Execute("select $flds from $tables $where for update");
return !empty($rs);
$rs = $this->Execute("select $col from $tables $where for update");
return !empty($rs);
}
// if magic quotes disabled, use mysql_real_escape_string()
// From readme.htm:
// Quotes a string to be sent to the database. The $magic_quotes_enabled
// parameter may look funny, but the idea is if you are quoting a
// string extracted from a POST/GET variable, then
// pass get_magic_quotes_gpc() as the second parameter. This will
// ensure that the variable is not quoted twice, once by qstr and once
// by the magic_quotes_gpc.
//
//Eg. $s = $db->qstr(_GET['name'],get_magic_quotes_gpc());
/**
* Quotes a string to be sent to the database
* When there is no active connection,
* @param string $s The string to quote
* @param boolean $magic_quotes If false, use mysqli_real_escape_string()
* if you are quoting a string extracted from a POST/GET variable,
* then pass get_magic_quotes_gpc() as the second parameter. This will
* ensure that the variable is not quoted twice, once by qstr() and
* once by the magic_quotes_gpc.
* Eg. $s = $db->qstr(_GET['name'],get_magic_quotes_gpc());
* @return string Quoted string
*/
function qstr($s, $magic_quotes = false)
{
if (is_null($s)) return 'NULL';
if (!$magic_quotes) {
if (PHP_VERSION >= 5)
return "'" . mysqli_real_escape_string($this->_connectionID, $s) . "'";
if ($this->replaceQuote[0] == '\\')
$s = adodb_str_replace(array('\\',"\0"),array('\\\\',"\\\0"),$s);
return "'".str_replace("'",$this->replaceQuote,$s)."'";
}
// undo magic quotes for "
$s = str_replace('\\"','"',$s);
return "'$s'";
// mysqli_real_escape_string() throws a warning when the given
// connection is invalid
if (PHP_VERSION >= 5 && $this->_connectionID) {
return "'" . mysqli_real_escape_string($this->_connectionID, $s) . "'";
}
if ($this->replaceQuote[0] == '\\') {
$s = adodb_str_replace(array('\\',"\0"), array('\\\\',"\\\0") ,$s);
}
return "'" . str_replace("'", $this->replaceQuote, $s) . "'";
}
// undo magic quotes for "
$s = str_replace('\\"','"',$s);
return "'$s'";
}
function _insertid()
{
$result = @mysqli_insert_id($this->_connectionID);
if ($result == -1){
if ($this->debug) ADOConnection::outp("mysqli_insert_id() failed : " . $this->ErrorMsg());
}
return $result;
$result = @mysqli_insert_id($this->_connectionID);
if ($result == -1) {
if ($this->debug) ADOConnection::outp("mysqli_insert_id() failed : " . $this->ErrorMsg());
}
return $result;
}
// Only works for INSERT, UPDATE and DELETE query's
function _affectedrows()
{
$result = @mysqli_affected_rows($this->_connectionID);
if ($result == -1) {
if ($this->debug) ADOConnection::outp("mysqli_affected_rows() failed : " . $this->ErrorMsg());
}
return $result;
$result = @mysqli_affected_rows($this->_connectionID);
if ($result == -1) {
if ($this->debug) ADOConnection::outp("mysqli_affected_rows() failed : " . $this->ErrorMsg());
}
return $result;
}
// See http://www.mysql.com/doc/M/i/Miscellaneous_functions.html
// See http://www.mysql.com/doc/M/i/Miscellaneous_functions.html
// Reference on Last_Insert_ID on the recommended way to simulate sequences
var $_genIDSQL = "update %s set id=LAST_INSERT_ID(id+1);";
var $_genSeqSQL = "create table %s (id int not null)";
var $_genIDSQL = "update %s set id=LAST_INSERT_ID(id+1);";
var $_genSeqSQL = "create table if not exists %s (id int not null)";
var $_genSeqCountSQL = "select count(*) from %s";
var $_genSeq2SQL = "insert into %s values (%s)";
var $_dropSeqSQL = "drop table %s";
var $_dropSeqSQL = "drop table if exists %s";
function CreateSequence($seqname='adodbseq',$startID=1)
{
if (empty($this->_genSeqSQL)) return false;
$u = strtoupper($seqname);
$ok = $this->Execute(sprintf($this->_genSeqSQL,$seqname));
if (!$ok) return false;
return $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1));
}
function GenID($seqname='adodbseq',$startID=1)
{
// post-nuke sets hasGenID to false
if (!$this->hasGenID) return false;
$getnext = sprintf($this->_genIDSQL,$seqname);
$holdtransOK = $this->_transOK; // save the current status
$rs = @$this->Execute($getnext);
@@ -281,89 +305,89 @@ class ADODB_mysqli extends ADOConnection {
if (!$cnt) $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1));
$rs = $this->Execute($getnext);
}
if ($rs) {
$this->genID = mysqli_insert_id($this->_connectionID);
$rs->Close();
} else
$this->genID = 0;
return $this->genID;
}
function MetaDatabases()
function MetaDatabases()
{
$query = "SHOW DATABASES";
$ret = $this->Execute($query);
if ($ret && is_object($ret)){
$arr = array();
$arr = array();
while (!$ret->EOF){
$db = $ret->Fields('Database');
if ($db != 'mysql') $arr[] = $db;
$ret->MoveNext();
}
return $arr;
return $arr;
}
return $ret;
return $ret;
}
function MetaIndexes ($table, $primary = FALSE)
function MetaIndexes ($table, $primary = FALSE, $owner = false)
{
// save old fetch mode
global $ADODB_FETCH_MODE;
$false = false;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== FALSE) {
$savem = $this->SetFetchMode(FALSE);
$savem = $this->SetFetchMode(FALSE);
}
// get index details
$rs = $this->Execute(sprintf('SHOW INDEXES FROM %s',$table));
// restore fetchmode
if (isset($savem)) {
$this->SetFetchMode($savem);
$this->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
if (!is_object($rs)) {
return $false;
return $false;
}
$indexes = array ();
// parse index data into array
while ($row = $rs->FetchRow()) {
if ($primary == FALSE AND $row[2] == 'PRIMARY') {
continue;
}
if (!isset($indexes[$row[2]])) {
$indexes[$row[2]] = array(
'unique' => ($row[1] == 0),
'columns' => array()
);
}
$indexes[$row[2]]['columns'][$row[3] - 1] = $row[4];
if ($primary == FALSE AND $row[2] == 'PRIMARY') {
continue;
}
if (!isset($indexes[$row[2]])) {
$indexes[$row[2]] = array(
'unique' => ($row[1] == 0),
'columns' => array()
);
}
$indexes[$row[2]]['columns'][$row[3] - 1] = $row[4];
}
// sort columns by order in the index
foreach ( array_keys ($indexes) as $index )
{
ksort ($indexes[$index]['columns']);
ksort ($indexes[$index]['columns']);
}
return $indexes;
}
// Format date column in sql string given an input format that understands Y M D
function SQLDate($fmt, $col=false)
{
{
if (!$col) $col = $this->sysTimeStamp;
$s = 'DATE_FORMAT('.$col.",'";
$concat = false;
@@ -378,7 +402,7 @@ class ADODB_mysqli extends ADOConnection {
case 'Q':
case 'q':
$s .= "'),Quarter($col)";
if ($len > $i+1) $s .= ",DATE_FORMAT($col,'";
else $s .= ",('";
$concat = true;
@@ -386,7 +410,7 @@ class ADODB_mysqli extends ADOConnection {
case 'M':
$s .= '%b';
break;
case 'm':
$s .= '%m';
break;
@@ -394,38 +418,38 @@ class ADODB_mysqli extends ADOConnection {
case 'd':
$s .= '%d';
break;
case 'H':
case 'H':
$s .= '%H';
break;
case 'h':
$s .= '%I';
break;
case 'i':
$s .= '%i';
break;
case 's':
$s .= '%s';
break;
case 'a':
case 'A':
$s .= '%p';
break;
case 'w':
$s .= '%w';
break;
case 'l':
$s .= '%W';
break;
default:
if ($ch == '\\') {
$i++;
$ch = substr($fmt,$i,1);
@@ -438,100 +462,168 @@ class ADODB_mysqli extends ADOConnection {
if ($concat) $s = "CONCAT($s)";
return $s;
}
// returns concatenated string
// much easier to run "mysqld --ansi" or "mysqld --sql-mode=PIPES_AS_CONCAT" and use || operator
function Concat()
{
$s = "";
$arr = func_get_args();
// suggestion by andrew005@mnogo.ru
$s = implode(',',$arr);
$s = implode(',',$arr);
if (strlen($s) > 0) return "CONCAT($s)";
else return '';
}
// dayFraction is a day in floating point
function OffsetDate($dayFraction,$date=false)
{
{
if (!$date) $date = $this->sysDate;
$fraction = $dayFraction * 24 * 3600;
return $date . ' + INTERVAL ' . $fraction.' SECOND';
// return "from_unixtime(unix_timestamp($date)+$fraction)";
}
function MetaTables($ttype=false,$showSchema=false,$mask=false)
{
function MetaProcedures($NamePattern = false, $catalog = null, $schemaPattern = null)
{
// save old fetch mode
global $ADODB_FETCH_MODE;
$false = false;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== FALSE) {
$savem = $this->SetFetchMode(FALSE);
}
$procedures = array ();
// get index details
$likepattern = '';
if ($NamePattern) {
$likepattern = " LIKE '".$NamePattern."'";
}
$rs = $this->Execute('SHOW PROCEDURE STATUS'.$likepattern);
if (is_object($rs)) {
// parse index data into array
while ($row = $rs->FetchRow()) {
$procedures[$row[1]] = array(
'type' => 'PROCEDURE',
'catalog' => '',
'schema' => '',
'remarks' => $row[7],
);
}
}
$rs = $this->Execute('SHOW FUNCTION STATUS'.$likepattern);
if (is_object($rs)) {
// parse index data into array
while ($row = $rs->FetchRow()) {
$procedures[$row[1]] = array(
'type' => 'FUNCTION',
'catalog' => '',
'schema' => '',
'remarks' => $row[7]
);
}
}
// restore fetchmode
if (isset($savem)) {
$this->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
return $procedures;
}
/**
* Retrieves a list of tables based on given criteria
*
* @param string $ttype Table type = 'TABLE', 'VIEW' or false=both (default)
* @param string $showSchema schema name, false = current schema (default)
* @param string $mask filters the table by name
*
* @return array list of tables
*/
function MetaTables($ttype=false,$showSchema=false,$mask=false)
{
$save = $this->metaTablesSQL;
if ($showSchema && is_string($showSchema)) {
$this->metaTablesSQL .= " from $showSchema";
$this->metaTablesSQL .= $this->qstr($showSchema);
} else {
$this->metaTablesSQL .= "schema()";
}
if ($mask) {
$mask = $this->qstr($mask);
$this->metaTablesSQL .= " like $mask";
$this->metaTablesSQL .= " AND table_name LIKE $mask";
}
$ret = ADOConnection::MetaTables($ttype,$showSchema);
$this->metaTablesSQL = $save;
return $ret;
}
// "Innox - Juan Carlos Gonzalez" <jgonzalez#innox.com.mx>
function MetaForeignKeys( $table, $owner = FALSE, $upper = FALSE, $associative = FALSE )
{
global $ADODB_FETCH_MODE;
if ($ADODB_FETCH_MODE == ADODB_FETCH_ASSOC || $this->fetchMode == ADODB_FETCH_ASSOC) $associative = true;
if ( !empty($owner) ) {
$table = "$owner.$table";
}
$a_create_table = $this->getRow(sprintf('SHOW CREATE TABLE %s', $table));
if ( !empty($owner) ) {
$table = "$owner.$table";
}
$a_create_table = $this->getRow(sprintf('SHOW CREATE TABLE %s', $table));
if ($associative) {
$create_sql = isset($a_create_table["Create Table"]) ? $a_create_table["Create Table"] : $a_create_table["Create View"];
} else $create_sql = $a_create_table[1];
$matches = array();
if (!preg_match_all("/FOREIGN KEY \(`(.*?)`\) REFERENCES `(.*?)` \(`(.*?)`\)/", $create_sql, $matches)) return false;
$foreign_keys = array();
$num_keys = count($matches[0]);
for ( $i = 0; $i < $num_keys; $i ++ ) {
$my_field = explode('`, `', $matches[1][$i]);
$ref_table = $matches[2][$i];
$ref_field = explode('`, `', $matches[3][$i]);
if ( $upper ) {
$ref_table = strtoupper($ref_table);
}
// see https://sourceforge.net/tracker/index.php?func=detail&aid=2287278&group_id=42718&atid=433976
} else $create_sql = $a_create_table[1];
$matches = array();
if (!preg_match_all("/FOREIGN KEY \(`(.*?)`\) REFERENCES `(.*?)` \(`(.*?)`\)/", $create_sql, $matches)) return false;
$foreign_keys = array();
$num_keys = count($matches[0]);
for ( $i = 0; $i < $num_keys; $i ++ ) {
$my_field = explode('`, `', $matches[1][$i]);
$ref_table = $matches[2][$i];
$ref_field = explode('`, `', $matches[3][$i]);
if ( $upper ) {
$ref_table = strtoupper($ref_table);
}
// see https://sourceforge.net/tracker/index.php?func=detail&aid=2287278&group_id=42718&atid=433976
if (!isset($foreign_keys[$ref_table])) {
$foreign_keys[$ref_table] = array();
}
$num_fields = count($my_field);
for ( $j = 0; $j < $num_fields; $j ++ ) {
if ( $associative ) {
$foreign_keys[$ref_table][$ref_field[$j]] = $my_field[$j];
} else {
$foreign_keys[$ref_table][] = "{$my_field[$j]}={$ref_field[$j]}";
}
}
}
return $foreign_keys;
$num_fields = count($my_field);
for ( $j = 0; $j < $num_fields; $j ++ ) {
if ( $associative ) {
$foreign_keys[$ref_table][$ref_field[$j]] = $my_field[$j];
} else {
$foreign_keys[$ref_table][] = "{$my_field[$j]}={$ref_field[$j]}";
}
}
}
return $foreign_keys;
}
function MetaColumns($table, $normalize=true)
function MetaColumns($table, $normalize=true)
{
$false = false;
if (!$this->metaColumnsSQL)
return $false;
global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
@@ -542,13 +634,13 @@ class ADODB_mysqli extends ADOConnection {
$ADODB_FETCH_MODE = $save;
if (!is_object($rs))
return $false;
$retarr = array();
while (!$rs->EOF) {
$fld = new ADOFieldObject();
$fld->name = $rs->fields[0];
$type = $rs->fields[1];
// split type into type(length):
$fld->scale = null;
if (preg_match("/^(.+)\((\d+),(\d+)/", $type, $query_array)) {
@@ -584,7 +676,7 @@ class ADODB_mysqli extends ADOConnection {
$fld->has_default = false;
}
}
if ($save == ADODB_FETCH_NUM) {
$retarr[] = $fld;
} else {
@@ -592,47 +684,47 @@ class ADODB_mysqli extends ADOConnection {
}
$rs->MoveNext();
}
$rs->Close();
return $retarr;
}
// returns true or false
function SelectDB($dbName)
function SelectDB($dbName)
{
// $this->_connectionID = $this->mysqli_resolve_link($this->_connectionID);
$this->database = $dbName;
// $this->_connectionID = $this->mysqli_resolve_link($this->_connectionID);
$this->database = $dbName;
$this->databaseName = $dbName; # obsolete, retained for compat with older adodb versions
if ($this->_connectionID) {
$result = @mysqli_select_db($this->_connectionID, $dbName);
if ($this->_connectionID) {
$result = @mysqli_select_db($this->_connectionID, $dbName);
if (!$result) {
ADOConnection::outp("Select of database " . $dbName . " failed. " . $this->ErrorMsg());
ADOConnection::outp("Select of database " . $dbName . " failed. " . $this->ErrorMsg());
}
return $result;
return $result;
}
return false;
return false;
}
// parameters use PostgreSQL convention, not MySQL
function SelectLimit($sql,
$nrows = -1,
$offset = -1,
$inputarr = false,
$secs = 0)
$nrows = -1,
$offset = -1,
$inputarr = false,
$secs = 0)
{
$offsetStr = ($offset >= 0) ? "$offset," : '';
if ($nrows < 0) $nrows = '18446744073709551615';
if ($secs)
$rs = $this->CacheExecute($secs, $sql . " LIMIT $offsetStr$nrows" , $inputarr );
else
$rs = $this->Execute($sql . " LIMIT $offsetStr$nrows" , $inputarr );
return $rs;
}
function Prepare($sql)
{
return $sql;
@@ -643,8 +735,8 @@ class ADODB_mysqli extends ADOConnection {
}
return array($sql,$stmt);
}
// returns queryID or false
function _query($sql, $inputarr)
{
@@ -655,173 +747,176 @@ class ADODB_mysqli extends ADOConnection {
// return value of the stored proc (ie the number of rows affected).
// Commented out for reasons of performance. You should retrieve every recordset yourself.
// if (!mysqli_next_result($this->connection->_connectionID)) return false;
if (is_array($sql)) {
// Prepare() not supported because mysqli_stmt_execute does not return a recordset, but
// returns as bound variables.
$stmt = $sql[1];
$a = '';
foreach($inputarr as $k => $v) {
if (is_string($v)) $a .= 's';
else if (is_integer($v)) $a .= 'i';
else if (is_integer($v)) $a .= 'i';
else $a .= 'd';
}
$fnarr = array_merge( array($stmt,$a) , $inputarr);
$ret = call_user_func_array('mysqli_stmt_bind_param',$fnarr);
$ret = mysqli_stmt_execute($stmt);
return $ret;
}
/*
if (!$mysql_res = mysqli_query($this->_connectionID, $sql, ($ADODB_COUNTRECS) ? MYSQLI_STORE_RESULT : MYSQLI_USE_RESULT)) {
if ($this->debug) ADOConnection::outp("Query: " . $sql . " failed. " . $this->ErrorMsg());
return false;
}
return $mysql_res;
*/
if( $rs = mysqli_multi_query($this->_connectionID, $sql.';') )//Contributed by "Geisel Sierote" <geisel#4up.com.br>
{
$rs = ($ADODB_COUNTRECS) ? @mysqli_store_result( $this->_connectionID ) : @mysqli_use_result( $this->_connectionID );
return $rs ? $rs : true; // mysqli_more_results( $this->_connectionID )
} else {
if($this->debug)
ADOConnection::outp("Query: " . $sql . " failed. " . $this->ErrorMsg());
if ($this->debug) ADOConnection::outp("Query: " . $sql . " failed. " . $this->ErrorMsg());
return false;
}
return $mysql_res;
*/
if ($this->multiQuery) {
$rs = mysqli_multi_query($this->_connectionID, $sql.';');
if ($rs) {
$rs = ($ADODB_COUNTRECS) ? @mysqli_store_result( $this->_connectionID ) : @mysqli_use_result( $this->_connectionID );
return $rs ? $rs : true; // mysqli_more_results( $this->_connectionID )
}
} else {
$rs = mysqli_query($this->_connectionID, $sql, $ADODB_COUNTRECS ? MYSQLI_STORE_RESULT : MYSQLI_USE_RESULT);
if ($rs) return $rs;
}
if($this->debug)
ADOConnection::outp("Query: " . $sql . " failed. " . $this->ErrorMsg());
return false;
}
/* Returns: the last error message from previous database operation */
function ErrorMsg()
{
if (empty($this->_connectionID))
$this->_errorMsg = @mysqli_connect_error();
else
$this->_errorMsg = @mysqli_error($this->_connectionID);
return $this->_errorMsg;
}
/* Returns: the last error number from previous database operation */
function ErrorNo()
{
if (empty($this->_connectionID))
return @mysqli_connect_errno();
else
return @mysqli_errno($this->_connectionID);
}
/* Returns: the last error message from previous database operation */
function ErrorMsg()
{
if (empty($this->_connectionID))
$this->_errorMsg = @mysqli_connect_error();
else
$this->_errorMsg = @mysqli_error($this->_connectionID);
return $this->_errorMsg;
}
/* Returns: the last error number from previous database operation */
function ErrorNo()
{
if (empty($this->_connectionID))
return @mysqli_connect_errno();
else
return @mysqli_errno($this->_connectionID);
}
// returns true or false
function _close()
{
@mysqli_close($this->_connectionID);
$this->_connectionID = false;
}
{
@mysqli_close($this->_connectionID);
$this->_connectionID = false;
}
/*
* Maximum size of C field
*/
function CharMax()
{
return 255;
return 255;
}
/*
* Maximum size of X field
*/
function TextMax()
{
return 4294967295;
return 4294967295;
}
// this is a set of functions for managing client encoding - very important if the encodings
// of your database and your output target (i.e. HTML) don't match
// for instance, you may have UTF8 database and server it on-site as latin1 etc.
// GetCharSet - get the name of the character set the client is using now
// Under Windows, the functions should work with MySQL 4.1.11 and above, the set of charsets supported
// depends on compile flags of mysql distribution
// depends on compile flags of mysql distribution
function GetCharSet()
{
//we will use ADO's builtin property charSet
if (!method_exists($this->_connectionID,'character_set_name'))
return false;
$this->charSet = @$this->_connectionID->character_set_name();
if (!$this->charSet) {
return false;
} else {
return $this->charSet;
}
}
// SetCharSet - switch the client encoding
function SetCharSet($charset_name)
{
if (!method_exists($this->_connectionID,'set_charset'))
return false;
if ($this->charSet !== $charset_name) {
$if = @$this->_connectionID->set_charset($charset_name);
if ($if == "0" & $this->GetCharSet() == $charset_name) {
return true;
} else return false;
} else return true;
}
function GetCharSet()
{
//we will use ADO's builtin property charSet
if (!method_exists($this->_connectionID,'character_set_name'))
return false;
$this->charSet = @$this->_connectionID->character_set_name();
if (!$this->charSet) {
return false;
} else {
return $this->charSet;
}
}
// SetCharSet - switch the client encoding
function SetCharSet($charset_name)
{
if (!method_exists($this->_connectionID,'set_charset')) {
return false;
}
if ($this->charSet !== $charset_name) {
$if = @$this->_connectionID->set_charset($charset_name);
return ($if === true & $this->GetCharSet() == $charset_name);
} else {
return true;
}
}
}
/*--------------------------------------------------------------------------------------
Class Name: Recordset
--------------------------------------------------------------------------------------*/
class ADORecordSet_mysqli extends ADORecordSet{
class ADORecordSet_mysqli extends ADORecordSet{
var $databaseType = "mysqli";
var $canSeek = true;
function ADORecordSet_mysqli($queryID, $mode = 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 = MYSQLI_NUM;
break;
case ADODB_FETCH_ASSOC:
$this->fetchMode = MYSQLI_ASSOC;
break;
case ADODB_FETCH_DEFAULT:
case ADODB_FETCH_BOTH:
default:
$this->fetchMode = MYSQLI_BOTH;
break;
}
$this->adodbFetchMode = $mode;
$this->ADORecordSet($queryID);
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
switch ($mode) {
case ADODB_FETCH_NUM:
$this->fetchMode = MYSQLI_NUM;
break;
case ADODB_FETCH_ASSOC:
$this->fetchMode = MYSQLI_ASSOC;
break;
case ADODB_FETCH_DEFAULT:
case ADODB_FETCH_BOTH:
default:
$this->fetchMode = MYSQLI_BOTH;
break;
}
$this->adodbFetchMode = $mode;
parent::__construct($queryID);
}
function _initrs()
{
global $ADODB_COUNTRECS;
$this->_numOfRows = $ADODB_COUNTRECS ? @mysqli_num_rows($this->_queryID) : -1;
$this->_numOfFields = @mysqli_num_fields($this->_queryID);
}
/*
1 = MYSQLI_NOT_NULL_FLAG
2 = MYSQLI_PRI_KEY_FLAG
@@ -842,14 +937,19 @@ class ADORecordSet_mysqli extends ADORecordSet{
131072 = MYSQLI_BINCMP_FLAG
*/
function FetchField($fieldOffset = -1)
{
function FetchField($fieldOffset = -1)
{
$fieldnr = $fieldOffset;
if ($fieldOffset != -1) {
$fieldOffset = @mysqli_field_seek($this->_queryID, $fieldnr);
$fieldOffset = @mysqli_field_seek($this->_queryID, $fieldnr);
}
$o = @mysqli_fetch_field($this->_queryID);
if (!$o) return false;
//Fix for HHVM
if ( !isset($o->flags) ) {
$o->flags = 0;
}
/* Properties of an ADOFieldObject as set by MetaColumns */
$o->primary_key = $o->flags & MYSQLI_PRI_KEY_FLAG;
$o->not_null = $o->flags & MYSQLI_NOT_NULL_FLAG;
@@ -861,48 +961,48 @@ class ADORecordSet_mysqli extends ADORecordSet{
return $o;
}
function GetRowAssoc($upper = true)
function GetRowAssoc($upper = ADODB_ASSOC_CASE)
{
if ($this->fetchMode == MYSQLI_ASSOC && !$upper)
return $this->fields;
if ($this->fetchMode == MYSQLI_ASSOC && $upper == ADODB_ASSOC_CASE_LOWER) {
return $this->fields;
}
$row = ADORecordSet::GetRowAssoc($upper);
return $row;
}
/* Use associative array to get fields array */
function Fields($colname)
{
if ($this->fetchMode != MYSQLI_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)]];
{
if ($this->fetchMode != MYSQLI_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)
{
if ($this->_numOfRows == 0)
return false;
if ($this->_numOfRows == 0 || $row < 0) {
return false;
}
if ($row < 0)
return false;
mysqli_data_seek($this->_queryID, $row);
$this->EOF = false;
return true;
mysqli_data_seek($this->_queryID, $row);
$this->EOF = false;
return true;
}
function NextRecordSet()
{
global $ADODB_COUNTRECS;
mysqli_free_result($this->_queryID);
$this->_queryID = -1;
// Move to the next recordset, or return false if there is none. In a stored proc
@@ -928,29 +1028,44 @@ class ADORecordSet_mysqli extends ADORecordSet{
// 10% speedup to move MoveNext to child class
// This is the only implementation that works now (23-10-2003).
// Other functions return no or the wrong results.
function MoveNext()
function MoveNext()
{
if ($this->EOF) return false;
$this->_currentRow++;
$this->fields = @mysqli_fetch_array($this->_queryID,$this->fetchMode);
if (is_array($this->fields)) return true;
if (is_array($this->fields)) {
$this->_updatefields();
return true;
}
$this->EOF = true;
return false;
}
}
function _fetch()
{
$this->fields = mysqli_fetch_array($this->_queryID,$this->fetchMode);
return is_array($this->fields);
$this->fields = mysqli_fetch_array($this->_queryID,$this->fetchMode);
$this->_updatefields();
return is_array($this->fields);
}
function _close()
function _close()
{
mysqli_free_result($this->_queryID);
$this->_queryID = false;
//if results are attached to this pointer from Stored Proceedure calls, the next standard query will die 2014
//only a problem with persistant connections
if(isset($this->connection->_connectionID) && $this->connection->_connectionID) {
while(mysqli_more_results($this->connection->_connectionID)){
mysqli_next_result($this->connection->_connectionID);
}
}
if($this->_queryID instanceof mysqli_result) {
mysqli_free_result($this->_queryID);
}
$this->_queryID = false;
}
/*
0 = MYSQLI_TYPE_DECIMAL
@@ -983,205 +1098,196 @@ class ADORecordSet_mysqli extends ADORecordSet{
function MetaType($t, $len = -1, $fieldobj = false)
{
if (is_object($t)) {
$fieldobj = $t;
$t = $fieldobj->type;
$len = $fieldobj->max_length;
$fieldobj = $t;
$t = $fieldobj->type;
$len = $fieldobj->max_length;
}
$len = -1; // mysql max_length is not accurate
switch (strtoupper($t)) {
case 'STRING':
case 'CHAR':
case 'VARCHAR':
case 'TINYBLOB':
case 'TINYTEXT':
case 'ENUM':
case 'SET':
$len = -1; // mysql max_length is not accurate
switch (strtoupper($t)) {
case 'STRING':
case 'CHAR':
case 'VARCHAR':
case 'TINYBLOB':
case 'TINYTEXT':
case 'ENUM':
case 'SET':
case MYSQLI_TYPE_TINY_BLOB :
#case MYSQLI_TYPE_CHAR :
case MYSQLI_TYPE_STRING :
case MYSQLI_TYPE_ENUM :
case MYSQLI_TYPE_SET :
case 253 :
if ($len <= $this->blobSize) return 'C';
if ($len <= $this->blobSize) return 'C';
case 'TEXT':
case 'LONGTEXT':
case 'LONGTEXT':
case 'MEDIUMTEXT':
return 'X';
// php_mysql extension always returns 'blob' even if 'text'
// so we have to check whether binary...
return 'X';
// php_mysql extension always returns 'blob' even if 'text'
// so we have to check whether binary...
case 'IMAGE':
case 'LONGBLOB':
case 'LONGBLOB':
case 'BLOB':
case 'MEDIUMBLOB':
case MYSQLI_TYPE_BLOB :
case MYSQLI_TYPE_LONG_BLOB :
case MYSQLI_TYPE_MEDIUM_BLOB :
return !empty($fieldobj->binary) ? 'B' : 'X';
return !empty($fieldobj->binary) ? 'B' : 'X';
case 'YEAR':
case 'DATE':
case 'DATE':
case MYSQLI_TYPE_DATE :
case MYSQLI_TYPE_YEAR :
return 'D';
return 'D';
case 'TIME':
case 'DATETIME':
case 'TIMESTAMP':
case MYSQLI_TYPE_DATETIME :
case MYSQLI_TYPE_NEWDATE :
case MYSQLI_TYPE_TIME :
case MYSQLI_TYPE_TIMESTAMP :
return 'T';
case 'INT':
case 'INT':
case 'INTEGER':
case 'BIGINT':
case 'TINYINT':
case 'MEDIUMINT':
case 'SMALLINT':
case 'SMALLINT':
case MYSQLI_TYPE_INT24 :
case MYSQLI_TYPE_LONG :
case MYSQLI_TYPE_LONGLONG :
case MYSQLI_TYPE_SHORT :
case MYSQLI_TYPE_TINY :
if (!empty($fieldobj->primary_key)) return 'R';
return 'I';
// Added floating-point types
// Maybe not necessery.
case 'FLOAT':
case 'DOUBLE':
// case 'DOUBLE PRECISION':
case 'DECIMAL':
case 'DEC':
case 'FIXED':
default:
//if (!is_numeric($t)) echo "<p>--- Error in type matching $t -----</p>";
return 'N';
if (!empty($fieldobj->primary_key)) return 'R';
return 'I';
// Added floating-point types
// Maybe not necessery.
case 'FLOAT':
case 'DOUBLE':
// case 'DOUBLE PRECISION':
case 'DECIMAL':
case 'DEC':
case 'FIXED':
default:
//if (!is_numeric($t)) echo "<p>--- Error in type matching $t -----</p>";
return 'N';
}
} // function
} // rs class
}
class ADORecordSet_array_mysqli extends ADORecordSet_array {
function ADORecordSet_array_mysqli($id=-1,$mode=false)
{
$this->ADORecordSet_array($id,$mode);
}
function __construct($id=-1,$mode=false)
{
parent::__construct($id,$mode);
}
function MetaType($t, $len = -1, $fieldobj = false)
{
if (is_object($t)) {
$fieldobj = $t;
$t = $fieldobj->type;
$len = $fieldobj->max_length;
$fieldobj = $t;
$t = $fieldobj->type;
$len = $fieldobj->max_length;
}
$len = -1; // mysql max_length is not accurate
switch (strtoupper($t)) {
case 'STRING':
case 'CHAR':
case 'VARCHAR':
case 'TINYBLOB':
case 'TINYTEXT':
case 'ENUM':
case 'SET':
$len = -1; // mysql max_length is not accurate
switch (strtoupper($t)) {
case 'STRING':
case 'CHAR':
case 'VARCHAR':
case 'TINYBLOB':
case 'TINYTEXT':
case 'ENUM':
case 'SET':
case MYSQLI_TYPE_TINY_BLOB :
#case MYSQLI_TYPE_CHAR :
case MYSQLI_TYPE_STRING :
case MYSQLI_TYPE_ENUM :
case MYSQLI_TYPE_SET :
case 253 :
if ($len <= $this->blobSize) return 'C';
if ($len <= $this->blobSize) return 'C';
case 'TEXT':
case 'LONGTEXT':
case 'LONGTEXT':
case 'MEDIUMTEXT':
return 'X';
// php_mysql extension always returns 'blob' even if 'text'
// so we have to check whether binary...
return 'X';
// php_mysql extension always returns 'blob' even if 'text'
// so we have to check whether binary...
case 'IMAGE':
case 'LONGBLOB':
case 'LONGBLOB':
case 'BLOB':
case 'MEDIUMBLOB':
case MYSQLI_TYPE_BLOB :
case MYSQLI_TYPE_LONG_BLOB :
case MYSQLI_TYPE_MEDIUM_BLOB :
return !empty($fieldobj->binary) ? 'B' : 'X';
return !empty($fieldobj->binary) ? 'B' : 'X';
case 'YEAR':
case 'DATE':
case 'DATE':
case MYSQLI_TYPE_DATE :
case MYSQLI_TYPE_YEAR :
return 'D';
return 'D';
case 'TIME':
case 'DATETIME':
case 'TIMESTAMP':
case MYSQLI_TYPE_DATETIME :
case MYSQLI_TYPE_NEWDATE :
case MYSQLI_TYPE_TIME :
case MYSQLI_TYPE_TIMESTAMP :
return 'T';
case 'INT':
case 'INT':
case 'INTEGER':
case 'BIGINT':
case 'TINYINT':
case 'MEDIUMINT':
case 'SMALLINT':
case 'SMALLINT':
case MYSQLI_TYPE_INT24 :
case MYSQLI_TYPE_LONG :
case MYSQLI_TYPE_LONGLONG :
case MYSQLI_TYPE_SHORT :
case MYSQLI_TYPE_TINY :
if (!empty($fieldobj->primary_key)) return 'R';
return 'I';
// Added floating-point types
// Maybe not necessery.
case 'FLOAT':
case 'DOUBLE':
// case 'DOUBLE PRECISION':
case 'DECIMAL':
case 'DEC':
case 'FIXED':
default:
//if (!is_numeric($t)) echo "<p>--- Error in type matching $t -----</p>";
return 'N';
if (!empty($fieldobj->primary_key)) return 'R';
return 'I';
// Added floating-point types
// Maybe not necessery.
case 'FLOAT':
case 'DOUBLE':
// case 'DOUBLE PRECISION':
case 'DECIMAL':
case 'DEC':
case 'FIXED':
default:
//if (!is_numeric($t)) echo "<p>--- Error in type matching $t -----</p>";
return 'N';
}
} // function
}
?>
}
+40 -50
View File
@@ -1,15 +1,22 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
@version v5.20.9 21-Dec-2016
@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.
Set tabs to 8.
MySQL code that supports transactions. For MySQL 3.23 or later.
Code from James Poon <jpoon88@yahoo.com>
This driver extends the deprecated mysql driver, and was originally designed to be a
portable driver in the same manner as oci8po and mssqlpo. Its functionality
is exactly duplicated in the mysqlt driver, which is itself deprecated.
This driver will be removed in ADOdb version 6.0.0.
Requires mysql client. Works on Windows and Unix.
*/
@@ -23,33 +30,33 @@ class ADODB_mysqlt extends ADODB_mysql {
var $databaseType = 'mysqlt';
var $ansiOuter = true; // for Version 3.23.17 or later
var $hasTransactions = true;
var $autoRollback = true; // apparently mysql does not autorollback properly
function ADODB_mysqlt()
{
var $autoRollback = true; // apparently mysql does not autorollback properly
function __construct()
{
global $ADODB_EXTENSION; if ($ADODB_EXTENSION) $this->rsPrefix .= 'ext_';
}
function BeginTrans()
{
{
if ($this->transOff) return true;
$this->transCnt += 1;
$this->Execute('SET AUTOCOMMIT=0');
$this->Execute('BEGIN');
return true;
}
function CommitTrans($ok=true)
function CommitTrans($ok=true)
{
if ($this->transOff) return true;
if ($this->transOff) return true;
if (!$ok) return $this->RollbackTrans();
if ($this->transCnt) $this->transCnt -= 1;
$this->Execute('COMMIT');
$this->Execute('SET AUTOCOMMIT=1');
return true;
}
function RollbackTrans()
{
if ($this->transOff) return true;
@@ -58,41 +65,41 @@ class ADODB_mysqlt extends ADODB_mysql {
$this->Execute('SET AUTOCOMMIT=1');
return true;
}
function RowLock($tables,$where='',$flds='1 as adodb_ignore')
function RowLock($tables,$where='',$col='1 as adodbignore')
{
if ($this->transCnt==0) $this->BeginTrans();
if ($where) $where = ' where '.$where;
$rs = $this->Execute("select $flds from $tables $where for update");
return !empty($rs);
$rs = $this->Execute("select $col from $tables $where for update");
return !empty($rs);
}
}
class ADORecordSet_mysqlt extends ADORecordSet_mysql{
class ADORecordSet_mysqlt extends ADORecordSet_mysql{
var $databaseType = "mysqlt";
function ADORecordSet_mysqlt($queryID,$mode=false)
function __construct($queryID,$mode=false)
{
if ($mode === false) {
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
switch ($mode)
{
case ADODB_FETCH_NUM: $this->fetchMode = MYSQL_NUM; break;
case ADODB_FETCH_ASSOC:$this->fetchMode = MYSQL_ASSOC; break;
case ADODB_FETCH_DEFAULT:
case ADODB_FETCH_BOTH:
default: $this->fetchMode = MYSQL_BOTH; break;
}
$this->adodbFetchMode = $mode;
$this->ADORecordSet($queryID);
parent::__construct($queryID);
}
function MoveNext()
{
if (@$this->fields = mysql_fetch_array($this->_queryID,$this->fetchMode)) {
@@ -107,32 +114,15 @@ class ADORecordSet_mysqlt extends ADORecordSet_mysql{
}
}
class ADORecordSet_ext_mysqlt extends ADORecordSet_mysqlt {
class ADORecordSet_ext_mysqlt extends ADORecordSet_mysqlt {
function ADORecordSet_ext_mysqlt($queryID,$mode=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 = MYSQL_NUM; break;
case ADODB_FETCH_ASSOC:$this->fetchMode = MYSQL_ASSOC; break;
case ADODB_FETCH_DEFAULT:
case ADODB_FETCH_BOTH:
default:
$this->fetchMode = MYSQL_BOTH; break;
}
$this->adodbFetchMode = $mode;
$this->ADORecordSet($queryID);
parent::__construct($queryID,$mode);
}
function MoveNext()
{
return adodb_movenext($this);
}
}
?>
+40 -58
View File
@@ -1,15 +1,19 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
@version v5.20.9 21-Dec-2016
@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.
Set tabs to 8.
MySQL code that supports transactions. For MySQL 3.23 or later.
Code from James Poon <jpoon88@yahoo.com>
This driver only supports the original MySQL driver in transactional mode. It
is deprected in PHP version 5.5 and removed in PHP version 7. It is deprecated
as of ADOdb version 5.20.0. Use the mysqli driver instead, which supports both
transactional and non-transactional updates
Requires mysql client. Works on Windows and Unix.
*/
@@ -23,20 +27,20 @@ class ADODB_mysqlt extends ADODB_mysql {
var $databaseType = 'mysqlt';
var $ansiOuter = true; // for Version 3.23.17 or later
var $hasTransactions = true;
var $autoRollback = true; // apparently mysql does not autorollback properly
function ADODB_mysqlt()
{
var $autoRollback = true; // apparently mysql does not autorollback properly
function __construct()
{
global $ADODB_EXTENSION; if ($ADODB_EXTENSION) $this->rsPrefix .= 'ext_';
}
/* set transaction mode
SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL
{ READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE }
*/
function SetTransactionMode( $transaction_mode )
function SetTransactionMode( $transaction_mode )
{
$this->_transmode = $transaction_mode;
if (empty($transaction_mode)) {
@@ -46,27 +50,27 @@ class ADODB_mysqlt extends ADODB_mysql {
if (!stristr($transaction_mode,'isolation')) $transaction_mode = 'ISOLATION LEVEL '.$transaction_mode;
$this->Execute("SET SESSION TRANSACTION ".$transaction_mode);
}
function BeginTrans()
{
{
if ($this->transOff) return true;
$this->transCnt += 1;
$this->Execute('SET AUTOCOMMIT=0');
$this->Execute('BEGIN');
return true;
}
function CommitTrans($ok=true)
function CommitTrans($ok=true)
{
if ($this->transOff) return true;
if ($this->transOff) return true;
if (!$ok) return $this->RollbackTrans();
if ($this->transCnt) $this->transCnt -= 1;
$ok = $this->Execute('COMMIT');
$this->Execute('SET AUTOCOMMIT=1');
return $ok ? true : false;
}
function RollbackTrans()
{
if ($this->transOff) return true;
@@ -75,41 +79,41 @@ class ADODB_mysqlt extends ADODB_mysql {
$this->Execute('SET AUTOCOMMIT=1');
return $ok ? true : false;
}
function RowLock($tables,$where='',$flds='1 as adodb_ignore')
function RowLock($tables,$where='',$col='1 as adodbignore')
{
if ($this->transCnt==0) $this->BeginTrans();
if ($where) $where = ' where '.$where;
$rs = $this->Execute("select $flds from $tables $where for update");
return !empty($rs);
$rs = $this->Execute("select $col from $tables $where for update");
return !empty($rs);
}
}
class ADORecordSet_mysqlt extends ADORecordSet_mysql{
class ADORecordSet_mysqlt extends ADORecordSet_mysql{
var $databaseType = "mysqlt";
function ADORecordSet_mysqlt($queryID,$mode=false)
function __construct($queryID,$mode=false)
{
if ($mode === false) {
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
switch ($mode)
{
case ADODB_FETCH_NUM: $this->fetchMode = MYSQL_NUM; break;
case ADODB_FETCH_ASSOC:$this->fetchMode = MYSQL_ASSOC; break;
case ADODB_FETCH_DEFAULT:
case ADODB_FETCH_BOTH:
default: $this->fetchMode = MYSQL_BOTH; break;
}
$this->adodbFetchMode = $mode;
$this->ADORecordSet($queryID);
parent::__construct($queryID);
}
function MoveNext()
{
if (@$this->fields = mysql_fetch_array($this->_queryID,$this->fetchMode)) {
@@ -124,32 +128,10 @@ class ADORecordSet_mysqlt extends ADORecordSet_mysql{
}
}
class ADORecordSet_ext_mysqlt extends ADORecordSet_mysqlt {
class ADORecordSet_ext_mysqlt extends ADORecordSet_mysqlt {
function ADORecordSet_ext_mysqlt($queryID,$mode=false)
{
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
switch ($mode)
{
case ADODB_FETCH_NUM: $this->fetchMode = MYSQL_NUM; break;
case ADODB_FETCH_ASSOC:$this->fetchMode = MYSQL_ASSOC; break;
case ADODB_FETCH_DEFAULT:
case ADODB_FETCH_BOTH:
default:
$this->fetchMode = MYSQL_BOTH; break;
}
$this->adodbFetchMode = $mode;
$this->ADORecordSet($queryID);
}
function MoveNext()
{
return adodb_movenext($this);
}
}
?>
+36 -49
View File
@@ -1,7 +1,9 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved.
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
First cut at the Netezza Driver by Josh Eldridge joshuae74#hotmail.com
Based on the previous postgres drivers.
http://www.netezza.com/
@@ -20,7 +22,7 @@ if (!defined('ADODB_DIR')) die();
include_once(ADODB_DIR.'/drivers/adodb-postgres64.inc.php');
class ADODB_netezza extends ADODB_postgres64 {
var $databaseType = 'netezza';
var $databaseType = 'netezza';
var $dataProvider = 'netezza';
var $hasInsertID = false;
var $_resultid = false;
@@ -34,11 +36,11 @@ class ADODB_netezza extends ADODB_postgres64 {
var $blobEncodeType = 'C';
var $metaColumnsSQL = "SELECT attname, atttype FROM _v_relation_column_def WHERE name = '%s' AND attnum > 0 ORDER BY attnum";
var $metaColumnsSQL1 = "SELECT attname, atttype FROM _v_relation_column_def WHERE name = '%s' AND attnum > 0 ORDER BY attnum";
// netezza doesn't have keys. it does have distributions, so maybe this is
// netezza doesn't have keys. it does have distributions, so maybe this is
// something that can be pulled from the system tables
var $metaKeySQL = "";
var $hasAffectedRows = true;
var $hasLimit = true;
var $hasLimit = true;
var $true = 't'; // string that represents TRUE for a database
var $false = 'f'; // string that represents FALSE for a database
var $fmtDate = "'Y-m-d'"; // used by DBDate() as the default date format used by the database
@@ -47,52 +49,52 @@ class ADODB_netezza extends ADODB_postgres64 {
var $autoRollback = true; // apparently pgsql does not autorollback properly before 4.3.4
// http://bugs.php.net/bug.php?id=25404
function ADODB_netezza()
function __construct()
{
}
function MetaColumns($table,$upper=true)
function MetaColumns($table,$upper=true)
{
// Changed this function to support Netezza which has no concept of keys
// could posisbly work on other things from the system table later.
global $ADODB_FETCH_MODE;
$table = strtolower($table);
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
$rs = $this->Execute(sprintf($this->metaColumnsSQL,$table,$table));
if (isset($savem)) $this->SetFetchMode($savem);
$ADODB_FETCH_MODE = $save;
if ($rs === false) return false;
$retarr = array();
while (!$rs->EOF) {
while (!$rs->EOF) {
$fld = new ADOFieldObject();
$fld->name = $rs->fields[0];
// since we're returning type and length as one string,
// since we're returning type and length as one string,
// split them out here.
if ($first = strstr($rs->fields[1], "(")) {
$fld->max_length = trim($first, "()");
} else {
$fld->max_length = -1;
}
if ($first = strpos($rs->fields[1], "(")) {
$fld->type = substr($rs->fields[1], 0, $first);
} else {
$fld->type = $rs->fields[1];
}
switch ($fld->type) {
case "byteint":
case "boolean":
@@ -116,20 +118,20 @@ class ADODB_netezza extends ADODB_postgres64 {
$fld->max_length = 12;
break;
}
if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;
if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;
else $retarr[($upper) ? strtoupper($fld->name) : $fld->name] = $fld;
$rs->MoveNext();
}
$rs->Close();
return $retarr;
return $retarr;
}
}
/*--------------------------------------------------------------------------------------
Class Name: Recordset
--------------------------------------------------------------------------------------*/
@@ -138,33 +140,18 @@ class ADORecordSet_netezza extends ADORecordSet_postgres64
{
var $databaseType = "netezza";
var $canSeek = true;
function ADORecordSet_netezza($queryID,$mode=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 = PGSQL_NUM; break;
case ADODB_FETCH_ASSOC:$this->fetchMode = PGSQL_ASSOC; break;
case ADODB_FETCH_DEFAULT:
case ADODB_FETCH_BOTH:
default: $this->fetchMode = PGSQL_BOTH; break;
}
$this->adodbFetchMode = $mode;
$this->ADORecordSet($queryID);
parent::__construct($queryID,$mode);
}
// _initrs modified to disable blob handling
function _initrs()
{
global $ADODB_COUNTRECS;
$this->_numOfRows = ($ADODB_COUNTRECS)? @pg_numrows($this->_queryID):-1;
$this->_numOfFields = @pg_numfields($this->_queryID);
$this->_numOfRows = ($ADODB_COUNTRECS)? @pg_num_rows($this->_queryID):-1;
$this->_numOfFields = @pg_num_fields($this->_queryID);
}
}
?>
+978 -776
View File
@@ -1,16 +1,18 @@
<?php
/*
version V5.06 16 Oct 2008 (c) 2000-2009 John Lim. All rights reserved.
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim. 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,
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
Code contributed by George Fourlanos <fou@infomap.gr>
13 Nov 2000 jlim - removed all ora_* references.
*/
@@ -30,26 +32,25 @@ For Oracle the default is dd-mon-yy or dd-mon-yyyy, and for SQL-92 the default i
yy-mm-dd or yyyy-mm-dd.
Using 'RR' in the format forces two-digit years less than or equal to 49 to be
interpreted as years in the 21st century (2000?049), and years over 50 as years in
the 20th century (1950?999). Setting the RR format as the default for all two-digit
interpreted as years in the 21st century (2000-2049), and years over 50 as years in
the 20th century (1950-1999). Setting the RR format as the default for all two-digit
year entries allows you to become year-2000 compliant. For example:
NLS_DATE_FORMAT='RR-MM-DD'
You can also modify the date format using the ALTER SESSION command.
You can also modify the date format using the ALTER SESSION command.
*/
# define the LOB descriptor type for the given type
# returns false if no LOB descriptor
function oci_lob_desc($type) {
switch ($type) {
case OCI_B_BFILE: $result = OCI_D_FILE; break;
case OCI_B_CFILEE: $result = OCI_D_FILE; break;
case OCI_B_CLOB: $result = OCI_D_LOB; break;
case OCI_B_BLOB: $result = OCI_D_LOB; break;
case OCI_B_ROWID: $result = OCI_D_ROWID; break;
default: $result = false; break;
case OCI_B_BFILE: return OCI_D_FILE;
case OCI_B_CFILEE: return OCI_D_FILE;
case OCI_B_CLOB: return OCI_D_LOB;
case OCI_B_BLOB: return OCI_D_LOB;
case OCI_B_ROWID: return OCI_D_ROWID;
}
return $result;
return false;
}
class ADODB_oci8 extends ADOConnection {
@@ -65,10 +66,22 @@ class ADODB_oci8 extends ADOConnection {
var $_initdate = true; // init date to YYYY-MM-DD
var $metaTablesSQL = "select table_name,table_type from cat where table_type in ('TABLE','VIEW') and table_name not like 'BIN\$%'"; // bin$ tables are recycle bin tables
var $metaColumnsSQL = "select cname,coltype,width, SCALE, PRECISION, NULLS, DEFAULTVAL from col where tname='%s' order by colno"; //changed by smondino@users.sourceforge. net
var $metaColumnsSQL2 = "select column_name,data_type,data_length, data_scale, data_precision,
case when nullable = 'Y' then 'NULL'
else 'NOT NULL' end as nulls,
data_default from all_tab_cols
where owner='%s' and table_name='%s' order by column_id"; // when there is a schema
var $_bindInputArray = true;
var $hasGenID = true;
var $_genIDSQL = "SELECT (%s.nextval) FROM DUAL";
var $_genSeqSQL = "CREATE SEQUENCE %s START WITH %s";
var $_genSeqSQL = "
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
execute immediate 'CREATE SEQUENCE %s START WITH %s';
END;
";
var $_dropSeqSQL = "DROP SEQUENCE %s";
var $hasAffectedRows = true;
var $random = "abs(mod(DBMS_RANDOM.RANDOM,10000001)/10000000)";
@@ -76,135 +89,152 @@ class ADODB_oci8 extends ADOConnection {
var $connectSID = false;
var $_bind = false;
var $_nestedSQL = true;
var $_hasOCIFetchStatement = false;
var $_hasOciFetchStatement = false;
var $_getarray = false; // currently not working
var $leftOuter = ''; // oracle wierdness, $col = $value (+) for LEFT OUTER, $col (+)= $value for RIGHT OUTER
var $session_sharing_force_blob = false; // alter session on updateblob if set to true
var $session_sharing_force_blob = false; // alter session on updateblob if set to true
var $firstrows = true; // enable first rows optimization on SelectLimit()
var $selectOffsetAlg1 = 1000; // when to use 1st algorithm of selectlimit.
var $NLS_DATE_FORMAT = 'YYYY-MM-DD'; // To include time, use 'RRRR-MM-DD HH24:MI:SS'
var $dateformat = 'YYYY-MM-DD'; // DBDate format
var $useDBDateFormatForTextInput=false;
var $useDBDateFormatForTextInput=false;
var $datetime = false; // MetaType('DATE') returns 'D' (datetime==false) or 'T' (datetime == true)
var $_refLOBs = array();
// var $ansiOuter = true; // if oracle9
function ADODB_oci8()
function __construct()
{
$this->_hasOCIFetchStatement = ADODB_PHPVER >= 0x4200;
if (defined('ADODB_EXTENSION')) $this->rsPrefix .= 'ext_';
$this->_hasOciFetchStatement = ADODB_PHPVER >= 0x4200;
if (defined('ADODB_EXTENSION')) {
$this->rsPrefix .= 'ext_';
}
}
/* function MetaColumns($table, $normalize=true) added by smondino@users.sourceforge.net*/
function MetaColumns($table, $normalize=true)
function MetaColumns($table, $normalize=true)
{
global $ADODB_FETCH_MODE;
$false = false;
$schema = '';
$this->_findschema($table, $schema);
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
$rs = $this->Execute(sprintf($this->metaColumnsSQL,strtoupper($table)));
if (isset($savem)) $this->SetFetchMode($savem);
if ($this->fetchMode !== false) {
$savem = $this->SetFetchMode(false);
}
if ($schema){
$rs = $this->Execute(sprintf($this->metaColumnsSQL2, strtoupper($schema), strtoupper($table)));
}
else {
$rs = $this->Execute(sprintf($this->metaColumnsSQL,strtoupper($table)));
}
if (isset($savem)) {
$this->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
if (!$rs) {
return $false;
return false;
}
$retarr = array();
while (!$rs->EOF) { //print_r($rs->fields);
while (!$rs->EOF) {
$fld = new ADOFieldObject();
$fld->name = $rs->fields[0];
$fld->type = $rs->fields[1];
$fld->max_length = $rs->fields[2];
$fld->name = $rs->fields[0];
$fld->type = $rs->fields[1];
$fld->max_length = $rs->fields[2];
$fld->scale = $rs->fields[3];
if ($rs->fields[1] == 'NUMBER') {
if ($rs->fields[3] == 0) $fld->type = 'INT';
$fld->max_length = $rs->fields[4];
}
$fld->not_null = (strncmp($rs->fields[5], 'NOT',3) === 0);
if ($rs->fields[3] == 0) {
$fld->type = 'INT';
}
$fld->max_length = $rs->fields[4];
}
$fld->not_null = (strncmp($rs->fields[5], 'NOT',3) === 0);
$fld->binary = (strpos($fld->type,'BLOB') !== false);
$fld->default_value = $rs->fields[6];
if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;
else $retarr[strtoupper($fld->name)] = $fld;
if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) {
$retarr[] = $fld;
}
else {
$retarr[strtoupper($fld->name)] = $fld;
}
$rs->MoveNext();
}
$rs->Close();
if (empty($retarr))
return $false;
else
return $retarr;
if (empty($retarr)) {
return false;
}
return $retarr;
}
function Time()
{
$rs = $this->Execute("select TO_CHAR($this->sysTimeStamp,'YYYY-MM-DD HH24:MI:SS') from dual");
if ($rs && !$rs->EOF) return $this->UnixTimeStamp(reset($rs->fields));
if ($rs && !$rs->EOF) {
return $this->UnixTimeStamp(reset($rs->fields));
}
return false;
}
/*
Multiple modes of connection are supported:
a. Local Database
$conn->Connect(false,'scott','tiger');
b. From tnsnames.ora
$conn->Connect(false,'scott','tiger',$tnsname);
$conn->Connect($tnsname,'scott','tiger');
c. Server + service name
$conn->Connect($serveraddress,'scott,'tiger',$service_name);
d. Server + SID
$conn->connectSID = true;
$conn->Connect($serveraddress,'scott,'tiger',$SID);
Example TNSName:
---------------
NATSOFT.DOMAIN =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = kermit)(PORT = 1523))
)
(CONNECT_DATA =
(SERVICE_NAME = natsoft.domain)
)
)
There are 3 connection modes, 0 = non-persistent, 1 = persistent, 2 = force new connection
*/
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename,$mode=0)
/**
* Multiple modes of connection are supported:
*
* a. Local Database
* $conn->Connect(false,'scott','tiger');
*
* b. From tnsnames.ora
* $conn->Connect($tnsname,'scott','tiger');
* $conn->Connect(false,'scott','tiger',$tnsname);
*
* c. Server + service name
* $conn->Connect($serveraddress,'scott,'tiger',$service_name);
*
* d. Server + SID
* $conn->connectSID = true;
* $conn->Connect($serveraddress,'scott,'tiger',$SID);
*
* @param string|false $argHostname DB server hostname or TNS name
* @param string $argUsername
* @param string $argPassword
* @param string $argDatabasename Service name, SID (defaults to null)
* @param int $mode Connection mode, defaults to 0
* (0 = non-persistent, 1 = persistent, 2 = force new connection)
*
* @return bool
*/
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename=null, $mode=0)
{
if (!function_exists('OCIPLogon')) return null;
#adodb_backtrace();
$this->_errorMsg = false;
if (!function_exists('oci_pconnect')) {
return null;
}
#adodb_backtrace();
$this->_errorMsg = false;
$this->_errorCode = false;
if($argHostname) { // added by Jorma Tuomainen <jorma.tuomainen@ppoy.fi>
if (empty($argDatabasename)) $argDatabasename = $argHostname;
if (empty($argDatabasename)) {
$argDatabasename = $argHostname;
}
else {
if(strpos($argHostname,":")) {
$argHostinfo=explode(":",$argHostname);
$argHostname=$argHostinfo[0];
$argHostname=$argHostinfo[0];
$argHostport=$argHostinfo[1];
} else {
} else {
$argHostport = empty($this->port)? "1521" : $this->port;
}
}
if (strncasecmp($argDatabasename,'SID=',4) == 0) {
$argDatabasename = substr($argDatabasename,4);
$this->connectSID = true;
}
if ($this->connectSID) {
$argDatabasename="(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=".$argHostname
.")(PORT=$argHostport))(CONNECT_DATA=(SID=$argDatabasename)))";
@@ -213,43 +243,43 @@ NATSOFT.DOMAIN =
.")(PORT=$argHostport))(CONNECT_DATA=(SERVICE_NAME=$argDatabasename)))";
}
}
//if ($argHostname) print "<p>Connect: 1st argument should be left blank for $this->databaseType</p>";
//if ($argHostname) print "<p>Connect: 1st argument should be left blank for $this->databaseType</p>";
if ($mode==1) {
$this->_connectionID = ($this->charSet) ?
OCIPLogon($argUsername,$argPassword, $argDatabasename,$this->charSet)
:
OCIPLogon($argUsername,$argPassword, $argDatabasename)
;
if ($this->_connectionID && $this->autoRollback) OCIrollback($this->_connectionID);
$this->_connectionID = ($this->charSet)
? oci_pconnect($argUsername,$argPassword, $argDatabasename,$this->charSet)
: oci_pconnect($argUsername,$argPassword, $argDatabasename);
if ($this->_connectionID && $this->autoRollback) {
oci_rollback($this->_connectionID);
}
} else if ($mode==2) {
$this->_connectionID = ($this->charSet) ?
OCINLogon($argUsername,$argPassword, $argDatabasename,$this->charSet)
:
OCINLogon($argUsername,$argPassword, $argDatabasename);
$this->_connectionID = ($this->charSet)
? oci_new_connect($argUsername,$argPassword, $argDatabasename,$this->charSet)
: oci_new_connect($argUsername,$argPassword, $argDatabasename);
} else {
$this->_connectionID = ($this->charSet) ?
OCILogon($argUsername,$argPassword, $argDatabasename,$this->charSet)
:
OCILogon($argUsername,$argPassword, $argDatabasename);
$this->_connectionID = ($this->charSet)
? oci_connect($argUsername,$argPassword, $argDatabasename,$this->charSet)
: oci_connect($argUsername,$argPassword, $argDatabasename);
}
if (!$this->_connectionID) return false;
if (!$this->_connectionID) {
return false;
}
if ($this->_initdate) {
$this->Execute("ALTER SESSION SET NLS_DATE_FORMAT='".$this->NLS_DATE_FORMAT."'");
}
// looks like:
// looks like:
// Oracle8i Enterprise Edition Release 8.1.7.0.0 - Production With the Partitioning option JServer Release 8.1.7.0.0 - Production
// $vers = OCIServerVersion($this->_connectionID);
// $vers = oci_server_version($this->_connectionID);
// if (strpos($vers,'8i') !== false) $this->ansiOuter = true;
return true;
}
}
function ServerInfo()
{
$arr['compat'] = $this->GetOne('select value from sys.database_compatible_level');
$arr['description'] = @OCIServerVersion($this->_connectionID);
$arr['description'] = @oci_server_version($this->_connectionID);
$arr['version'] = ADOConnection::_findvers($arr['description']);
return $arr;
}
@@ -258,77 +288,113 @@ NATSOFT.DOMAIN =
{
return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename,1);
}
// returns true or false
function _nconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename,2);
}
function _affectedrows()
{
if (is_resource($this->_stmt)) return @OCIRowCount($this->_stmt);
if (is_resource($this->_stmt)) {
return @oci_num_rows($this->_stmt);
}
return 0;
}
function IfNull( $field, $ifNull )
function IfNull( $field, $ifNull )
{
return " NVL($field, $ifNull) "; // if Oracle
}
// format and return date string in database date format
function DBDate($d,$isfld=false)
{
if (empty($d) && $d !== 0) return 'null';
if ($isfld) return 'TO_DATE('.$d.",'".$this->dateformat."')";
if (is_string($d)) $d = ADORecordSet::UnixDate($d);
if (is_object($d)) $ds = $d->format($this->fmtDate);
else $ds = adodb_date($this->fmtDate,$d);
if (empty($d) && $d !== 0) {
return 'null';
}
if ($isfld) {
$d = _adodb_safedate($d);
return 'TO_DATE('.$d.",'".$this->dateformat."')";
}
if (is_string($d)) {
$d = ADORecordSet::UnixDate($d);
}
if (is_object($d)) {
$ds = $d->format($this->fmtDate);
}
else {
$ds = adodb_date($this->fmtDate,$d);
}
return "TO_DATE(".$ds.",'".$this->dateformat."')";
}
function BindDate($d)
{
$d = ADOConnection::DBDate($d);
if (strncmp($d,"'",1)) return $d;
return substr($d,1,strlen($d)-2);
if (strncmp($d, "'", 1)) {
return $d;
}
return substr($d, 1, strlen($d)-2);
}
function BindTimeStamp($ts)
{
if (empty($ts) && $ts !== 0) return 'null';
if (is_string($ts)) $ts = ADORecordSet::UnixTimeStamp($ts);
if (is_object($ts)) $tss = $ts->format("'Y-m-d H:i:s'");
else $tss = adodb_date("'Y-m-d H:i:s'",$ts);
if (empty($ts) && $ts !== 0) {
return 'null';
}
if (is_string($ts)) {
$ts = ADORecordSet::UnixTimeStamp($ts);
}
if (is_object($ts)) {
$tss = $ts->format("'Y-m-d H:i:s'");
}
else {
$tss = adodb_date("'Y-m-d H:i:s'",$ts);
}
return $tss;
}
// format and return date string in database timestamp format
function DBTimeStamp($ts,$isfld=false)
{
if (empty($ts) && $ts !== 0) return 'null';
if ($isfld) return 'TO_DATE(substr('.$ts.",1,19),'RRRR-MM-DD, HH24:MI:SS')";
if (is_string($ts)) $ts = ADORecordSet::UnixTimeStamp($ts);
if (is_object($ts)) $tss = $ts->format("'Y-m-d H:i:s'");
else $tss = adodb_date("'Y-m-d H:i:s'",$ts);
if (empty($ts) && $ts !== 0) {
return 'null';
}
if ($isfld) {
return 'TO_DATE(substr('.$ts.",1,19),'RRRR-MM-DD, HH24:MI:SS')";
}
if (is_string($ts)) {
$ts = ADORecordSet::UnixTimeStamp($ts);
}
if (is_object($ts)) {
$tss = $ts->format("'Y-m-d H:i:s'");
}
else {
$tss = date("'Y-m-d H:i:s'",$ts);
}
return 'TO_DATE('.$tss.",'RRRR-MM-DD, HH24:MI:SS')";
}
function RowLock($tables,$where,$flds='1 as ignore')
function RowLock($tables,$where,$col='1 as adodbignore')
{
if ($this->autoCommit) $this->BeginTrans();
return $this->GetOne("select $flds from $tables where $where for update");
if ($this->autoCommit) {
$this->BeginTrans();
}
return $this->GetOne("select $col from $tables where $where for update");
}
function MetaTables($ttype=false,$showSchema=false,$mask=false)
function MetaTables($ttype=false,$showSchema=false,$mask=false)
{
if ($mask) {
$save = $this->metaTablesSQL;
@@ -336,25 +402,25 @@ NATSOFT.DOMAIN =
$this->metaTablesSQL .= " AND upper(table_name) like $mask";
}
$ret = ADOConnection::MetaTables($ttype,$showSchema);
if ($mask) {
$this->metaTablesSQL = $save;
}
return $ret;
}
// Mark Newnham
// Mark Newnham
function MetaIndexes ($table, $primary = FALSE, $owner=false)
{
// save old fetch mode
global $ADODB_FETCH_MODE;
// save old fetch mode
global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== FALSE) {
$savem = $this->SetFetchMode(FALSE);
}
if ($this->fetchMode !== FALSE) {
$savem = $this->SetFetchMode(FALSE);
}
// get index details
$table = strtoupper($table);
@@ -362,133 +428,183 @@ NATSOFT.DOMAIN =
// get Primary index
$primary_key = '';
$false = false;
$rs = $this->Execute(sprintf("SELECT * FROM ALL_CONSTRAINTS WHERE UPPER(TABLE_NAME)='%s' AND CONSTRAINT_TYPE='P'",$table));
if ($row = $rs->FetchRow())
$primary_key = $row[1]; //constraint_name
if (!is_object($rs)) {
if (isset($savem)) {
$this->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
return false;
}
if ($row = $rs->FetchRow()) {
$primary_key = $row[1]; //constraint_name
}
if ($primary==TRUE && $primary_key=='') {
if (isset($savem))
$this->SetFetchMode($savem);
if (isset($savem)) {
$this->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
return $false; //There is no primary key
return false; //There is no primary key
}
$rs = $this->Execute(sprintf("SELECT ALL_INDEXES.INDEX_NAME, ALL_INDEXES.UNIQUENESS, ALL_IND_COLUMNS.COLUMN_POSITION, ALL_IND_COLUMNS.COLUMN_NAME FROM ALL_INDEXES,ALL_IND_COLUMNS WHERE UPPER(ALL_INDEXES.TABLE_NAME)='%s' AND ALL_IND_COLUMNS.INDEX_NAME=ALL_INDEXES.INDEX_NAME",$table));
$rs = $this->Execute(sprintf("SELECT ALL_INDEXES.INDEX_NAME, ALL_INDEXES.UNIQUENESS, ALL_IND_COLUMNS.COLUMN_POSITION, ALL_IND_COLUMNS.COLUMN_NAME FROM ALL_INDEXES,ALL_IND_COLUMNS WHERE UPPER(ALL_INDEXES.TABLE_NAME)='%s' AND ALL_IND_COLUMNS.INDEX_NAME=ALL_INDEXES.INDEX_NAME",$table));
if (!is_object($rs)) {
if (isset($savem))
if (!is_object($rs)) {
if (isset($savem)) {
$this->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
return $false;
}
return false;
}
$indexes = array ();
// parse index data into array
// parse index data into array
while ($row = $rs->FetchRow()) {
if ($primary && $row[0] != $primary_key) continue;
if (!isset($indexes[$row[0]])) {
while ($row = $rs->FetchRow()) {
if ($primary && $row[0] != $primary_key) {
continue;
}
if (!isset($indexes[$row[0]])) {
$indexes[$row[0]] = array(
'unique' => ($row[1] == 'UNIQUE'),
'columns' => array()
'unique' => ($row[1] == 'UNIQUE'),
'columns' => array()
);
}
$indexes[$row[0]]['columns'][$row[2] - 1] = $row[3];
}
}
$indexes[$row[0]]['columns'][$row[2] - 1] = $row[3];
}
// sort columns by order in the index
foreach ( array_keys ($indexes) as $index ) {
ksort ($indexes[$index]['columns']);
}
// sort columns by order in the index
foreach ( array_keys ($indexes) as $index ) {
ksort ($indexes[$index]['columns']);
}
if (isset($savem)) {
$this->SetFetchMode($savem);
if (isset($savem)) {
$this->SetFetchMode($savem);
$ADODB_FETCH_MODE = $save;
}
return $indexes;
return $indexes;
}
function BeginTrans()
{
if ($this->transOff) return true;
{
if ($this->transOff) {
return true;
}
$this->transCnt += 1;
$this->autoCommit = false;
$this->_commit = OCI_DEFAULT;
if ($this->_transmode) $ok = $this->Execute("SET TRANSACTION ".$this->_transmode);
else $ok = true;
if ($this->_transmode) {
$ok = $this->Execute("SET TRANSACTION ".$this->_transmode);
}
else {
$ok = true;
}
return $ok ? true : false;
}
function CommitTrans($ok=true)
{
if ($this->transOff) return true;
if (!$ok) return $this->RollbackTrans();
if ($this->transCnt) $this->transCnt -= 1;
$ret = OCIcommit($this->_connectionID);
function CommitTrans($ok=true)
{
if ($this->transOff) {
return true;
}
if (!$ok) {
return $this->RollbackTrans();
}
if ($this->transCnt) {
$this->transCnt -= 1;
}
$ret = oci_commit($this->_connectionID);
$this->_commit = OCI_COMMIT_ON_SUCCESS;
$this->autoCommit = true;
return $ret;
}
function RollbackTrans()
{
if ($this->transOff) return true;
if ($this->transCnt) $this->transCnt -= 1;
$ret = OCIrollback($this->_connectionID);
if ($this->transOff) {
return true;
}
if ($this->transCnt) {
$this->transCnt -= 1;
}
$ret = oci_rollback($this->_connectionID);
$this->_commit = OCI_COMMIT_ON_SUCCESS;
$this->autoCommit = true;
return $ret;
}
function SelectDB($dbName)
function SelectDB($dbName)
{
return false;
}
function ErrorMsg()
function ErrorMsg()
{
if ($this->_errorMsg !== false) return $this->_errorMsg;
if ($this->_errorMsg !== false) {
return $this->_errorMsg;
}
if (is_resource($this->_stmt)) $arr = @OCIError($this->_stmt);
if (is_resource($this->_stmt)) {
$arr = @oci_error($this->_stmt);
}
if (empty($arr)) {
if (is_resource($this->_connectionID)) $arr = @OCIError($this->_connectionID);
else $arr = @OCIError();
if ($arr === false) return '';
if (is_resource($this->_connectionID)) {
$arr = @oci_error($this->_connectionID);
}
else {
$arr = @oci_error();
}
if ($arr === false) {
return '';
}
}
$this->_errorMsg = $arr['message'];
$this->_errorCode = $arr['code'];
return $this->_errorMsg;
}
function ErrorNo()
function ErrorNo()
{
if ($this->_errorCode !== false) return $this->_errorCode;
if (is_resource($this->_stmt)) $arr = @OCIError($this->_stmt);
if (empty($arr)) {
$arr = @OCIError($this->_connectionID);
if ($arr == false) $arr = @OCIError();
if ($arr == false) return '';
if ($this->_errorCode !== false) {
return $this->_errorCode;
}
if (is_resource($this->_stmt)) {
$arr = @oci_error($this->_stmt);
}
if (empty($arr)) {
$arr = @oci_error($this->_connectionID);
if ($arr == false) {
$arr = @oci_error();
}
if ($arr == false) {
return '';
}
}
$this->_errorMsg = $arr['message'];
$this->_errorCode = $arr['code'];
return $arr['code'];
}
// Format date column in sql string given an input format that understands Y M D
/**
* Format date column in sql string given an input format that understands Y M D
*/
function SQLDate($fmt, $col=false)
{
if (!$col) $col = $this->sysTimeStamp;
{
if (!$col) {
$col = $this->sysTimeStamp;
}
$s = 'TO_CHAR('.$col.",'";
$len = strlen($fmt);
for ($i=0; $i < $len; $i++) {
$ch = $fmt[$i];
@@ -501,11 +617,11 @@ NATSOFT.DOMAIN =
case 'q':
$s .= 'Q';
break;
case 'M':
$s .= 'Mon';
break;
case 'm':
$s .= 'MM';
break;
@@ -513,227 +629,268 @@ NATSOFT.DOMAIN =
case 'd':
$s .= 'DD';
break;
case 'H':
$s.= 'HH24';
break;
case 'h':
$s .= 'HH';
break;
case 'i':
$s .= 'MI';
break;
case 's':
$s .= 'SS';
break;
case 'a':
case 'A':
$s .= 'AM';
break;
case 'w':
$s .= 'D';
break;
case 'l':
$s .= 'DAY';
break;
case 'W':
case 'W':
$s .= 'WW';
break;
default:
// handle escape characters...
// handle escape characters...
if ($ch == '\\') {
$i++;
$ch = substr($fmt,$i,1);
}
if (strpos('-/.:;, ',$ch) !== false) $s .= $ch;
else $s .= '"'.$ch.'"';
if (strpos('-/.:;, ',$ch) !== false) {
$s .= $ch;
}
else {
$s .= '"'.$ch.'"';
}
}
}
return $s. "')";
}
function GetRandRow($sql, $arr = false)
{
$sql = "SELECT * FROM ($sql ORDER BY dbms_random.value) WHERE rownum = 1";
return $this->GetRow($sql,$arr);
}
/*
This algorithm makes use of
a. FIRST_ROWS hint
The FIRST_ROWS hint explicitly chooses the approach to optimize response time,
that is, minimum resource usage to return the first row. Results will be returned
as soon as they are identified.
b. Uses rownum tricks to obtain only the required rows from a given offset.
As this uses complicated sql statements, we only use this if the $offset >= 100.
This idea by Tomas V V Cox.
This implementation does not appear to work with oracle 8.0.5 or earlier. Comment
out this function then, and the slower SelectLimit() in the base class will be used.
*/
/**
* This algorithm makes use of
*
* a. FIRST_ROWS hint
* The FIRST_ROWS hint explicitly chooses the approach to optimize response
* time, that is, minimum resource usage to return the first row. Results
* will be returned as soon as they are identified.
*
* b. Uses rownum tricks to obtain only the required rows from a given offset.
* As this uses complicated sql statements, we only use this if $offset >= 100.
* This idea by Tomas V V Cox.
*
* This implementation does not appear to work with oracle 8.0.5 or earlier.
* Comment out this function then, and the slower SelectLimit() in the base
* class will be used.
*
* Note: FIRST_ROWS hinting is only used if $sql is a string; when
* processing a prepared statement's handle, no hinting is performed.
*/
function SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
{
// Since the methods used to limit the number of returned rows rely
// on modifying the provided SQL query, we can't work with prepared
// statements so we just extract the SQL string.
if(is_array($sql)) {
$sql = $sql[0];
}
// seems that oracle only supports 1 hint comment in 8i
if ($this->firstrows) {
if (strpos($sql,'/*+') !== false)
$sql = str_replace('/*+ ','/*+FIRST_ROWS ',$sql);
else
$sql = preg_replace('/^[ \t\n]*select/i','SELECT /*+FIRST_ROWS*/',$sql);
if ($nrows > 500 && $nrows < 1000) {
$hint = "FIRST_ROWS($nrows)";
}
else {
$hint = 'FIRST_ROWS';
}
if (strpos($sql,'/*+') !== false) {
$sql = str_replace('/*+ ',"/*+$hint ",$sql);
}
else {
$sql = preg_replace('/^[ \t\n]*select/i',"SELECT /*+$hint*/",$sql);
}
$hint = "/*+ $hint */";
} else {
$hint = '';
}
if ($offset == -1 || ($offset < $this->selectOffsetAlg1 && 0 < $nrows && $nrows < 1000)) {
if ($nrows > 0) {
if ($offset > 0) $nrows += $offset;
//$inputarr['adodb_rownum'] = $nrows;
if ($this->databaseType == 'oci8po') {
$sql = "select * from (".$sql.") where rownum <= ?";
} else {
$sql = "select * from (".$sql.") where rownum <= :adodb_offset";
}
if ($nrows > 0) {
if ($offset > 0) {
$nrows += $offset;
}
$sql = "select * from (".$sql.") where rownum <= :adodb_offset";
$inputarr['adodb_offset'] = $nrows;
$nrows = -1;
}
// note that $nrows = 0 still has to work ==> no rows returned
$rs = ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
return $rs;
return ADOConnection::SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
} else {
// Algorithm by Tomas V V Cox, from PEAR DB oci8.php
// Let Oracle return the name of the columns
// Algorithm by Tomas V V Cox, from PEAR DB oci8.php
// Let Oracle return the name of the columns
$q_fields = "SELECT * FROM (".$sql.") WHERE NULL = NULL";
$false = false;
if (! $stmt_arr = $this->Prepare($q_fields)) {
return $false;
return false;
}
$stmt = $stmt_arr[1];
if (is_array($inputarr)) {
foreach($inputarr as $k => $v) {
foreach($inputarr as $k => $v) {
$i=0;
if ($this->databaseType == 'oci8po') {
$bv_name = ":".$i++;
} else {
$bv_name = ":".$k;
}
if (is_array($v)) {
if (sizeof($v) == 2) // suggested by g.giunta@libero.
OCIBindByName($stmt,":$k",$inputarr[$k][0],$v[1]);
else
OCIBindByName($stmt,":$k",$inputarr[$k][0],$v[1],$v[2]);
// suggested by g.giunta@libero.
if (sizeof($v) == 2) {
oci_bind_by_name($stmt,$bv_name,$inputarr[$k][0],$v[1]);
}
else {
oci_bind_by_name($stmt,$bv_name,$inputarr[$k][0],$v[1],$v[2]);
}
} else {
$len = -1;
if ($v === ' ') $len = 1;
if (isset($bindarr)) { // is prepared sql, so no need to ocibindbyname again
if ($v === ' ') {
$len = 1;
}
if (isset($bindarr)) { // is prepared sql, so no need to oci_bind_by_name again
$bindarr[$k] = $v;
} else { // dynamic sql, so rebind every time
OCIBindByName($stmt,":$k",$inputarr[$k],$len);
oci_bind_by_name($stmt,$bv_name,$inputarr[$k],$len);
}
}
}
}
if (!OCIExecute($stmt, OCI_DEFAULT)) {
OCIFreeStatement($stmt);
return $false;
}
$ncols = OCINumCols($stmt);
for ( $i = 1; $i <= $ncols; $i++ ) {
$cols[] = '"'.OCIColumnName($stmt, $i).'"';
}
$result = false;
OCIFreeStatement($stmt);
$fields = implode(',', $cols);
if ($nrows <= 0) $nrows = 999999999999;
else $nrows += $offset;
$offset += 1; // in Oracle rownum starts at 1
if ($this->databaseType == 'oci8po') {
$sql = "SELECT /*+ FIRST_ROWS */ $fields FROM".
"(SELECT rownum as adodb_rownum, $fields FROM".
" ($sql) WHERE rownum <= ?".
") WHERE adodb_rownum >= ?";
} else {
$sql = "SELECT /*+ FIRST_ROWS */ $fields FROM".
"(SELECT rownum as adodb_rownum, $fields FROM".
" ($sql) WHERE rownum <= :adodb_nrows".
") WHERE adodb_rownum >= :adodb_offset";
}
$inputarr['adodb_nrows'] = $nrows;
$inputarr['adodb_offset'] = $offset;
if ($secs2cache>0) $rs = $this->CacheExecute($secs2cache, $sql,$inputarr);
else $rs = $this->Execute($sql,$inputarr);
if (!oci_execute($stmt, OCI_DEFAULT)) {
oci_free_statement($stmt);
return false;
}
$ncols = oci_num_fields($stmt);
for ( $i = 1; $i <= $ncols; $i++ ) {
$cols[] = '"'.oci_field_name($stmt, $i).'"';
}
$result = false;
oci_free_statement($stmt);
$fields = implode(',', $cols);
if ($nrows <= 0) {
$nrows = 999999999999;
}
else {
$nrows += $offset;
}
$offset += 1; // in Oracle rownum starts at 1
$sql = "SELECT $hint $fields FROM".
"(SELECT rownum as adodb_rownum, $fields FROM".
" ($sql) WHERE rownum <= :adodb_nrows".
") WHERE adodb_rownum >= :adodb_offset";
$inputarr['adodb_nrows'] = $nrows;
$inputarr['adodb_offset'] = $offset;
if ($secs2cache > 0) {
$rs = $this->CacheExecute($secs2cache, $sql,$inputarr);
}
else {
$rs = $this->Execute($sql, $inputarr);
}
return $rs;
}
}
/**
* Usage:
* Store BLOBs and CLOBs
*
* Example: to store $var in a blob
*
* $conn->Execute('insert into TABLE (id,ablob) values(12,empty_blob())');
* $conn->UpdateBlob('TABLE', 'ablob', $varHoldingBlob, 'ID=12', 'BLOB');
*
* $blobtype supports 'BLOB' and 'CLOB', but you need to change to 'empty_clob()'.
*
* to get length of LOB:
* select DBMS_LOB.GETLENGTH(ablob) from TABLE
*
* If you are using CURSOR_SHARING = force, it appears this will case a segfault
* under oracle 8.1.7.0. Run:
* $db->Execute('ALTER SESSION SET CURSOR_SHARING=EXACT');
* before UpdateBlob() then...
*/
/**
* Usage:
* Store BLOBs and CLOBs
*
* Example: to store $var in a blob
* $conn->Execute('insert into TABLE (id,ablob) values(12,empty_blob())');
* $conn->UpdateBlob('TABLE', 'ablob', $varHoldingBlob, 'ID=12', 'BLOB');
*
* $blobtype supports 'BLOB' and 'CLOB', but you need to change to 'empty_clob()'.
*
* to get length of LOB:
* select DBMS_LOB.GETLENGTH(ablob) from TABLE
*
* If you are using CURSOR_SHARING = force, it appears this will case a segfault
* under oracle 8.1.7.0. Run:
* $db->Execute('ALTER SESSION SET CURSOR_SHARING=EXACT');
* before UpdateBlob() then...
*/
function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
{
//if (strlen($val) < 4000) return $this->Execute("UPDATE $table SET $column=:blob WHERE $where",array('blob'=>$val)) != false;
switch(strtoupper($blobtype)) {
default: ADOConnection::outp("<b>UpdateBlob</b>: Unknown blobtype=$blobtype"); return false;
case 'BLOB': $type = OCI_B_BLOB; break;
case 'CLOB': $type = OCI_B_CLOB; break;
}
if ($this->databaseType == 'oci8po')
if ($this->databaseType == 'oci8po')
$sql = "UPDATE $table set $column=EMPTY_{$blobtype}() WHERE $where RETURNING $column INTO ?";
else
else
$sql = "UPDATE $table set $column=EMPTY_{$blobtype}() WHERE $where RETURNING $column INTO :blob";
$desc = OCINewDescriptor($this->_connectionID, OCI_D_LOB);
$desc = oci_new_descriptor($this->_connectionID, OCI_D_LOB);
$arr['blob'] = array($desc,-1,$type);
if ($this->session_sharing_force_blob) $this->Execute('ALTER SESSION SET CURSOR_SHARING=EXACT');
if ($this->session_sharing_force_blob) {
$this->Execute('ALTER SESSION SET CURSOR_SHARING=EXACT');
}
$commit = $this->autoCommit;
if ($commit) $this->BeginTrans();
if ($commit) {
$this->BeginTrans();
}
$rs = $this->_Execute($sql,$arr);
if ($rez = !empty($rs)) $desc->save($val);
if ($rez = !empty($rs)) {
$desc->save($val);
}
$desc->free();
if ($commit) $this->CommitTrans();
if ($this->session_sharing_force_blob) $this->Execute('ALTER SESSION SET CURSOR_SHARING=FORCE');
if ($rez) $rs->Close();
if ($commit) {
$this->CommitTrans();
}
if ($this->session_sharing_force_blob) {
$this->Execute('ALTER SESSION SET CURSOR_SHARING=FORCE');
}
if ($rez) {
$rs->Close();
}
return $rez;
}
/**
* Usage: store file pointed to by $val in a blob
*/
* Usage: store file pointed to by $val in a blob
*/
function UpdateBlobFile($table,$column,$val,$where,$blobtype='BLOB')
{
switch(strtoupper($blobtype)) {
@@ -741,69 +898,88 @@ NATSOFT.DOMAIN =
case 'BLOB': $type = OCI_B_BLOB; break;
case 'CLOB': $type = OCI_B_CLOB; break;
}
if ($this->databaseType == 'oci8po')
if ($this->databaseType == 'oci8po')
$sql = "UPDATE $table set $column=EMPTY_{$blobtype}() WHERE $where RETURNING $column INTO ?";
else
else
$sql = "UPDATE $table set $column=EMPTY_{$blobtype}() WHERE $where RETURNING $column INTO :blob";
$desc = OCINewDescriptor($this->_connectionID, OCI_D_LOB);
$desc = oci_new_descriptor($this->_connectionID, OCI_D_LOB);
$arr['blob'] = array($desc,-1,$type);
$this->BeginTrans();
$rs = ADODB_oci8::Execute($sql,$arr);
if ($rez = !empty($rs)) $desc->savefile($val);
if ($rez = !empty($rs)) {
$desc->savefile($val);
}
$desc->free();
$this->CommitTrans();
if ($rez) $rs->Close();
if ($rez) {
$rs->Close();
}
return $rez;
}
/**
* Execute SQL
/**
* Execute SQL
*
* @param sql SQL statement to execute, or possibly an array holding prepared statement ($sql[0] will hold sql text)
* @param [inputarr] holds the input data to bind to. Null elements will be set to null.
* @return RecordSet or false
*/
function Execute($sql,$inputarr=false)
function Execute($sql,$inputarr=false)
{
if ($this->fnExecute) {
$fn = $this->fnExecute;
$ret = $fn($this,$sql,$inputarr);
if (isset($ret)) return $ret;
if (isset($ret)) {
return $ret;
}
}
if ($inputarr) {
#if (!is_array($inputarr)) $inputarr = array($inputarr);
if ($inputarr !== false) {
if (!is_array($inputarr)) {
$inputarr = array($inputarr);
}
$element0 = reset($inputarr);
if (!$this->_bindInputArray) {
# is_object check because oci8 descriptors can be passed in
if (is_array($element0) && !is_object(reset($element0))) {
if (is_string($sql))
$stmt = $this->Prepare($sql);
else
$stmt = $sql;
foreach($inputarr as $arr) {
$ret = $this->_Execute($stmt,$arr);
if (!$ret) return $ret;
}
} else {
$sqlarr = explode(':',$sql);
$sql = '';
$lastnomatch = -2;
#var_dump($sqlarr);echo "<hr>";var_dump($inputarr);echo"<hr>";
foreach($sqlarr as $k => $str) {
if ($k == 0) { $sql = $str; continue; }
// we need $lastnomatch because of the following datetime,
$array2d = $this->bulkBind && is_array($element0) && !is_object(reset($element0));
# see http://phplens.com/lens/lensforum/msgs.php?id=18786
if ($array2d || !$this->_bindInputArray) {
# is_object check because oci8 descriptors can be passed in
if ($array2d && $this->_bindInputArray) {
if (is_string($sql)) {
$stmt = $this->Prepare($sql);
} else {
$stmt = $sql;
}
foreach($inputarr as $arr) {
$ret = $this->_Execute($stmt,$arr);
if (!$ret) {
return $ret;
}
}
return $ret;
} else {
$sqlarr = explode(':', $sql);
$sql = '';
$lastnomatch = -2;
#var_dump($sqlarr);echo "<hr>";var_dump($inputarr);echo"<hr>";
foreach($sqlarr as $k => $str) {
if ($k == 0) {
$sql = $str;
continue;
}
// we need $lastnomatch because of the following datetime,
// eg. '10:10:01', which causes code to think that there is bind param :10 and :1
$ok = preg_match('/^([0-9]*)/', $str, $arr);
if (!$ok) $sql .= $str;
else {
$ok = preg_match('/^([0-9]*)/', $str, $arr);
if (!$ok) {
$sql .= $str;
} else {
$at = $arr[1];
if (isset($inputarr[$at]) || is_null($inputarr[$at])) {
if ((strlen($at) == strlen($str) && $k < sizeof($arr)-1)) {
@@ -812,79 +988,84 @@ NATSOFT.DOMAIN =
} else if ($lastnomatch == $k-1) {
$sql .= ':'.$str;
} else {
if (is_null($inputarr[$at])) $sql .= 'null';
else $sql .= $this->qstr($inputarr[$at]);
if (is_null($inputarr[$at])) {
$sql .= 'null';
}
else {
$sql .= $this->qstr($inputarr[$at]);
}
$sql .= substr($str, strlen($at));
}
} else {
$sql .= ':'.$str;
}
}
}
$inputarr = false;
}
}
$ret = $this->_Execute($sql,$inputarr);
} else {
$ret = $this->_Execute($sql,false);
}
return $ret;
}
/*
Example of usage:
$stmt = $this->Prepare('insert into emp (empno, ename) values (:empno, :ename)');
* Example of usage:
* $stmt = $this->Prepare('insert into emp (empno, ename) values (:empno, :ename)');
*/
function Prepare($sql,$cursor=false)
{
static $BINDNUM = 0;
$stmt = OCIParse($this->_connectionID,$sql);
$stmt = oci_parse($this->_connectionID,$sql);
if (!$stmt) {
$this->_errorMsg = false;
$this->_errorCode = false;
$arr = @OCIError($this->_connectionID);
if ($arr === false) return false;
$arr = @oci_error($this->_connectionID);
if ($arr === false) {
return false;
}
$this->_errorMsg = $arr['message'];
$this->_errorCode = $arr['code'];
return false;
}
$BINDNUM += 1;
$sttype = @OCIStatementType($stmt);
$sttype = @oci_statement_type($stmt);
if ($sttype == 'BEGIN' || $sttype == 'DECLARE') {
return array($sql,$stmt,0,$BINDNUM, ($cursor) ? OCINewCursor($this->_connectionID) : false);
return array($sql,$stmt,0,$BINDNUM, ($cursor) ? oci_new_cursor($this->_connectionID) : false);
}
return array($sql,$stmt,0,$BINDNUM);
}
/*
Call an oracle stored procedure and returns a cursor variable as a recordset.
Call an oracle stored procedure and returns a cursor variable as a recordset.
Concept by Robert Tuttle robert@ud.com
Example:
Note: we return a cursor variable in :RS2
$rs = $db->ExecuteCursor("BEGIN adodb.open_tab(:RS2); END;",'RS2');
$rs = $db->ExecuteCursor(
"BEGIN :RS2 = adodb.getdata(:VAR1); END;",
"BEGIN :RS2 = adodb.getdata(:VAR1); END;",
'RS2',
array('VAR1' => 'Mr Bean'));
*/
function ExecuteCursor($sql,$cursorName='rs',$params=false)
{
if (is_array($sql)) $stmt = $sql;
else $stmt = ADODB_oci8::Prepare($sql,true); # true to allocate OCINewCursor
if (is_array($sql)) {
$stmt = $sql;
}
else $stmt = ADODB_oci8::Prepare($sql,true); # true to allocate oci_new_cursor
if (is_array($stmt) && sizeof($stmt) >= 5) {
$hasref = true;
$ignoreCur = false;
@@ -896,73 +1077,82 @@ NATSOFT.DOMAIN =
}
} else
$hasref = false;
$rs = $this->Execute($stmt);
if ($rs) {
if ($rs->databaseType == 'array') OCIFreeCursor($stmt[4]);
else if ($hasref) $rs->_refcursor = $stmt[4];
if ($rs->databaseType == 'array') {
oci_free_cursor($stmt[4]);
}
elseif ($hasref) {
$rs->_refcursor = $stmt[4];
}
}
return $rs;
}
/*
Bind a variable -- very, very fast for executing repeated statements in oracle.
Better than using
for ($i = 0; $i < $max; $i++) {
$p1 = ?; $p2 = ?; $p3 = ?;
$this->Execute("insert into table (col0, col1, col2) values (:0, :1, :2)",
array($p1,$p2,$p3));
}
Usage:
$stmt = $DB->Prepare("insert into table (col0, col1, col2) values (:0, :1, :2)");
$DB->Bind($stmt, $p1);
$DB->Bind($stmt, $p2);
$DB->Bind($stmt, $p3);
for ($i = 0; $i < $max; $i++) {
$p1 = ?; $p2 = ?; $p3 = ?;
$DB->Execute($stmt);
}
Some timings:
** Test table has 3 cols, and 1 index. Test to insert 1000 records
Time 0.6081s (1644.60 inserts/sec) with direct OCIParse/OCIExecute
Time 0.6341s (1577.16 inserts/sec) with ADOdb Prepare/Bind/Execute
Time 1.5533s ( 643.77 inserts/sec) with pure SQL using Execute
Now if PHP only had batch/bulk updating like Java or PL/SQL...
Note that the order of parameters differs from OCIBindByName,
because we default the names to :0, :1, :2
*/
/**
* Bind a variable -- very, very fast for executing repeated statements in oracle.
*
* Better than using
* for ($i = 0; $i < $max; $i++) {
* $p1 = ?; $p2 = ?; $p3 = ?;
* $this->Execute("insert into table (col0, col1, col2) values (:0, :1, :2)", array($p1,$p2,$p3));
* }
*
* Usage:
* $stmt = $DB->Prepare("insert into table (col0, col1, col2) values (:0, :1, :2)");
* $DB->Bind($stmt, $p1);
* $DB->Bind($stmt, $p2);
* $DB->Bind($stmt, $p3);
* for ($i = 0; $i < $max; $i++) {
* $p1 = ?; $p2 = ?; $p3 = ?;
* $DB->Execute($stmt);
* }
*
* Some timings to insert 1000 records, test table has 3 cols, and 1 index.
* - Time 0.6081s (1644.60 inserts/sec) with direct oci_parse/oci_execute
* - Time 0.6341s (1577.16 inserts/sec) with ADOdb Prepare/Bind/Execute
* - Time 1.5533s ( 643.77 inserts/sec) with pure SQL using Execute
*
* Now if PHP only had batch/bulk updating like Java or PL/SQL...
*
* Note that the order of parameters differs from oci_bind_by_name,
* because we default the names to :0, :1, :2
*/
function Bind(&$stmt,&$var,$size=4000,$type=false,$name=false,$isOutput=false)
{
if (!is_array($stmt)) return false;
if (($type == OCI_B_CURSOR) && sizeof($stmt) >= 5) {
return OCIBindByName($stmt[1],":".$name,$stmt[4],$size,$type);
}
if (!is_array($stmt)) {
return false;
}
if (($type == OCI_B_CURSOR) && sizeof($stmt) >= 5) {
return oci_bind_by_name($stmt[1],":".$name,$stmt[4],$size,$type);
}
if ($name == false) {
if ($type !== false) $rez = OCIBindByName($stmt[1],":".$stmt[2],$var,$size,$type);
else $rez = OCIBindByName($stmt[1],":".$stmt[2],$var,$size); // +1 byte for null terminator
if ($type !== false) {
$rez = oci_bind_by_name($stmt[1],":".$stmt[2],$var,$size,$type);
}
else {
$rez = oci_bind_by_name($stmt[1],":".$stmt[2],$var,$size); // +1 byte for null terminator
}
$stmt[2] += 1;
} else if (oci_lob_desc($type)) {
if ($this->debug) {
ADOConnection::outp("<b>Bind</b>: name = $name");
}
//we have to create a new Descriptor here
//we have to create a new Descriptor here
$numlob = count($this->_refLOBs);
$this->_refLOBs[$numlob]['LOB'] = OCINewDescriptor($this->_connectionID, oci_lob_desc($type));
$this->_refLOBs[$numlob]['LOB'] = oci_new_descriptor($this->_connectionID, oci_lob_desc($type));
$this->_refLOBs[$numlob]['TYPE'] = $isOutput;
$tmp = $this->_refLOBs[$numlob]['LOB'];
$rez = OCIBindByName($stmt[1], ":".$name, $tmp, -1, $type);
$rez = oci_bind_by_name($stmt[1], ":".$name, $tmp, -1, $type);
if ($this->debug) {
ADOConnection::outp("<b>Bind</b>: descriptor has been allocated, var (".$name.") binded");
}
// if type is input then write data to lob now
if ($isOutput == false) {
$var = $this->BlobEncode($var);
@@ -972,40 +1162,44 @@ NATSOFT.DOMAIN =
ADOConnection::outp("<b>Bind</b>: LOB has been written to temp");
}
} else {
$this->_refLOBs[$numlob]['VAR'] = $var;
$this->_refLOBs[$numlob]['VAR'] = &$var;
}
$rez = $tmp;
} else {
if ($this->debug)
if ($this->debug)
ADOConnection::outp("<b>Bind</b>: name = $name");
if ($type !== false) $rez = OCIBindByName($stmt[1],":".$name,$var,$size,$type);
else $rez = OCIBindByName($stmt[1],":".$name,$var,$size); // +1 byte for null terminator
if ($type !== false) {
$rez = oci_bind_by_name($stmt[1],":".$name,$var,$size,$type);
}
else {
$rez = oci_bind_by_name($stmt[1],":".$name,$var,$size); // +1 byte for null terminator
}
}
return $rez;
}
function Param($name,$type=false)
function Param($name,$type='C')
{
return ':'.$name;
}
/*
Usage:
$stmt = $db->Prepare('select * from table where id =:myid and group=:group');
$db->Parameter($stmt,$id,'myid');
$db->Parameter($stmt,$group,'group');
$db->Execute($stmt);
@param $stmt Statement returned by Prepare() or PrepareSP().
@param $var PHP variable to bind to
@param $name Name of stored procedure variable name to bind to.
@param [$isOutput] Indicates direction of parameter 0/false=IN 1=OUT 2= IN/OUT. This is ignored in oci8.
@param [$maxLen] Holds an maximum length of the variable.
@param [$type] The data type of $var. Legal values depend on driver.
See OCIBindByName documentation at php.net.
/**
* Usage:
* $stmt = $db->Prepare('select * from table where id =:myid and group=:group');
* $db->Parameter($stmt,$id,'myid');
* $db->Parameter($stmt,$group,'group');
* $db->Execute($stmt);
*
* @param $stmt Statement returned by Prepare() or PrepareSP().
* @param $var PHP variable to bind to
* @param $name Name of stored procedure variable name to bind to.
* @param [$isOutput] Indicates direction of parameter 0/false=IN 1=OUT 2= IN/OUT. This is ignored in oci8.
* @param [$maxLen] Holds an maximum length of the variable.
* @param [$type] The data type of $var. Legal values depend on driver.
*
* @link http://php.net/oci_bind_by_name
*/
function Parameter(&$stmt,&$var,$name,$isOutput=false,$maxLen=4000,$type=false)
{
@@ -1016,28 +1210,28 @@ NATSOFT.DOMAIN =
}
return $this->Bind($stmt,$var,$maxLen,$type,$name,$isOutput);
}
/*
returns query ID if successful, otherwise false
this version supports:
1. $db->execute('select * from table');
2. $db->prepare('insert into table (a,b,c) values (:0,:1,:2)');
$db->execute($prepared_statement, array(1,2,3));
3. $db->execute('insert into table (a,b,c) values (:a,:b,:c)',array('a'=>1,'b'=>2,'c'=>3));
4. $db->prepare('insert into table (a,b,c) values (:0,:1,:2)');
$db->bind($stmt,1); $db->bind($stmt,2); $db->bind($stmt,3);
$db->execute($stmt);
*/
/**
* returns query ID if successful, otherwise false
* this version supports:
*
* 1. $db->execute('select * from table');
*
* 2. $db->prepare('insert into table (a,b,c) values (:0,:1,:2)');
* $db->execute($prepared_statement, array(1,2,3));
*
* 3. $db->execute('insert into table (a,b,c) values (:a,:b,:c)',array('a'=>1,'b'=>2,'c'=>3));
*
* 4. $db->prepare('insert into table (a,b,c) values (:0,:1,:2)');
* $db->bind($stmt,1); $db->bind($stmt,2); $db->bind($stmt,3);
* $db->execute($stmt);
*/
function _query($sql,$inputarr=false)
{
if (is_array($sql)) { // is prepared sql
$stmt = $sql[1];
// we try to bind to permanent array, so that OCIBindByName is persistent
// we try to bind to permanent array, so that oci_bind_by_name is persistent
// and carried out once only - note that max array element size is 4000 chars
if (is_array($inputarr)) {
$bindpos = $sql[3];
@@ -1049,53 +1243,64 @@ NATSOFT.DOMAIN =
$bindarr = array();
foreach($inputarr as $k => $v) {
$bindarr[$k] = $v;
OCIBindByName($stmt,":$k",$bindarr[$k],is_string($v) && strlen($v)>4000 ? -1 : 4000);
oci_bind_by_name($stmt,":$k",$bindarr[$k],is_string($v) && strlen($v)>4000 ? -1 : 4000);
}
$this->_bind[$bindpos] = $bindarr;
}
}
} else {
$stmt=OCIParse($this->_connectionID,$sql);
$stmt=oci_parse($this->_connectionID,$sql);
}
$this->_stmt = $stmt;
if (!$stmt) return false;
if (defined('ADODB_PREFETCH_ROWS')) @OCISetPrefetch($stmt,ADODB_PREFETCH_ROWS);
if (!$stmt) {
return false;
}
if (defined('ADODB_PREFETCH_ROWS')) {
@oci_set_prefetch($stmt,ADODB_PREFETCH_ROWS);
}
if (is_array($inputarr)) {
foreach($inputarr as $k => $v) {
if (is_array($v)) {
if (sizeof($v) == 2) // suggested by g.giunta@libero.
OCIBindByName($stmt,":$k",$inputarr[$k][0],$v[1]);
else
OCIBindByName($stmt,":$k",$inputarr[$k][0],$v[1],$v[2]);
// suggested by g.giunta@libero.
if (sizeof($v) == 2) {
oci_bind_by_name($stmt,":$k",$inputarr[$k][0],$v[1]);
}
else {
oci_bind_by_name($stmt,":$k",$inputarr[$k][0],$v[1],$v[2]);
}
if ($this->debug==99) {
if (is_object($v[0]))
if (is_object($v[0])) {
echo "name=:$k",' len='.$v[1],' type='.$v[2],'<br>';
else
}
else {
echo "name=:$k",' var='.$inputarr[$k][0],' len='.$v[1],' type='.$v[2],'<br>';
}
}
} else {
$len = -1;
if ($v === ' ') $len = 1;
if (isset($bindarr)) { // is prepared sql, so no need to ocibindbyname again
if ($v === ' ') {
$len = 1;
}
if (isset($bindarr)) { // is prepared sql, so no need to oci_bind_by_name again
$bindarr[$k] = $v;
} else { // dynamic sql, so rebind every time
OCIBindByName($stmt,":$k",$inputarr[$k],$len);
oci_bind_by_name($stmt,":$k",$inputarr[$k],$len);
}
}
}
}
$this->_errorMsg = false;
$this->_errorMsg = false;
$this->_errorCode = false;
if (OCIExecute($stmt,$this->_commit)) {
//OCIInternalDebug(1);
if (oci_execute($stmt,$this->_commit)) {
if (count($this -> _refLOBs) > 0) {
foreach ($this -> _refLOBs as $key => $value) {
if ($this -> _refLOBs[$key]['TYPE'] == true) {
$tmp = $this -> _refLOBs[$key]['LOB'] -> load();
@@ -1105,45 +1310,45 @@ NATSOFT.DOMAIN =
//$_GLOBALS[$this -> _refLOBs[$key]['VAR']] = $tmp;
$this -> _refLOBs[$key]['VAR'] = $tmp;
} else {
$this->_refLOBs[$key]['LOB']->save($this->_refLOBs[$key]['VAR']);
$this->_refLOBs[$key]['LOB']->save($this->_refLOBs[$key]['VAR']);
$this -> _refLOBs[$key]['LOB']->free();
unset($this -> _refLOBs[$key]);
if ($this->debug) {
if ($this->debug) {
ADOConnection::outp("<b>IN LOB</b>: LOB has been saved. <br>");
}
}
}
}
}
switch (@OCIStatementType($stmt)) {
case "SELECT":
switch (@oci_statement_type($stmt)) {
case "SELECT":
return $stmt;
case 'DECLARE':
case "BEGIN":
if (is_array($sql) && !empty($sql[4])) {
case "BEGIN":
if (is_array($sql) && !empty($sql[4])) {
$cursor = $sql[4];
if (is_resource($cursor)) {
$ok = OCIExecute($cursor);
return $cursor;
$ok = oci_execute($cursor);
return $cursor;
}
return $stmt;
} else {
} else {
if (is_resource($stmt)) {
OCIFreeStatement($stmt);
oci_free_statement($stmt);
return true;
}
return $stmt;
}
break;
default :
// ociclose -- no because it could be used in a LOB?
return true;
}
return $stmt;
}
break;
default :
return true;
}
}
return false;
}
// From Oracle Whitepaper: PHP Scalability and High Availability
function IsConnectionError($err)
{
@@ -1169,30 +1374,37 @@ NATSOFT.DOMAIN =
}
return false;
}
// returns true or false
function _close()
{
if (!$this->_connectionID) return;
if (!$this->autoCommit) OCIRollback($this->_connectionID);
if (!$this->_connectionID) {
return;
}
if (!$this->autoCommit) {
oci_rollback($this->_connectionID);
}
if (count($this->_refLOBs) > 0) {
foreach ($this ->_refLOBs as $key => $value) {
$this->_refLOBs[$key]['LOB']->free();
unset($this->_refLOBs[$key]);
}
}
OCILogoff($this->_connectionID);
oci_close($this->_connectionID);
$this->_stmt = false;
$this->_connectionID = false;
}
function MetaPrimaryKeys($table, $owner=false,$internalKey=false)
{
if ($internalKey) return array('ROWID');
// tested with oracle 8.1.7
if ($internalKey) {
return array('ROWID');
}
// tested with oracle 8.1.7
$table = strtoupper($table);
if ($owner) {
$owner_clause = "AND ((a.OWNER = b.OWNER) AND (a.OWNER = UPPER('$owner')))";
@@ -1210,7 +1422,7 @@ SELECT /*+ RULE */ distinct b.column_name
$owner_clause
AND (a.constraint_name = b.constraint_name)";
$rs = $this->Execute($sql);
$rs = $this->Execute($sql);
if ($rs && !$rs->EOF) {
$arr = $rs->GetArray();
$a = array();
@@ -1221,12 +1433,21 @@ SELECT /*+ RULE */ distinct b.column_name
}
else return false;
}
// http://gis.mit.edu/classes/11.521/sqlnotes/referential_integrity.html
function MetaForeignKeys($table, $owner=false)
/**
* returns assoc array where keys are tables, and values are foreign keys
*
* @param str $table
* @param str $owner [optional][default=NULL]
* @param bool $upper [optional][discarded]
* @return mixed[] Array of foreign key information
*
* @link http://gis.mit.edu/classes/11.521/sqlnotes/referential_integrity.html
*/
function MetaForeignKeys($table, $owner=false, $upper=false)
{
global $ADODB_FETCH_MODE;
global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$table = $this->qstr(strtoupper($table));
@@ -1235,14 +1456,14 @@ SELECT /*+ RULE */ distinct b.column_name
$tabp = 'user_';
} else
$tabp = 'all_';
$owner = ' and owner='.$this->qstr(strtoupper($owner));
$sql =
"select constraint_name,r_owner,r_constraint_name
$sql =
"select constraint_name,r_owner,r_constraint_name
from {$tabp}constraints
where constraint_type = 'R' and table_name = $table $owner";
$constraints = $this->GetArray($sql);
$arr = false;
foreach($constraints as $constr) {
@@ -1251,50 +1472,52 @@ SELECT /*+ RULE */ distinct b.column_name
$rcons = $this->qstr($constr[2]);
$cols = $this->GetArray("select column_name from {$tabp}cons_columns where constraint_name=$cons $owner order by position");
$tabcol = $this->GetArray("select table_name,column_name from {$tabp}cons_columns where owner=$rowner and constraint_name=$rcons order by position");
if ($cols && $tabcol)
if ($cols && $tabcol)
for ($i=0, $max=sizeof($cols); $i < $max; $i++) {
$arr[$tabcol[$i][0]] = $cols[$i][0].'='.$tabcol[$i][1];
}
}
$ADODB_FETCH_MODE = $save;
return $arr;
}
function CharMax()
{
return 4000;
}
function TextMax()
{
return 4000;
}
/**
* Quotes a string.
* An example is $db->qstr("Don't bother",magic_quotes_runtime());
*
* @param s the string to quote
* @param [magic_quotes] if $s is GET/POST var, set to get_magic_quotes_gpc().
* This undoes the stupidity of magic quotes for GPC.
*
* @return quoted string to be sent back to database
* @param string $s the string to quote
* @param bool $magic_quotes if $s is GET/POST var, set to get_magic_quotes_gpc().
* This undoes the stupidity of magic quotes for GPC.
*
* @return string quoted string to be sent back to database
*/
function qstr($s,$magic_quotes=false)
{
{
//$nofixquotes=false;
if ($this->noNullStrings && strlen($s)==0)$s = ' ';
if (!$magic_quotes) {
if ($this->noNullStrings && strlen($s)==0) {
$s = ' ';
}
if (!$magic_quotes) {
if ($this->replaceQuote[0] == '\\'){
$s = str_replace('\\','\\\\',$s);
}
return "'".str_replace("'",$this->replaceQuote,$s)."'";
}
// undo magic quotes for " unless sybase is on
if (!ini_get('magic_quotes_sybase')) {
$s = str_replace('\\"','"',$s);
@@ -1304,11 +1527,11 @@ SELECT /*+ RULE */ distinct b.column_name
return "'".$s."'";
}
}
}
/*--------------------------------------------------------------------------------------
Class Name: Recordset
Class Name: Recordset
--------------------------------------------------------------------------------------*/
class ADORecordset_oci8 extends ADORecordSet {
@@ -1316,25 +1539,27 @@ class ADORecordset_oci8 extends ADORecordSet {
var $databaseType = 'oci8';
var $bind=false;
var $_fieldobjs;
//var $_arr = false;
function ADORecordset_oci8($queryID,$mode=false)
function __construct($queryID,$mode=false)
{
if ($mode === false) {
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
switch ($mode)
{
case ADODB_FETCH_ASSOC:$this->fetchMode = OCI_ASSOC+OCI_RETURN_NULLS+OCI_RETURN_LOBS; break;
case ADODB_FETCH_DEFAULT:
case ADODB_FETCH_BOTH:$this->fetchMode = OCI_NUM+OCI_ASSOC+OCI_RETURN_NULLS+OCI_RETURN_LOBS; break;
case ADODB_FETCH_NUM:
default:
$this->fetchMode = OCI_NUM+OCI_RETURN_NULLS+OCI_RETURN_LOBS; break;
switch ($mode) {
case ADODB_FETCH_ASSOC:
$this->fetchMode = OCI_ASSOC;
break;
case ADODB_FETCH_DEFAULT:
case ADODB_FETCH_BOTH:
$this->fetchMode = OCI_NUM + OCI_ASSOC;
break;
case ADODB_FETCH_NUM:
default:
$this->fetchMode = OCI_NUM;
break;
}
$this->fetchMode += OCI_RETURN_NULLS + OCI_RETURN_LOBS;
$this->adodbFetchMode = $mode;
$this->_queryID = $queryID;
}
@@ -1342,22 +1567,29 @@ class ADORecordset_oci8 extends ADORecordSet {
function Init()
{
if ($this->_inited) return;
if ($this->_inited) {
return;
}
$this->_inited = true;
if ($this->_queryID) {
$this->_currentRow = 0;
@$this->_initrs();
$this->EOF = !$this->_fetch();
if ($this->_numOfFields) {
$this->EOF = !$this->_fetch();
}
else $this->EOF = true;
/*
// based on idea by Gaetano Giunta to detect unusual oracle errors
// see http://phplens.com/lens/lensforum/msgs.php?id=6771
$err = OCIError($this->_queryID);
if ($err && $this->connection->debug) ADOConnection::outp($err);
$err = oci_error($this->_queryID);
if ($err && $this->connection->debug) {
ADOConnection::outp($err);
}
*/
if (!is_array($this->fields)) {
$this->_numOfRows = 0;
$this->fields = array();
@@ -1369,11 +1601,11 @@ class ADORecordset_oci8 extends ADORecordSet {
$this->EOF = true;
}
}
function _initrs()
{
$this->_numOfRows = -1;
$this->_numOfFields = OCInumcols($this->_queryID);
$this->_numOfFields = oci_num_fields($this->_queryID);
if ($this->_numOfFields>0) {
$this->_fieldobjs = array();
$max = $this->_numOfFields;
@@ -1381,62 +1613,56 @@ class ADORecordset_oci8 extends ADORecordSet {
}
}
/* Returns: an object containing field information.
Get column information in the Recordset object. fetchField() can be used in order to obtain information about
fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
fetchField() is retrieved. */
/**
* Get column information in the Recordset object.
* fetchField() can be used in order to obtain information about fields
* in a certain query result. If the field offset isn't specified, the next
* field that wasn't yet retrieved by fetchField() is retrieved
*
* @return object containing field information
*/
function _FetchField($fieldOffset = -1)
{
$fld = new ADOFieldObject;
$fieldOffset += 1;
$fld->name =OCIcolumnname($this->_queryID, $fieldOffset);
$fld->type = OCIcolumntype($this->_queryID, $fieldOffset);
$fld->max_length = OCIcolumnsize($this->_queryID, $fieldOffset);
switch($fld->type) {
case 'NUMBER':
$p = OCIColumnPrecision($this->_queryID, $fieldOffset);
$sc = OCIColumnScale($this->_queryID, $fieldOffset);
if ($p != 0 && $sc == 0) $fld->type = 'INT';
break;
case 'CLOB':
case 'NCLOB':
case 'BLOB':
$fld->max_length = -1;
break;
$fld->name =oci_field_name($this->_queryID, $fieldOffset);
if (ADODB_ASSOC_CASE == ADODB_ASSOC_CASE_LOWER) {
$fld->name = strtolower($fld->name);
}
$fld->type = oci_field_type($this->_queryID, $fieldOffset);
$fld->max_length = oci_field_size($this->_queryID, $fieldOffset);
switch($fld->type) {
case 'NUMBER':
$p = oci_field_precision($this->_queryID, $fieldOffset);
$sc = oci_field_scale($this->_queryID, $fieldOffset);
if ($p != 0 && $sc == 0) {
$fld->type = 'INT';
}
$fld->scale = $p;
break;
case 'CLOB':
case 'NCLOB':
case 'BLOB':
$fld->max_length = -1;
break;
}
return $fld;
}
/* For some reason, OCIcolumnname fails when called after _initrs() so we cache it */
/* For some reason, oci_field_name fails when called after _initrs() so we cache it */
function FetchField($fieldOffset = -1)
{
return $this->_fieldobjs[$fieldOffset];
}
/*
// 10% speedup to move MoveNext to child class
function _MoveNext()
{
//global $ADODB_EXTENSION;if ($ADODB_EXTENSION) return @adodb_movenext($this);
if ($this->EOF) return false;
$this->_currentRow++;
if(@OCIfetchinto($this->_queryID,$this->fields,$this->fetchMode))
return true;
$this->EOF = true;
return false;
} */
function MoveNext()
{
if (@OCIfetchinto($this->_queryID,$this->fields,$this->fetchMode)) {
if ($this->fields = @oci_fetch_array($this->_queryID,$this->fetchMode)) {
$this->_currentRow += 1;
$this->_updatefields();
return true;
}
if (!$this->EOF) {
@@ -1445,65 +1671,37 @@ class ADORecordset_oci8 extends ADORecordSet {
}
return false;
}
/*
# does not work as first record is retrieved in _initrs(), so is not included in GetArray()
function GetArray($nRows = -1)
{
global $ADODB_OCI8_GETARRAY;
if (true || !empty($ADODB_OCI8_GETARRAY)) {
# does not support $ADODB_ANSI_PADDING_OFF
//OCI_RETURN_NULLS and OCI_RETURN_LOBS is set by OCIfetchstatement
switch($this->adodbFetchMode) {
case ADODB_FETCH_NUM:
$ncols = @OCIfetchstatement($this->_queryID, $results, 0, $nRows, OCI_FETCHSTATEMENT_BY_ROW+OCI_NUM);
$results = array_merge(array($this->fields),$results);
return $results;
case ADODB_FETCH_ASSOC:
if (ADODB_ASSOC_CASE != 2 || $this->databaseType != 'oci8') break;
$ncols = @OCIfetchstatement($this->_queryID, $assoc, 0, $nRows, OCI_FETCHSTATEMENT_BY_ROW);
$results = array_merge(array($this->fields),$assoc);
return $results;
default:
break;
}
}
$results = ADORecordSet::GetArray($nRows);
return $results;
} */
/* Optimize SelectLimit() by using OCIFetch() instead of OCIFetchInto() */
function GetArrayLimit($nrows,$offset=-1)
// Optimize SelectLimit() by using oci_fetch()
function GetArrayLimit($nrows,$offset=-1)
{
if ($offset <= 0) {
$arr = $this->GetArray($nrows);
return $arr;
}
$arr = array();
for ($i=1; $i < $offset; $i++)
if (!@OCIFetch($this->_queryID)) return $arr;
if (!@OCIfetchinto($this->_queryID,$this->fields,$this->fetchMode)) return $arr;;
for ($i=1; $i < $offset; $i++) {
if (!@oci_fetch($this->_queryID)) {
return $arr;
}
}
if (!$this->fields = @oci_fetch_array($this->_queryID,$this->fetchMode)) {
return $arr;
}
$this->_updatefields();
$results = array();
$cnt = 0;
while (!$this->EOF && $nrows != $cnt) {
$results[$cnt++] = $this->fields;
$this->MoveNext();
}
return $results;
}
/* Use associative array to get fields array */
// Use associative array to get fields array
function Fields($colname)
{
if (!$this->bind) {
@@ -1513,10 +1711,9 @@ class ADORecordset_oci8 extends ADORecordSet {
$this->bind[strtoupper($o->name)] = $i;
}
}
return $this->fields[$this->bind[strtoupper($colname)]];
return $this->fields[$this->bind[strtoupper($colname)]];
}
function _seek($row)
@@ -1524,93 +1721,98 @@ class ADORecordset_oci8 extends ADORecordSet {
return false;
}
function _fetch()
function _fetch()
{
return @OCIfetchinto($this->_queryID,$this->fields,$this->fetchMode);
$this->fields = @oci_fetch_array($this->_queryID,$this->fetchMode);
$this->_updatefields();
return $this->fields;
}
/* close() only needs to be called if you are worried about using too much memory while your script
is running. All associated result memory for the specified result identifier will automatically be freed. */
function _close()
/**
* close() only needs to be called if you are worried about using too much
* memory while your script is running. All associated result memory for the
* specified result identifier will automatically be freed.
*/
function _close()
{
if ($this->connection->_stmt === $this->_queryID) $this->connection->_stmt = false;
if ($this->connection->_stmt === $this->_queryID) {
$this->connection->_stmt = false;
}
if (!empty($this->_refcursor)) {
OCIFreeCursor($this->_refcursor);
oci_free_cursor($this->_refcursor);
$this->_refcursor = false;
}
@OCIFreeStatement($this->_queryID);
$this->_queryID = false;
@oci_free_statement($this->_queryID);
$this->_queryID = false;
}
function MetaType($t,$len=-1)
/**
* not the fastest implementation - quick and dirty - jlim
* for best performance, use the actual $rs->MetaType().
*
* @param mixed $t
* @param int $len [optional] Length of blobsize
* @param bool $fieldobj [optional][discarded]
* @return str The metatype of the field
*/
function MetaType($t, $len=-1, $fieldobj=false)
{
if (is_object($t)) {
$fieldobj = $t;
$t = $fieldobj->type;
$len = $fieldobj->max_length;
}
switch (strtoupper($t)) {
case 'VARCHAR':
case 'VARCHAR2':
case 'VARCHAR':
case 'VARCHAR2':
case 'CHAR':
case 'VARBINARY':
case 'BINARY':
case 'NCHAR':
case 'NVARCHAR':
case 'NVARCHAR2':
if ($len <= $this->blobSize) return 'C';
if ($len <= $this->blobSize) {
return 'C';
}
case 'NCLOB':
case 'LONG':
case 'LONG VARCHAR':
case 'CLOB':
return 'X';
case 'LONG RAW':
case 'LONG VARBINARY':
case 'BLOB':
return 'B';
case 'DATE':
case 'DATE':
return ($this->connection->datetime) ? 'T' : 'D';
case 'TIMESTAMP': return 'T';
case 'INT':
case 'INT':
case 'SMALLINT':
case 'INTEGER':
case 'INTEGER':
return 'I';
default: return 'N';
default:
return 'N';
}
}
}
class ADORecordSet_ext_oci8 extends ADORecordSet_oci8 {
function ADORecordSet_ext_oci8($queryID,$mode=false)
class ADORecordSet_ext_oci8 extends ADORecordSet_oci8 {
function __construct($queryID,$mode=false)
{
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
switch ($mode)
{
case ADODB_FETCH_ASSOC:$this->fetchMode = OCI_ASSOC+OCI_RETURN_NULLS+OCI_RETURN_LOBS; break;
case ADODB_FETCH_DEFAULT:
case ADODB_FETCH_BOTH:$this->fetchMode = OCI_NUM+OCI_ASSOC+OCI_RETURN_NULLS+OCI_RETURN_LOBS; break;
case ADODB_FETCH_NUM:
default: $this->fetchMode = OCI_NUM+OCI_RETURN_NULLS+OCI_RETURN_LOBS; break;
}
$this->adodbFetchMode = $mode;
$this->_queryID = $queryID;
parent::__construct($queryID, $mode);
}
function MoveNext()
{
return adodb_movenext($this);
}
}
?>
+17 -21
View File
@@ -1,12 +1,14 @@
<?php
/**
* @version V5.06 16 Oct 2008 (c) 2000-2009 John Lim (jlim#natsoft.com). 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.
/**
* @version v5.20.9 21-Dec-2016
* @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.
*
* Set tabs to 4 for best viewing.
*
*
* Latest version is available at http://php.weblogs.com
*
* Oracle 8.0.5 driver
@@ -18,14 +20,9 @@ if (!defined('ADODB_DIR')) die();
include_once(ADODB_DIR.'/drivers/adodb-oci8.inc.php');
class ADODB_oci805 extends ADODB_oci8 {
var $databaseType = "oci805";
var $databaseType = "oci805";
var $connectSID = true;
function ADODB_oci805()
{
$this->ADODB_oci8();
}
function SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
{
// seems that oracle only supports 1 hint comment in 8i
@@ -33,12 +30,12 @@ class ADODB_oci805 extends ADODB_oci8 {
$sql = str_replace('/*+ ','/*+FIRST_ROWS ',$sql);
else
$sql = preg_replace('/^[ \t\n]*select/i','SELECT /*+FIRST_ROWS*/',$sql);
/*
The following is only available from 8.1.5 because order by in inline views not
/*
The following is only available from 8.1.5 because order by in inline views not
available before then...
http://www.jlcomp.demon.co.uk/faq/top_sql.html
if ($nrows > 0) {
if ($nrows > 0) {
if ($offset > 0) $nrows += $offset;
$sql = "select * from ($sql) where rownum <= $nrows";
$nrows = -1;
@@ -49,11 +46,10 @@ class ADODB_oci805 extends ADODB_oci8 {
}
}
class ADORecordset_oci805 extends ADORecordset_oci8 {
class ADORecordset_oci805 extends ADORecordset_oci8 {
var $databaseType = "oci805";
function ADORecordset_oci805($id,$mode=false)
function __construct($id,$mode=false)
{
$this->ADORecordset_oci8($id,$mode);
parent::__construct($id,$mode);
}
}
?>
+102 -93
View File
@@ -1,12 +1,14 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim. All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim. 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 http://adodb.sourceforge.net
Portable version of oci8 driver, to make it more similar to other database drivers.
The main differences are
@@ -14,7 +16,7 @@ V5.09 25 June 2009 (c) 2000-2009 John Lim. All rights reserved.
2. bind variables are mapped using ? instead of :<bindvar>
Should some emulation of RecordCount() be implemented?
*/
// security - hide paths
@@ -27,28 +29,48 @@ class ADODB_oci8po extends ADODB_oci8 {
var $dataProvider = 'oci8';
var $metaColumnsSQL = "select lower(cname),coltype,width, SCALE, PRECISION, NULLS, DEFAULTVAL from col where tname='%s' order by colno"; //changed by smondino@users.sourceforge. net
var $metaTablesSQL = "select lower(table_name),table_type from cat where table_type in ('TABLE','VIEW')";
function ADODB_oci8po()
function __construct()
{
$this->_hasOCIFetchStatement = ADODB_PHPVER >= 0x4200;
# oci8po does not support adodb extension: adodb_movenext()
}
function Param($name)
function Param($name,$type='C')
{
return '?';
}
function Prepare($sql,$cursor=false)
{
$sqlarr = explode('?',$sql);
$sql = $sqlarr[0];
for ($i = 1, $max = sizeof($sqlarr); $i < $max; $i++) {
$sql .= ':'.($i-1) . $sqlarr[$i];
}
}
return ADODB_oci8::Prepare($sql,$cursor);
}
function Execute($sql,$inputarr=false)
{
return ADOConnection::Execute($sql,$inputarr);
}
/**
* The optimizations performed by ADODB_oci8::SelectLimit() are not
* compatible with the oci8po driver, so we rely on the slower method
* from the base class.
* We can't properly handle prepared statements either due to preprocessing
* of query parameters, so we treat them as regular SQL statements.
*/
function SelectLimit($sql, $nrows=-1, $offset=-1, $inputarr=false, $secs2cache=0)
{
if(is_array($sql)) {
// $sql = $sql[0];
}
return ADOConnection::SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
}
// emulate handling of parameters ? ?, replacing with :bind0 :bind1
function _query($sql,$inputarr=false)
{
@@ -57,13 +79,27 @@ class ADODB_oci8po extends ADODB_oci8 {
if (is_array($sql)) {
foreach($inputarr as $v) {
$arr['bind'.$i++] = $v;
}
} else {
$sqlarr = explode('?',$sql);
$sql = $sqlarr[0];
foreach($inputarr as $k => $v) {
$sql .= ":$k" . $sqlarr[++$i];
}
} else {
// Need to identify if the ? is inside a quoted string, and if
// so not use it as a bind variable
preg_match_all('/".*\??"|\'.*\?.*?\'/', $sql, $matches);
foreach($matches[0] as $qmMatch){
$qmReplace = str_replace('?', '-QUESTIONMARK-', $qmMatch);
$sql = str_replace($qmMatch, $qmReplace, $sql);
}
// Replace parameters if any were found
$sqlarr = explode('?',$sql);
if(count($sqlarr) > 1) {
$sql = $sqlarr[0];
foreach ($inputarr as $k => $v) {
$sql .= ":$k" . $sqlarr[++$i];
}
}
$sql = str_replace('-QUESTIONMARK-', '?', $sql);
}
}
return ADODB_oci8::_query($sql,$inputarr);
@@ -77,16 +113,16 @@ class ADODB_oci8po extends ADODB_oci8 {
class ADORecordset_oci8po extends ADORecordset_oci8 {
var $databaseType = 'oci8po';
function ADORecordset_oci8po($queryID,$mode=false)
function __construct($queryID,$mode=false)
{
$this->ADORecordset_oci8($queryID,$mode);
parent::__construct($queryID,$mode);
}
function Fields($colname)
{
if ($this->fetchMode & OCI_ASSOC) return $this->fields[$colname];
if (!$this->bind) {
$this->bind = array();
for ($i=0; $i < $this->_numOfFields; $i++) {
@@ -96,45 +132,37 @@ class ADORecordset_oci8po extends ADORecordset_oci8 {
}
return $this->fields[$this->bind[strtoupper($colname)]];
}
// lowercase field names...
function _FetchField($fieldOffset = -1)
{
$fld = new ADOFieldObject;
$fieldOffset += 1;
$fld->name = OCIcolumnname($this->_queryID, $fieldOffset);
if (ADODB_ASSOC_CASE == 0) $fld->name = strtolower($fld->name);
$fld->type = OCIcolumntype($this->_queryID, $fieldOffset);
$fld->max_length = OCIcolumnsize($this->_queryID, $fieldOffset);
if ($fld->type == 'NUMBER') {
//$p = OCIColumnPrecision($this->_queryID, $fieldOffset);
$fld = new ADOFieldObject;
$fieldOffset += 1;
$fld->name = OCIcolumnname($this->_queryID, $fieldOffset);
if (ADODB_ASSOC_CASE == ADODB_ASSOC_CASE_LOWER) {
$fld->name = strtolower($fld->name);
}
$fld->type = OCIcolumntype($this->_queryID, $fieldOffset);
$fld->max_length = OCIcolumnsize($this->_queryID, $fieldOffset);
if ($fld->type == 'NUMBER') {
$sc = OCIColumnScale($this->_queryID, $fieldOffset);
if ($sc == 0) $fld->type = 'INT';
}
return $fld;
if ($sc == 0) {
$fld->type = 'INT';
}
}
return $fld;
}
/*
function MoveNext()
{
if (@OCIfetchinto($this->_queryID,$this->fields,$this->fetchMode)) {
$this->_currentRow += 1;
return true;
}
if (!$this->EOF) {
$this->_currentRow += 1;
$this->EOF = true;
}
return false;
}*/
// 10% speedup to move MoveNext to child class
function MoveNext()
function MoveNext()
{
if(@OCIfetchinto($this->_queryID,$this->fields,$this->fetchMode)) {
$ret = @oci_fetch_array($this->_queryID,$this->fetchMode);
if($ret !== false) {
global $ADODB_ANSI_PADDING_OFF;
$this->fields = $ret;
$this->_currentRow++;
if ($this->fetchMode & OCI_ASSOC) $this->_updatefields();
$this->_updatefields();
if (!empty($ADODB_ANSI_PADDING_OFF)) {
foreach($this->fields as $k => $v) {
if (is_string($v)) $this->fields[$k] = rtrim($v);
@@ -147,72 +175,53 @@ class ADORecordset_oci8po extends ADORecordset_oci8 {
$this->_currentRow++;
}
return false;
}
}
/* Optimize SelectLimit() by using OCIFetch() instead of OCIFetchInto() */
function GetArrayLimit($nrows,$offset=-1)
function GetArrayLimit($nrows,$offset=-1)
{
if ($offset <= 0) {
$arr = $this->GetArray($nrows);
return $arr;
}
for ($i=1; $i < $offset; $i++)
for ($i=1; $i < $offset; $i++)
if (!@OCIFetch($this->_queryID)) {
$arr = array();
return $arr;
}
if (!@OCIfetchinto($this->_queryID,$this->fields,$this->fetchMode)) {
$ret = @oci_fetch_array($this->_queryID,$this->fetchMode);
if ($ret === false) {
$arr = array();
return $arr;
}
if ($this->fetchMode & OCI_ASSOC) $this->_updatefields();
$this->fields = $ret;
$this->_updatefields();
$results = array();
$cnt = 0;
while (!$this->EOF && $nrows != $cnt) {
$results[$cnt++] = $this->fields;
$this->MoveNext();
}
return $results;
}
// Create associative array
function _updatefields()
function _fetch()
{
if (ADODB_ASSOC_CASE == 2) return; // native
$arr = array();
$lowercase = (ADODB_ASSOC_CASE == 0);
foreach($this->fields as $k => $v) {
if (is_integer($k)) $arr[$k] = $v;
else {
if ($lowercase)
$arr[strtolower($k)] = $v;
else
$arr[strtoupper($k)] = $v;
global $ADODB_ANSI_PADDING_OFF;
$ret = @oci_fetch_array($this->_queryID,$this->fetchMode);
if ($ret) {
$this->fields = $ret;
$this->_updatefields();
if (!empty($ADODB_ANSI_PADDING_OFF)) {
foreach($this->fields as $k => $v) {
if (is_string($v)) $this->fields[$k] = rtrim($v);
}
}
}
$this->fields = $arr;
return $ret !== false;
}
function _fetch()
{
$ret = @OCIfetchinto($this->_queryID,$this->fields,$this->fetchMode);
if ($ret) {
global $ADODB_ANSI_PADDING_OFF;
if ($this->fetchMode & OCI_ASSOC) $this->_updatefields();
if (!empty($ADODB_ANSI_PADDING_OFF)) {
foreach($this->fields as $k => $v) {
if (is_string($v)) $this->fields[$k] = rtrim($v);
}
}
}
return $ret;
}
}
?>
@@ -0,0 +1,89 @@
<?php
/*
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim. 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 http://adodb.sourceforge.net
Portable version of oci8 driver, to make it more similar to other database drivers.
The main differences are
1. that the OCI_ASSOC names are in lowercase instead of uppercase.
2. bind variables are mapped using ? instead of :<bindvar>
Should some emulation of RecordCount() be implemented?
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
include_once(ADODB_DIR.'/drivers/adodb-oci8.inc.php');
class ADODB_oci8quercus extends ADODB_oci8 {
var $databaseType = 'oci8quercus';
var $dataProvider = 'oci8';
function __construct()
{
}
}
/*--------------------------------------------------------------------------------------
Class Name: Recordset
--------------------------------------------------------------------------------------*/
class ADORecordset_oci8quercus extends ADORecordset_oci8 {
var $databaseType = 'oci8quercus';
function __construct($queryID,$mode=false)
{
parent::__construct($queryID,$mode);
}
function _FetchField($fieldOffset = -1)
{
global $QUERCUS;
$fld = new ADOFieldObject;
if (!empty($QUERCUS)) {
$fld->name = oci_field_name($this->_queryID, $fieldOffset);
$fld->type = oci_field_type($this->_queryID, $fieldOffset);
$fld->max_length = oci_field_size($this->_queryID, $fieldOffset);
//if ($fld->name == 'VAL6_NUM_12_4') $fld->type = 'NUMBER';
switch($fld->type) {
case 'string': $fld->type = 'VARCHAR'; break;
case 'real': $fld->type = 'NUMBER'; break;
}
} else {
$fieldOffset += 1;
$fld->name = oci_field_name($this->_queryID, $fieldOffset);
$fld->type = oci_field_type($this->_queryID, $fieldOffset);
$fld->max_length = oci_field_size($this->_queryID, $fieldOffset);
}
switch($fld->type) {
case 'NUMBER':
$p = oci_field_precision($this->_queryID, $fieldOffset);
$sc = oci_field_scale($this->_queryID, $fieldOffset);
if ($p != 0 && $sc == 0) $fld->type = 'INT';
$fld->scale = $p;
break;
case 'CLOB':
case 'NCLOB':
case 'BLOB':
$fld->max_length = -1;
break;
}
return $fld;
}
}
+158 -158
View File
@@ -1,26 +1,28 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). 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.
/*
@version v5.20.9 21-Dec-2016
@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.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
Requires ODBC. Works on Windows and Unix.
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
define("_ADODB_ODBC_LAYER", 2 );
/*--------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------*/
class ADODB_odbc extends ADOConnection {
var $databaseType = "odbc";
var $databaseType = "odbc";
var $fmtDate = "'Y-m-d'";
var $fmtTimeStamp = "'Y-m-d, h:i:sA'";
var $replaceQuote = "''"; // string to use to replace quotes
@@ -30,7 +32,7 @@ class ADODB_odbc extends ADOConnection {
var $useFetchArray = false; // setting this to true will make array elements in FETCH_ASSOC mode case-sensitive
// breaking backward-compat
//var $longreadlen = 8000; // default number of chars to return for a Blob/Long field
var $_bindInputArray = false;
var $_bindInputArray = false;
var $curmode = SQL_CUR_USE_DRIVER; // See sqlext.h, SQL_CUR_DEFAULT == SQL_CUR_USE_DRIVER == 2L
var $_genSeqSQL = "create table %s (id integer)";
var $_autocommit = true;
@@ -38,39 +40,43 @@ class ADODB_odbc extends ADOConnection {
var $_has_stupid_odbc_fetch_api_change = true;
var $_lastAffectedRows = 0;
var $uCaseTables = true; // for meta* functions, uppercase table names
function ADODB_odbc()
{
function __construct()
{
$this->_haserrorfunctions = ADODB_PHPVER >= 0x4050;
$this->_has_stupid_odbc_fetch_api_change = ADODB_PHPVER >= 0x4200;
}
// returns true or false
function _connect($argDSN, $argUsername, $argPassword, $argDatabasename)
{
global $php_errormsg;
if (!function_exists('odbc_connect')) return null;
if ($this->debug && $argDatabasename && $this->databaseType != 'vfp') {
ADOConnection::outp("For odbc Connect(), $argDatabasename is not used. Place dsn in 1st parameter.");
if (!empty($argDatabasename) && stristr($argDSN, 'Database=') === false) {
$argDSN = trim($argDSN);
$endDSN = substr($argDSN, strlen($argDSN) - 1);
if ($endDSN != ';') $argDSN .= ';';
$argDSN .= 'Database='.$argDatabasename;
}
if (isset($php_errormsg)) $php_errormsg = '';
if ($this->curmode === false) $this->_connectionID = odbc_connect($argDSN,$argUsername,$argPassword);
else $this->_connectionID = odbc_connect($argDSN,$argUsername,$argPassword,$this->curmode);
$this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
if (isset($this->connectStmt)) $this->Execute($this->connectStmt);
return $this->_connectionID != false;
}
// returns true or false
function _pconnect($argDSN, $argUsername, $argPassword, $argDatabasename)
{
global $php_errormsg;
if (!function_exists('odbc_connect')) return null;
if (isset($php_errormsg)) $php_errormsg = '';
$this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
if ($this->debug && $argDatabasename) {
@@ -79,27 +85,27 @@ class ADODB_odbc extends ADOConnection {
// print "dsn=$argDSN u=$argUsername p=$argPassword<br>"; flush();
if ($this->curmode === false) $this->_connectionID = odbc_connect($argDSN,$argUsername,$argPassword);
else $this->_connectionID = odbc_pconnect($argDSN,$argUsername,$argPassword,$this->curmode);
$this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
if ($this->_connectionID && $this->autoRollback) @odbc_rollback($this->_connectionID);
if (isset($this->connectStmt)) $this->Execute($this->connectStmt);
return $this->_connectionID != false;
}
function ServerInfo()
{
if (!empty($this->host) && ADODB_PHPVER >= 0x4300) {
$dsn = strtoupper($this->host);
$first = true;
$found = false;
if (!function_exists('odbc_data_source')) return false;
while(true) {
$rez = @odbc_data_source($this->_connectionID,
$first ? SQL_FETCH_FIRST : SQL_FETCH_NEXT);
$first = false;
@@ -108,7 +114,7 @@ class ADODB_odbc extends ADOConnection {
$found = true;
break;
}
}
}
if (!$found) return ADOConnection::ServerInfo();
if (!isset($rez['version'])) $rez['version'] = '';
return $rez;
@@ -117,7 +123,7 @@ class ADODB_odbc extends ADOConnection {
}
}
function CreateSequence($seqname='adodbseq',$start=1)
{
if (empty($this->_genSeqSQL)) return false;
@@ -126,22 +132,22 @@ class ADODB_odbc extends ADOConnection {
$start -= 1;
return $this->Execute("insert into $seqname values($start)");
}
var $_dropSeqSQL = 'drop table %s';
function DropSequence($seqname)
function DropSequence($seqname = 'adodbseq')
{
if (empty($this->_dropSeqSQL)) return false;
return $this->Execute(sprintf($this->_dropSeqSQL,$seqname));
}
/*
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.
*/
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;
@@ -149,18 +155,24 @@ class ADODB_odbc extends ADOConnection {
while (--$MAXLOOPS>=0) {
$num = $this->GetOne("select id from $seq");
if ($num === false) {
$this->Execute(sprintf($this->_genSeqSQL ,$seq));
$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;
} elseif ($this->affected_rows() == 0) {
// some drivers do not return a valid value => try with another method
$value = $this->GetOne("select id from $seq");
if ($value == $num + 1) {
return $value;
}
}
}
if ($fn = $this->raiseErrorFn) {
@@ -178,40 +190,40 @@ class ADODB_odbc extends ADOConnection {
return @odbc_errormsg($this->_connectionID);
} else return ADOConnection::ErrorMsg();
}
function ErrorNo()
{
if ($this->_haserrorfunctions) {
if ($this->_errorCode !== false) {
// bug in 4.0.6, error number can be corrupted string (should be 6 digits)
return (strlen($this->_errorCode)<=2) ? 0 : $this->_errorCode;
}
if (empty($this->_connectionID)) $e = @odbc_error();
if (empty($this->_connectionID)) $e = @odbc_error();
else $e = @odbc_error($this->_connectionID);
// bug in 4.0.6, error number can be corrupted string (should be 6 digits)
// so we check and patch
if (strlen($e)<=2) return 0;
return $e;
} else return ADOConnection::ErrorNo();
}
function BeginTrans()
{
{
if (!$this->hasTransactions) return false;
if ($this->transOff) return true;
if ($this->transOff) return true;
$this->transCnt += 1;
$this->_autocommit = false;
return odbc_autocommit($this->_connectionID,false);
}
function CommitTrans($ok=true)
{
if ($this->transOff) return true;
function CommitTrans($ok=true)
{
if ($this->transOff) return true;
if (!$ok) return $this->RollbackTrans();
if ($this->transCnt) $this->transCnt -= 1;
$this->_autocommit = true;
@@ -219,21 +231,21 @@ class ADODB_odbc extends ADOConnection {
odbc_autocommit($this->_connectionID,true);
return $ret;
}
function RollbackTrans()
{
if ($this->transOff) return true;
if ($this->transOff) return true;
if ($this->transCnt) $this->transCnt -= 1;
$this->_autocommit = true;
$ret = odbc_rollback($this->_connectionID);
odbc_autocommit($this->_connectionID,true);
return $ret;
}
function MetaPrimaryKeys($table)
function MetaPrimaryKeys($table,$owner=false)
{
global $ADODB_FETCH_MODE;
if ($this->uCaseTables) $table = strtoupper($table);
$schema = '';
$this->_findschema($table,$schema);
@@ -241,17 +253,17 @@ class ADODB_odbc extends ADOConnection {
$savem = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$qid = @odbc_primarykeys($this->_connectionID,'',$schema,$table);
if (!$qid) {
$ADODB_FETCH_MODE = $savem;
return false;
}
$rs = new ADORecordSet_odbc($qid);
$ADODB_FETCH_MODE = $savem;
if (!$rs) return false;
$rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
$arr = $rs->GetArray();
$rs->Close();
//print_r($arr);
@@ -261,39 +273,39 @@ class ADODB_odbc extends ADOConnection {
}
return $arr2;
}
function MetaTables($ttype=false)
function MetaTables($ttype=false,$showSchema=false,$mask=false)
{
global $ADODB_FETCH_MODE;
$savem = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$qid = odbc_tables($this->_connectionID);
$rs = new ADORecordSet_odbc($qid);
$ADODB_FETCH_MODE = $savem;
if (!$rs) {
$false = false;
return $false;
}
$rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
$arr = $rs->GetArray();
//print_r($arr);
$rs->Close();
$arr2 = array();
if ($ttype) {
$isview = strncmp($ttype,'V',1) === 0;
}
for ($i=0; $i < sizeof($arr); $i++) {
if (!$arr[$i][2]) continue;
$type = $arr[$i][3];
if ($ttype) {
if ($ttype) {
if ($isview) {
if (strncmp($type,'V',1) === 0) $arr2[] = $arr[$i][2];
} else if (strncmp($type,'SYS',3) !== 0) $arr2[] = $arr[$i][2];
@@ -301,7 +313,7 @@ class ADODB_odbc extends ADOConnection {
}
return $arr2;
}
/*
See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/odbcdatetime_data_type_changes.asp
/ SQL data type codes /
@@ -333,7 +345,7 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/od
function ODBCTypes($t)
{
switch ((integer)$t) {
case 1:
case 1:
case 12:
case 0:
case -95:
@@ -344,52 +356,52 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/od
return 'X';
case -4: //image
return 'B';
case 9:
case 9:
case 91:
return 'D';
case 10:
case 11:
case 92:
case 93:
return 'T';
case 4:
case 5:
case -6:
return 'I';
case -11: // uniqidentifier
return 'R';
case -7: //bit
return 'L';
default:
return 'N';
}
}
function MetaColumns($table, $normalize=true)
{
global $ADODB_FETCH_MODE;
$false = false;
if ($this->uCaseTables) $table = strtoupper($table);
$schema = '';
$this->_findschema($table,$schema);
$savem = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
/*if (false) { // after testing, confirmed that the following does not work becoz of a bug
$qid2 = odbc_tables($this->_connectionID);
$rs = new ADORecordSet_odbc($qid2);
$rs = new ADORecordSet_odbc($qid2);
$ADODB_FETCH_MODE = $savem;
if (!$rs) return false;
$rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
$rs->_fetch();
while (!$rs->EOF) {
if ($table == strtoupper($rs->fields[2])) {
$q = $rs->fields[0];
@@ -399,38 +411,38 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/od
$rs->MoveNext();
}
$rs->Close();
$qid = odbc_columns($this->_connectionID,$q,$o,strtoupper($table),'%');
} */
switch ($this->databaseType) {
case 'access':
case 'vfp':
$qid = odbc_columns($this->_connectionID);#,'%','',strtoupper($table),'%');
break;
case 'db2':
$colname = "%";
$qid = odbc_columns($this->_connectionID, "", $schema, $table, $colname);
break;
default:
$qid = @odbc_columns($this->_connectionID,'%','%',strtoupper($table),'%');
if (empty($qid)) $qid = odbc_columns($this->_connectionID);
break;
}
if (empty($qid)) return $false;
$rs = new ADORecordSet_odbc($qid);
$ADODB_FETCH_MODE = $savem;
if (!$rs) return $false;
$rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
$rs->_fetch();
$retarr = array();
/*
$rs->fields indices
0 TABLE_QUALIFIER
@@ -452,31 +464,31 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/od
$fld = new ADOFieldObject();
$fld->name = $rs->fields[3];
$fld->type = $this->ODBCTypes($rs->fields[4]);
// ref: http://msdn.microsoft.com/library/default.asp?url=/archive/en-us/dnaraccgen/html/msdn_odk.asp
// access uses precision to store length for char/varchar
if ($fld->type == 'C' or $fld->type == 'X') {
if ($this->databaseType == 'access')
if ($this->databaseType == 'access')
$fld->max_length = $rs->fields[6];
else if ($rs->fields[4] <= -95) // UNICODE
$fld->max_length = $rs->fields[7]/2;
else
$fld->max_length = $rs->fields[7];
} else
} else
$fld->max_length = $rs->fields[7];
$fld->not_null = !empty($rs->fields[10]);
$fld->scale = $rs->fields[8];
$retarr[strtoupper($fld->name)] = $fld;
$retarr[strtoupper($fld->name)] = $fld;
} else if (sizeof($retarr)>0)
break;
$rs->MoveNext();
}
$rs->Close(); //-- crashes 4.03pl1 -- why?
if (empty($retarr)) $retarr = false;
return $retarr;
}
function Prepare($sql)
{
if (! $this->_bindInputArray) return $sql; // no binding
@@ -489,24 +501,24 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/od
}
/* returns queryID or false */
function _query($sql,$inputarr=false)
function _query($sql,$inputarr=false)
{
GLOBAL $php_errormsg;
if (isset($php_errormsg)) $php_errormsg = '';
$this->_error = '';
if ($inputarr) {
if (is_array($sql)) {
$stmtid = $sql[1];
} else {
$stmtid = odbc_prepare($this->_connectionID,$sql);
if ($stmtid == false) {
$this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
return false;
}
}
if (! odbc_execute($stmtid,$inputarr)) {
//@odbc_free_result($stmtid);
if ($this->_haserrorfunctions) {
@@ -515,7 +527,7 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/od
}
return false;
}
} else if (is_array($sql)) {
$stmtid = $sql[1];
if (!odbc_execute($stmtid)) {
@@ -528,7 +540,7 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/od
}
} else
$stmtid = odbc_exec($this->_connectionID,$sql);
$this->_lastAffectedRows = 0;
if ($stmtid) {
if (@odbc_num_fields($stmtid) == 0) {
@@ -539,7 +551,7 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/od
odbc_binmode($stmtid,$this->binmode);
odbc_longreadlen($stmtid,$this->maxblobsize);
}
if ($this->_haserrorfunctions) {
$this->_errorMsg = '';
$this->_errorCode = 0;
@@ -558,9 +570,9 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/od
/*
Insert a null into the blob field of the table first.
Then use UpdateBlob to store the blob.
Usage:
$conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, null)');
$conn->UpdateBlob('blobtable','blobcol',$blob,'id=1');
*/
@@ -568,7 +580,7 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/od
{
return $this->Execute("UPDATE $table SET $column=? WHERE $where",array($val)) != false;
}
// returns true or false
function _close()
{
@@ -581,44 +593,44 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/od
{
return $this->_lastAffectedRows;
}
}
/*--------------------------------------------------------------------------------------
Class Name: Recordset
--------------------------------------------------------------------------------------*/
class ADORecordSet_odbc extends ADORecordSet {
class ADORecordSet_odbc extends ADORecordSet {
var $bind = false;
var $databaseType = "odbc";
var $databaseType = "odbc";
var $dataProvider = "odbc";
var $useFetchArray;
var $_has_stupid_odbc_fetch_api_change;
function ADORecordSet_odbc($id,$mode=false)
function __construct($id,$mode=false)
{
if ($mode === false) {
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
$this->fetchMode = $mode;
$this->_queryID = $id;
// the following is required for mysql odbc driver in 4.3.1 -- why?
$this->EOF = false;
$this->_currentRow = -1;
//$this->ADORecordSet($id);
//parent::__construct($id);
}
// returns the field object
function FetchField($fieldOffset = -1)
function FetchField($fieldOffset = -1)
{
$off=$fieldOffset+1; // offsets begin at 1
$o= new ADOFieldObject();
$o->name = @odbc_field_name($this->_queryID,$off);
$o->type = @odbc_field_type($this->_queryID,$off);
@@ -627,7 +639,7 @@ class ADORecordSet_odbc extends ADORecordSet {
else if (ADODB_ASSOC_CASE == 1) $o->name = strtoupper($o->name);
return $o;
}
/* Use associative array to get fields array */
function Fields($colname)
{
@@ -642,8 +654,8 @@ class ADORecordSet_odbc extends ADORecordSet {
return $this->fields[$this->bind[strtoupper($colname)]];
}
function _initrs()
{
global $ADODB_COUNTRECS;
@@ -653,15 +665,15 @@ class ADORecordSet_odbc extends ADORecordSet {
if ($this->_numOfRows == 0) $this->_numOfRows = -1;
//$this->useFetchArray = $this->connection->useFetchArray;
$this->_has_stupid_odbc_fetch_api_change = ADODB_PHPVER >= 0x4200;
}
}
function _seek($row)
{
return false;
}
// speed up SelectLimit() by switching to ADODB_FETCH_NUM as ADODB_FETCH_ASSOC is emulated
function GetArrayLimit($nrows,$offset=-1)
function GetArrayLimit($nrows,$offset=-1)
{
if ($offset <= 0) {
$rs = $this->GetArray($nrows);
@@ -671,48 +683,38 @@ class ADORecordSet_odbc extends ADORecordSet {
$this->fetchMode = ADODB_FETCH_NUM;
$this->Move($offset);
$this->fetchMode = $savem;
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
$this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
$this->fields = $this->GetRowAssoc();
}
$results = array();
$cnt = 0;
while (!$this->EOF && $nrows != $cnt) {
$results[$cnt++] = $this->fields;
$this->MoveNext();
}
return $results;
}
function MoveNext()
function MoveNext()
{
if ($this->_numOfRows != 0 && !$this->EOF) {
if ($this->_numOfRows != 0 && !$this->EOF) {
$this->_currentRow++;
if ($this->_has_stupid_odbc_fetch_api_change)
$rez = @odbc_fetch_into($this->_queryID,$this->fields);
else {
$row = 0;
$rez = @odbc_fetch_into($this->_queryID,$row,$this->fields);
}
if ($rez) {
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
$this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
}
if( $this->_fetch() ) {
return true;
}
}
$this->fields = false;
$this->EOF = true;
return false;
}
}
function _fetch()
{
$this->fields = false;
if ($this->_has_stupid_odbc_fetch_api_change)
$rez = @odbc_fetch_into($this->_queryID,$this->fields);
else {
@@ -721,18 +723,16 @@ class ADORecordSet_odbc extends ADORecordSet {
}
if ($rez) {
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
$this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
$this->fields = $this->GetRowAssoc();
}
return true;
}
$this->fields = false;
return false;
}
function _close()
function _close()
{
return @odbc_free_result($this->_queryID);
return @odbc_free_result($this->_queryID);
}
}
?>
+72 -71
View File
@@ -1,15 +1,17 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). 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.
/*
@version v5.20.9 21-Dec-2016
@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.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
DB2 data driver. Requires ODBC.
From phpdb list:
Hi Andrew,
@@ -40,18 +42,18 @@ Kind regards,
Christian Szardenings
2 Oct 2001
Mark Newnham has discovered that the SQL_CUR_USE_ODBC is not supported by
Mark Newnham has discovered that the SQL_CUR_USE_ODBC is not supported by
IBM's DB2 ODBC driver, so this must be a 3rd party ODBC driver.
From the IBM CLI Reference:
SQL_ATTR_ODBC_CURSORS (DB2 CLI v5)
SQL_ATTR_ODBC_CURSORS (DB2 CLI v5)
This connection attribute is defined by ODBC, but is not supported by DB2
CLI. Any attempt to set or get this attribute will result in an SQLSTATE of
HYC00 (Driver not capable).
HYC00 (Driver not capable).
A 32-bit option specifying how the Driver Manager uses the ODBC cursor
library.
library.
So I guess this means the message [above] was related to using a 3rd party
odbc driver.
@@ -69,15 +71,15 @@ $db->Connect($dsn, $userid, $pwd);
USING CLI INTERFACE
===================
I have had reports that the $host and $database params have to be reversed in
I have had reports that the $host and $database params have to be reversed in
Connect() when using the CLI interface. From Halmai Csongor csongor.halmai#nexum.hu:
> The symptom is that if I change the database engine from postgres or any other to DB2 then the following
> connection command becomes wrong despite being described this version to be correct in the docs.
> connection command becomes wrong despite being described this version to be correct in the docs.
>
> $connection_object->Connect( $DATABASE_HOST, $DATABASE_AUTH_USER_NAME, $DATABASE_AUTH_PASSWORD, $DATABASE_NAME )
>
> In case of DB2 I had to swap the first and last arguments in order to connect properly.
> In case of DB2 I had to swap the first and last arguments in order to connect properly.
System Error 5
@@ -96,12 +98,12 @@ if (!defined('ADODB_ODBC_DB2')){
define('ADODB_ODBC_DB2',1);
class ADODB_ODBC_DB2 extends ADODB_odbc {
var $databaseType = "db2";
var $databaseType = "db2";
var $concat_operator = '||';
var $sysTime = 'CURRENT TIME';
var $sysDate = 'CURRENT DATE';
var $sysTimeStamp = 'CURRENT TIMESTAMP';
// The complete string representation of a timestamp has the form
// The complete string representation of a timestamp has the form
// yyyy-mm-dd-hh.mm.ss.nnnnnn.
var $fmtTimeStamp = "'Y-m-d-H.i.s'";
var $ansiOuter = true;
@@ -109,18 +111,18 @@ class ADODB_ODBC_DB2 extends ADODB_odbc {
var $_bindInputArray = true;
var $hasInsertID = true;
var $rsPrefix = 'ADORecordset_odbc_';
function ADODB_DB2()
function __construct()
{
if (strncmp(PHP_OS,'WIN',3) === 0) $this->curmode = SQL_CUR_USE_ODBC;
$this->ADODB_odbc();
parent::__construct();
}
function IfNull( $field, $ifNull )
function IfNull( $field, $ifNull )
{
return " COALESCE($field, $ifNull) "; // if DB2 UDB
}
function ServerInfo()
{
//odbc_setoption($this->_connectionID,1,101 /*SQL_ATTR_ACCESS_MODE*/, 1 /*SQL_MODE_READ_ONLY*/);
@@ -128,54 +130,54 @@ class ADODB_ODBC_DB2 extends ADODB_odbc {
//odbc_setoption($this->_connectionID,1,101, 0 /*SQL_MODE_READ_WRITE*/);
return array('description'=>'DB2 ODBC driver', 'version'=>$vers);
}
function _insertid()
{
return $this->GetOne($this->identitySQL);
}
function RowLock($tables,$where,$flds='1 as ignore')
function RowLock($tables,$where,$col='1 as adodbignore')
{
if ($this->_autocommit) $this->BeginTrans();
return $this->GetOne("select $flds from $tables where $where for update");
return $this->GetOne("select $col from $tables where $where for update");
}
function MetaTables($ttype=false,$showSchema=false, $qtable="%", $qschema="%")
{
global $ADODB_FETCH_MODE;
$savem = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$qid = odbc_tables($this->_connectionID, "", $qschema, $qtable, "");
$rs = new ADORecordSet_odbc($qid);
$ADODB_FETCH_MODE = $savem;
if (!$rs) {
$false = false;
return $false;
}
$rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
$arr = $rs->GetArray();
//print_r($arr);
$rs->Close();
$arr2 = array();
if ($ttype) {
$isview = strncmp($ttype,'V',1) === 0;
}
for ($i=0; $i < sizeof($arr); $i++) {
if (!$arr[$i][2]) continue;
if (strncmp($arr[$i][1],'SYS',3) === 0) continue;
$type = $arr[$i][3];
if ($showSchema) $arr[$i][2] = $arr[$i][1].'.'.$arr[$i][2];
if ($ttype) {
if ($ttype) {
if ($isview) {
if (strncmp($type,'V',1) === 0) $arr2[] = $arr[$i][2];
} else if (strncmp($type,'T',1) === 0) $arr2[] = $arr[$i][2];
@@ -197,11 +199,11 @@ class ADODB_ODBC_DB2 extends ADODB_odbc {
// get index details
$table = strtoupper($table);
$SQL="SELECT NAME, UNIQUERULE, COLNAMES FROM SYSIBM.SYSINDEXES WHERE TBNAME='$table'";
if ($primary)
if ($primary)
$SQL.= " AND UNIQUERULE='P'";
$rs = $this->Execute($SQL);
if (!is_object($rs)) {
if (isset($savem))
if (isset($savem))
$this->SetFetchMode($savem);
$ADODB_FETCH_MODE = $save;
return $false;
@@ -216,20 +218,20 @@ class ADODB_ODBC_DB2 extends ADODB_odbc {
$cols = ltrim($row[2],'+');
$indexes[$row[0]]['columns'] = explode('+', $cols);
}
if (isset($savem)) {
if (isset($savem)) {
$this->SetFetchMode($savem);
$ADODB_FETCH_MODE = $save;
}
return $indexes;
}
// Format date column in sql string given an input format that understands Y M D
function SQLDate($fmt, $col=false)
{
{
// use right() and replace() ?
if (!$col) $col = $this->sysDate;
$s = '';
$len = strlen($fmt);
for ($i=0; $i < $len; $i++) {
if ($s) $s .= '||';
@@ -251,7 +253,7 @@ class ADODB_ODBC_DB2 extends ADODB_odbc {
break;
case 'H':
case 'h':
if ($col != $this->sysDate) $s .= "right(digits(hour($col)),2)";
if ($col != $this->sysDate) $s .= "right(digits(hour($col)),2)";
else $s .= "''";
break;
case 'i':
@@ -275,10 +277,10 @@ class ADODB_ODBC_DB2 extends ADODB_odbc {
}
}
return $s;
}
function SelectLimit($sql,$nrows=-1,$offset=-1,$inputArr=false)
}
function SelectLimit($sql, $nrows = -1, $offset = -1, $inputArr = false, $secs2cache = 0)
{
$nrows = (integer) $nrows;
if ($offset <= 0) {
@@ -293,20 +295,20 @@ class ADODB_ODBC_DB2 extends ADODB_odbc {
}
$rs = ADOConnection::SelectLimit($sql,-1,$offset,$inputArr);
}
return $rs;
}
};
class ADORecordSet_odbc_db2 extends ADORecordSet_odbc {
var $databaseType = "db2";
function ADORecordSet_db2($id,$mode=false)
};
class ADORecordSet_odbc_db2 extends ADORecordSet_odbc {
var $databaseType = "db2";
function __construct($id,$mode=false)
{
$this->ADORecordSet_odbc($id,$mode);
parent::__construct($id,$mode);
}
function MetaType($t,$len=-1,$fieldobj=false)
@@ -316,53 +318,52 @@ class ADORecordSet_odbc_db2 extends ADORecordSet_odbc {
$t = $fieldobj->type;
$len = $fieldobj->max_length;
}
switch (strtoupper($t)) {
case 'VARCHAR':
case 'CHAR':
case 'CHARACTER':
case 'C':
if ($len <= $this->blobSize) return 'C';
case 'LONGCHAR':
case 'TEXT':
case 'CLOB':
case 'DBCLOB': // double-byte
case 'X':
return 'X';
case 'BLOB':
case 'GRAPHIC':
case 'VARGRAPHIC':
return 'B';
case 'DATE':
case 'D':
return 'D';
case 'TIME':
case 'TIMESTAMP':
case 'T':
return 'T';
//case 'BOOLEAN':
//case 'BOOLEAN':
//case 'BIT':
// return 'L';
//case 'COUNTER':
// return 'R';
case 'INT':
case 'INTEGER':
case 'BIGINT':
case 'SMALLINT':
case 'I':
return 'I';
default: return 'N';
}
}
}
} //define
?>
+135 -78
View File
@@ -1,14 +1,16 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). 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.
/*
@version v5.20.9 21-Dec-2016
@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.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
MSSQL support via ODBC. Requires ODBC. Works on Windows and Unix.
MSSQL support via ODBC. Requires ODBC. Works on Windows and Unix.
For Unix configuration, see http://phpbuilder.com/columns/alberto20000919.php3
*/
@@ -19,14 +21,19 @@ if (!defined('_ADODB_ODBC_LAYER')) {
include(ADODB_DIR."/drivers/adodb-odbc.inc.php");
}
class ADODB_odbc_mssql extends ADODB_odbc {
class ADODB_odbc_mssql extends ADODB_odbc {
var $databaseType = 'odbc_mssql';
var $fmtDate = "'Y-m-d'";
var $fmtTimeStamp = "'Y-m-d H:i:s'";
var $fmtTimeStamp = "'Y-m-d\TH:i:s'";
var $_bindInputArray = true;
var $metaDatabasesSQL = "select name from sysdatabases where name <> 'master'";
var $metaTablesSQL="select name,case when type='U' then 'T' else 'V' end from sysobjects where (type='U' or type='V') and (name not in ('sysallocations','syscolumns','syscomments','sysdepends','sysfilegroups','sysfiles','sysfiles1','sysforeignkeys','sysfulltextcatalogs','sysindexes','sysindexkeys','sysmembers','sysobjects','syspermissions','sysprotects','sysreferences','systypes','sysusers','sysalternates','sysconstraints','syssegments','REFERENTIAL_CONSTRAINTS','CHECK_CONSTRAINTS','CONSTRAINT_TABLE_USAGE','CONSTRAINT_COLUMN_USAGE','VIEWS','VIEW_TABLE_USAGE','VIEW_COLUMN_USAGE','SCHEMATA','TABLES','TABLE_CONSTRAINTS','TABLE_PRIVILEGES','COLUMNS','COLUMN_DOMAIN_USAGE','COLUMN_PRIVILEGES','DOMAINS','DOMAIN_CONSTRAINTS','KEY_COLUMN_USAGE'))";
var $metaColumnsSQL = "select c.name,t.name,c.length from syscolumns c join systypes t on t.xusertype=c.xusertype join sysobjects o on o.id=c.id where o.name='%s'";
var $metaColumnsSQL = # xtype==61 is datetime
"select c.name,t.name,c.length,c.isnullable, c.status,
(case when c.xusertype=61 then 0 else c.xprec end),
(case when c.xusertype=61 then 0 else c.xscale end)
from syscolumns c join systypes t on t.xusertype=c.xusertype join sysobjects o on o.id=c.id where o.name='%s'";
var $hasTop = 'top'; // support mssql/interbase SELECT TOP 10 * FROM TABLE
var $sysDate = 'GetDate()';
var $sysTimeStamp = 'GetDate()';
@@ -37,13 +44,13 @@ class ADODB_odbc_mssql extends ADODB_odbc {
var $ansiOuter = true; // for mssql7 or later
var $identitySQL = 'select SCOPE_IDENTITY()'; // 'select SCOPE_IDENTITY'; # for mssql 2000
var $hasInsertID = true;
var $connectStmt = 'SET CONCAT_NULL_YIELDS_NULL OFF'; # When SET CONCAT_NULL_YIELDS_NULL is ON,
var $connectStmt = 'SET CONCAT_NULL_YIELDS_NULL OFF'; # When SET CONCAT_NULL_YIELDS_NULL is ON,
# concatenating a null value with a string yields a NULL result
function ADODB_odbc_mssql()
function __construct()
{
$this->ADODB_odbc();
//$this->curmode = SQL_CUR_USE_ODBC;
parent::__construct();
//$this->curmode = SQL_CUR_USE_ODBC;
}
// crashes php...
@@ -60,31 +67,31 @@ class ADODB_odbc_mssql extends ADODB_odbc {
return $arr;
}
function IfNull( $field, $ifNull )
function IfNull( $field, $ifNull )
{
return " ISNULL($field, $ifNull) "; // if MS SQL Server
}
function _insertid()
{
// SCOPE_IDENTITY()
// Returns the last IDENTITY value inserted into an IDENTITY column in
// the same scope. A scope is a module -- a stored procedure, trigger,
// function, or batch. Thus, two statements are in the same scope if
// Returns the last IDENTITY value inserted into an IDENTITY column in
// the same scope. A scope is a module -- a stored procedure, trigger,
// function, or batch. Thus, two statements are in the same scope if
// they are in the same stored procedure, function, or batch.
return $this->GetOne($this->identitySQL);
}
function MetaForeignKeys($table, $owner=false, $upper=false)
{
global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$table = $this->qstr(strtoupper($table));
$sql =
$sql =
"select object_name(constid) as constraint_name,
col_name(fkeyid, fkey) as column_name,
object_name(rkeyid) as referenced_table_name,
@@ -92,20 +99,20 @@ class ADODB_odbc_mssql extends ADODB_odbc {
from sysforeignkeys
where upper(object_name(fkeyid)) = $table
order by constraint_name, referenced_table_name, keyno";
$constraints = $this->GetArray($sql);
$ADODB_FETCH_MODE = $save;
$arr = false;
foreach($constraints as $constr) {
//print_r($constr);
$arr[$constr[0]][$constr[2]][] = $constr[1].'='.$constr[3];
$arr[$constr[0]][$constr[2]][] = $constr[1].'='.$constr[3];
}
if (!$arr) return false;
$arr2 = false;
foreach($arr as $k => $v) {
foreach($v as $a => $b) {
if ($upper) $a = strtoupper($a);
@@ -114,38 +121,89 @@ order by constraint_name, referenced_table_name, keyno";
}
return $arr2;
}
function MetaTables($ttype=false,$showSchema=false,$mask=false)
function MetaTables($ttype=false,$showSchema=false,$mask=false)
{
if ($mask) {$this->debug=1;
if ($mask) {//$this->debug=1;
$save = $this->metaTablesSQL;
$mask = $this->qstr($mask);
$this->metaTablesSQL .= " AND name like $mask";
}
$ret = ADOConnection::MetaTables($ttype,$showSchema);
if ($mask) {
$this->metaTablesSQL = $save;
}
return $ret;
}
function MetaColumns($table, $normalize=true)
{
$arr = ADOConnection::MetaColumns($table);
return $arr;
$this->_findschema($table,$schema);
if ($schema) {
$dbName = $this->database;
$this->SelectDB($schema);
}
global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
$rs = $this->Execute(sprintf($this->metaColumnsSQL,$table));
if ($schema) {
$this->SelectDB($dbName);
}
if (isset($savem)) $this->SetFetchMode($savem);
$ADODB_FETCH_MODE = $save;
if (!is_object($rs)) {
$false = false;
return $false;
}
$retarr = array();
while (!$rs->EOF){
$fld = new ADOFieldObject();
$fld->name = $rs->fields[0];
$fld->type = $rs->fields[1];
$fld->not_null = (!$rs->fields[3]);
$fld->auto_increment = ($rs->fields[4] == 128); // sys.syscolumns status field. 0x80 = 128 ref: http://msdn.microsoft.com/en-us/library/ms186816.aspx
if (isset($rs->fields[5]) && $rs->fields[5]) {
if ($rs->fields[5]>0) $fld->max_length = $rs->fields[5];
$fld->scale = $rs->fields[6];
if ($fld->scale>0) $fld->max_length += 1;
} else
$fld->max_length = $rs->fields[2];
if ($save == ADODB_FETCH_NUM) {
$retarr[] = $fld;
} else {
$retarr[strtoupper($fld->name)] = $fld;
}
$rs->MoveNext();
}
$rs->Close();
return $retarr;
}
function MetaIndexes($table,$primary=false, $owner=false)
{
$table = $this->qstr($table);
$sql = "SELECT i.name AS ind_name, C.name AS col_name, USER_NAME(O.uid) AS Owner, c.colid, k.Keyno,
$sql = "SELECT i.name AS ind_name, C.name AS col_name, USER_NAME(O.uid) AS Owner, c.colid, k.Keyno,
CASE WHEN I.indid BETWEEN 1 AND 254 AND (I.status & 2048 = 2048 OR I.Status = 16402 AND O.XType = 'V') THEN 1 ELSE 0 END AS IsPK,
CASE WHEN I.status & 2 = 2 THEN 1 ELSE 0 END AS IsUnique
FROM dbo.sysobjects o INNER JOIN dbo.sysindexes I ON o.id = i.id
INNER JOIN dbo.sysindexkeys K ON I.id = K.id AND I.Indid = K.Indid
FROM dbo.sysobjects o INNER JOIN dbo.sysindexes I ON o.id = i.id
INNER JOIN dbo.sysindexkeys K ON I.id = K.id AND I.Indid = K.Indid
INNER JOIN dbo.syscolumns c ON K.id = C.id AND K.colid = C.Colid
WHERE LEFT(i.name, 8) <> '_WA_Sys_' AND o.status >= 0 AND O.Name LIKE $table
ORDER BY O.name, I.Name, K.keyno";
@@ -156,7 +214,7 @@ order by constraint_name, referenced_table_name, keyno";
if ($this->fetchMode !== FALSE) {
$savem = $this->SetFetchMode(FALSE);
}
$rs = $this->Execute($sql);
if (isset($savem)) {
$this->SetFetchMode($savem);
@@ -170,20 +228,20 @@ order by constraint_name, referenced_table_name, keyno";
$indexes = array();
while ($row = $rs->FetchRow()) {
if (!$primary && $row[5]) continue;
$indexes[$row[0]]['unique'] = $row[6];
$indexes[$row[0]]['columns'][] = $row[1];
}
return $indexes;
}
function _query($sql,$inputarr=false)
{
if (is_string($sql)) $sql = str_replace('||','+',$sql);
return ADODB_odbc::_query($sql,$inputarr);
}
function SetTransactionMode( $transaction_mode )
function SetTransactionMode( $transaction_mode )
{
$this->_transmode = $transaction_mode;
if (empty($transaction_mode)) {
@@ -193,33 +251,33 @@ order by constraint_name, referenced_table_name, keyno";
if (!stristr($transaction_mode,'isolation')) $transaction_mode = 'ISOLATION LEVEL '.$transaction_mode;
$this->Execute("SET TRANSACTION ".$transaction_mode);
}
// "Stein-Aksel Basma" <basma@accelero.no>
// tested with MSSQL 2000
function MetaPrimaryKeys($table)
function MetaPrimaryKeys($table, $owner = false)
{
global $ADODB_FETCH_MODE;
$schema = '';
$this->_findschema($table,$schema);
//if (!$schema) $schema = $this->database;
if ($schema) $schema = "and k.table_catalog like '$schema%'";
if ($schema) $schema = "and k.table_catalog like '$schema%'";
$sql = "select distinct k.column_name,ordinal_position from information_schema.key_column_usage k,
information_schema.table_constraints tc
information_schema.table_constraints tc
where tc.constraint_name = k.constraint_name and tc.constraint_type =
'PRIMARY KEY' and k.table_name = '$table' $schema order by ordinal_position ";
$savem = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
$a = $this->GetCol($sql);
$ADODB_FETCH_MODE = $savem;
if ($a && sizeof($a)>0) return $a;
$false = false;
return $false;
return $false;
}
function SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
{
if ($nrows > 0 && $offset <= 0) {
@@ -228,16 +286,16 @@ order by constraint_name, referenced_table_name, keyno";
$rs = $this->Execute($sql,$inputarr);
} else
$rs = ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
return $rs;
}
// Format date column in sql string given an input format that understands Y M D
function SQLDate($fmt, $col=false)
{
{
if (!$col) $col = $this->sysTimeStamp;
$s = '';
$len = strlen($fmt);
for ($i=0; $i < $len; $i++) {
if ($s) $s .= '+';
@@ -264,11 +322,11 @@ order by constraint_name, referenced_table_name, keyno";
case 'h':
$s .= "substring(convert(char(14),$col,0),13,2)";
break;
case 'H':
$s .= "replace(str(datepart(hh,$col),2),' ','0')";
break;
case 'i':
$s .= "replace(str(datepart(mi,$col),2),' ','0')";
break;
@@ -279,7 +337,7 @@ order by constraint_name, referenced_table_name, keyno";
case 'A':
$s .= "substring(convert(char(19),$col,0),18,2)";
break;
default:
if ($ch == '\\') {
$i++;
@@ -292,15 +350,14 @@ order by constraint_name, referenced_table_name, keyno";
return $s;
}
}
class ADORecordSet_odbc_mssql extends ADORecordSet_odbc {
var $databaseType = 'odbc_mssql';
function ADORecordSet_odbc_mssql($id,$mode=false)
{
return $this->ADORecordSet_odbc($id,$mode);
}
}
?>
class ADORecordSet_odbc_mssql extends ADORecordSet_odbc {
var $databaseType = 'odbc_mssql';
function __construct($id,$mode=false)
{
return parent::__construct($id,$mode);
}
}
+35 -39
View File
@@ -1,14 +1,16 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). 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.
/*
@version v5.20.9 21-Dec-2016
@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.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
Oracle support via ODBC. Requires ODBC. Works on Windows.
Oracle support via ODBC. Requires ODBC. Works on Windows.
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
@@ -17,26 +19,21 @@ if (!defined('_ADODB_ODBC_LAYER')) {
include(ADODB_DIR."/drivers/adodb-odbc.inc.php");
}
class ADODB_odbc_oracle extends ADODB_odbc {
class ADODB_odbc_oracle extends ADODB_odbc {
var $databaseType = 'odbc_oracle';
var $replaceQuote = "''"; // string to use to replace quotes
var $concat_operator='||';
var $fmtDate = "'Y-m-d 00:00:00'";
var $fmtDate = "'Y-m-d 00:00:00'";
var $fmtTimeStamp = "'Y-m-d h:i:sA'";
var $metaTablesSQL = 'select table_name from cat';
var $metaColumnsSQL = "select cname,coltype,width from col where tname='%s' order by colno";
var $sysDate = "TRUNC(SYSDATE)";
var $sysTimeStamp = 'SYSDATE';
//var $_bindInputArray = false;
function ADODB_odbc_oracle()
{
$this->ADODB_odbc();
}
function MetaTables()
function MetaTables($ttype = false, $showSchema = false, $mask = false)
{
$false = false;
$rs = $this->Execute($this->metaTablesSQL);
@@ -49,13 +46,13 @@ class ADODB_odbc_oracle extends ADODB_odbc {
$rs->Close();
return $arr2;
}
function MetaColumns($table, $normalize=true)
function MetaColumns($table, $normalize=true)
{
global $ADODB_FETCH_MODE;
$rs = $this->Execute(sprintf($this->metaColumnsSQL,strtoupper($table)));
if ($rs === false) {
if ($rs === false) {
$false = false;
return $false;
}
@@ -65,26 +62,26 @@ class ADODB_odbc_oracle extends ADODB_odbc {
$fld->name = $rs->fields[0];
$fld->type = $rs->fields[1];
$fld->max_length = $rs->fields[2];
if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;
if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;
else $retarr[strtoupper($fld->name)] = $fld;
$rs->MoveNext();
}
$rs->Close();
return $retarr;
return $retarr;
}
// returns true or false
function _connect($argDSN, $argUsername, $argPassword, $argDatabasename)
{
global $php_errormsg;
$php_errormsg = '';
$this->_connectionID = odbc_connect($argDSN,$argUsername,$argPassword,SQL_CUR_USE_ODBC );
$this->_errorMsg = $php_errormsg;
$this->Execute("ALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS'");
//if ($this->_connectionID) odbc_autocommit($this->_connectionID,true);
return $this->_connectionID != false;
@@ -96,20 +93,19 @@ class ADODB_odbc_oracle extends ADODB_odbc {
$php_errormsg = '';
$this->_connectionID = odbc_pconnect($argDSN,$argUsername,$argPassword,SQL_CUR_USE_ODBC );
$this->_errorMsg = $php_errormsg;
$this->Execute("ALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS'");
//if ($this->_connectionID) odbc_autocommit($this->_connectionID,true);
return $this->_connectionID != false;
}
}
class ADORecordSet_odbc_oracle extends ADORecordSet_odbc {
}
class ADORecordSet_odbc_oracle extends ADORecordSet_odbc {
var $databaseType = 'odbc_oracle';
function ADORecordSet_odbc_oracle($id,$mode=false)
function __construct($id,$mode=false)
{
return $this->ADORecordSet_odbc($id,$mode);
return parent::__construct($id,$mode);
}
}
?>
+53 -49
View File
@@ -1,6 +1,8 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved.
@version v5.20.9 21-Dec-2016
@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. See License.txt.
@@ -33,7 +35,7 @@ class ADODB_odbtp extends ADOConnection{
var $_canPrepareSP = false;
var $_dontPoolDBC = true;
function ADODB_odbtp()
function __construct()
{
}
@@ -61,23 +63,23 @@ class ADODB_odbtp extends ADOConnection{
{
if (empty($d) && $d !== 0) return 'null';
if ($isfld) return "convert(date, $d, 120)";
if (is_string($d)) $d = ADORecordSet::UnixDate($d);
$d = adodb_date($this->fmtDate,$d);
return "convert(date, $d, 120)";
return "convert(date, $d, 120)";
}
function DBTimeStamp($d,$isfld=false)
{
if (empty($d) && $d !== 0) return 'null';
if ($isfld) return "convert(datetime, $d, 120)";
if (is_string($d)) $d = ADORecordSet::UnixDate($d);
$d = adodb_date($this->fmtDate,$d);
return "convert(datetime, $d, 120)";
return "convert(datetime, $d, 120)";
}
*/
function _insertid()
{
// SCOPE_IDENTITY()
@@ -120,7 +122,7 @@ class ADODB_odbtp extends ADOConnection{
return $this->Execute("insert into adodb_seq values('$seqname',$start)");
}
function DropSequence($seqname)
function DropSequence($seqname = 'adodbseq')
{
if (empty($this->_dropSeqSQL)) return false;
return $this->Execute(sprintf($this->_dropSeqSQL,$seqname));
@@ -172,14 +174,17 @@ class ADODB_odbtp extends ADOConnection{
//if uid & pwd can be separate
function _connect($HostOrInterface, $UserOrDSN='', $argPassword='', $argDatabase='')
{
$this->_connectionID = odbtp_connect($HostOrInterface,$UserOrDSN,$argPassword,$argDatabase);
if ($argPassword && stripos($UserOrDSN,'DRIVER=') !== false) {
$this->_connectionID = odbtp_connect($HostOrInterface,$UserOrDSN.';PWD='.$argPassword);
} else
$this->_connectionID = odbtp_connect($HostOrInterface,$UserOrDSN,$argPassword,$argDatabase);
if ($this->_connectionID === false) {
$this->_errorMsg = $this->ErrorMsg() ;
return false;
}
odbtp_convert_datetime($this->_connectionID,true);
if ($this->_dontPoolDBC) {
if (function_exists('odbtp_dont_pool_dbc'))
@odbtp_dont_pool_dbc($this->_connectionID);
@@ -190,7 +195,7 @@ class ADODB_odbtp extends ADOConnection{
$this->odbc_driver = @odbtp_get_attr(ODB_ATTR_DRIVER, $this->_connectionID);
$dbms = strtolower(@odbtp_get_attr(ODB_ATTR_DBMSNAME, $this->_connectionID));
$this->odbc_name = $dbms;
// Account for inconsistent DBMS names
if( $this->odbc_driver == ODB_DRIVER_ORACLE )
$dbms = 'oracle';
@@ -295,7 +300,7 @@ class ADODB_odbtp extends ADOConnection{
$this->databaseName = $dbName; # obsolete, retained for compat with older adodb versions
return true;
}
function MetaTables($ttype='',$showSchema=false,$mask=false)
{
global $ADODB_FETCH_MODE;
@@ -303,9 +308,9 @@ class ADODB_odbtp extends ADOConnection{
$savem = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== false) $savefm = $this->SetFetchMode(false);
$arr = $this->GetArray("||SQLTables||||$ttype");
if (isset($savefm)) $this->SetFetchMode($savefm);
$ADODB_FETCH_MODE = $savem;
@@ -317,7 +322,7 @@ class ADODB_odbtp extends ADOConnection{
}
return $arr2;
}
function MetaColumns($table,$upper=true)
{
global $ADODB_FETCH_MODE;
@@ -329,9 +334,9 @@ class ADODB_odbtp extends ADOConnection{
$savem = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== false) $savefm = $this->SetFetchMode(false);
$rs = $this->Execute( "||SQLColumns||$schema|$table" );
if (isset($savefm)) $this->SetFetchMode($savefm);
$ADODB_FETCH_MODE = $savem;
@@ -399,7 +404,7 @@ class ADODB_odbtp extends ADOConnection{
$false = false;
return $false;
}
$arr2 = array();
foreach($arr as $k => $v) {
@@ -460,10 +465,10 @@ class ADODB_odbtp extends ADOConnection{
function Prepare($sql)
{
if (! $this->_bindInputArray) return $sql; // no binding
$this->_errorMsg = false;
$this->_errorCode = false;
$stmt = @odbtp_prepare($sql,$this->_connectionID);
if (!$stmt) {
// print "Prepare Error for ($sql) ".$this->ErrorMsg()."<br>";
@@ -472,13 +477,13 @@ class ADODB_odbtp extends ADOConnection{
return array($sql,$stmt,false);
}
function PrepareSP($sql)
function PrepareSP($sql, $param = true)
{
if (!$this->_canPrepareSP) return $sql; // Can't prepare procedures
$this->_errorMsg = false;
$this->_errorCode = false;
$stmt = @odbtp_prepare_proc($sql,$this->_connectionID);
if (!$stmt) return false;
return array($sql,$stmt);
@@ -550,16 +555,16 @@ class ADODB_odbtp extends ADOConnection{
return array();
}
}
function MetaIndexes_mssql($table,$primary=false)
function MetaIndexes_mssql($table,$primary=false, $owner = false)
{
$table = strtolower($this->qstr($table));
$sql = "SELECT i.name AS ind_name, C.name AS col_name, USER_NAME(O.uid) AS Owner, c.colid, k.Keyno,
$sql = "SELECT i.name AS ind_name, C.name AS col_name, USER_NAME(O.uid) AS Owner, c.colid, k.Keyno,
CASE WHEN I.indid BETWEEN 1 AND 254 AND (I.status & 2048 = 2048 OR I.Status = 16402 AND O.XType = 'V') THEN 1 ELSE 0 END AS IsPK,
CASE WHEN I.status & 2 = 2 THEN 1 ELSE 0 END AS IsUnique
FROM dbo.sysobjects o INNER JOIN dbo.sysindexes I ON o.id = i.id
INNER JOIN dbo.sysindexkeys K ON I.id = K.id AND I.Indid = K.Indid
FROM dbo.sysobjects o INNER JOIN dbo.sysindexes I ON o.id = i.id
INNER JOIN dbo.sysindexkeys K ON I.id = K.id AND I.Indid = K.Indid
INNER JOIN dbo.syscolumns c ON K.id = C.id AND K.colid = C.Colid
WHERE LEFT(i.name, 8) <> '_WA_Sys_' AND o.status >= 0 AND lower(O.Name) = $table
ORDER BY O.name, I.Name, K.keyno";
@@ -570,7 +575,7 @@ class ADODB_odbtp extends ADOConnection{
if ($this->fetchMode !== FALSE) {
$savem = $this->SetFetchMode(FALSE);
}
$rs = $this->Execute($sql);
if (isset($savem)) {
$this->SetFetchMode($savem);
@@ -584,13 +589,13 @@ class ADODB_odbtp extends ADOConnection{
$indexes = array();
while ($row = $rs->FetchRow()) {
if ($primary && !$row[5]) continue;
$indexes[$row[0]]['unique'] = $row[6];
$indexes[$row[0]]['columns'][] = $row[1];
}
return $indexes;
}
function IfNull( $field, $ifNull )
{
switch( $this->odbc_driver ) {
@@ -605,10 +610,10 @@ class ADODB_odbtp extends ADOConnection{
function _query($sql,$inputarr=false)
{
global $php_errormsg;
$this->_errorMsg = false;
$this->_errorCode = false;
if ($inputarr) {
if (is_array($sql)) {
$stmtid = $sql[1];
@@ -625,7 +630,7 @@ class ADODB_odbtp extends ADOConnection{
@odbtp_input( $stmtid, $param );
@odbtp_set( $stmtid, $param, $inputarr[$param-1] );
}*/
$param = 1;
foreach($inputarr as $v) {
@odbtp_input( $stmtid, $param );
@@ -633,7 +638,7 @@ class ADODB_odbtp extends ADOConnection{
$param += 1;
if ($param > $num_params) break;
}
if (!@odbtp_execute($stmtid) ) {
return false;
}
@@ -665,14 +670,14 @@ class ADORecordSet_odbtp extends ADORecordSet {
var $databaseType = 'odbtp';
var $canSeek = true;
function ADORecordSet_odbtp($queryID,$mode=false)
function __construct($queryID,$mode=false)
{
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
$this->fetchMode = $mode;
$this->ADORecordSet($queryID);
parent::__construct($queryID);
}
function _initrs()
@@ -788,9 +793,9 @@ class ADORecordSet_odbtp_mssql extends ADORecordSet_odbtp {
var $databaseType = 'odbtp_mssql';
function ADORecordSet_odbtp_mssql($id,$mode=false)
function __construct($id,$mode=false)
{
return $this->ADORecordSet_odbtp($id,$mode);
return parent::__construct($id,$mode);
}
}
@@ -798,9 +803,9 @@ class ADORecordSet_odbtp_access extends ADORecordSet_odbtp {
var $databaseType = 'odbtp_access';
function ADORecordSet_odbtp_access($id,$mode=false)
function __construct($id,$mode=false)
{
return $this->ADORecordSet_odbtp($id,$mode);
return parent::__construct($id,$mode);
}
}
@@ -808,9 +813,9 @@ class ADORecordSet_odbtp_vfp extends ADORecordSet_odbtp {
var $databaseType = 'odbtp_vfp';
function ADORecordSet_odbtp_vfp($id,$mode=false)
function __construct($id,$mode=false)
{
return $this->ADORecordSet_odbtp($id,$mode);
return parent::__construct($id,$mode);
}
}
@@ -818,9 +823,9 @@ class ADORecordSet_odbtp_oci8 extends ADORecordSet_odbtp {
var $databaseType = 'odbtp_oci8';
function ADORecordSet_odbtp_oci8($id,$mode=false)
function __construct($id,$mode=false)
{
return $this->ADORecordSet_odbtp($id,$mode);
return parent::__construct($id,$mode);
}
}
@@ -828,9 +833,8 @@ class ADORecordSet_odbtp_sybase extends ADORecordSet_odbtp {
var $databaseType = 'odbtp_sybase';
function ADORecordSet_odbtp_sybase($id,$mode=false)
function __construct($id,$mode=false)
{
return $this->ADORecordSet_odbtp($id,$mode);
return parent::__construct($id,$mode);
}
}
?>
@@ -1,6 +1,8 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved.
@version v5.20.9 21-Dec-2016
@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. See License.txt.
@@ -30,10 +32,4 @@ if (!defined('_ADODB_ODBTP_LAYER')) {
class ADODB_odbtp_unicode extends ADODB_odbtp {
var $databaseType = 'odbtp';
var $_useUnicodeSQL = true;
function ADODB_odbtp_unicode()
{
$this->ADODB_odbtp();
}
}
?>
+50 -49
View File
@@ -1,14 +1,16 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
@version v5.20.9 21-Dec-2016
@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 http://adodb.sourceforge.net
Oracle data driver. Requires Oracle client. Works on Windows and Unix and Oracle 7.
If you are using Oracle 8 or later, use the oci8 driver which is much better and more reliable.
*/
@@ -21,27 +23,27 @@ class ADODB_oracle extends ADOConnection {
var $concat_operator='||';
var $_curs;
var $_initdate = true; // init date to YYYY-MM-DD
var $metaTablesSQL = 'select table_name from cat';
var $metaTablesSQL = 'select table_name from cat';
var $metaColumnsSQL = "select cname,coltype,width from col where tname='%s' order by colno";
var $sysDate = "TO_DATE(TO_CHAR(SYSDATE,'YYYY-MM-DD'),'YYYY-MM-DD')";
var $sysTimeStamp = 'SYSDATE';
var $connectSID = true;
function ADODB_oracle()
function __construct()
{
}
// format and return date string in database date format
function DBDate($d)
function DBDate($d, $isfld = false)
{
if (is_string($d)) $d = ADORecordSet::UnixDate($d);
if (is_object($d)) $ds = $d->format($this->fmtDate);
else $ds = adodb_date($this->fmtDate,$d);
return 'TO_DATE('.$ds.",'YYYY-MM-DD')";
}
// format and return date string in database timestamp format
function DBTimeStamp($ts)
function DBTimeStamp($ts, $isfld = false)
{
if (is_string($ts)) $ts = ADORecordSet::UnixTimeStamp($ts);
@@ -49,43 +51,43 @@ class ADODB_oracle extends ADOConnection {
else $ds = adodb_date($this->fmtTimeStamp,$ts);
return 'TO_DATE('.$ds.",'RRRR-MM-DD, HH:MI:SS AM')";
}
function BindDate($d)
{
$d = ADOConnection::DBDate($d);
if (strncmp($d,"'",1)) return $d;
return substr($d,1,strlen($d)-2);
}
function BindTimeStamp($d)
{
$d = ADOConnection::DBTimeStamp($d);
if (strncmp($d,"'",1)) return $d;
return substr($d,1,strlen($d)-2);
}
function BeginTrans()
{
{
$this->autoCommit = false;
ora_commitoff($this->_connectionID);
return true;
}
function CommitTrans($ok=true)
{
function CommitTrans($ok=true)
{
if (!$ok) return $this->RollbackTrans();
$ret = ora_commit($this->_connectionID);
ora_commiton($this->_connectionID);
return $ret;
}
function RollbackTrans()
{
$ret = ora_rollback($this->_connectionID);
@@ -95,8 +97,8 @@ class ADODB_oracle extends ADOConnection {
/* there seems to be a bug in the oracle extension -- always returns ORA-00000 - no error */
function ErrorMsg()
{
function ErrorMsg()
{
if ($this->_errorMsg !== false) return $this->_errorMsg;
if (is_resource($this->_curs)) $this->_errorMsg = @ora_error($this->_curs);
@@ -104,8 +106,8 @@ class ADODB_oracle extends ADOConnection {
return $this->_errorMsg;
}
function ErrorNo()
function ErrorNo()
{
if ($this->_errorCode !== false) return $this->_errorCode;
@@ -114,17 +116,17 @@ class ADODB_oracle extends ADOConnection {
return $this->_errorCode;
}
// returns true or false
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename, $mode=0)
{
if (!function_exists('ora_plogon')) return null;
// <G. Giunta 2003/03/03/> Reset error messages before connecting
$this->_errorMsg = false;
$this->_errorCode = false;
// G. Giunta 2003/08/13 - This looks danegrously suspicious: why should we want to set
// the oracle home to the host name of remote DB?
// if ($argHostname) putenv("ORACLE_HOME=$argHostname");
@@ -184,7 +186,7 @@ class ADODB_oracle extends ADOConnection {
$this->_errorCode = false;
$curs = ora_open($this->_connectionID);
if ($curs === false) return false;
$this->_curs = $curs;
if (!ora_parse($curs,$sql)) return false;
@@ -193,7 +195,7 @@ class ADODB_oracle extends ADOConnection {
// that we can obtain ONLY from the cursor (and not from the connection)
$this->_errorCode = @ora_errorcode($curs);
$this->_errorMsg = @ora_error($curs);
// </G. Giunta 2004/03/03>
// </G. Giunta 2004/03/03>
@ora_close($curs);
return false;
}
@@ -219,17 +221,17 @@ class ADORecordset_oracle extends ADORecordSet {
var $databaseType = "oracle";
var $bind = false;
function ADORecordset_oracle($queryID,$mode=false)
function __construct($queryID,$mode=false)
{
if ($mode === false) {
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
$this->fetchMode = $mode;
$this->_queryID = $queryID;
$this->_inited = true;
$this->fields = array();
if ($queryID) {
@@ -241,7 +243,7 @@ class ADORecordset_oracle extends ADORecordSet {
$this->_numOfFields = 0;
$this->EOF = true;
}
return $this->_queryID;
}
@@ -271,10 +273,10 @@ class ADORecordset_oracle extends ADORecordSet {
$this->bind[strtoupper($o->name)] = $i;
}
}
return $this->fields[$this->bind[strtoupper($colname)]];
}
function _initrs()
{
$this->_numOfRows = -1;
@@ -291,26 +293,26 @@ class ADORecordset_oracle extends ADORecordSet {
// should remove call by reference, but ora_fetch_into requires it in 4.0.3pl1
if ($this->fetchMode & ADODB_FETCH_ASSOC)
return @ora_fetch_into($this->_queryID,$this->fields,ORA_FETCHINTO_NULLS|ORA_FETCHINTO_ASSOC);
else
else
return @ora_fetch_into($this->_queryID,$this->fields,ORA_FETCHINTO_NULLS);
}
/* close() only needs to be called if you are worried about using too much memory while your script
is running. All associated result memory for the specified result identifier will automatically be freed. */
function _close()
function _close()
{
return @ora_close($this->_queryID);
}
function MetaType($t,$len=-1)
function MetaType($t, $len = -1, $fieldobj = false)
{
if (is_object($t)) {
$fieldobj = $t;
$t = $fieldobj->type;
$len = $fieldobj->max_length;
}
switch (strtoupper($t)) {
case 'VARCHAR':
case 'VARCHAR2':
@@ -326,17 +328,16 @@ class ADORecordset_oracle extends ADORecordSet {
case 'LONG VARBINARY':
case 'BLOB':
return 'B';
case 'DATE': return 'D';
//case 'T': return 'T';
case 'BIT': return 'L';
case 'INT':
case 'INT':
case 'SMALLINT':
case 'INTEGER': return 'I';
default: return 'N';
}
}
}
?>
+401 -224
View File
@@ -1,19 +1,24 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). 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.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
Requires ODBC. Works on Windows and Unix.
/**
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Problems:
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.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
Requires ODBC. Works on Windows and Unix.
Problems:
Where is float/decimal type in pdo_param_type
LOB handling for CLOB/BLOB differs significantly
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
@@ -24,30 +29,30 @@ PDO::PARAM_NULL, 0
/* int as in long (the php native int type).
* If you mark a column as an int, PDO expects get_col to return
* a pointer to a long
* a pointer to a long
PDO::PARAM_INT, 1
/* get_col ptr should point to start of the string buffer
/* get_col ptr should point to start of the string buffer
PDO::PARAM_STR, 2
/* get_col: when len is 0 ptr should point to a php_stream *,
* otherwise it should behave like a string. Indicate a NULL field
* value by setting the ptr to NULL
* value by setting the ptr to NULL
PDO::PARAM_LOB, 3
/* get_col: will expect the ptr to point to a new PDOStatement object handle,
* but this isn't wired up yet
PDO::PARAM_STMT, 4 /* hierarchical result set
* but this isn't wired up yet
PDO::PARAM_STMT, 4 /* hierarchical result set
/* get_col ptr should point to a zend_bool
/* get_col ptr should point to a zend_bool
PDO::PARAM_BOOL, 5
/* magic flag to denote a parameter as being input/output
/* magic flag to denote a parameter as being input/output
PDO::PARAM_INPUT_OUTPUT = 0x80000000
};
*/
function adodb_pdo_type($t)
{
switch($t) {
@@ -56,40 +61,36 @@ function adodb_pdo_type($t)
default: return 'NUMERIC';
}
}
/*--------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------*/
////////////////////////////////////////////////
/*----------------------------------------------------------------------------*/
class ADODB_pdo extends ADOConnection {
var $databaseType = "pdo";
var $databaseType = "pdo";
var $dataProvider = "pdo";
var $fmtDate = "'Y-m-d'";
var $fmtTimeStamp = "'Y-m-d, h:i:sA'";
var $replaceQuote = "''"; // string to use to replace quotes
var $hasAffectedRows = true;
var $_bindInputArray = true;
var $_bindInputArray = true;
var $_genIDSQL;
var $_genSeqSQL = "create table %s (id integer)";
var $_dropSeqSQL;
var $_autocommit = true;
var $_haserrorfunctions = true;
var $_lastAffectedRows = 0;
var $_errormsg = false;
var $_errorno = false;
var $dsnType = '';
var $stmt = false;
function ADODB_pdo()
var $_driver;
function __construct()
{
}
function _UpdatePDO()
{
$d = $this->_driver;
@@ -101,7 +102,7 @@ class ADODB_pdo extends ADOConnection {
$this->random = $d->random;
$this->concat_operator = $d->concat_operator;
$this->nameQuote = $d->nameQuote;
$this->hasGenID = $d->hasGenID;
$this->_genIDSQL = $d->_genIDSQL;
$this->_genSeqSQL = $d->_genSeqSQL;
@@ -109,18 +110,24 @@ class ADODB_pdo extends ADOConnection {
$d->_init($this);
}
function Time()
{
if (!empty($this->_driver->_hasdual)) $sql = "select $this->sysTimeStamp from dual";
else $sql = "select $this->sysTimeStamp";
if (!empty($this->_driver->_hasdual)) {
$sql = "select $this->sysTimeStamp from dual";
}
else {
$sql = "select $this->sysTimeStamp";
}
$rs = $this->_Execute($sql);
if ($rs && !$rs->EOF) return $this->UnixTimeStamp(reset($rs->fields));
if ($rs && !$rs->EOF) {
return $this->UnixTimeStamp(reset($rs->fields));
}
return false;
}
// returns true or false
function _connect($argDSN, $argUsername, $argPassword, $argDatabasename, $persist=false)
{
@@ -128,7 +135,18 @@ class ADODB_pdo extends ADOConnection {
$this->dsnType = substr($argDSN,0,$at);
if ($argDatabasename) {
$argDSN .= ';dbname='.$argDatabasename;
switch($this->dsnType){
case 'sqlsrv':
$argDSN .= ';database='.$argDatabasename;
break;
case 'mssql':
case 'mysql':
case 'oci':
case 'pgsql':
case 'sqlite':
default:
$argDSN .= ';dbname='.$argDatabasename;
}
}
try {
$this->_connectionID = new PDO($argDSN, $argUsername, $argPassword);
@@ -139,224 +157,309 @@ class ADODB_pdo extends ADOConnection {
$this->_errormsg = 'Connection attempt failed: '.$e->getMessage();
return false;
}
if ($this->_connectionID) {
switch(ADODB_ASSOC_CASE){
case 0: $m = PDO::CASE_LOWER; break;
case 1: $m = PDO::CASE_UPPER; break;
default:
case 2: $m = PDO::CASE_NATURAL; break;
case ADODB_ASSOC_CASE_LOWER:
$m = PDO::CASE_LOWER;
break;
case ADODB_ASSOC_CASE_UPPER:
$m = PDO::CASE_UPPER;
break;
default:
case ADODB_ASSOC_CASE_NATIVE:
$m = PDO::CASE_NATURAL;
break;
}
//$this->_connectionID->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_SILENT );
$this->_connectionID->setAttribute(PDO::ATTR_CASE,$m);
$class = 'ADODB_pdo_'.$this->dsnType;
//$this->_connectionID->setAttribute(PDO::ATTR_AUTOCOMMIT,true);
switch($this->dsnType) {
case 'oci':
case 'mysql':
case 'pgsql':
case 'mssql':
case 'sqlite':
include_once(ADODB_DIR.'/drivers/adodb-pdo_'.$this->dsnType.'.inc.php');
break;
case 'mssql':
case 'mysql':
case 'oci':
case 'pgsql':
case 'sqlite':
case 'sqlsrv':
include_once(ADODB_DIR.'/drivers/adodb-pdo_'.$this->dsnType.'.inc.php');
break;
}
if (class_exists($class))
if (class_exists($class)) {
$this->_driver = new $class();
else
}
else {
$this->_driver = new ADODB_pdo_base();
}
$this->_driver->_connectionID = $this->_connectionID;
$this->_UpdatePDO();
$this->_driver->database = $this->database;
return true;
}
$this->_driver = new ADODB_pdo_base();
return false;
}
function Concat()
function Concat()
{
$args = func_get_args();
if(method_exists($this->_driver, 'Concat'))
return call_user_func_array(array($this->_driver, 'Concat'), $args);
return call_user_func_array(array($this,'parent::Concat'), $args);
if(method_exists($this->_driver, 'Concat')) {
return call_user_func_array(array($this->_driver, 'Concat'), $args);
}
if (PHP_VERSION >= 5.3) {
return call_user_func_array('parent::Concat', $args);
}
return call_user_func_array(array($this,'parent::Concat'), $args);
}
// returns true or false
function _pconnect($argDSN, $argUsername, $argPassword, $argDatabasename)
{
return $this->_connect($argDSN, $argUsername, $argPassword, $argDatabasename, true);
}
/*------------------------------------------------------------------------------*/
function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
{
function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
{
$save = $this->_driver->fetchMode;
$this->_driver->fetchMode = $this->fetchMode;
$this->_driver->debug = $this->debug;
$this->_driver->debug = $this->debug;
$ret = $this->_driver->SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
$this->_driver->fetchMode = $save;
return $ret;
}
function ServerInfo()
{
return $this->_driver->ServerInfo();
}
function MetaTables($ttype=false,$showSchema=false,$mask=false)
{
return $this->_driver->MetaTables($ttype,$showSchema,$mask);
}
function MetaColumns($table,$normalize=true)
{
return $this->_driver->MetaColumns($table,$normalize);
}
function InParameter(&$stmt,&$var,$name,$maxLen=4000,$type=false)
{
$obj = $stmt[1];
if ($type) $obj->bindParam($name,$var,$type,$maxLen);
else $obj->bindParam($name, $var);
if ($type) {
$obj->bindParam($name, $var, $type, $maxLen);
}
else {
$obj->bindParam($name, $var);
}
}
function OffsetDate($dayFraction,$date=false)
{
return $this->_driver->OffsetDate($dayFraction,$date);
}
{
return $this->_driver->OffsetDate($dayFraction,$date);
}
function SelectDB($dbName)
{
return $this->_driver->SelectDB($dbName);
}
function SQLDate($fmt, $col=false)
{
return $this->_driver->SQLDate($fmt, $col);
}
function ErrorMsg()
{
if ($this->_errormsg !== false) return $this->_errormsg;
if (!empty($this->_stmt)) $arr = $this->_stmt->errorInfo();
else if (!empty($this->_connectionID)) $arr = $this->_connectionID->errorInfo();
else return 'No Connection Established';
if ($this->_errormsg !== false) {
return $this->_errormsg;
}
if (!empty($this->_stmt)) {
$arr = $this->_stmt->errorInfo();
}
else if (!empty($this->_connectionID)) {
$arr = $this->_connectionID->errorInfo();
}
else {
return 'No Connection Established';
}
if ($arr) {
if (sizeof($arr)<2) return '';
if ((integer)$arr[1]) return $arr[2];
else return '';
} else return '-1';
if (sizeof($arr)<2) {
return '';
}
if ((integer)$arr[0]) {
return $arr[2];
}
else {
return '';
}
}
else {
return '-1';
}
}
function ErrorNo()
{
if ($this->_errorno !== false) return $this->_errorno;
if (!empty($this->_stmt)) $err = $this->_stmt->errorCode();
if ($this->_errorno !== false) {
return $this->_errorno;
}
if (!empty($this->_stmt)) {
$err = $this->_stmt->errorCode();
}
else if (!empty($this->_connectionID)) {
$arr = $this->_connectionID->errorInfo();
if (isset($arr[0])) $err = $arr[0];
else $err = -1;
} else
if (isset($arr[0])) {
$err = $arr[0];
}
else {
$err = -1;
}
} else {
return 0;
if ($err == '00000') return 0; // allows empty check
}
if ($err == '00000') {
return 0; // allows empty check
}
return $err;
}
function SetTransactionMode($transaction_mode)
function SetTransactionMode($transaction_mode)
{
if(method_exists($this->_driver, 'SetTransactionMode'))
return $this->_driver->SetTransactionMode($transaction_mode);
return parent::SetTransactionMode($seqname);
if(method_exists($this->_driver, 'SetTransactionMode')) {
return $this->_driver->SetTransactionMode($transaction_mode);
}
return parent::SetTransactionMode($seqname);
}
function BeginTrans()
{
if(method_exists($this->_driver, 'BeginTrans'))
return $this->_driver->BeginTrans();
if (!$this->hasTransactions) return false;
if ($this->transOff) return true;
{
if(method_exists($this->_driver, 'BeginTrans')) {
return $this->_driver->BeginTrans();
}
if (!$this->hasTransactions) {
return false;
}
if ($this->transOff) {
return true;
}
$this->transCnt += 1;
$this->_autocommit = false;
$this->_connectionID->setAttribute(PDO::ATTR_AUTOCOMMIT,false);
return $this->_connectionID->beginTransaction();
}
function CommitTrans($ok=true)
{
if(method_exists($this->_driver, 'CommitTrans'))
return $this->_driver->CommitTrans($ok);
if (!$this->hasTransactions) return false;
if ($this->transOff) return true;
if (!$ok) return $this->RollbackTrans();
if ($this->transCnt) $this->transCnt -= 1;
function CommitTrans($ok=true)
{
if(method_exists($this->_driver, 'CommitTrans')) {
return $this->_driver->CommitTrans($ok);
}
if (!$this->hasTransactions) {
return false;
}
if ($this->transOff) {
return true;
}
if (!$ok) {
return $this->RollbackTrans();
}
if ($this->transCnt) {
$this->transCnt -= 1;
}
$this->_autocommit = true;
$ret = $this->_connectionID->commit();
$this->_connectionID->setAttribute(PDO::ATTR_AUTOCOMMIT,true);
return $ret;
}
function RollbackTrans()
{
if(method_exists($this->_driver, 'RollbackTrans'))
return $this->_driver->RollbackTrans();
if (!$this->hasTransactions) return false;
if ($this->transOff) return true;
if ($this->transCnt) $this->transCnt -= 1;
if(method_exists($this->_driver, 'RollbackTrans')) {
return $this->_driver->RollbackTrans();
}
if (!$this->hasTransactions) {
return false;
}
if ($this->transOff) {
return true;
}
if ($this->transCnt) {
$this->transCnt -= 1;
}
$this->_autocommit = true;
$ret = $this->_connectionID->rollback();
$this->_connectionID->setAttribute(PDO::ATTR_AUTOCOMMIT,true);
return $ret;
}
function Prepare($sql)
{
$this->_stmt = $this->_connectionID->prepare($sql);
if ($this->_stmt) return array($sql,$this->_stmt);
if ($this->_stmt) {
return array($sql,$this->_stmt);
}
return false;
}
function PrepareStmt($sql)
{
$stmt = $this->_connectionID->prepare($sql);
if (!$stmt) return false;
if (!$stmt) {
return false;
}
$obj = new ADOPDOStatement($stmt,$this);
return $obj;
}
function CreateSequence($seqname='adodbseq',$startID=1)
{
if(method_exists($this->_driver, 'CreateSequence'))
return $this->_driver->CreateSequence($seqname, $startID);
return parent::CreateSequence($seqname, $startID);
if(method_exists($this->_driver, 'CreateSequence')) {
return $this->_driver->CreateSequence($seqname, $startID);
}
return parent::CreateSequence($seqname, $startID);
}
function DropSequence($seqname='adodbseq')
{
if(method_exists($this->_driver, 'DropSequence'))
return $this->_driver->DropSequence($seqname);
return parent::DropSequence($seqname);
if(method_exists($this->_driver, 'DropSequence')) {
return $this->_driver->DropSequence($seqname);
}
return parent::DropSequence($seqname);
}
function GenID($seqname='adodbseq',$startID=1)
{
if(method_exists($this->_driver, 'GenID'))
return $this->_driver->GenID($seqname, $startID);
return parent::GenID($seqname, $startID);
if(method_exists($this->_driver, 'GenID')) {
return $this->_driver->GenID($seqname, $startID);
}
return parent::GenID($seqname, $startID);
}
/* returns queryID or false */
function _query($sql,$inputarr=false)
function _query($sql,$inputarr=false)
{
if (is_array($sql)) {
$stmt = $sql[1];
@@ -367,21 +470,25 @@ class ADODB_pdo extends ADOConnection {
#var_dump($this->_bindInputArray);
if ($stmt) {
$this->_driver->debug = $this->debug;
if ($inputarr) $ok = $stmt->execute($inputarr);
else $ok = $stmt->execute();
}
if ($inputarr) {
$ok = $stmt->execute($inputarr);
}
else {
$ok = $stmt->execute();
}
}
$this->_errormsg = false;
$this->_errorno = false;
if ($ok) {
$this->_stmt = $stmt;
return $stmt;
}
if ($stmt) {
$arr = $stmt->errorinfo();
if ((integer)$arr[1]) {
$this->_errormsg = $arr[2];
@@ -406,42 +513,66 @@ class ADODB_pdo extends ADOConnection {
{
return ($this->_stmt) ? $this->_stmt->rowCount() : 0;
}
function _insertid()
{
return ($this->_connectionID) ? $this->_connectionID->lastInsertId() : 0;
}
/**
* Quotes a string to be sent to the database.
* If we have an active connection, delegates quoting to the underlying
* PDO object. Otherwise, replace "'" by the value of $replaceQuote (same
* behavior as mysqli driver)
* @param string $s The string to quote
* @param boolean $magic_quotes If false, use PDO::quote().
* @return string Quoted string
*/
function qstr($s, $magic_quotes = false)
{
if (!$magic_quotes) {
if ($this->_connectionID) {
return $this->_connectionID->quote($s);
}
return "'" . str_replace("'", $this->replaceQuote, $s) . "'";
}
// undo magic quotes for "
$s = str_replace('\\"', '"', $s);
return "'$s'";
}
}
class ADODB_pdo_base extends ADODB_pdo {
var $sysDate = "'?'";
var $sysTimeStamp = "'?'";
function _init($parentDriver)
{
$parentDriver->_bindInputArray = true;
#$parentDriver->_connectionID->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY,true);
}
function ServerInfo()
{
return ADOConnection::ServerInfo();
}
function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
{
$ret = ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
return $ret;
}
function MetaTables()
function MetaTables($ttype=false,$showSchema=false,$mask=false)
{
return false;
}
function MetaColumns()
function MetaColumns($table,$normalize=true)
{
return false;
}
@@ -449,17 +580,17 @@ class ADODB_pdo_base extends ADODB_pdo {
class ADOPDOStatement {
var $databaseType = "pdo";
var $databaseType = "pdo";
var $dataProvider = "pdo";
var $_stmt;
var $_connectionID;
function ADOPDOStatement($stmt,$connection)
function __construct($stmt,$connection)
{
$this->_stmt = $stmt;
$this->_connectionID = $connection;
}
function Execute($inputArr=false)
{
$savestmt = $this->_connectionID->_stmt;
@@ -467,55 +598,73 @@ class ADOPDOStatement {
$this->_connectionID->_stmt = $savestmt;
return $rs;
}
function InParameter(&$var,$name,$maxLen=4000,$type=false)
{
if ($type) $this->_stmt->bindParam($name,$var,$type,$maxLen);
else $this->_stmt->bindParam($name, $var);
if ($type) {
$this->_stmt->bindParam($name,$var,$type,$maxLen);
}
else {
$this->_stmt->bindParam($name, $var);
}
}
function Affected_Rows()
{
return ($this->_stmt) ? $this->_stmt->rowCount() : 0;
}
function ErrorMsg()
{
if ($this->_stmt) $arr = $this->_stmt->errorInfo();
else $arr = $this->_connectionID->errorInfo();
if ($this->_stmt) {
$arr = $this->_stmt->errorInfo();
}
else {
$arr = $this->_connectionID->errorInfo();
}
if (is_array($arr)) {
if ((integer) $arr[0] && isset($arr[2])) return $arr[2];
else return '';
} else return '-1';
if ((integer) $arr[0] && isset($arr[2])) {
return $arr[2];
}
else {
return '';
}
} else {
return '-1';
}
}
function NumCols()
{
return ($this->_stmt) ? $this->_stmt->columnCount() : 0;
}
function ErrorNo()
{
if ($this->_stmt) return $this->_stmt->errorCode();
else return $this->_connectionID->errorInfo();
if ($this->_stmt) {
return $this->_stmt->errorCode();
}
else {
return $this->_connectionID->errorInfo();
}
}
}
/*--------------------------------------------------------------------------------------
Class Name: Recordset
Class Name: Recordset
--------------------------------------------------------------------------------------*/
class ADORecordSet_pdo extends ADORecordSet {
class ADORecordSet_pdo extends ADORecordSet {
var $bind = false;
var $databaseType = "pdo";
var $databaseType = "pdo";
var $dataProvider = "pdo";
function ADORecordSet_pdo($id,$mode=false)
function __construct($id,$mode=false)
{
if ($mode === false) {
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
@@ -523,22 +672,26 @@ class ADORecordSet_pdo extends ADORecordSet {
switch($mode) {
case ADODB_FETCH_NUM: $mode = PDO::FETCH_NUM; break;
case ADODB_FETCH_ASSOC: $mode = PDO::FETCH_ASSOC; break;
case ADODB_FETCH_BOTH:
case ADODB_FETCH_BOTH:
default: $mode = PDO::FETCH_BOTH; break;
}
$this->fetchMode = $mode;
$this->_queryID = $id;
$this->ADORecordSet($id);
parent::__construct($id);
}
function Init()
{
if ($this->_inited) return;
if ($this->_inited) {
return;
}
$this->_inited = true;
if ($this->_queryID) @$this->_initrs();
if ($this->_queryID) {
@$this->_initrs();
}
else {
$this->_numOfRows = 0;
$this->_numOfFields = 0;
@@ -552,21 +705,23 @@ class ADORecordSet_pdo extends ADORecordSet {
$this->EOF = true;
}
}
function _initrs()
{
global $ADODB_COUNTRECS;
$this->_numOfRows = ($ADODB_COUNTRECS) ? @$this->_queryID->rowCount() : -1;
if (!$this->_numOfRows) $this->_numOfRows = -1;
if (!$this->_numOfRows) {
$this->_numOfRows = -1;
}
$this->_numOfFields = $this->_queryID->columnCount();
}
// returns the field object
function FetchField($fieldOffset = -1)
function FetchField($fieldOffset = -1)
{
$off=$fieldOffset+1; // offsets begin at 1
$o= new ADOFieldObject();
$arr = @$this->_queryID->getColumnMeta($fieldOffset);
if (!$arr) {
@@ -579,38 +734,62 @@ class ADORecordSet_pdo extends ADORecordSet {
}
//adodb_pr($arr);
$o->name = $arr['name'];
if (isset($arr['native_type']) && $arr['native_type'] <> "null") $o->type = $arr['native_type'];
else $o->type = adodb_pdo_type($arr['pdo_type']);
if (isset($arr['sqlsrv:decl_type']) && $arr['sqlsrv:decl_type'] <> "null")
{
/*
* If the database is SQL server, use the native built-ins
*/
$o->type = $arr['sqlsrv:decl_type'];
}
elseif (isset($arr['native_type']) && $arr['native_type'] <> "null")
{
$o->type = $arr['native_type'];
}
else
{
$o->type = adodb_pdo_type($arr['pdo_type']);
}
$o->max_length = $arr['len'];
$o->precision = $arr['precision'];
if (ADODB_ASSOC_CASE == 0) $o->name = strtolower($o->name);
else if (ADODB_ASSOC_CASE == 1) $o->name = strtoupper($o->name);
switch(ADODB_ASSOC_CASE) {
case ADODB_ASSOC_CASE_LOWER:
$o->name = strtolower($o->name);
break;
case ADODB_ASSOC_CASE_UPPER:
$o->name = strtoupper($o->name);
break;
}
return $o;
}
function _seek($row)
{
return false;
}
function _fetch()
{
if (!$this->_queryID) return false;
if (!$this->_queryID) {
return false;
}
$this->fields = $this->_queryID->fetch($this->fetchMode);
return !empty($this->fields);
}
function _close()
function _close()
{
$this->_queryID = false;
}
function Fields($colname)
{
if ($this->adodbFetchMode != ADODB_FETCH_NUM) return @$this->fields[$colname];
if ($this->adodbFetchMode != ADODB_FETCH_NUM) {
return @$this->fields[$colname];
}
if (!$this->bind) {
$this->bind = array();
for ($i=0; $i < $this->_numOfFields; $i++) {
@@ -618,9 +797,7 @@ class ADORecordSet_pdo extends ADORecordSet {
$this->bind[strtoupper($o->name)] = $i;
}
}
return $this->fields[$this->bind[strtoupper($colname)]];
return $this->fields[$this->bind[strtoupper($colname)]];
}
}
?>
+18 -17
View File
@@ -2,41 +2,43 @@
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
@version v5.20.9 21-Dec-2016
@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.
Set tabs to 8.
*/
*/
class ADODB_pdo_mssql extends ADODB_pdo {
var $hasTop = 'top';
var $sysDate = 'convert(datetime,convert(char,GetDate(),102),102)';
var $sysTimeStamp = 'GetDate()';
function _init($parentDriver)
{
$parentDriver->hasTransactions = false; ## <<< BUG IN PDO mssql driver
$parentDriver->_bindInputArray = false;
$parentDriver->hasInsertID = true;
}
function ServerInfo()
{
return ADOConnection::ServerInfo();
}
function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
{
$ret = ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
return $ret;
}
function SetTransactionMode( $transaction_mode )
function SetTransactionMode( $transaction_mode )
{
$this->_transmode = $transaction_mode;
if (empty($transaction_mode)) {
@@ -46,16 +48,15 @@ class ADODB_pdo_mssql extends ADODB_pdo {
if (!stristr($transaction_mode,'isolation')) $transaction_mode = 'ISOLATION LEVEL '.$transaction_mode;
$this->Execute("SET TRANSACTION ".$transaction_mode);
}
function MetaTables($ttype=false,$showSchema=false,$mask=false)
function MetaTables($ttype=false,$showSchema=false,$mask=false)
{
return false;
}
function MetaColumns($table,$normalize=true)
{
return false;
}
}
?>
+192 -72
View File
@@ -1,17 +1,22 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
@version v5.20.9 21-Dec-2016
@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.
Set tabs to 8.
*/
*/
class ADODB_pdo_mysql extends ADODB_pdo {
var $metaTablesSQL = "SHOW TABLES";
var $metaTablesSQL = "SELECT
TABLE_NAME,
CASE WHEN TABLE_TYPE = 'VIEW' THEN 'V' ELSE 'T' END
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA=";
var $metaColumnsSQL = "SHOW COLUMNS FROM `%s`";
var $sysDate = 'CURDATE()';
var $sysTimeStamp = 'NOW()';
@@ -23,72 +28,79 @@ class ADODB_pdo_mysql extends ADODB_pdo {
function _init($parentDriver)
{
$parentDriver->hasTransactions = false;
#$parentDriver->_bindInputArray = false;
$parentDriver->hasInsertID = true;
$parentDriver->_connectionID->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY,true);
$parentDriver->_connectionID->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
}
// dayFraction is a day in floating point
function OffsetDate($dayFraction,$date=false)
{
if (!$date) $date = $this->sysDate;
// dayFraction is a day in floating point
function OffsetDate($dayFraction, $date=false)
{
if (!$date) {
$date = $this->sysDate;
}
$fraction = $dayFraction * 24 * 3600;
return $date . ' + INTERVAL ' . $fraction.' SECOND';
return $date . ' + INTERVAL ' . $fraction . ' SECOND';
// return "from_unixtime(unix_timestamp($date)+$fraction)";
}
function Concat()
{
$s = "";
function Concat()
{
$s = '';
$arr = func_get_args();
// suggestion by andrew005#mnogo.ru
$s = implode(',',$arr);
if (strlen($s) > 0) return "CONCAT($s)"; return '';
$s = implode(',', $arr);
if (strlen($s) > 0) {
return "CONCAT($s)";
}
return '';
}
function ServerInfo()
{
$arr['description'] = ADOConnection::GetOne("select version()");
$arr['description'] = ADOConnection::GetOne('select version()');
$arr['version'] = ADOConnection::_findvers($arr['description']);
return $arr;
}
function MetaTables($ttype=false,$showSchema=false,$mask=false)
{
function MetaTables($ttype=false, $showSchema=false, $mask=false)
{
$save = $this->metaTablesSQL;
if ($showSchema && is_string($showSchema)) {
$this->metaTablesSQL .= " from $showSchema";
$this->metaTablesSQL .= $this->qstr($showSchema);
} else {
$this->metaTablesSQL .= 'schema()';
}
if ($mask) {
$mask = $this->qstr($mask);
$this->metaTablesSQL .= " like $mask";
}
$ret = ADOConnection::MetaTables($ttype,$showSchema);
$ret = ADOConnection::MetaTables($ttype, $showSchema);
$this->metaTablesSQL = $save;
return $ret;
}
function SetTransactionMode( $transaction_mode )
function SetTransactionMode($transaction_mode)
{
$this->_transmode = $transaction_mode;
if (empty($transaction_mode)) {
$this->Execute('SET TRANSACTION ISOLATION LEVEL REPEATABLE READ');
return;
}
if (!stristr($transaction_mode,'isolation')) $transaction_mode = 'ISOLATION LEVEL '.$transaction_mode;
$this->Execute("SET SESSION TRANSACTION ".$transaction_mode);
if (!stristr($transaction_mode, 'isolation')) {
$transaction_mode = 'ISOLATION LEVEL ' . $transaction_mode;
}
$this->Execute('SET SESSION TRANSACTION ' . $transaction_mode);
}
function MetaColumns($table,$normalize=true)
function MetaColumns($table, $normalize=true)
{
$this->_findschema($table,$schema);
$this->_findschema($table, $schema);
if ($schema) {
$dbName = $this->database;
$this->SelectDB($schema);
@@ -96,41 +108,45 @@ class ADODB_pdo_mysql extends ADODB_pdo {
global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
$rs = $this->Execute(sprintf($this->metaColumnsSQL,$table));
if ($this->fetchMode !== false) {
$savem = $this->SetFetchMode(false);
}
$rs = $this->Execute(sprintf($this->metaColumnsSQL, $table));
if ($schema) {
$this->SelectDB($dbName);
}
if (isset($savem)) $this->SetFetchMode($savem);
if (isset($savem)) {
$this->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
if (!is_object($rs)) {
$false = false;
return $false;
}
$retarr = array();
while (!$rs->EOF){
$fld = new ADOFieldObject();
$fld->name = $rs->fields[0];
$type = $rs->fields[1];
// split type into type(length):
$fld->scale = null;
if (preg_match("/^(.+)\((\d+),(\d+)/", $type, $query_array)) {
if (preg_match('/^(.+)\((\d+),(\d+)/', $type, $query_array)) {
$fld->type = $query_array[1];
$fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1;
$fld->scale = is_numeric($query_array[3]) ? $query_array[3] : -1;
} elseif (preg_match("/^(.+)\((\d+)/", $type, $query_array)) {
} elseif (preg_match('/^(.+)\((\d+)/', $type, $query_array)) {
$fld->type = $query_array[1];
$fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1;
} elseif (preg_match("/^(enum)\((.*)\)$/i", $type, $query_array)) {
} elseif (preg_match('/^(enum)\((.*)\)$/i', $type, $query_array)) {
$fld->type = $query_array[1];
$arr = explode(",",$query_array[2]);
$arr = explode(',', $query_array[2]);
$fld->enums = $arr;
$zlen = max(array_map("strlen",$arr)) - 2; // PHP >= 4.0.6
$zlen = max(array_map('strlen', $arr)) - 2; // PHP >= 4.0.6
$fld->max_length = ($zlen > 0) ? $zlen : 1;
} else {
$fld->type = $type;
@@ -139,9 +155,9 @@ class ADODB_pdo_mysql extends ADODB_pdo {
$fld->not_null = ($rs->fields[2] != 'YES');
$fld->primary_key = ($rs->fields[3] == 'PRI');
$fld->auto_increment = (strpos($rs->fields[5], 'auto_increment') !== false);
$fld->binary = (strpos($type,'blob') !== false);
$fld->unsigned = (strpos($type,'unsigned') !== false);
$fld->binary = (strpos($type, 'blob') !== false);
$fld->unsigned = (strpos($type, 'unsigned') !== false);
if (!$fld->binary) {
$d = $rs->fields[4];
if ($d != '' && $d != 'NULL') {
@@ -151,32 +167,136 @@ class ADODB_pdo_mysql extends ADODB_pdo {
$fld->has_default = false;
}
}
if ($save == ADODB_FETCH_NUM) {
$retarr[] = $fld;
} else {
$retarr[strtoupper($fld->name)] = $fld;
}
$rs->MoveNext();
}
$rs->Close();
return $retarr;
$rs->MoveNext();
}
$rs->Close();
return $retarr;
}
// returns true or false
function SelectDB($dbName)
{
$this->database = $dbName;
$this->databaseName = $dbName; # obsolete, retained for compat with older adodb versions
$try = $this->Execute('use ' . $dbName);
return ($try !== false);
}
// parameters use PostgreSQL convention, not MySQL
function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs=0)
function SelectLimit($sql, $nrows=-1, $offset=-1, $inputarr=false, $secs=0)
{
$offsetStr =($offset>=0) ? "$offset," : '';
// jason judge, see http://phplens.com/lens/lensforum/msgs.php?id=9220
if ($nrows < 0) $nrows = '18446744073709551615';
if ($secs)
$rs = $this->CacheExecute($secs,$sql." LIMIT $offsetStr$nrows",$inputarr);
else
$rs = $this->Execute($sql." LIMIT $offsetStr$nrows",$inputarr);
if ($nrows < 0) {
$nrows = '18446744073709551615';
}
if ($secs) {
$rs = $this->CacheExecute($secs, $sql . " LIMIT $offsetStr$nrows", $inputarr);
} else {
$rs = $this->Execute($sql . " LIMIT $offsetStr$nrows", $inputarr);
}
return $rs;
}
function SQLDate($fmt, $col=false)
{
if (!$col) {
$col = $this->sysTimeStamp;
}
$s = 'DATE_FORMAT(' . $col . ",'";
$concat = false;
$len = strlen($fmt);
for ($i=0; $i < $len; $i++) {
$ch = $fmt[$i];
switch($ch) {
default:
if ($ch == '\\') {
$i++;
$ch = substr($fmt, $i, 1);
}
// FALL THROUGH
case '-':
case '/':
$s .= $ch;
break;
case 'Y':
case 'y':
$s .= '%Y';
break;
case 'M':
$s .= '%b';
break;
case 'm':
$s .= '%m';
break;
case 'D':
case 'd':
$s .= '%d';
break;
case 'Q':
case 'q':
$s .= "'),Quarter($col)";
if ($len > $i+1) {
$s .= ",DATE_FORMAT($col,'";
} else {
$s .= ",('";
}
$concat = true;
break;
case 'H':
$s .= '%H';
break;
case 'h':
$s .= '%I';
break;
case 'i':
$s .= '%i';
break;
case 's':
$s .= '%s';
break;
case 'a':
case 'A':
$s .= '%p';
break;
case 'w':
$s .= '%w';
break;
case 'W':
$s .= '%U';
break;
case 'l':
$s .= '%W';
break;
}
}
$s .= "')";
if ($concat) {
$s = "CONCAT($s)";
}
return $s;
}
}
?>
+21 -21
View File
@@ -2,13 +2,15 @@
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
@version v5.20.9 21-Dec-2016
@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.
Set tabs to 8.
*/
*/
class ADODB_pdo_oci extends ADODB_pdo_base {
@@ -18,11 +20,11 @@ class ADODB_pdo_oci extends ADODB_pdo_base {
var $NLS_DATE_FORMAT = 'YYYY-MM-DD'; // To include time, use 'RRRR-MM-DD HH24:MI:SS'
var $random = "abs(mod(DBMS_RANDOM.RANDOM,10000001)/10000000)";
var $metaTablesSQL = "select table_name,table_type from cat where table_type in ('TABLE','VIEW')";
var $metaColumnsSQL = "select cname,coltype,width, SCALE, PRECISION, NULLS, DEFAULTVAL from col where tname='%s' order by colno";
var $metaColumnsSQL = "select cname,coltype,width, SCALE, PRECISION, NULLS, DEFAULTVAL from col where tname='%s' order by colno";
var $_initdate = true;
var $_hasdual = true;
function _init($parentDriver)
{
$parentDriver->_bindInputArray = true;
@@ -31,8 +33,8 @@ class ADODB_pdo_oci extends ADODB_pdo_base {
$parentDriver->Execute("ALTER SESSION SET NLS_DATE_FORMAT='".$this->NLS_DATE_FORMAT."'");
}
}
function MetaTables($ttype=false,$showSchema=false,$mask=false)
function MetaTables($ttype=false,$showSchema=false,$mask=false)
{
if ($mask) {
$save = $this->metaTablesSQL;
@@ -40,24 +42,24 @@ class ADODB_pdo_oci extends ADODB_pdo_base {
$this->metaTablesSQL .= " AND table_name like $mask";
}
$ret = ADOConnection::MetaTables($ttype,$showSchema);
if ($mask) {
$this->metaTablesSQL = $save;
}
return $ret;
}
function MetaColumns($table,$normalize=true)
{
global $ADODB_FETCH_MODE;
$false = false;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
$rs = $this->Execute(sprintf($this->metaColumnsSQL,strtoupper($table)));
if (isset($savem)) $this->SetFetchMode($savem);
$ADODB_FETCH_MODE = $save;
if (!$rs) {
@@ -73,21 +75,19 @@ class ADODB_pdo_oci extends ADODB_pdo_base {
if ($rs->fields[1] == 'NUMBER' && $rs->fields[3] == 0) {
$fld->type ='INT';
$fld->max_length = $rs->fields[4];
}
}
$fld->not_null = (strncmp($rs->fields[5], 'NOT',3) === 0);
$fld->binary = (strpos($fld->type,'BLOB') !== false);
$fld->default_value = $rs->fields[6];
if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;
if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;
else $retarr[strtoupper($fld->name)] = $fld;
$rs->MoveNext();
}
$rs->Close();
if (empty($retarr))
return $false;
else
else
return $retarr;
}
}
?>
+55 -55
View File
@@ -1,46 +1,48 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
@version v5.20.9 21-Dec-2016
@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.
Set tabs to 8.
*/
*/
class ADODB_pdo_pgsql extends ADODB_pdo {
var $metaDatabasesSQL = "select datname from pg_database where datname not in ('template0','template1') order by 1";
var $metaTablesSQL = "select tablename,'T' from pg_tables where tablename not like 'pg\_%'
and tablename not in ('sql_features', 'sql_implementation_info', 'sql_languages',
'sql_packages', 'sql_sizing', 'sql_sizing_profiles')
union
'sql_packages', 'sql_sizing', 'sql_sizing_profiles')
union
select viewname,'V' from pg_views where viewname not like 'pg\_%'";
//"select tablename from pg_tables where tablename not like 'pg_%' order by 1";
var $isoDates = true; // accepts dates in ISO format
var $sysDate = "CURRENT_DATE";
var $sysTimeStamp = "CURRENT_TIMESTAMP";
var $blobEncodeType = 'C';
var $metaColumnsSQL = "SELECT a.attname,t.typname,a.attlen,a.atttypmod,a.attnotnull,a.atthasdef,a.attnum
FROM pg_class c, pg_attribute a,pg_type t
var $metaColumnsSQL = "SELECT a.attname,t.typname,a.attlen,a.atttypmod,a.attnotnull,a.atthasdef,a.attnum
FROM pg_class c, pg_attribute a,pg_type t
WHERE relkind in ('r','v') AND (c.relname='%s' or c.relname = lower('%s')) and a.attname not like '....%%'
AND a.attnum > 0 AND a.atttypid = t.oid AND a.attrelid = c.oid ORDER BY a.attnum";
// used when schema defined
var $metaColumnsSQL1 = "SELECT a.attname, t.typname, a.attlen, a.atttypmod, a.attnotnull, a.atthasdef, a.attnum
FROM pg_class c, pg_attribute a, pg_type t, pg_namespace n
var $metaColumnsSQL1 = "SELECT a.attname, t.typname, a.attlen, a.atttypmod, a.attnotnull, a.atthasdef, a.attnum
FROM pg_class c, pg_attribute a, pg_type t, pg_namespace n
WHERE relkind in ('r','v') AND (c.relname='%s' or c.relname = lower('%s'))
and c.relnamespace=n.oid and n.nspname='%s'
and a.attname not like '....%%' AND a.attnum > 0
and c.relnamespace=n.oid and n.nspname='%s'
and a.attname not like '....%%' AND a.attnum > 0
AND a.atttypid = t.oid AND a.attrelid = c.oid ORDER BY a.attnum";
// get primary key etc -- from Freek Dijkstra
var $metaKeySQL = "SELECT ic.relname AS index_name, a.attname AS column_name,i.indisunique AS unique_key, i.indisprimary AS primary_key
var $metaKeySQL = "SELECT ic.relname AS index_name, a.attname AS column_name,i.indisunique AS unique_key, i.indisprimary AS primary_key
FROM pg_class bc, pg_class ic, pg_index i, pg_attribute a WHERE bc.oid = i.indrelid AND ic.oid = i.indexrelid AND (i.indkey[0] = a.attnum OR i.indkey[1] = a.attnum OR i.indkey[2] = a.attnum OR i.indkey[3] = a.attnum OR i.indkey[4] = a.attnum OR i.indkey[5] = a.attnum OR i.indkey[6] = a.attnum OR i.indkey[7] = a.attnum) AND a.attrelid = bc.oid AND bc.relname = '%s'";
var $hasAffectedRows = true;
var $hasLimit = false; // set to true for pgsql 7 only. support pgsql/mysql SELECT * FROM TABLE LIMIT 10
// below suggested by Freek Dijkstra
// below suggested by Freek Dijkstra
var $true = 't'; // string that represents TRUE for a database
var $false = 'f'; // string that represents FALSE for a database
var $fmtDate = "'Y-m-d'"; // used by DBDate() as the default date format used by the database
@@ -53,23 +55,23 @@ WHERE relkind in ('r','v') AND (c.relname='%s' or c.relname = lower('%s'))
var $metaDefaultsSQL = "SELECT d.adnum as num, d.adsrc as def from pg_attrdef d, pg_class c where d.adrelid=c.oid and c.relname='%s' order by d.adnum";
var $random = 'random()'; /// random function
var $concat_operator='||';
function _init($parentDriver)
{
$parentDriver->hasTransactions = false; ## <<< BUG IN PDO pgsql driver
$parentDriver->hasInsertID = true;
$parentDriver->_nestedSQL = true;
}
function ServerInfo()
{
$arr['description'] = ADOConnection::GetOne("select version()");
$arr['version'] = ADOConnection::_findvers($arr['description']);
return $arr;
}
function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
{
$offsetStr = ($offset >= 0) ? " OFFSET $offset" : '';
$limitStr = ($nrows >= 0) ? " LIMIT $nrows" : '';
@@ -77,17 +79,17 @@ WHERE relkind in ('r','v') AND (c.relname='%s' or c.relname = lower('%s'))
$rs = $this->CacheExecute($secs2cache,$sql."$limitStr$offsetStr",$inputarr);
else
$rs = $this->Execute($sql."$limitStr$offsetStr",$inputarr);
return $rs;
}
function MetaTables($ttype=false,$showSchema=false,$mask=false)
function MetaTables($ttype=false,$showSchema=false,$mask=false)
{
$info = $this->ServerInfo();
if ($info['version'] >= 7.3) {
$this->metaTablesSQL = "select tablename,'T' from pg_tables where tablename not like 'pg\_%'
and schemaname not in ( 'pg_catalog','information_schema')
union
union
select viewname,'V' from pg_views where viewname not like 'pg\_%' and schemaname not in ( 'pg_catalog','information_schema') ";
}
if ($mask) {
@@ -95,59 +97,59 @@ WHERE relkind in ('r','v') AND (c.relname='%s' or c.relname = lower('%s'))
$mask = $this->qstr(strtolower($mask));
if ($info['version']>=7.3)
$this->metaTablesSQL = "
select tablename,'T' from pg_tables where tablename like $mask and schemaname not in ( 'pg_catalog','information_schema')
union
select tablename,'T' from pg_tables where tablename like $mask and schemaname not in ( 'pg_catalog','information_schema')
union
select viewname,'V' from pg_views where viewname like $mask and schemaname not in ( 'pg_catalog','information_schema') ";
else
$this->metaTablesSQL = "
select tablename,'T' from pg_tables where tablename like $mask
union
select tablename,'T' from pg_tables where tablename like $mask
union
select viewname,'V' from pg_views where viewname like $mask";
}
$ret = ADOConnection::MetaTables($ttype,$showSchema);
if ($mask) {
$this->metaTablesSQL = $save;
}
return $ret;
}
function MetaColumns($table,$normalize=true)
function MetaColumns($table,$normalize=true)
{
global $ADODB_FETCH_MODE;
$schema = false;
$this->_findschema($table,$schema);
if ($normalize) $table = strtolower($table);
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
if ($schema) $rs = $this->Execute(sprintf($this->metaColumnsSQL1,$table,$table,$schema));
else $rs = $this->Execute(sprintf($this->metaColumnsSQL,$table,$table));
if (isset($savem)) $this->SetFetchMode($savem);
$ADODB_FETCH_MODE = $save;
if ($rs === false) {
$false = false;
return $false;
}
if (!empty($this->metaKeySQL)) {
// If we want the primary keys, we have to issue a separate query
// Of course, a modified version of the metaColumnsSQL query using a
// LEFT JOIN would have been much more elegant, but postgres does
// Of course, a modified version of the metaColumnsSQL query using a
// LEFT JOIN would have been much more elegant, but postgres does
// not support OUTER JOINS. So here is the clumsy way.
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
$rskey = $this->Execute(sprintf($this->metaKeySQL,($table)));
// fetch all result in once for performance.
$keys = $rskey->GetArray();
if (isset($savem)) $this->SetFetchMode($savem);
$ADODB_FETCH_MODE = $save;
$rskey->Close();
unset($rskey);
}
@@ -159,7 +161,7 @@ select viewname,'V' from pg_views where viewname like $mask";
$rsdef = $this->Execute($sql);
if (isset($savem)) $this->SetFetchMode($savem);
$ADODB_FETCH_MODE = $save;
if ($rsdef) {
while (!$rsdef->EOF) {
$num = $rsdef->fields['num'];
@@ -177,9 +179,9 @@ select viewname,'V' from pg_views where viewname like $mask";
}
unset($rsdef);
}
$retarr = array();
while (!$rs->EOF) {
while (!$rs->EOF) {
$fld = new ADOFieldObject();
$fld->name = $rs->fields[0];
$fld->type = $rs->fields[1];
@@ -201,30 +203,28 @@ select viewname,'V' from pg_views where viewname like $mask";
if ($rs->fields[4] == $this->true) {
$fld->not_null = true;
}
// Freek
if (is_array($keys)) {
foreach($keys as $key) {
if ($fld->name == $key['column_name'] AND $key['primary_key'] == $this->true)
if ($fld->name == $key['column_name'] AND $key['primary_key'] == $this->true)
$fld->primary_key = true;
if ($fld->name == $key['column_name'] AND $key['unique_key'] == $this->true)
if ($fld->name == $key['column_name'] AND $key['unique_key'] == $this->true)
$fld->unique = true; // What name is more compatible?
}
}
if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;
if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;
else $retarr[($normalize) ? strtoupper($fld->name) : $fld->name] = $fld;
$rs->MoveNext();
}
$rs->Close();
if (empty($retarr)) {
$false = false;
return $false;
} else return $retarr;
} else return $retarr;
}
}
?>
+41 -27
View File
@@ -1,14 +1,16 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). 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. See License.txt.
/*
@version v5.20.9 21-Dec-2016
@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. See License.txt.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
Thanks Diogo Toscano (diogo#scriptcase.net) for the code.
And also Sid Dunayer [sdunayer#interserv.com] for extensive fixes.
*/
@@ -27,12 +29,13 @@ class ADODB_pdo_sqlite extends ADODB_pdo {
var $_dropSeqSQL = 'DROP TABLE %s';
var $concat_operator = '||';
var $pdoDriver = false;
var $random='abs(random())';
function _init($parentDriver)
{
$this->pdoDriver = $parentDriver;
$parentDriver->_bindInputArray = true;
$parentDriver->hasTransactions = true;
$parentDriver->hasTransactions = false; // // should be set to false because of PDO SQLite driver not supporting changing autocommit mode
$parentDriver->hasInsertID = true;
}
@@ -40,7 +43,7 @@ class ADODB_pdo_sqlite extends ADODB_pdo {
{
$parent = $this->pdoDriver;
@($ver = array_pop($parent->GetCol("SELECT sqlite_version()")));
@($end = array_pop($parent->GetCol("PRAGMA encoding")));
@($enc = array_pop($parent->GetCol("PRAGMA encoding")));
$arr['version'] = $ver;
$arr['description'] = 'SQLite ';
@@ -48,8 +51,8 @@ class ADODB_pdo_sqlite extends ADODB_pdo {
return $arr;
}
function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
{
$parent = $this->pdoDriver;
$offsetStr = ($offset >= 0) ? " OFFSET $offset" : '';
@@ -110,33 +113,33 @@ class ADODB_pdo_sqlite extends ADODB_pdo {
}
function BeginTrans()
{
{
$parent = $this->pdoDriver;
if ($parent->transOff) return true;
if ($parent->transOff) return true;
$parent->transCnt += 1;
$parent->_autocommit = false;
return $parent->Execute("BEGIN {$parent->_transmode}");
}
function CommitTrans($ok=true)
{
function CommitTrans($ok=true)
{
$parent = $this->pdoDriver;
if ($parent->transOff) return true;
if ($parent->transOff) return true;
if (!$ok) return $parent->RollbackTrans();
if ($parent->transCnt) $parent->transCnt -= 1;
$parent->_autocommit = true;
$ret = $parent->Execute('COMMIT');
return $ret;
}
function RollbackTrans()
{
$parent = $this->pdoDriver;
if ($parent->transOff) return true;
if ($parent->transOff) return true;
if ($parent->transCnt) $parent->transCnt -= 1;
$parent->_autocommit = true;
$ret = $parent->Execute('ROLLBACK');
return $ret;
}
@@ -155,7 +158,7 @@ class ADODB_pdo_sqlite extends ADODB_pdo {
$rs = $parent->Execute("PRAGMA table_info('$tab')");
if (isset($savem)) $parent->SetFetchMode($savem);
if (!$rs) {
$ADODB_FETCH_MODE = $save;
$ADODB_FETCH_MODE = $save;
return $false;
}
$arr = array();
@@ -173,7 +176,7 @@ class ADODB_pdo_sqlite extends ADODB_pdo {
$fld->primary_key = $r['pk'];
$fld->default_value = $r['dflt_value'];
$fld->scale = 0;
if ($save == ADODB_FETCH_NUM) $arr[] = $fld;
if ($save == ADODB_FETCH_NUM) $arr[] = $fld;
else $arr[strtoupper($fld->name)] = $fld;
}
$rs->Close();
@@ -184,7 +187,18 @@ class ADODB_pdo_sqlite extends ADODB_pdo {
function MetaTables($ttype=false,$showSchema=false,$mask=false)
{
$parent = $this->pdoDriver;
return $parent->GetCol($this->metaTablesSQL);
}
if ($mask) {
$save = $this->metaTablesSQL;
$mask = $this->qstr(strtoupper($mask));
$this->metaTablesSQL .= " AND name LIKE $mask";
}
$ret = $parent->GetCol($this->metaTablesSQL);
if ($mask) {
$this->metaTablesSQL = $save;
}
return $ret;
}
}
?>
@@ -0,0 +1,49 @@
<?php
/**
* Provided by Ned Andre to support sqlsrv library
*/
class ADODB_pdo_sqlsrv extends ADODB_pdo
{
var $hasTop = 'top';
var $sysDate = 'convert(datetime,convert(char,GetDate(),102),102)';
var $sysTimeStamp = 'GetDate()';
function _init(ADODB_pdo $parentDriver)
{
$parentDriver->hasTransactions = true;
$parentDriver->_bindInputArray = true;
$parentDriver->hasInsertID = true;
$parentDriver->fmtTimeStamp = "'Y-m-d H:i:s'";
$parentDriver->fmtDate = "'Y-m-d'";
}
function BeginTrans()
{
$returnval = parent::BeginTrans();
return $returnval;
}
function MetaColumns($table, $normalize = true)
{
return false;
}
function MetaTables($ttype = false, $showSchema = false, $mask = false)
{
return false;
}
function SelectLimit($sql, $nrows = -1, $offset = -1, $inputarr = false, $secs2cache = 0)
{
$ret = ADOConnection::SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
return $ret;
}
function ServerInfo()
{
return ADOConnection::ServerInfo();
}
}
+6 -6
View File
@@ -1,14 +1,14 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
@version v5.20.9 21-Dec-2016
@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.
Set tabs to 4.
NOTE: Since 3.31, this file is no longer used, and the "postgres" driver is
remapped to "postgres7". Maintaining multiple postgres drivers is no easy
job, so hopefully this will ensure greater consistency and fewer bugs.
*/
?>
+404 -357
View File
@@ -1,29 +1,31 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
@version v5.20.9 21-Dec-2016
@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.
Set tabs to 8.
Original version derived from Alberto Cerezal (acerezalp@dbnet.es) - DBNet Informatica & Comunicaciones.
Original version derived from Alberto Cerezal (acerezalp@dbnet.es) - DBNet Informatica & Comunicaciones.
08 Nov 2000 jlim - Minor corrections, removing mysql stuff
09 Nov 2000 jlim - added insertid support suggested by "Christopher Kings-Lynne" <chriskl@familyhealth.com.au>
jlim - changed concat operator to || and data types to MetaType to match documented pgsql types
see http://www.postgresql.org/devel-corner/docs/postgres/datatype.htm
jlim - changed concat operator to || and data types to MetaType to match documented pgsql types
see http://www.postgresql.org/devel-corner/docs/postgres/datatype.htm
22 Nov 2000 jlim - added changes to FetchField() and MetaTables() contributed by "raser" <raser@mail.zen.com.tw>
27 Nov 2000 jlim - added changes to _connect/_pconnect from ideas by "Lennie" <leen@wirehub.nl>
15 Dec 2000 jlim - added changes suggested by Additional code changes by "Eric G. Werk" egw@netguide.dk.
15 Dec 2000 jlim - added changes suggested by Additional code changes by "Eric G. Werk" egw@netguide.dk.
31 Jan 2002 jlim - finally installed postgresql. testing
01 Mar 2001 jlim - Freek Dijkstra changes, also support for text type
See http://www.varlena.com/varlena/GeneralBits/47.php
-- What indexes are on my table?
select * from pg_indexes where tablename = 'tablename';
-- What triggers are on my table?
select c.relname as "Table", t.tgname as "Trigger Name",
select c.relname as "Table", t.tgname as "Trigger Name",
t.tgconstrname as "Constraint Name", t.tgenabled as "Enabled",
t.tgisconstraint as "Is Constraint", cc.relname as "Referenced Table",
p.proname as "Function Name"
@@ -31,7 +33,7 @@
where t.tgfoid = p.oid and t.tgrelid = c.oid
and t.tgconstrrelid = cc.oid
and c.relname = 'tablename';
-- What constraints are on my table?
select r.relname as "Table", c.conname as "Constraint Name",
contype as "Constraint Type", conkey as "Key Columns",
@@ -50,7 +52,7 @@ function adodb_addslashes($s)
$len = strlen($s);
if ($len == 0) return "''";
if (strncmp($s,"'",1) === 0 && substr($s,$len-1) == "'") return $s; // already quoted
return "'".addslashes($s)."'";
}
@@ -59,38 +61,41 @@ class ADODB_postgres64 extends ADOConnection{
var $dataProvider = 'postgres';
var $hasInsertID = true;
var $_resultid = false;
var $concat_operator='||';
var $concat_operator='||';
var $metaDatabasesSQL = "select datname from pg_database where datname not in ('template0','template1') order by 1";
var $metaTablesSQL = "select tablename,'T' from pg_tables where tablename not like 'pg\_%'
and tablename not in ('sql_features', 'sql_implementation_info', 'sql_languages',
'sql_packages', 'sql_sizing', 'sql_sizing_profiles')
union
select viewname,'V' from pg_views where viewname not like 'pg\_%'";
var $metaTablesSQL = "select tablename,'T' from pg_tables where tablename not like 'pg\_%'
and tablename not in ('sql_features', 'sql_implementation_info', 'sql_languages',
'sql_packages', 'sql_sizing', 'sql_sizing_profiles')
union
select viewname,'V' from pg_views where viewname not like 'pg\_%'";
//"select tablename from pg_tables where tablename not like 'pg_%' order by 1";
var $isoDates = true; // accepts dates in ISO format
var $sysDate = "CURRENT_DATE";
var $sysTimeStamp = "CURRENT_TIMESTAMP";
var $blobEncodeType = 'C';
var $metaColumnsSQL = "SELECT a.attname,t.typname,a.attlen,a.atttypmod,a.attnotnull,a.atthasdef,a.attnum
FROM pg_class c, pg_attribute a,pg_type t
var $metaColumnsSQL = "SELECT a.attname,t.typname,a.attlen,a.atttypmod,a.attnotnull,a.atthasdef,a.attnum
FROM pg_class c, pg_attribute a,pg_type t
WHERE relkind in ('r','v') AND (c.relname='%s' or c.relname = lower('%s')) and a.attname not like '....%%'
AND a.attnum > 0 AND a.atttypid = t.oid AND a.attrelid = c.oid ORDER BY a.attnum";
AND a.attnum > 0 AND a.atttypid = t.oid AND a.attrelid = c.oid ORDER BY a.attnum";
// used when schema defined
var $metaColumnsSQL1 = "SELECT a.attname, t.typname, a.attlen, a.atttypmod, a.attnotnull, a.atthasdef, a.attnum
FROM pg_class c, pg_attribute a, pg_type t, pg_namespace n
WHERE relkind in ('r','v') AND (c.relname='%s' or c.relname = lower('%s'))
and c.relnamespace=n.oid and n.nspname='%s'
and a.attname not like '....%%' AND a.attnum > 0
AND a.atttypid = t.oid AND a.attrelid = c.oid ORDER BY a.attnum";
var $metaColumnsSQL1 = "SELECT a.attname, t.typname, a.attlen, a.atttypmod, a.attnotnull, a.atthasdef, a.attnum
FROM pg_class c, pg_attribute a, pg_type t, pg_namespace n
WHERE relkind in ('r','v') AND (c.relname='%s' or c.relname = lower('%s'))
and c.relnamespace=n.oid and n.nspname='%s'
and a.attname not like '....%%' AND a.attnum > 0
AND a.atttypid = t.oid AND a.attrelid = c.oid ORDER BY a.attnum";
// get primary key etc -- from Freek Dijkstra
var $metaKeySQL = "SELECT ic.relname AS index_name, a.attname AS column_name,i.indisunique AS unique_key, i.indisprimary AS primary_key
FROM pg_class bc, pg_class ic, pg_index i, pg_attribute a WHERE bc.oid = i.indrelid AND ic.oid = i.indexrelid AND (i.indkey[0] = a.attnum OR i.indkey[1] = a.attnum OR i.indkey[2] = a.attnum OR i.indkey[3] = a.attnum OR i.indkey[4] = a.attnum OR i.indkey[5] = a.attnum OR i.indkey[6] = a.attnum OR i.indkey[7] = a.attnum) AND a.attrelid = bc.oid AND bc.relname = '%s'";
var $metaKeySQL = "SELECT ic.relname AS index_name, a.attname AS column_name,i.indisunique AS unique_key, i.indisprimary AS primary_key
FROM pg_class bc, pg_class ic, pg_index i, pg_attribute a
WHERE bc.oid = i.indrelid AND ic.oid = i.indexrelid
AND (i.indkey[0] = a.attnum OR i.indkey[1] = a.attnum OR i.indkey[2] = a.attnum OR i.indkey[3] = a.attnum OR i.indkey[4] = a.attnum OR i.indkey[5] = a.attnum OR i.indkey[6] = a.attnum OR i.indkey[7] = a.attnum)
AND a.attrelid = bc.oid AND bc.relname = '%s'";
var $hasAffectedRows = true;
var $hasLimit = false; // set to true for pgsql 7 only. support pgsql/mysql SELECT * FROM TABLE LIMIT 10
// below suggested by Freek Dijkstra
// below suggested by Freek Dijkstra
var $true = 'TRUE'; // string that represents TRUE for a database
var $false = 'FALSE'; // string that represents FALSE for a database
var $fmtDate = "'Y-m-d'"; // used by DBDate() as the default date format used by the database
@@ -104,55 +109,59 @@ WHERE relkind in ('r','v') AND (c.relname='%s' or c.relname = lower('%s'))
var $random = 'random()'; /// random function
var $autoRollback = true; // apparently pgsql does not autorollback properly before php 4.3.4
// http://bugs.php.net/bug.php?id=25404
var $uniqueIisR = true;
var $_bindInputArray = false; // requires postgresql 7.3+ and ability to modify database
var $disableBlobs = false; // set to true to disable blob checking, resulting in 2-5% improvement in performance.
// The last (fmtTimeStamp is not entirely correct:
// PostgreSQL also has support for time zones,
// and writes these time in this format: "2001-03-01 18:59:26+02".
// There is no code for the "+02" time zone information, so I just left that out.
// I'm not familiar enough with both ADODB as well as Postgres
// to know what the concequences are. The other values are correct (wheren't in 0.94)
// -- Freek Dijkstra
function ADODB_postgres64()
var $_pnum = 0;
// The last (fmtTimeStamp is not entirely correct:
// PostgreSQL also has support for time zones,
// and writes these time in this format: "2001-03-01 18:59:26+02".
// There is no code for the "+02" time zone information, so I just left that out.
// I'm not familiar enough with both ADODB as well as Postgres
// to know what the concequences are. The other values are correct (wheren't in 0.94)
// -- Freek Dijkstra
function __construct()
{
// changes the metaColumnsSQL, adds columns: attnum[6]
// changes the metaColumnsSQL, adds columns: attnum[6]
}
function ServerInfo()
{
if (isset($this->version)) return $this->version;
$arr['description'] = $this->GetOne("select version()");
$arr['version'] = ADOConnection::_findvers($arr['description']);
$this->version = $arr;
return $arr;
}
function IfNull( $field, $ifNull )
function IfNull( $field, $ifNull )
{
return " coalesce($field, $ifNull) ";
return " coalesce($field, $ifNull) ";
}
// get the last id - never tested
function pg_insert_id($tablename,$fieldname)
{
$result=pg_exec($this->_connectionID, "SELECT last_value FROM ${tablename}_${fieldname}_seq");
$result=pg_query($this->_connectionID, 'SELECT last_value FROM '. $tablename .'_'. $fieldname .'_seq');
if ($result) {
$arr = @pg_fetch_row($result,0);
pg_freeresult($result);
pg_free_result($result);
if (isset($arr[0])) return $arr[0];
}
return false;
}
/* Warning from http://www.php.net/manual/function.pg-getlastoid.php:
Using a OID as a unique identifier is not generally wise.
Unless you are very careful, you might end up with a tuple having
a different OID if a database must be reloaded. */
/**
* Warning from http://www.php.net/manual/function.pg-getlastoid.php:
* Using a OID as a unique identifier is not generally wise.
* Unless you are very careful, you might end up with a tuple having
* a different OID if a database must be reloaded.
*/
function _insertid($table,$column)
{
if (!is_resource($this->_resultid) || get_resource_type($this->_resultid) !== 'pgsql result') return false;
@@ -161,110 +170,110 @@ a different OID if a database must be reloaded. */
return empty($table) || empty($column) ? $oid : $this->GetOne("SELECT $column FROM $table WHERE oid=".(int)$oid);
}
// I get this error with PHP before 4.0.6 - jlim
// Warning: This compilation does not support pg_cmdtuples() in adodb-postgres.inc.php on line 44
function _affectedrows()
{
if (!is_resource($this->_resultid) || get_resource_type($this->_resultid) !== 'pgsql result') return false;
return pg_cmdtuples($this->_resultid);
}
// returns true/false
function _affectedrows()
{
if (!is_resource($this->_resultid) || get_resource_type($this->_resultid) !== 'pgsql result') return false;
return pg_affected_rows($this->_resultid);
}
/**
* @return true/false
*/
function BeginTrans()
{
if ($this->transOff) return true;
$this->transCnt += 1;
return @pg_Exec($this->_connectionID, "begin ".$this->_transmode);
}
function RowLock($tables,$where,$flds='1 as ignore')
{
if (!$this->transCnt) $this->BeginTrans();
return $this->GetOne("select $flds from $tables where $where for update");
return pg_query($this->_connectionID, 'begin '.$this->_transmode);
}
// returns true/false.
function CommitTrans($ok=true)
{
function RowLock($tables,$where,$col='1 as adodbignore')
{
if (!$this->transCnt) $this->BeginTrans();
return $this->GetOne("select $col from $tables where $where for update");
}
// returns true/false.
function CommitTrans($ok=true)
{
if ($this->transOff) return true;
if (!$ok) return $this->RollbackTrans();
$this->transCnt -= 1;
return @pg_Exec($this->_connectionID, "commit");
return pg_query($this->_connectionID, 'commit');
}
// returns true/false
function RollbackTrans()
{
if ($this->transOff) return true;
$this->transCnt -= 1;
return @pg_Exec($this->_connectionID, "rollback");
return pg_query($this->_connectionID, 'rollback');
}
function MetaTables($ttype=false,$showSchema=false,$mask=false)
function MetaTables($ttype=false,$showSchema=false,$mask=false)
{
$info = $this->ServerInfo();
if ($info['version'] >= 7.3) {
$this->metaTablesSQL = "select tablename,'T' from pg_tables where tablename not like 'pg\_%'
and schemaname not in ( 'pg_catalog','information_schema')
union
select viewname,'V' from pg_views where viewname not like 'pg\_%' and schemaname not in ( 'pg_catalog','information_schema') ";
$this->metaTablesSQL = "
select table_name,'T' from information_schema.tables where table_schema not in ( 'pg_catalog','information_schema')
union
select table_name,'V' from information_schema.views where table_schema not in ( 'pg_catalog','information_schema') ";
}
if ($mask) {
$save = $this->metaTablesSQL;
$mask = $this->qstr(strtolower($mask));
if ($info['version']>=7.3)
$this->metaTablesSQL = "
select tablename,'T' from pg_tables where tablename like $mask and schemaname not in ( 'pg_catalog','information_schema')
union
select viewname,'V' from pg_views where viewname like $mask and schemaname not in ( 'pg_catalog','information_schema') ";
select table_name,'T' from information_schema.tables where table_name like $mask and table_schema not in ( 'pg_catalog','information_schema')
union
select table_name,'V' from information_schema.views where table_name like $mask and table_schema not in ( 'pg_catalog','information_schema') ";
else
$this->metaTablesSQL = "
select tablename,'T' from pg_tables where tablename like $mask
union
select viewname,'V' from pg_views where viewname like $mask";
select tablename,'T' from pg_tables where tablename like $mask
union
select viewname,'V' from pg_views where viewname like $mask";
}
$ret = ADOConnection::MetaTables($ttype,$showSchema);
if ($mask) {
$this->metaTablesSQL = $save;
}
return $ret;
}
// if magic quotes disabled, use pg_escape_string()
function qstr($s,$magic_quotes=false)
{
if (is_bool($s)) return $s ? 'true' : 'false';
if (!$magic_quotes) {
if (ADODB_PHPVER >= 0x5200) {
if (ADODB_PHPVER >= 0x5200 && $this->_connectionID) {
return "'".pg_escape_string($this->_connectionID,$s)."'";
}
}
if (ADODB_PHPVER >= 0x4200) {
return "'".pg_escape_string($s)."'";
}
if ($this->replaceQuote[0] == '\\'){
$s = adodb_str_replace(array('\\',"\0"),array('\\\\',"\\\\000"),$s);
}
return "'".str_replace("'",$this->replaceQuote,$s)."'";
return "'".str_replace("'",$this->replaceQuote,$s)."'";
}
// undo magic quotes for "
$s = str_replace('\\"','"',$s);
return "'$s'";
}
// Format date column in sql string given an input format that understands Y M D
function SQLDate($fmt, $col=false)
{
{
if (!$col) $col = $this->sysTimeStamp;
$s = 'TO_CHAR('.$col.",'";
$len = strlen($fmt);
for ($i=0; $i < $len; $i++) {
$ch = $fmt[$i];
@@ -277,11 +286,11 @@ select viewname,'V' from pg_views where viewname like $mask";
case 'q':
$s .= 'Q';
break;
case 'M':
$s .= 'Mon';
break;
case 'm':
$s .= 'MM';
break;
@@ -289,37 +298,37 @@ select viewname,'V' from pg_views where viewname like $mask";
case 'd':
$s .= 'DD';
break;
case 'H':
$s.= 'HH24';
break;
case 'h':
$s .= 'HH';
break;
case 'i':
$s .= 'MI';
break;
case 's':
$s .= 'SS';
break;
case 'a':
case 'A':
$s .= 'AM';
break;
case 'w':
$s .= 'D';
break;
case 'l':
$s .= 'DAY';
break;
case 'W':
case 'W':
$s .= 'WW';
break;
@@ -331,44 +340,44 @@ select viewname,'V' from pg_views where viewname like $mask";
}
if (strpos('-/.:;, ',$ch) !== false) $s .= $ch;
else $s .= '"'.$ch.'"';
}
}
return $s. "')";
}
/*
* Load a Large Object from a file
* - the procedure stores the object id in the table and imports the object using
* postgres proprietary blob handling routines
/*
* Load a Large Object from a file
* - the procedure stores the object id in the table and imports the object using
* postgres proprietary blob handling routines
*
* contributed by Mattia Rossi mattia@technologist.com
* modified for safe mode by juraj chlebec
*/
function UpdateBlobFile($table,$column,$path,$where,$blobtype='BLOB')
{
pg_exec ($this->_connectionID, "begin");
*/
function UpdateBlobFile($table,$column,$path,$where,$blobtype='BLOB')
{
pg_query($this->_connectionID, 'begin');
$fd = fopen($path,'r');
$contents = fread($fd,filesize($path));
fclose($fd);
$oid = pg_lo_create($this->_connectionID);
$handle = pg_lo_open($this->_connectionID, $oid, 'w');
pg_lo_write($handle, $contents);
pg_lo_close($handle);
// $oid = pg_lo_import ($path);
pg_exec($this->_connectionID, "commit");
$rs = ADOConnection::UpdateBlob($table,$column,$oid,$where,$blobtype);
$rez = !empty($rs);
return $rez;
}
// $oid = pg_lo_import ($path);
pg_query($this->_connectionID, 'commit');
$rs = ADOConnection::UpdateBlob($table,$column,$oid,$where,$blobtype);
$rez = !empty($rs);
return $rez;
}
/*
* Deletes/Unlinks a Blob from the database, otherwise it
* Deletes/Unlinks a Blob from the database, otherwise it
* will be left behind
*
* Returns TRUE on success or FALSE on failure.
@@ -377,9 +386,9 @@ select viewname,'V' from pg_views where viewname like $mask";
*/
function BlobDelete( $blob )
{
pg_exec ($this->_connectionID, "begin");
pg_query($this->_connectionID, 'begin');
$result = @pg_lo_unlink($blob);
pg_exec ($this->_connectionID, "commit");
pg_query($this->_connectionID, 'commit');
return( $result );
}
@@ -391,8 +400,8 @@ select viewname,'V' from pg_views where viewname like $mask";
if (strlen($oid)>16) return false;
return is_numeric($oid);
}
/*
/*
* If an OID is detected, then we use pg_lo_* to open the oid file and read the
* real blob from the db using the oid supplied as a parameter. If you are storing
* blobs using bytea, we autodetect and process it so this function is not needed.
@@ -403,109 +412,122 @@ select viewname,'V' from pg_views where viewname like $mask";
*
* Since adodb 4.54, this returns the blob, instead of sending it to stdout. Also
* added maxsize parameter, which defaults to $db->maxblobsize if not defined.
*/
function BlobDecode($blob,$maxsize=false,$hastrans=true)
*/
function BlobDecode($blob,$maxsize=false,$hastrans=true)
{
if (!$this->GuessOID($blob)) return $blob;
if ($hastrans) @pg_exec($this->_connectionID,"begin");
$fd = @pg_lo_open($this->_connectionID,$blob,"r");
if ($hastrans) pg_query($this->_connectionID,'begin');
$fd = @pg_lo_open($this->_connectionID,$blob,'r');
if ($fd === false) {
if ($hastrans) @pg_exec($this->_connectionID,"commit");
if ($hastrans) pg_query($this->_connectionID,'commit');
return $blob;
}
if (!$maxsize) $maxsize = $this->maxblobsize;
$realblob = @pg_loread($fd,$maxsize);
@pg_loclose($fd);
if ($hastrans) @pg_exec($this->_connectionID,"commit");
$realblob = @pg_lo_read($fd,$maxsize);
@pg_loclose($fd);
if ($hastrans) pg_query($this->_connectionID,'commit');
return $realblob;
}
/*
/*
See http://www.postgresql.org/idocs/index.php?datatype-binary.html
NOTE: SQL string literals (input strings) must be preceded with two backslashes
due to the fact that they must pass through two parsers in the PostgreSQL
NOTE: SQL string literals (input strings) must be preceded with two backslashes
due to the fact that they must pass through two parsers in the PostgreSQL
backend.
*/
function BlobEncode($blob)
{
if (ADODB_PHPVER >= 0x5200) return pg_escape_bytea($this->_connectionID, $blob);
if (ADODB_PHPVER >= 0x4200) return pg_escape_bytea($blob);
/*92=backslash, 0=null, 39=single-quote*/
$badch = array(chr(92),chr(0),chr(39)); # \ null '
$fixch = array('\\\\134','\\\\000','\\\\047');
return adodb_str_replace($badch,$fixch,$blob);
// note that there is a pg_escape_bytea function only for php 4.2.0 or later
}
// assumes bytea for blob, and varchar for clob
function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
{
if ($blobtype == 'CLOB') {
return $this->Execute("UPDATE $table SET $column=" . $this->qstr($val) . " WHERE $where");
return $this->Execute("UPDATE $table SET $column=" . $this->qstr($val) . " WHERE $where");
}
// do not use bind params which uses qstr(), as blobencode() already quotes data
return $this->Execute("UPDATE $table SET $column='".$this->BlobEncode($val)."'::bytea WHERE $where");
}
function OffsetDate($dayFraction,$date=false)
{
{
if (!$date) $date = $this->sysDate;
else if (strncmp($date,"'",1) == 0) {
$len = strlen($date);
if (10 <= $len && $len <= 12) $date = 'date '.$date;
else $date = 'timestamp '.$date;
}
return "($date+interval'".($dayFraction * 1440)." minutes')";
#return "($date+interval'$dayFraction days')";
}
/**
* Generate the SQL to retrieve MetaColumns data
* @param string $table Table name
* @param string $schema Schema name (can be blank)
* @return string SQL statement to execute
*/
protected function _generateMetaColumnsSQL($table, $schema)
{
if ($schema) {
return sprintf($this->metaColumnsSQL1, $table, $table, $schema);
}
else {
return sprintf($this->metaColumnsSQL, $table, $table, $schema);
}
}
// for schema support, pass in the $table param "$schema.$tabname".
// converts field names to lowercase, $upper is ignored
// see http://phplens.com/lens/lensforum/msgs.php?id=14018 for more info
function MetaColumns($table,$normalize=true)
function MetaColumns($table,$normalize=true)
{
global $ADODB_FETCH_MODE;
global $ADODB_FETCH_MODE;
$schema = false;
$false = false;
$this->_findschema($table,$schema);
if ($normalize) $table = strtolower($table);
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
if ($schema) $rs = $this->Execute(sprintf($this->metaColumnsSQL1,$table,$table,$schema));
else $rs = $this->Execute(sprintf($this->metaColumnsSQL,$table,$table));
$rs = $this->Execute($this->_generateMetaColumnsSQL($table, $schema));
if (isset($savem)) $this->SetFetchMode($savem);
$ADODB_FETCH_MODE = $save;
if ($rs === false) {
return $false;
}
if (!empty($this->metaKeySQL)) {
// If we want the primary keys, we have to issue a separate query
// Of course, a modified version of the metaColumnsSQL query using a
// LEFT JOIN would have been much more elegant, but postgres does
// Of course, a modified version of the metaColumnsSQL query using a
// LEFT JOIN would have been much more elegant, but postgres does
// not support OUTER JOINS. So here is the clumsy way.
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
$rskey = $this->Execute(sprintf($this->metaKeySQL,($table)));
// fetch all result in once for performance.
$keys = $rskey->GetArray();
if (isset($savem)) $this->SetFetchMode($savem);
$ADODB_FETCH_MODE = $save;
$rskey->Close();
unset($rskey);
}
@@ -517,7 +539,7 @@ select viewname,'V' from pg_views where viewname like $mask";
$rsdef = $this->Execute($sql);
if (isset($savem)) $this->SetFetchMode($savem);
$ADODB_FETCH_MODE = $save;
if ($rsdef) {
while (!$rsdef->EOF) {
$num = $rsdef->fields['num'];
@@ -535,15 +557,15 @@ select viewname,'V' from pg_views where viewname like $mask";
}
unset($rsdef);
}
$retarr = array();
while (!$rs->EOF) {
while (!$rs->EOF) {
$fld = new ADOFieldObject();
$fld->name = $rs->fields[0];
$fld->type = $rs->fields[1];
$fld->max_length = $rs->fields[2];
$fld->attnum = $rs->fields[6];
if ($fld->max_length <= 0) $fld->max_length = $rs->fields[3]-4;
if ($fld->max_length <= 0) $fld->max_length = -1;
if ($fld->type == 'numeric') {
@@ -559,93 +581,107 @@ select viewname,'V' from pg_views where viewname like $mask";
//Freek
$fld->not_null = $rs->fields[4] == 't';
// Freek
if (is_array($keys)) {
foreach($keys as $key) {
if ($fld->name == $key['column_name'] AND $key['primary_key'] == 't')
if ($fld->name == $key['column_name'] AND $key['primary_key'] == 't')
$fld->primary_key = true;
if ($fld->name == $key['column_name'] AND $key['unique_key'] == 't')
if ($fld->name == $key['column_name'] AND $key['unique_key'] == 't')
$fld->unique = true; // What name is more compatible?
}
}
if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;
if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;
else $retarr[($normalize) ? strtoupper($fld->name) : $fld->name] = $fld;
$rs->MoveNext();
}
$rs->Close();
if (empty($retarr))
return $false;
else
return $retarr;
return $retarr;
}
function MetaIndexes ($table, $primary = FALSE)
{
global $ADODB_FETCH_MODE;
$schema = false;
$this->_findschema($table,$schema);
function Param($name,$type='C')
{
if ($name) {
$this->_pnum += 1;
} else {
// Reset param num if $name is false
$this->_pnum = 1;
}
return '$'.$this->_pnum;
}
if ($schema) { // requires pgsql 7.3+ - pg_namespace used.
$sql = '
SELECT c.relname as "Name", i.indisunique as "Unique", i.indkey as "Columns"
FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_index i ON i.indexrelid=c.oid
JOIN pg_catalog.pg_class c2 ON c2.oid=i.indrelid
,pg_namespace n
WHERE (c2.relname=\'%s\' or c2.relname=lower(\'%s\')) and c.relnamespace=c2.relnamespace and c.relnamespace=n.oid and n.nspname=\'%s\'';
} else {
$sql = '
SELECT c.relname as "Name", i.indisunique as "Unique", i.indkey as "Columns"
FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_index i ON i.indexrelid=c.oid
JOIN pg_catalog.pg_class c2 ON c2.oid=i.indrelid
WHERE (c2.relname=\'%s\' or c2.relname=lower(\'%s\'))';
}
if ($primary == FALSE) {
$sql .= ' AND i.indisprimary=false;';
}
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== FALSE) {
$savem = $this->SetFetchMode(FALSE);
}
$rs = $this->Execute(sprintf($sql,$table,$table,$schema));
if (isset($savem)) {
$this->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
function MetaIndexes ($table, $primary = FALSE, $owner = false)
{
global $ADODB_FETCH_MODE;
if (!is_object($rs)) {
$false = false;
return $false;
}
$col_names = $this->MetaColumnNames($table,true,true);
//3rd param is use attnum,
// see http://sourceforge.net/tracker/index.php?func=detail&aid=1451245&group_id=42718&atid=433976
$indexes = array();
while ($row = $rs->FetchRow()) {
$columns = array();
foreach (explode(' ', $row[2]) as $col) {
$columns[] = $col_names[$col];
}
$indexes[$row[0]] = array(
'unique' => ($row[1] == 't'),
'columns' => $columns
);
}
return $indexes;
}
$schema = false;
$this->_findschema($table,$schema);
if ($schema) { // requires pgsql 7.3+ - pg_namespace used.
$sql = '
SELECT c.relname as "Name", i.indisunique as "Unique", i.indkey as "Columns"
FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_index i ON i.indexrelid=c.oid
JOIN pg_catalog.pg_class c2 ON c2.oid=i.indrelid
,pg_namespace n
WHERE (c2.relname=\'%s\' or c2.relname=lower(\'%s\'))
and c.relnamespace=c2.relnamespace
and c.relnamespace=n.oid
and n.nspname=\'%s\'';
} else {
$sql = '
SELECT c.relname as "Name", i.indisunique as "Unique", i.indkey as "Columns"
FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_index i ON i.indexrelid=c.oid
JOIN pg_catalog.pg_class c2 ON c2.oid=i.indrelid
WHERE (c2.relname=\'%s\' or c2.relname=lower(\'%s\'))';
}
if ($primary == FALSE) {
$sql .= ' AND i.indisprimary=false;';
}
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== FALSE) {
$savem = $this->SetFetchMode(FALSE);
}
$rs = $this->Execute(sprintf($sql,$table,$table,$schema));
if (isset($savem)) {
$this->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
if (!is_object($rs)) {
$false = false;
return $false;
}
$col_names = $this->MetaColumnNames($table,true,true);
//3rd param is use attnum,
// see http://sourceforge.net/tracker/index.php?func=detail&aid=1451245&group_id=42718&atid=433976
$indexes = array();
while ($row = $rs->FetchRow()) {
$columns = array();
foreach (explode(' ', $row[2]) as $col) {
$columns[] = $col_names[$col];
}
$indexes[$row[0]] = array(
'unique' => ($row[1] == 't'),
'columns' => $columns
);
}
return $indexes;
}
// returns true or false
//
@@ -654,59 +690,67 @@ WHERE (c2.relname=\'%s\' or c2.relname=lower(\'%s\'))';
// $db->Connect('host1','user1','secret');
function _connect($str,$user='',$pwd='',$db='',$ctype=0)
{
if (!function_exists('pg_connect')) return null;
$this->_errorMsg = false;
if ($user || $pwd || $db) {
$user = adodb_addslashes($user);
$pwd = adodb_addslashes($pwd);
if (strlen($db) == 0) $db = 'template1';
$db = adodb_addslashes($db);
if ($str) {
$host = split(":", $str);
if ($str) {
$host = explode(":", $str);
if ($host[0]) $str = "host=".adodb_addslashes($host[0]);
else $str = '';
if (isset($host[1])) $str .= " port=$host[1]";
else if (!empty($this->port)) $str .= " port=".$this->port;
}
if ($user) $str .= " user=".$user;
if ($pwd) $str .= " password=".$pwd;
if ($db) $str .= " dbname=".$db;
if ($user) $str .= " user=".$user;
if ($pwd) $str .= " password=".$pwd;
if ($db) $str .= " dbname=".$db;
}
//if ($user) $linea = "user=$user host=$linea password=$pwd dbname=$db port=5432";
if ($ctype === 1) { // persistent
$this->_connectionID = pg_pconnect($str);
} else {
if ($ctype === -1) { // nconnect, we trick pgsql ext by changing the connection str
static $ncnt;
static $ncnt;
if (empty($ncnt)) $ncnt = 1;
else $ncnt += 1;
$str .= str_repeat(' ',$ncnt);
}
$this->_connectionID = pg_connect($str);
}
if ($this->_connectionID === false) return false;
$this->Execute("set datestyle='ISO'");
$info = $this->ServerInfo();
$this->pgVersion = (float) substr($info['version'],0,3);
if ($this->pgVersion >= 7.1) { // good till version 999
$this->_nestedSQL = true;
}
# PostgreSQL 9.0 changed the default output for bytea from 'escape' to 'hex'
# PHP does not handle 'hex' properly ('x74657374' is returned as 't657374')
# https://bugs.php.net/bug.php?id=59831 states this is in fact not a bug,
# so we manually set bytea_output
if ( !empty($this->connection->noBlobs) && version_compare($info['version'], '9.0', '>=')) {
$this->Execute('set bytea_output=escape');
}
return true;
}
function _nconnect($argHostname, $argUsername, $argPassword, $argDatabaseName)
{
return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabaseName,-1);
return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabaseName,-1);
}
// returns true or false
//
// examples:
@@ -716,28 +760,26 @@ WHERE (c2.relname=\'%s\' or c2.relname=lower(\'%s\'))';
{
return $this->_connect($str,$user,$pwd,$db,1);
}
// returns queryID or false
function _query($sql,$inputarr=false)
{
$this->_pnum = 0;
$this->_errorMsg = false;
if ($inputarr) {
/*
It appears that PREPARE/EXECUTE is slower for many queries.
For query executed 1000 times:
"select id,firstname,lastname from adoxyz
"select id,firstname,lastname from adoxyz
where firstname not like ? and lastname not like ? and id = ?"
with plan = 1.51861286163 secs
no plan = 1.26903700829 secs
*/
$plan = 'P'.md5($sql);
$execp = '';
foreach($inputarr as $v) {
if ($execp) $execp .= ',';
@@ -747,12 +789,12 @@ WHERE (c2.relname=\'%s\' or c2.relname=lower(\'%s\'))';
$execp .= $v;
}
}
if ($execp) $exsql = "EXECUTE $plan ($execp)";
else $exsql = "EXECUTE $plan";
$rez = @pg_exec($this->_connectionID,$exsql);
$rez = @pg_execute($this->_connectionID,$exsql);
if (!$rez) {
# Perhaps plan does not exist? Prepare/compile plan.
$params = '';
@@ -774,37 +816,37 @@ WHERE (c2.relname=\'%s\' or c2.relname=lower(\'%s\'))';
$sql .= $v.' $'.$i;
$i++;
}
$s = "PREPARE $plan ($params) AS ".substr($sql,0,strlen($sql)-2);
$s = "PREPARE $plan ($params) AS ".substr($sql,0,strlen($sql)-2);
//adodb_pr($s);
$rez = pg_exec($this->_connectionID,$s);
$rez = pg_execute($this->_connectionID,$s);
//echo $this->ErrorMsg();
}
if ($rez)
$rez = pg_exec($this->_connectionID,$exsql);
$rez = pg_execute($this->_connectionID,$exsql);
} else {
//adodb_backtrace();
$rez = pg_exec($this->_connectionID,$sql);
$rez = pg_query($this->_connectionID,$sql);
}
// check if no data returned, then no need to create real recordset
if ($rez && pg_numfields($rez) <= 0) {
if ($rez && pg_num_fields($rez) <= 0) {
if (is_resource($this->_resultid) && get_resource_type($this->_resultid) === 'pgsql result') {
pg_freeresult($this->_resultid);
pg_free_result($this->_resultid);
}
$this->_resultid = $rez;
return true;
}
return $rez;
}
function _errconnect()
{
if (defined('DB_ERROR_CONNECT_FAILED')) return DB_ERROR_CONNECT_FAILED;
else return 'Database connection failed';
}
/* Returns: the last error message from previous database operation */
function ErrorMsg()
/* Returns: the last error message from previous database operation */
function ErrorMsg()
{
if ($this->_errorMsg !== false) return $this->_errorMsg;
if (ADODB_PHPVER >= 0x4300) {
@@ -812,7 +854,7 @@ WHERE (c2.relname=\'%s\' or c2.relname=lower(\'%s\'))';
$this->_errorMsg = @pg_result_error($this->_resultid);
if ($this->_errorMsg) return $this->_errorMsg;
}
if (!empty($this->_connectionID)) {
$this->_errorMsg = @pg_last_error($this->_connectionID);
} else $this->_errorMsg = $this->_errconnect();
@@ -822,14 +864,14 @@ WHERE (c2.relname=\'%s\' or c2.relname=lower(\'%s\'))';
}
return $this->_errorMsg;
}
function ErrorNo()
{
$e = $this->ErrorMsg();
if (strlen($e)) {
return ADOConnection::MetaError($e);
}
return 0;
}
return 0;
}
// returns true or false
@@ -837,15 +879,15 @@ WHERE (c2.relname=\'%s\' or c2.relname=lower(\'%s\'))';
{
if ($this->transCnt) $this->RollbackTrans();
if ($this->_resultid) {
@pg_freeresult($this->_resultid);
@pg_free_result($this->_resultid);
$this->_resultid = false;
}
@pg_close($this->_connectionID);
$this->_connectionID = false;
return true;
}
/*
* Maximum size of C field
*/
@@ -853,7 +895,7 @@ WHERE (c2.relname=\'%s\' or c2.relname=lower(\'%s\'))';
{
return 1000000000; // should be 1 Gb?
}
/*
* Maximum size of X field
*/
@@ -861,21 +903,22 @@ WHERE (c2.relname=\'%s\' or c2.relname=lower(\'%s\'))';
{
return 1000000000; // should be 1 Gb?
}
}
/*--------------------------------------------------------------------------------------
Class Name: Recordset
Class Name: Recordset
--------------------------------------------------------------------------------------*/
class ADORecordSet_postgres64 extends ADORecordSet{
var $_blobArr;
var $databaseType = "postgres64";
var $canSeek = true;
function ADORecordSet_postgres64($queryID,$mode=false)
function __construct($queryID, $mode=false)
{
if ($mode === false) {
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
@@ -883,35 +926,40 @@ class ADORecordSet_postgres64 extends ADORecordSet{
{
case ADODB_FETCH_NUM: $this->fetchMode = PGSQL_NUM; break;
case ADODB_FETCH_ASSOC:$this->fetchMode = PGSQL_ASSOC; break;
case ADODB_FETCH_DEFAULT:
case ADODB_FETCH_BOTH:
default: $this->fetchMode = PGSQL_BOTH; break;
}
$this->adodbFetchMode = $mode;
$this->ADORecordSet($queryID);
// Parent's constructor
parent::__construct($queryID);
}
function GetRowAssoc($upper=true)
function GetRowAssoc($upper = ADODB_ASSOC_CASE)
{
if ($this->fetchMode == PGSQL_ASSOC && !$upper) return $this->fields;
if ($this->fetchMode == PGSQL_ASSOC && $upper == ADODB_ASSOC_CASE_LOWER) {
return $this->fields;
}
$row = ADORecordSet::GetRowAssoc($upper);
return $row;
}
function _initrs()
{
global $ADODB_COUNTRECS;
$qid = $this->_queryID;
$this->_numOfRows = ($ADODB_COUNTRECS)? @pg_numrows($qid):-1;
$this->_numOfFields = @pg_numfields($qid);
$this->_numOfRows = ($ADODB_COUNTRECS)? @pg_num_rows($qid):-1;
$this->_numOfFields = @pg_num_fields($qid);
// cache types for blob decode check
// apparently pg_fieldtype actually performs an sql query on the database to get the type.
// apparently pg_field_type actually performs an sql query on the database to get the type.
if (empty($this->connection->noBlobs))
for ($i=0, $max = $this->_numOfFields; $i < $max; $i++) {
if (pg_fieldtype($qid,$i) == 'bytea') {
$this->_blobArr[$i] = pg_fieldname($qid,$i);
for ($i=0, $max = $this->_numOfFields; $i < $max; $i++) {
if (pg_field_type($qid,$i) == 'bytea') {
$this->_blobArr[$i] = pg_field_name($qid,$i);
}
}
}
@@ -920,7 +968,7 @@ class ADORecordSet_postgres64 extends ADORecordSet{
function Fields($colname)
{
if ($this->fetchMode != PGSQL_NUM) return @$this->fields[$colname];
if (!$this->bind) {
$this->bind = array();
for ($i=0; $i < $this->_numOfFields; $i++) {
@@ -928,32 +976,32 @@ class ADORecordSet_postgres64 extends ADORecordSet{
$this->bind[strtoupper($o->name)] = $i;
}
}
return $this->fields[$this->bind[strtoupper($colname)]];
return $this->fields[$this->bind[strtoupper($colname)]];
}
function FetchField($off = 0)
function FetchField($off = 0)
{
// offsets begin at 0
$o= new ADOFieldObject();
$o->name = @pg_fieldname($this->_queryID,$off);
$o->type = @pg_fieldtype($this->_queryID,$off);
$o->name = @pg_field_name($this->_queryID,$off);
$o->type = @pg_field_type($this->_queryID,$off);
$o->max_length = @pg_fieldsize($this->_queryID,$off);
return $o;
return $o;
}
function _seek($row)
{
return @pg_fetch_row($this->_queryID,$row);
}
function _decode($blob)
{
if ($blob === NULL) return NULL;
eval('$realblob="'.adodb_str_replace(array('"','$'),array('\"','\$'),$blob).'";');
return $realblob;
// eval('$realblob="'.adodb_str_replace(array('"','$'),array('\"','\$'),$blob).'";');
return pg_unescape_bytea($blob);
}
function _fixblobs()
{
if ($this->fetchMode == PGSQL_NUM || $this->fetchMode == PGSQL_BOTH) {
@@ -967,9 +1015,9 @@ class ADORecordSet_postgres64 extends ADORecordSet{
}
}
}
// 10% speedup to move MoveNext to child class
function MoveNext()
function MoveNext()
{
if (!$this->EOF) {
$this->_currentRow++;
@@ -984,24 +1032,24 @@ class ADORecordSet_postgres64 extends ADORecordSet{
$this->EOF = true;
}
return false;
}
}
function _fetch()
{
if ($this->_currentRow >= $this->_numOfRows && $this->_numOfRows >= 0)
return false;
return false;
$this->fields = @pg_fetch_array($this->_queryID,$this->_currentRow,$this->fetchMode);
if ($this->fields && isset($this->_blobArr)) $this->_fixblobs();
return (is_array($this->fields));
}
function _close()
{
return @pg_freeresult($this->_queryID);
function _close()
{
return @pg_free_result($this->_queryID);
}
function MetaType($t,$len=-1,$fieldobj=false)
@@ -1018,54 +1066,53 @@ class ADORecordSet_postgres64 extends ADORecordSet{
case 'CHARACTER':
case 'VARCHAR':
case 'NAME':
case 'BPCHAR':
case 'BPCHAR':
case '_VARCHAR':
case 'INET':
case 'MACADDR':
if ($len <= $this->blobSize) return 'C';
case 'TEXT':
return 'X';
case 'IMAGE': // user defined type
case 'BLOB': // user defined type
case 'BIT': // This is a bit string, not a single bit, so don't return 'L'
case 'VARBIT':
case 'BYTEA':
return 'B';
case 'BOOL':
case 'BOOLEAN':
return 'L';
case 'DATE':
return 'D';
case 'TIMESTAMP WITHOUT TIME ZONE':
case 'TIME':
case 'DATETIME':
case 'TIMESTAMP':
case 'TIMESTAMPTZ':
return 'T';
case 'SMALLINT':
case 'BIGINT':
case 'INTEGER':
case 'INT8':
case 'SMALLINT':
case 'BIGINT':
case 'INTEGER':
case 'INT8':
case 'INT4':
case 'INT2':
if (isset($fieldobj) &&
empty($fieldobj->primary_key) && (!$this->uniqueIisR || empty($fieldobj->unique))) return 'I';
empty($fieldobj->primary_key) && (!$this->connection->uniqueIisR || empty($fieldobj->unique))) return 'I';
case 'OID':
case 'SERIAL':
return 'R';
default:
return 'N';
default:
return 'N';
}
}
}
?>
+203 -130
View File
@@ -1,11 +1,13 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
@version v5.20.9 21-Dec-2016
@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.
Set tabs to 4.
Postgres7 support.
28 Feb 2001: Currently indicate that we support LIMIT
01 Dec 2001: dannym added support for default values
@@ -17,36 +19,108 @@ if (!defined('ADODB_DIR')) die();
include_once(ADODB_DIR."/drivers/adodb-postgres64.inc.php");
class ADODB_postgres7 extends ADODB_postgres64 {
var $databaseType = 'postgres7';
var $databaseType = 'postgres7';
var $hasLimit = true; // set to true for pgsql 6.5+ only. support pgsql/mysql SELECT * FROM TABLE LIMIT 10
var $ansiOuter = true;
var $charSet = true; //set to true for Postgres 7 and above - PG client supports encodings
function ADODB_postgres7()
// Richard 3/18/2012 - Modified SQL to return SERIAL type correctly AS old driver no longer return SERIAL as data type.
var $metaColumnsSQL = "
SELECT
a.attname,
CASE
WHEN x.sequence_name != ''
THEN 'SERIAL'
ELSE t.typname
END AS typname,
a.attlen, a.atttypmod, a.attnotnull, a.atthasdef, a.attnum
FROM
pg_class c,
pg_attribute a
JOIN pg_type t ON a.atttypid = t.oid
LEFT JOIN (
SELECT
c.relname as sequence_name,
c1.relname as related_table,
a.attname as related_column
FROM pg_class c
JOIN pg_depend d ON d.objid = c.oid
LEFT JOIN pg_class c1 ON d.refobjid = c1.oid
LEFT JOIN pg_attribute a ON (d.refobjid, d.refobjsubid) = (a.attrelid, a.attnum)
WHERE c.relkind = 'S' AND c1.relname = '%s'
) x ON x.related_column= a.attname
WHERE
c.relkind in ('r','v')
AND (c.relname='%s' or c.relname = lower('%s'))
AND a.attname not like '....%%'
AND a.attnum > 0
AND a.attrelid = c.oid
ORDER BY
a.attnum";
// used when schema defined
var $metaColumnsSQL1 = "
SELECT
a.attname,
CASE
WHEN x.sequence_name != ''
THEN 'SERIAL'
ELSE t.typname
END AS typname,
a.attlen, a.atttypmod, a.attnotnull, a.atthasdef, a.attnum
FROM
pg_class c,
pg_namespace n,
pg_attribute a
JOIN pg_type t ON a.atttypid = t.oid
LEFT JOIN (
SELECT
c.relname as sequence_name,
c1.relname as related_table,
a.attname as related_column
FROM pg_class c
JOIN pg_depend d ON d.objid = c.oid
LEFT JOIN pg_class c1 ON d.refobjid = c1.oid
LEFT JOIN pg_attribute a ON (d.refobjid, d.refobjsubid) = (a.attrelid, a.attnum)
WHERE c.relkind = 'S' AND c1.relname = '%s'
) x ON x.related_column= a.attname
WHERE
c.relkind in ('r','v')
AND (c.relname='%s' or c.relname = lower('%s'))
AND c.relnamespace=n.oid and n.nspname='%s'
AND a.attname not like '....%%'
AND a.attnum > 0
AND a.atttypid = t.oid
AND a.attrelid = c.oid
ORDER BY a.attnum";
function __construct()
{
$this->ADODB_postgres64();
if (ADODB_ASSOC_CASE !== 2) {
parent::__construct();
if (ADODB_ASSOC_CASE !== ADODB_ASSOC_CASE_NATIVE) {
$this->rsPrefix .= 'assoc_';
}
$this->_bindInputArray = PHP_VERSION >= 5.1;
}
// the following should be compat with postgresql 7.2,
// the following should be compat with postgresql 7.2,
// which makes obsolete the LIMIT limit,offset syntax
function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
{
$offsetStr = ($offset >= 0) ? " OFFSET ".((integer)$offset) : '';
$limitStr = ($nrows >= 0) ? " LIMIT ".((integer)$nrows) : '';
if ($secs2cache)
$rs = $this->CacheExecute($secs2cache,$sql."$limitStr$offsetStr",$inputarr);
else
$rs = $this->Execute($sql."$limitStr$offsetStr",$inputarr);
function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
{
$offsetStr = ($offset >= 0) ? " OFFSET ".((integer)$offset) : '';
$limitStr = ($nrows >= 0) ? " LIMIT ".((integer)$nrows) : '';
if ($secs2cache)
$rs = $this->CacheExecute($secs2cache,$sql."$limitStr$offsetStr",$inputarr);
else
$rs = $this->Execute($sql."$limitStr$offsetStr",$inputarr);
return $rs;
}
/*
function Prepare($sql)
}
/*
function Prepare($sql)
{
$info = $this->ServerInfo();
if ($info['version']>=7.3) {
@@ -54,58 +128,75 @@ class ADODB_postgres7 extends ADODB_postgres64 {
}
return $sql;
}
*/
/*
I discovered that the MetaForeignKeys method no longer worked for Postgres 8.3.
I went ahead and modified it to work for both 8.2 and 8.3.
Please feel free to include this change in your next release of adodb.
William Kolodny [William.Kolodny#gt-t.net]
*/
/**
* Generate the SQL to retrieve MetaColumns data
* @param string $table Table name
* @param string $schema Schema name (can be blank)
* @return string SQL statement to execute
*/
protected function _generateMetaColumnsSQL($table, $schema)
{
if ($schema) {
return sprintf($this->metaColumnsSQL1, $table, $table, $table, $schema);
}
else {
return sprintf($this->metaColumnsSQL, $table, $table, $schema);
}
}
/**
* @returns assoc array where keys are tables, and values are foreign keys
*/
function MetaForeignKeys($table, $owner=false, $upper=false)
{
$sql="
SELECT fum.ftblname AS lookup_table, split_part(fum.rf, ')'::text, 1) AS lookup_field,
fum.ltable AS dep_table, split_part(fum.lf, ')'::text, 1) AS dep_field
FROM (
SELECT fee.ltable, fee.ftblname, fee.consrc, split_part(fee.consrc,'('::text, 2) AS lf,
split_part(fee.consrc, '('::text, 3) AS rf
FROM (
SELECT foo.relname AS ltable, foo.ftblname,
pg_get_constraintdef(foo.oid) AS consrc
FROM (
SELECT c.oid, c.conname AS name, t.relname, ft.relname AS ftblname
FROM pg_constraint c
JOIN pg_class t ON (t.oid = c.conrelid)
JOIN pg_class ft ON (ft.oid = c.confrelid)
JOIN pg_namespace nft ON (nft.oid = ft.relnamespace)
LEFT JOIN pg_description ds ON (ds.objoid = c.oid)
JOIN pg_namespace n ON (n.oid = t.relnamespace)
WHERE c.contype = 'f'::\"char\"
ORDER BY t.relname, n.nspname, c.conname, c.oid
) foo
) fee) fum
WHERE fum.ltable='".strtolower($table)."'
ORDER BY fum.ftblname, fum.ltable, split_part(fum.lf, ')'::text, 1)
";
$rs = $this->Execute($sql);
if (!$rs || $rs->EOF) return false;
$a = array();
while (!$rs->EOF) {
if ($upper) {
$a[strtoupper($rs->Fields('lookup_table'))][] = strtoupper(str_replace('"','',$rs->Fields('dep_field').'='.$rs->Fields('lookup_field')));
} else {
$a[$rs->Fields('lookup_table')][] = str_replace('"','',$rs->Fields('dep_field').'='.$rs->Fields('lookup_field'));
}
$rs->MoveNext();
}
return $a;
# Regex isolates the 2 terms between parenthesis using subexpressions
$regex = '^.*\((.*)\).*\((.*)\).*$';
$sql="
SELECT
lookup_table,
regexp_replace(consrc, '$regex', '\\2') AS lookup_field,
dep_table,
regexp_replace(consrc, '$regex', '\\1') AS dep_field
FROM (
SELECT
pg_get_constraintdef(c.oid) AS consrc,
t.relname AS dep_table,
ft.relname AS lookup_table
FROM pg_constraint c
JOIN pg_class t ON (t.oid = c.conrelid)
JOIN pg_class ft ON (ft.oid = c.confrelid)
JOIN pg_namespace nft ON (nft.oid = ft.relnamespace)
LEFT JOIN pg_description ds ON (ds.objoid = c.oid)
JOIN pg_namespace n ON (n.oid = t.relnamespace)
WHERE c.contype = 'f'::\"char\"
ORDER BY t.relname, n.nspname, c.conname, c.oid
) constraints
WHERE
dep_table='".strtolower($table)."'
ORDER BY
lookup_table,
dep_table,
dep_field";
$rs = $this->Execute($sql);
if (!$rs || $rs->EOF) return false;
$a = array();
while (!$rs->EOF) {
if ($upper) {
$a[strtoupper($rs->Fields('lookup_table'))][] = strtoupper(str_replace('"','',$rs->Fields('dep_field').'='.$rs->Fields('lookup_field')));
} else {
$a[$rs->Fields('lookup_table')][] = str_replace('"','',$rs->Fields('dep_field').'='.$rs->Fields('lookup_field'));
}
$rs->MoveNext();
}
return $a;
}
// from Edward Jaramilla, improved version - works on pg 7.4
function _old_MetaForeignKeys($table, $owner=false, $upper=false)
{
@@ -120,20 +211,20 @@ class ADODB_postgres7 extends ADODB_postgres64 {
c.relname = \''.strtolower($table).'\'
ORDER BY
t.tgrelid';
$rs = $this->Execute($sql);
if (!$rs || $rs->EOF) return false;
$arr = $rs->GetArray();
$a = array();
foreach($arr as $v) {
$data = explode(chr(0), $v['args']);
$size = count($data)-1; //-1 because the last node is empty
for($i = 4; $i < $size; $i++) {
if ($upper)
if ($upper)
$a[strtoupper($data[2])][] = strtoupper($data[$i].'='.$data[++$i]);
else
else
$a[$data[2]][] = $data[$i].'='.$data[++$i];
}
}
@@ -146,6 +237,8 @@ class ADODB_postgres7 extends ADODB_postgres64 {
// We don't have native support for parameterized queries, so let's emulate it at the parent
return ADODB_postgres64::_query($sql, $inputarr);
}
$this->_pnum = 0;
$this->_errorMsg = false;
// -- added Cristiano da Cunha Duarte
if ($inputarr) {
@@ -158,23 +251,23 @@ class ADODB_postgres7 extends ADODB_postgres64 {
else $sql .= $v.' $'.$i;
$i++;
}
$rez = pg_query_params($this->_connectionID,$sql, $inputarr);
} else {
$rez = pg_query($this->_connectionID,$sql);
}
// check if no data returned, then no need to create real recordset
if ($rez && pg_numfields($rez) <= 0) {
if ($rez && pg_num_fields($rez) <= 0) {
if (is_resource($this->_resultid) && get_resource_type($this->_resultid) === 'pgsql result') {
pg_freeresult($this->_resultid);
pg_free_result($this->_resultid);
}
$this->_resultid = $rez;
return true;
}
}
return $rez;
}
// this is a set of functions for managing client encoding - very important if the encodings
// this is a set of functions for managing client encoding - very important if the encodings
// of your database and your output target (i.e. HTML) don't match
//for instance, you may have UNICODE database and server it on-site as WIN1251 etc.
// GetCharSet - get the name of the character set the client is using now
@@ -191,7 +284,7 @@ class ADODB_postgres7 extends ADODB_postgres64 {
return $this->charSet;
}
}
// SetCharSet - switch the client encoding
function SetCharSet($charset_name)
{
@@ -205,29 +298,29 @@ class ADODB_postgres7 extends ADODB_postgres64 {
}
}
/*--------------------------------------------------------------------------------------
Class Name: Recordset
Class Name: Recordset
--------------------------------------------------------------------------------------*/
class ADORecordSet_postgres7 extends ADORecordSet_postgres64{
var $databaseType = "postgres7";
function ADORecordSet_postgres7($queryID,$mode=false)
function __construct($queryID, $mode=false)
{
$this->ADORecordSet_postgres64($queryID,$mode);
parent::__construct($queryID, $mode);
}
// 10% speedup to move MoveNext to child class
function MoveNext()
// 10% speedup to move MoveNext to child class
function MoveNext()
{
if (!$this->EOF) {
$this->_currentRow++;
if ($this->_numOfRows < 0 || $this->_numOfRows > $this->_currentRow) {
$this->fields = @pg_fetch_array($this->_queryID,$this->_currentRow,$this->fetchMode);
if (is_array($this->fields)) {
if ($this->fields && isset($this->_blobArr)) $this->_fixblobs();
return true;
@@ -237,77 +330,57 @@ class ADORecordSet_postgres7 extends ADORecordSet_postgres64{
$this->EOF = true;
}
return false;
}
}
}
class ADORecordSet_assoc_postgres7 extends ADORecordSet_postgres64{
var $databaseType = "postgres7";
function ADORecordSet_assoc_postgres7($queryID,$mode=false)
function __construct($queryID, $mode=false)
{
$this->ADORecordSet_postgres64($queryID,$mode);
parent::__construct($queryID, $mode);
}
function _fetch()
{
if ($this->_currentRow >= $this->_numOfRows && $this->_numOfRows >= 0)
return false;
if ($this->_currentRow >= $this->_numOfRows && $this->_numOfRows >= 0) {
return false;
}
$this->fields = @pg_fetch_array($this->_queryID,$this->_currentRow,$this->fetchMode);
if ($this->fields) {
if (isset($this->_blobArr)) $this->_fixblobs();
$this->_updatefields();
}
return (is_array($this->fields));
}
// Create associative array
function _updatefields()
{
if (ADODB_ASSOC_CASE == 2) return; // native
$arr = array();
$lowercase = (ADODB_ASSOC_CASE == 0);
foreach($this->fields as $k => $v) {
if (is_integer($k)) $arr[$k] = $v;
else {
if ($lowercase)
$arr[strtolower($k)] = $v;
else
$arr[strtoupper($k)] = $v;
}
}
$this->fields = $arr;
}
function MoveNext()
function MoveNext()
{
if (!$this->EOF) {
$this->_currentRow++;
if ($this->_numOfRows < 0 || $this->_numOfRows > $this->_currentRow) {
$this->fields = @pg_fetch_array($this->_queryID,$this->_currentRow,$this->fetchMode);
if (is_array($this->fields)) {
if ($this->fields) {
if (isset($this->_blobArr)) $this->_fixblobs();
$this->_updatefields();
}
return true;
}
}
$this->fields = false;
$this->EOF = true;
}
return false;
}
}
?>
+44 -6
View File
@@ -1,12 +1,50 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
@version v5.20.9 21-Dec-2016
@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.
Set tabs to 4.
NOTE: The "postgres8" driver is remapped to "postgres7".
Postgres8 support.
*/
?>
// security - hide paths
if (!defined('ADODB_DIR')) die();
include_once(ADODB_DIR."/drivers/adodb-postgres7.inc.php");
class ADODB_postgres8 extends ADODB_postgres7
{
var $databaseType = 'postgres8';
/**
* Retrieve last inserted ID
* Don't use OIDs, since as per {@link http://php.net/function.pg-last-oid php manual }
* they won't be there in Postgres 8.1
* (and they're not what the application wants back, anyway).
* @param string $table
* @param string $column
* @return int last inserted ID for given table/column, or the most recently
* returned one if $table or $column are empty
*/
function _insertid($table, $column)
{
return empty($table) || empty($column)
? $this->GetOne("SELECT lastval()")
: $this->GetOne("SELECT currval(pg_get_serial_sequence('$table', '$column'))");
}
}
class ADORecordSet_postgres8 extends ADORecordSet_postgres7
{
var $databaseType = "postgres8";
}
class ADORecordSet_assoc_postgres8 extends ADORecordSet_assoc_postgres7
{
var $databaseType = "postgres8";
}
@@ -0,0 +1,32 @@
<?php
/*
@version v5.20.9 21-Dec-2016
@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.
Set tabs to 4.
Postgres9 support.
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
include_once(ADODB_DIR."/drivers/adodb-postgres8.inc.php");
class ADODB_postgres9 extends ADODB_postgres8
{
var $databaseType = 'postgres9';
}
class ADORecordSet_postgres9 extends ADORecordSet_postgres8
{
var $databaseType = "postgres9";
}
class ADORecordSet_assoc_postgres9 extends ADORecordSet_assoc_postgres8
{
var $databaseType = "postgres9";
}
+12 -12
View File
@@ -1,13 +1,15 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
@version v5.20.9 21-Dec-2016
@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.
Set tabs to 4.
Synonym for csv driver.
*/
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
@@ -15,19 +17,17 @@ if (!defined('ADODB_DIR')) die();
if (! defined("_ADODB_PROXY_LAYER")) {
define("_ADODB_PROXY_LAYER", 1 );
include(ADODB_DIR."/drivers/adodb-csv.inc.php");
class ADODB_proxy extends ADODB_csv {
var $databaseType = 'proxy';
var $databaseProvider = 'csv';
}
class ADORecordset_proxy extends ADORecordset_csv {
var $databaseType = "proxy";
function ADORecordset_proxy($id,$mode=false)
var $databaseType = "proxy";
function __construct($id,$mode=false)
{
$this->ADORecordset($id,$mode);
parent::__construct($id,$mode);
}
};
} // define
?>
+38 -37
View File
@@ -1,13 +1,15 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). 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.
/*
@version v5.20.9 21-Dec-2016
@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.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
SAPDB data driver. Requires ODBC.
*/
@@ -22,7 +24,7 @@ if (!defined('ADODB_SAPDB')){
define('ADODB_SAPDB',1);
class ADODB_SAPDB extends ADODB_odbc {
var $databaseType = "sapdb";
var $databaseType = "sapdb";
var $concat_operator = '||';
var $sysDate = 'DATE';
var $sysTimeStamp = 'TIMESTAMP';
@@ -30,13 +32,13 @@ class ADODB_SAPDB extends ADODB_odbc {
var $fmtTimeStamp = "'Y-m-d H:i:s'"; /// used by DBTimeStamp as the default timestamp fmt.
var $hasInsertId = true;
var $_bindInputArray = true;
function ADODB_SAPDB()
function __construct()
{
//if (strncmp(PHP_OS,'WIN',3) === 0) $this->curmode = SQL_CUR_USE_ODBC;
$this->ADODB_odbc();
parent::__construct();
}
function ServerInfo()
{
$info = ADODB_odbc::ServerInfo();
@@ -46,14 +48,14 @@ class ADODB_SAPDB extends ADODB_odbc {
return $info;
}
function MetaPrimaryKeys($table)
function MetaPrimaryKeys($table, $owner = false)
{
$table = $this->Quote(strtoupper($table));
return $this->GetCol("SELECT columnname FROM COLUMNS WHERE tablename=$table AND mode='KEY' ORDER BY pos");
}
function MetaIndexes ($table, $primary = FALSE)
function MetaIndexes ($table, $primary = FALSE, $owner = false)
{
$table = $this->Quote(strtoupper($table));
@@ -67,7 +69,7 @@ class ADODB_SAPDB extends ADODB_odbc {
if ($this->fetchMode !== FALSE) {
$savem = $this->SetFetchMode(FALSE);
}
$rs = $this->Execute($sql);
if (isset($savem)) {
$this->SetFetchMode($savem);
@@ -91,8 +93,8 @@ class ADODB_SAPDB extends ADODB_odbc {
}
return $indexes;
}
function MetaColumns ($table)
function MetaColumns ($table, $normalize = true)
{
global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
@@ -101,7 +103,7 @@ class ADODB_SAPDB extends ADODB_odbc {
$savem = $this->SetFetchMode(FALSE);
}
$table = $this->Quote(strtoupper($table));
$retarr = array();
foreach($this->GetAll("SELECT COLUMNNAME,DATATYPE,LEN,DEC,NULLABLE,MODE,\"DEFAULT\",CASE WHEN \"DEFAULT\" IS NULL THEN 0 ELSE 1 END AS HAS_DEFAULT FROM COLUMNS WHERE tablename=$table ORDER BY pos") as $column)
{
@@ -130,7 +132,7 @@ class ADODB_SAPDB extends ADODB_odbc {
}
}
}
$retarr[$fld->name] = $fld;
$retarr[$fld->name] = $fld;
}
if (isset($savem)) {
$this->SetFetchMode($savem);
@@ -139,14 +141,14 @@ class ADODB_SAPDB extends ADODB_odbc {
return $retarr;
}
function MetaColumnNames($table)
function MetaColumnNames($table, $numIndexes = false, $useattnum = false)
{
$table = $this->Quote(strtoupper($table));
return $this->GetCol("SELECT columnname FROM COLUMNS WHERE tablename=$table ORDER BY pos");
}
// unlike it seems, this depends on the db-session and works in a multiuser environment
function _insertid($table,$column)
{
@@ -155,30 +157,29 @@ class ADODB_SAPDB extends ADODB_odbc {
/*
SelectLimit implementation problems:
The following will return random 10 rows as order by performed after "WHERE rowno<10"
which is not ideal...
select * from table where rowno < 10 order by 1
This means that we have to use the adoconnection base class SelectLimit when
there is an "order by".
See http://listserv.sap.com/pipermail/sapdb.general/2002-January/010405.html
*/
};
class ADORecordSet_sapdb extends ADORecordSet_odbc {
var $databaseType = "sapdb";
function ADORecordSet_sapdb($id,$mode=false)
};
class ADORecordSet_sapdb extends ADORecordSet_odbc {
var $databaseType = "sapdb";
function __construct($id,$mode=false)
{
$this->ADORecordSet_odbc($id,$mode);
parent::__construct($id,$mode);
}
}
} //define
?>
+13 -17
View File
@@ -1,10 +1,12 @@
<?php
/*
version V5.06 16 Oct 2008 (c) 2000-2009 John Lim (jlim#natsoft.com). All rights
/*
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
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.
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.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
@@ -30,7 +32,7 @@ Set tabs to 4 for best viewing.
.
'VALUES (\'test\', ' . $blobVarName . ')');
instead of loading blob from a file, you can also load from
instead of loading blob from a file, you can also load from
an unformatted (raw) blob variable:
$dbcon->load_blobvar_from_var($blobVarName, $varName);
@@ -53,13 +55,8 @@ if (!defined('ADODB_SYBASE_SQLANYWHERE')){
define('ADODB_SYBASE_SQLANYWHERE',1);
class ADODB_sqlanywhere extends ADODB_odbc {
var $databaseType = "sqlanywhere";
var $databaseType = "sqlanywhere";
var $hasInsertID = true;
function ADODB_sqlanywhere()
{
$this->ADODB_odbc();
}
function _insertid() {
return $this->GetOne('select @@identity');
@@ -152,13 +149,13 @@ if (!defined('ADODB_SYBASE_SQLANYWHERE')){
}
}; //class
class ADORecordSet_sqlanywhere extends ADORecordSet_odbc {
class ADORecordSet_sqlanywhere extends ADORecordSet_odbc {
var $databaseType = "sqlanywhere";
var $databaseType = "sqlanywhere";
function ADORecordSet_sqlanywhere($id,$mode=false)
function __construct($id,$mode=false)
{
$this->ADORecordSet_odbc($id,$mode);
parent::__construct($id,$mode);
}
@@ -166,4 +163,3 @@ if (!defined('ADODB_SYBASE_SQLANYWHERE')){
} //define
?>
+217 -164
View File
@@ -1,14 +1,16 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
@version v5.20.9 21-Dec-2016
@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 http://adodb.sourceforge.net
SQLite info: http://www.hwaci.com/sw/sqlite/
Install Instructions:
====================
1. Place this in adodb/drivers
@@ -23,27 +25,18 @@ class ADODB_sqlite extends ADOConnection {
var $replaceQuote = "''"; // string to use to replace quotes
var $concat_operator='||';
var $_errorNo = 0;
var $hasLimit = true;
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 __construct()
{
}
/*
function __get($name)
{
switch($name) {
case 'sysDate': return "'".date($this->fmtDate)."'";
case 'sysTimeStamp' : return "'".date($this->sysTimeStamp)."'";
}
}*/
function ServerInfo()
{
$arr['version'] = sqlite_libversion();
@@ -51,71 +44,93 @@ class ADODB_sqlite extends ADOConnection {
$arr['encoding'] = sqlite_libencoding();
return $arr;
}
function BeginTrans()
{
if ($this->transOff) return true;
$ret = $this->Execute("BEGIN TRANSACTION");
$this->transCnt += 1;
return true;
{
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();
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;
if ($this->transCnt > 0) {
$this->transCnt -= 1;
}
return !empty($ret);
}
function RollbackTrans()
{
if ($this->transOff) return true;
if ($this->transOff) {
return true;
}
$ret = $this->Execute("ROLLBACK");
if ($this->transCnt>0)$this->transCnt -= 1;
if ($this->transCnt > 0) {
$this->transCnt -= 1;
}
return !empty($ret);
}
// mark newnham
function MetaColumns($table, $normalize=true)
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 ($save == ADODB_FETCH_NUM) $arr[] = $fld;
else $arr[strtoupper($fld->name)] = $fld;
}
$rs->Close();
$ADODB_FETCH_MODE = $save;
return $arr;
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;
}
@@ -124,57 +139,71 @@ class ADODB_sqlite extends ADOConnection {
{
return sqlite_last_insert_rowid($this->_connectionID);
}
function _affectedrows()
{
return sqlite_changes($this->_connectionID);
}
function ErrorMsg()
return sqlite_changes($this->_connectionID);
}
function ErrorMsg()
{
if ($this->_logsql) return $this->_errorMsg;
if ($this->_logsql) {
return $this->_errorMsg;
}
return ($this->_errorNo) ? sqlite_error_string($this->_errorNo) : '';
}
function 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;
if (!function_exists('sqlite_open')) {
return null;
}
if (empty($argHostname) && $argDatabasename) {
$argHostname = $argDatabasename;
}
$this->_connectionID = sqlite_open($argHostname);
if ($this->_connectionID === false) return false;
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;
if (!function_exists('sqlite_open')) {
return null;
}
if (empty($argHostname) && $argDatabasename) {
$argHostname = $argDatabasename;
}
$this->_connectionID = sqlite_popen($argHostname);
if ($this->_connectionID === false) return false;
if ($this->_connectionID === false) {
return false;
}
$this->_createFunctions();
return true;
}
@@ -186,32 +215,38 @@ class ADODB_sqlite extends ADOConnection {
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)
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);
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;
@@ -219,14 +254,16 @@ class ADODB_sqlite extends ADOConnection {
while (--$MAXLOOPS>=0) {
@($num = $this->GetOne("select id from $seq"));
if ($num === false) {
$this->Execute(sprintf($this->_genSeqSQL ,$seq));
$this->Execute(sprintf($this->_genSeqSQL ,$seq));
$start -= 1;
$num = '0';
$ok = $this->Execute("insert into $seq values($start)");
if (!$ok) return false;
}
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;
@@ -241,76 +278,85 @@ class ADODB_sqlite extends ADOConnection {
function CreateSequence($seqname='adodbseq',$start=1)
{
if (empty($this->_genSeqSQL)) return false;
if (empty($this->_genSeqSQL)) {
return false;
}
$ok = $this->Execute(sprintf($this->_genSeqSQL,$seqname));
if (!$ok) return false;
if (!$ok) {
return false;
}
$start -= 1;
return $this->Execute("insert into $seqname values($start)");
}
var $_dropSeqSQL = 'drop table %s';
function DropSequence($seqname)
function DropSequence($seqname = 'adodbseq')
{
if (empty($this->_dropSeqSQL)) return false;
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)
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);
}
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))
$rs = $this->Execute($SQL);
if (!is_object($rs)) {
if (isset($savem)) {
$this->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
return $false;
}
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());
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)
*/
* 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);
if (isset($savem)) {
$this->SetFetchMode($savem);
$ADODB_FETCH_MODE = $save;
}
return $indexes;
return $indexes;
}
}
/*--------------------------------------------------------------------------------------
Class Name: Recordset
Class Name: Recordset
--------------------------------------------------------------------------------------*/
class ADORecordset_sqlite extends ADORecordSet {
@@ -318,22 +364,28 @@ class ADORecordset_sqlite extends ADORecordSet {
var $databaseType = "sqlite";
var $bind = false;
function ADORecordset_sqlite($queryID,$mode=false)
function __construct($queryID,$mode=false)
{
if ($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;
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) {
@@ -345,7 +397,7 @@ class ADORecordset_sqlite extends ADORecordSet {
$this->_numOfFields = 0;
$this->EOF = true;
}
return $this->_queryID;
}
@@ -358,16 +410,18 @@ class ADORecordset_sqlite extends ADORecordSet {
$fld->max_length = -1;
return $fld;
}
function _initrs()
{
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->fetchMode != SQLITE_NUM) {
return $this->fields[$colname];
}
if (!$this->bind) {
$this->bind = array();
for ($i=0; $i < $this->_numOfFields; $i++) {
@@ -375,24 +429,23 @@ class ADORecordset_sqlite extends ADORecordSet {
$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)
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()
function _close()
{
}
}
?>
+438
View File
@@ -0,0 +1,438 @@
<?php
/*
@version v5.20.9 21-Dec-2016
@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 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_sqlite3 extends ADOConnection {
var $databaseType = "sqlite3";
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 __construct()
{
}
function ServerInfo()
{
$version = SQLite3::version();
$arr['version'] = $version['versionString'];
$arr['description'] = 'SQLite 3';
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()
{
return $this->_connectionID->lastInsertRowID();
}
function _affectedrows()
{
return $this->_connectionID->changes();
}
function ErrorMsg()
{
if ($this->_logsql) {
return $this->_errorMsg;
}
return ($this->_errorNo) ? $this->ErrorNo() : ''; //**tochange?
}
function ErrorNo()
{
return $this->_connectionID->lastErrorCode(); //**tochange??
}
function SQLDate($fmt, $col=false)
{
$fmt = $this->qstr($fmt);
return ($col) ? "adodb_date2($fmt,$col)" : "adodb_date($fmt)";
}
function _createFunctions()
{
$this->_connectionID->createFunction('adodb_date', 'adodb_date', 1);
$this->_connectionID->createFunction('adodb_date2', 'adodb_date2', 2);
}
// returns true or false
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
if (empty($argHostname) && $argDatabasename) {
$argHostname = $argDatabasename;
}
$this->_connectionID = new SQLite3($argHostname);
$this->_createFunctions();
return true;
}
// returns true or false
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
// There's no permanent connect in SQLite3
return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename);
}
// returns query ID if successful, otherwise false
function _query($sql,$inputarr=false)
{
$rez = $this->_connectionID->query($sql);
if ($rez === false) {
$this->_errorNo = $this->_connectionID->lastErrorCode();
}
// If no data was returned, we don't need to create a real recordset
elseif ($rez->numColumns() == 0) {
$rez->finalize();
$rez = true;
}
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 = 'adodbseq')
{
if (empty($this->_dropSeqSQL)) {
return false;
}
return $this->Execute(sprintf($this->_dropSeqSQL,$seqname));
}
// returns true or false
function _close()
{
return $this->_connectionID->close();
}
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_sqlite3 extends ADORecordSet {
var $databaseType = "sqlite3";
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 = SQLITE3_NUM;
break;
case ADODB_FETCH_ASSOC:
$this->fetchMode = SQLITE3_ASSOC;
break;
default:
$this->fetchMode = SQLITE3_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 = $this->_queryID->columnName($fieldOffset);
$fld->type = 'VARCHAR';
$fld->max_length = -1;
return $fld;
}
function _initrs()
{
$this->_numOfFields = $this->_queryID->numColumns();
}
function Fields($colname)
{
if ($this->fetchMode != SQLITE3_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)
{
// sqlite3 does not implement seek
if ($this->debug) {
ADOConnection::outp("SQLite3 does not implement seek");
}
return false;
}
function _fetch($ignore_fields=false)
{
$this->fields = $this->_queryID->fetchArray($this->fetchMode);
return !empty($this->fields);
}
function _close()
{
}
}
+9 -13
View File
@@ -1,6 +1,8 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved.
@version v5.20.9 21-Dec-2016
@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.
@@ -10,11 +12,11 @@ V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reser
1. When selecting (joining) multiple tables, in assoc mode the table
names are included in the assoc keys in the "sqlite" driver.
In "sqlitepo" driver, the table names are stripped from the returned column names.
In "sqlitepo" driver, the table names are stripped from the returned column names.
When this results in a conflict, the first field get preference.
Contributed by Herman Kuiper herman#ozuzo.net
Contributed by Herman Kuiper herman#ozuzo.net
*/
if (!defined('ADODB_DIR')) die();
@@ -23,11 +25,6 @@ include_once(ADODB_DIR.'/drivers/adodb-sqlite.inc.php');
class ADODB_sqlitepo extends ADODB_sqlite {
var $databaseType = 'sqlitepo';
function ADODB_sqlitepo()
{
$this->ADODB_sqlite();
}
}
/*--------------------------------------------------------------------------------------
@@ -38,11 +35,11 @@ class ADORecordset_sqlitepo extends ADORecordset_sqlite {
var $databaseType = 'sqlitepo';
function ADORecordset_sqlitepo($queryID,$mode=false)
function __construct($queryID,$mode=false)
{
$this->ADORecordset_sqlite($queryID,$mode);
parent::__construct($queryID,$mode);
}
// Modified to strip table names from returned fields
function _fetch($ignore_fields=false)
{
@@ -59,4 +56,3 @@ class ADORecordset_sqlitepo extends ADORecordset_sqlite {
return !empty($this->fields);
}
}
?>
+188 -173
View File
@@ -1,25 +1,27 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim. 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.
/*
@version v5.20.9 21-Dec-2016
@copyright (c) 2000-2013 John Lim. 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.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
Sybase driver contributed by Toni (toni.tunkkari@finebyte.com)
- MSSQL date patch applied.
Date patch by Toni 15 Feb 2002
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
class ADODB_sybase extends ADOConnection {
var $databaseType = "sybase";
var $databaseType = "sybase";
var $dataProvider = 'sybase';
var $replaceQuote = "''"; // string to use to replace quotes
var $fmtDate = "'Y-m-d'";
@@ -30,20 +32,22 @@ class ADODB_sybase extends ADOConnection {
// see http://sybooks.sybase.com/onlinebooks/group-aw/awg0800e/dbrfen8/@ebt-link;pt=5981;uf=0?target=0;window=new;showtoc=true;book=dbrfen8
var $metaColumnsSQL = "SELECT c.column_name, c.column_type, c.width FROM syscolumn c, systable t WHERE t.table_name='%s' AND c.table_id=t.table_id AND t.table_type='BASE'";
/*
"select c.name,t.name,c.length from
syscolumns c join systypes t on t.xusertype=c.xusertype join sysobjects o on o.id=c.id
"select c.name,t.name,c.length from
syscolumns c join systypes t on t.xusertype=c.xusertype join sysobjects o on o.id=c.id
where o.name='%s'";
*/
var $concat_operator = '+';
var $concat_operator = '+';
var $arrayClass = 'ADORecordSet_array_sybase';
var $sysDate = 'GetDate()';
var $leftOuter = '*=';
var $rightOuter = '=*';
function ADODB_sybase()
{
var $port;
function __construct()
{
}
// might require begintrans -- committrans
function _insertid()
{
@@ -52,31 +56,31 @@ class ADODB_sybase extends ADOConnection {
// might require begintrans -- committrans
function _affectedrows()
{
return $this->GetOne('select @@rowcount');
return $this->GetOne('select @@rowcount');
}
function BeginTrans()
{
{
if ($this->transOff) return true;
$this->transCnt += 1;
$this->Execute('BEGIN TRAN');
return true;
}
function CommitTrans($ok=true)
{
function CommitTrans($ok=true)
{
if ($this->transOff) return true;
if (!$ok) return $this->RollbackTrans();
$this->transCnt -= 1;
$this->Execute('COMMIT TRAN');
return true;
}
function RollbackTrans()
{
if ($this->transOff) return true;
@@ -84,30 +88,30 @@ class ADODB_sybase extends ADOConnection {
$this->Execute('ROLLBACK TRAN');
return true;
}
// http://www.isug.com/Sybase_FAQ/ASE/section6.1.html#6.1.4
function RowLock($tables,$where,$flds='top 1 null as ignore')
function RowLock($tables,$where,$col='top 1 null as ignore')
{
if (!$this->_hastrans) $this->BeginTrans();
$tables = str_replace(',',' HOLDLOCK,',$tables);
return $this->GetOne("select $flds from $tables HOLDLOCK where $where");
}
function SelectDB($dbName)
return $this->GetOne("select $col from $tables HOLDLOCK where $where");
}
function SelectDB($dbName)
{
$this->database = $dbName;
$this->databaseName = $dbName; # obsolete, retained for compat with older adodb versions
if ($this->_connectionID) {
return @sybase_select_db($dbName);
return @sybase_select_db($dbName);
}
else return false;
else return false;
}
/* Returns: the last error message from previous database operation
Note: This function is NOT available for Microsoft SQL Server. */
Note: This function is NOT available for Microsoft SQL Server. */
function ErrorMsg()
{
if ($this->_logsql) return $this->_errorMsg;
@@ -122,164 +126,175 @@ class ADODB_sybase extends ADOConnection {
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
if (!function_exists('sybase_connect')) return null;
if ($this->charSet) {
$this->_connectionID = sybase_connect($argHostname,$argUsername,$argPassword, $this->charSet);
} else {
$this->_connectionID = sybase_connect($argHostname,$argUsername,$argPassword);
}
$this->_connectionID = sybase_connect($argHostname,$argUsername,$argPassword);
// Sybase connection on custom port
if ($this->port) {
$argHostname .= ':' . $this->port;
}
if ($this->charSet) {
$this->_connectionID = sybase_connect($argHostname,$argUsername,$argPassword, $this->charSet);
} else {
$this->_connectionID = sybase_connect($argHostname,$argUsername,$argPassword);
}
if ($this->_connectionID === false) return false;
if ($argDatabasename) return $this->SelectDB($argDatabasename);
return true;
return true;
}
// returns true or false
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
if (!function_exists('sybase_connect')) return null;
// Sybase connection on custom port
if ($this->port) {
$argHostname .= ':' . $this->port;
}
if ($this->charSet) {
$this->_connectionID = sybase_pconnect($argHostname,$argUsername,$argPassword, $this->charSet);
} else {
$this->_connectionID = sybase_pconnect($argHostname,$argUsername,$argPassword);
}
$this->_connectionID = sybase_pconnect($argHostname,$argUsername,$argPassword, $this->charSet);
} else {
$this->_connectionID = sybase_pconnect($argHostname,$argUsername,$argPassword);
}
if ($this->_connectionID === false) return false;
if ($argDatabasename) return $this->SelectDB($argDatabasename);
return true;
return true;
}
// returns query ID if successful, otherwise false
function _query($sql,$inputarr=false)
{
global $ADODB_COUNTRECS;
if ($ADODB_COUNTRECS == false && ADODB_PHPVER >= 0x4300)
return sybase_unbuffered_query($sql,$this->_connectionID);
else
return sybase_query($sql,$this->_connectionID);
}
// See http://www.isug.com/Sybase_FAQ/ASE/section6.2.html#6.2.12
function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
{
if ($secs2cache > 0) {// we do not cache rowcount, so we have to load entire recordset
$rs = ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
return $rs;
}
$nrows = (integer) $nrows;
$offset = (integer) $offset;
$cnt = ($nrows >= 0) ? $nrows : 999999999;
if ($offset > 0 && $cnt) $cnt += $offset;
$this->Execute("set rowcount $cnt");
$this->Execute("set rowcount $cnt");
$rs = ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,0);
$this->Execute("set rowcount 0");
return $rs;
}
// returns true or false
function _close()
{
{
return @sybase_close($this->_connectionID);
}
static function UnixDate($v)
{
return ADORecordSet_array_sybase::UnixDate($v);
}
static function UnixTimeStamp($v)
{
return ADORecordSet_array_sybase::UnixTimeStamp($v);
}
}
# Added 2003-10-05 by Chris Phillipson
# Used ASA SQL Reference Manual -- http://sybooks.sybase.com/onlinebooks/group-aw/awg0800e/dbrfen8/@ebt-link;pt=16756?target=%25N%15_12018_START_RESTART_N%25
# to convert similar Microsoft SQL*Server (mssql) API into Sybase compatible version
// Format date column in sql string given an input format that understands Y M D
function SQLDate($fmt, $col=false)
{
if (!$col) $col = $this->sysTimeStamp;
$s = '';
# Used ASA SQL Reference Manual -- http://sybooks.sybase.com/onlinebooks/group-aw/awg0800e/dbrfen8/@ebt-link;pt=16756?target=%25N%15_12018_START_RESTART_N%25
# to convert similar Microsoft SQL*Server (mssql) API into Sybase compatible version
// Format date column in sql string given an input format that understands Y M D
function SQLDate($fmt, $col=false)
{
if (!$col) $col = $this->sysTimeStamp;
$s = '';
$len = strlen($fmt);
for ($i=0; $i < $len; $i++) {
if ($s) $s .= '+';
$ch = $fmt[$i];
switch($ch) {
case 'Y':
case 'y':
$s .= "datename(yy,$col)";
break;
case 'M':
$s .= "convert(char(3),$col,0)";
break;
case 'm':
$s .= "str_replace(str(month($col),2),' ','0')";
break;
case 'Q':
case 'q':
$s .= "datename(qq,$col)";
break;
case 'D':
case 'd':
$s .= "str_replace(str(datepart(dd,$col),2),' ','0')";
break;
case 'h':
$s .= "substring(convert(char(14),$col,0),13,2)";
break;
$len = strlen($fmt);
for ($i=0; $i < $len; $i++) {
if ($s) $s .= '+';
$ch = $fmt[$i];
switch($ch) {
case 'Y':
case 'y':
$s .= "datename(yy,$col)";
break;
case 'M':
$s .= "convert(char(3),$col,0)";
break;
case 'm':
$s .= "str_replace(str(month($col),2),' ','0')";
break;
case 'Q':
case 'q':
$s .= "datename(qq,$col)";
break;
case 'D':
case 'd':
$s .= "str_replace(str(datepart(dd,$col),2),' ','0')";
break;
case 'h':
$s .= "substring(convert(char(14),$col,0),13,2)";
break;
case 'H':
$s .= "str_replace(str(datepart(hh,$col),2),' ','0')";
break;
case 'H':
$s .= "str_replace(str(datepart(hh,$col),2),' ','0')";
break;
case 'i':
$s .= "str_replace(str(datepart(mi,$col),2),' ','0')";
break;
case 's':
$s .= "str_replace(str(datepart(ss,$col),2),' ','0')";
break;
case 'a':
case 'A':
$s .= "substring(convert(char(19),$col,0),18,2)";
break;
case 'i':
$s .= "str_replace(str(datepart(mi,$col),2),' ','0')";
break;
case 's':
$s .= "str_replace(str(datepart(ss,$col),2),' ','0')";
break;
case 'a':
case 'A':
$s .= "substring(convert(char(19),$col,0),18,2)";
break;
default:
if ($ch == '\\') {
$i++;
$ch = substr($fmt,$i,1);
}
$s .= $this->qstr($ch);
break;
}
}
return $s;
}
default:
if ($ch == '\\') {
$i++;
$ch = substr($fmt,$i,1);
}
$s .= $this->qstr($ch);
break;
}
}
return $s;
}
# Added 2003-10-07 by Chris Phillipson
# Used ASA SQL Reference Manual -- http://sybooks.sybase.com/onlinebooks/group-aw/awg0800e/dbrfen8/@ebt-link;pt=5981;uf=0?target=0;window=new;showtoc=true;book=dbrfen8
# to convert similar Microsoft SQL*Server (mssql) API into Sybase compatible version
function MetaPrimaryKeys($table)
{
$sql = "SELECT c.column_name " .
"FROM syscolumn c, systable t " .
"WHERE t.table_name='$table' AND c.table_id=t.table_id " .
"AND t.table_type='BASE' " .
"AND c.pkey = 'Y' " .
"ORDER BY c.column_id";
# Used ASA SQL Reference Manual -- http://sybooks.sybase.com/onlinebooks/group-aw/awg0800e/dbrfen8/@ebt-link;pt=5981;uf=0?target=0;window=new;showtoc=true;book=dbrfen8
# to convert similar Microsoft SQL*Server (mssql) API into Sybase compatible version
function MetaPrimaryKeys($table, $owner = false)
{
$sql = "SELECT c.column_name " .
"FROM syscolumn c, systable t " .
"WHERE t.table_name='$table' AND c.table_id=t.table_id " .
"AND t.table_type='BASE' " .
"AND c.pkey = 'Y' " .
"ORDER BY c.column_id";
$a = $this->GetCol($sql);
if ($a && sizeof($a)>0) return $a;
return false;
}
$a = $this->GetCol($sql);
if ($a && sizeof($a)>0) return $a;
return false;
}
}
/*--------------------------------------------------------------------------------------
Class Name: Recordset
--------------------------------------------------------------------------------------*/
@@ -288,29 +303,29 @@ $ADODB_sybase_mths = array(
'JAN'=>1,'FEB'=>2,'MAR'=>3,'APR'=>4,'MAY'=>5,'JUN'=>6,
'JUL'=>7,'AUG'=>8,'SEP'=>9,'OCT'=>10,'NOV'=>11,'DEC'=>12);
class ADORecordset_sybase extends ADORecordSet {
class ADORecordset_sybase extends ADORecordSet {
var $databaseType = "sybase";
var $canSeek = true;
// _mths works only in non-localised system
var $_mths = array('JAN'=>1,'FEB'=>2,'MAR'=>3,'APR'=>4,'MAY'=>5,'JUN'=>6,'JUL'=>7,'AUG'=>8,'SEP'=>9,'OCT'=>10,'NOV'=>11,'DEC'=>12);
var $_mths = array('JAN'=>1,'FEB'=>2,'MAR'=>3,'APR'=>4,'MAY'=>5,'JUN'=>6,'JUL'=>7,'AUG'=>8,'SEP'=>9,'OCT'=>10,'NOV'=>11,'DEC'=>12);
function ADORecordset_sybase($id,$mode=false)
function __construct($id,$mode=false)
{
if ($mode === false) {
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
if (!$mode) $this->fetchMode = ADODB_FETCH_ASSOC;
else $this->fetchMode = $mode;
$this->ADORecordSet($id,$mode);
parent::__construct($id,$mode);
}
/* Returns: an object containing field information.
/* Returns: an object containing field information.
Get column information in the Recordset object. fetchField() can be used in order to obtain information about
fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
fetchField() is retrieved. */
function FetchField($fieldOffset = -1)
function FetchField($fieldOffset = -1)
{
if ($fieldOffset != -1) {
$o = @sybase_fetch_field($this->_queryID, $fieldOffset);
@@ -322,27 +337,28 @@ class ADORecordset_sybase extends ADORecordSet {
if ($o && !isset($o->type)) $o->type = ($o->numeric) ? 'float' : 'varchar';
return $o;
}
function _initrs()
{
global $ADODB_COUNTRECS;
$this->_numOfRows = ($ADODB_COUNTRECS)? @sybase_num_rows($this->_queryID):-1;
$this->_numOfFields = @sybase_num_fields($this->_queryID);
}
function _seek($row)
function _seek($row)
{
return @sybase_data_seek($this->_queryID, $row);
}
}
function _fetch($ignore_fields=false)
function _fetch($ignore_fields=false)
{
if ($this->fetchMode == ADODB_FETCH_NUM) {
$this->fields = @sybase_fetch_row($this->_queryID);
} else if ($this->fetchMode == ADODB_FETCH_ASSOC) {
$this->fields = @sybase_fetch_row($this->_queryID);
$this->fields = @sybase_fetch_assoc($this->_queryID);
if (is_array($this->fields)) {
$this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
$this->fields = $this->GetRowAssoc();
return true;
}
return false;
@@ -355,19 +371,19 @@ class ADORecordset_sybase extends ADORecordSet {
return false;
}
/* close() only needs to be called if you are worried about using too much memory while your script
is running. All associated result memory for the specified result identifier will automatically be freed. */
function _close() {
return @sybase_free_result($this->_queryID);
return @sybase_free_result($this->_queryID);
}
// sybase/mssql uses a default date like Dec 30 2000 12:00AM
static function UnixDate($v)
{
return ADORecordSet_array_sybase::UnixDate($v);
}
static function UnixTimeStamp($v)
{
return ADORecordSet_array_sybase::UnixTimeStamp($v);
@@ -375,29 +391,29 @@ class ADORecordset_sybase extends ADORecordSet {
}
class ADORecordSet_array_sybase extends ADORecordSet_array {
function ADORecordSet_array_sybase($id=-1)
function __construct($id=-1)
{
$this->ADORecordSet_array($id);
parent::__construct($id);
}
// sybase/mssql uses a default date like Dec 30 2000 12:00AM
static function UnixDate($v)
{
global $ADODB_sybase_mths;
//Dec 30 2000 12:00AM
if (!preg_match( "/([A-Za-z]{3})[-/\. ]+([0-9]{1,2})[-/\. ]+([0-9]{4})/"
,$v, $rr)) return parent::UnixDate($v);
if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
$themth = substr(strtoupper($rr[1]),0,3);
$themth = $ADODB_sybase_mths[$themth];
if ($themth <= 0) return false;
// h-m-s-MM-DD-YY
return mktime(0,0,0,$themth,$rr[2],$rr[3]);
return adodb_mktime(0,0,0,$themth,$rr[2],$rr[3]);
}
static function UnixTimeStamp($v)
{
global $ADODB_sybase_mths;
@@ -406,11 +422,11 @@ class ADORecordSet_array_sybase extends ADORecordSet_array {
if (!preg_match( "/([A-Za-z]{3})[-/\. ]([0-9 ]{1,2})[-/\. ]([0-9]{4}) +([0-9]{1,2}):([0-9]{1,2}) *([apAP]{0,1})/"
,$v, $rr)) return parent::UnixTimeStamp($v);
if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
$themth = substr(strtoupper($rr[1]),0,3);
$themth = $ADODB_sybase_mths[$themth];
if ($themth <= 0) return false;
switch (strtoupper($rr[6])) {
case 'P':
if ($rr[4]<12) $rr[4] += 12;
@@ -422,7 +438,6 @@ class ADORecordSet_array_sybase extends ADORecordSet_array {
break;
}
// h-m-s-MM-DD-YY
return mktime($rr[4],$rr[5],0,$themth,$rr[2],$rr[3]);
return adodb_mktime($rr[4],$rr[5],0,$themth,$rr[2],$rr[3]);
}
}
?>
+21 -20
View File
@@ -1,12 +1,14 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
@version v5.20.9 21-Dec-2016
@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.
Set tabs to 4.
Contributed by Interakt Online. Thx Cristian MARIN cristic#interaktonline.com
*/
@@ -15,31 +17,31 @@ require_once ADODB_DIR."/drivers/adodb-sybase.inc.php";
class ADODB_sybase_ase extends ADODB_sybase {
var $databaseType = "sybase_ase";
var $metaTablesSQL="SELECT sysobjects.name FROM sysobjects, sysusers WHERE sysobjects.type='U' AND sysobjects.uid = sysusers.uid";
var $metaColumnsSQL = "SELECT syscolumns.name AS field_name, systypes.name AS type, systypes.length AS width FROM sysobjects, syscolumns, systypes WHERE sysobjects.name='%s' AND syscolumns.id = sysobjects.id AND systypes.type=syscolumns.type";
var $metaDatabasesSQL ="SELECT a.name FROM master.dbo.sysdatabases a, master.dbo.syslogins b WHERE a.suid = b.suid and a.name like '%' and a.name != 'tempdb' and a.status3 != 256 order by 1";
function ADODB_sybase_ase()
function __construct()
{
}
// split the Views, Tables and procedures.
function MetaTables($ttype=false,$showSchema=false,$mask=false)
{
$false = false;
if ($this->metaTablesSQL) {
// complicated state saving by the need for backward compat
if ($ttype == 'VIEWS'){
$sql = str_replace('U', 'V', $this->metaTablesSQL);
}elseif (false === $ttype){
$sql = str_replace('U',"U' OR type='V", $this->metaTablesSQL);
}else{ // TABLES OR ANY OTHER
}else{ // TABLES OR ANY OTHER
$sql = $this->metaTablesSQL;
}
$rs = $this->Execute($sql);
if ($rs === false || !method_exists($rs, 'GetArray')){
return $false;
}
@@ -71,11 +73,11 @@ class ADODB_sybase_ase extends ADODB_sybase {
}
// fix a bug which prevent the metaColumns query to be executed for Sybase ASE
function MetaColumns($table,$upper=false)
function MetaColumns($table,$upper=false)
{
$false = false;
if (!empty($this->metaColumnsSQL)) {
$rs = $this->Execute(sprintf($this->metaColumnsSQL,$table));
if ($rs === false) return $false;
@@ -89,11 +91,11 @@ class ADODB_sybase_ase extends ADODB_sybase {
$rs->MoveNext();
}
$rs->Close();
return $retarr;
return $retarr;
}
return $false;
}
function getProcedureList($schema)
{
return false;
@@ -104,16 +106,15 @@ class ADODB_sybase_ase extends ADODB_sybase {
if (!function_exists('sybase_connect')){
return 'Your PHP doesn\'t contain the Sybase connection module!';
}
return parent::ErrorMsg();
return parent::ErrorMsg();
}
}
class adorecordset_sybase_ase extends ADORecordset_sybase {
var $databaseType = "sybase_ase";
function ADORecordset_sybase_ase($id,$mode=false)
function __construct($id,$mode=false)
{
$this->ADORecordSet_sybase($id,$mode);
parent::__construct($id,$mode);
}
}
?>
+28 -32
View File
@@ -1,13 +1,15 @@
<?php
/*
V5.09 25 June 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). 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.
/*
@version v5.20.9 21-Dec-2016
@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.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.sourceforge.net
Microsoft Visual FoxPro data driver. Requires ODBC. Works only on MS Windows.
*/
@@ -20,7 +22,7 @@ if (!defined('_ADODB_ODBC_LAYER')) {
if (!defined('ADODB_VFP')){
define('ADODB_VFP',1);
class ADODB_vfp extends ADODB_odbc {
var $databaseType = "vfp";
var $databaseType = "vfp";
var $fmtDate = "{^Y-m-d}";
var $fmtTimeStamp = "{^Y-m-d, h:i:sA}";
var $replaceQuote = "'+chr(39)+'" ;
@@ -33,19 +35,14 @@ class ADODB_vfp extends ADODB_odbc {
var $ansiOuter = true;
var $hasTransactions = false;
var $curmode = false ; // See sqlext.h, SQL_CUR_DEFAULT == SQL_CUR_USE_DRIVER == 2L
function ADODB_vfp()
{
$this->ADODB_odbc();
}
function Time()
{
return time();
}
function BeginTrans() { return false;}
// quote string to be sent back to database
function qstr($s,$nofixquotes=false)
{
@@ -53,7 +50,7 @@ class ADODB_vfp extends ADODB_odbc {
return "'".$s."'";
}
// TOP requires ORDER BY for VFP
function SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
{
@@ -61,23 +58,23 @@ class ADODB_vfp extends ADODB_odbc {
$ret = ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
return $ret;
}
};
class ADORecordSet_vfp extends ADORecordSet_odbc {
var $databaseType = "vfp";
function ADORecordSet_vfp($id,$mode=false)
class ADORecordSet_vfp extends ADORecordSet_odbc {
var $databaseType = "vfp";
function __construct($id,$mode=false)
{
return $this->ADORecordSet_odbc($id,$mode);
return parent::__construct($id,$mode);
}
function MetaType($t,$len=-1)
function MetaType($t, $len = -1, $fieldobj = false)
{
if (is_object($t)) {
$fieldobj = $t;
@@ -89,19 +86,18 @@ class ADORecordSet_vfp extends ADORecordSet_odbc {
if ($len <= $this->blobSize) return 'C';
case 'M':
return 'X';
case 'D': return 'D';
case 'T': return 'T';
case 'L': return 'L';
case 'I': return 'I';
default: return 'N';
}
}
}
} //define
?>