Zikula 1.0.1
[ class tree: Zikula 1.0.1 ] [ index: Zikula 1.0.1 ] [ all elements ]

Source for file adodb-ado.inc.php

Documentation is available at adodb-ado.inc.php

  1. <?php
  2. /* 
  3. V4.97 22 Jan 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
  4.   Released under both BSD license and Lesser GPL library license. 
  5.   Whenever there is any discrepancy between the two licenses, 
  6.   the BSD license will take precedence. 
  7. Set tabs to 4 for best viewing.
  8.   
  9.   Latest version is available at http://adodb.sourceforge.net
  10.   
  11.     Microsoft ADO data driver. Requires ADO. Works only on MS Windows.
  12. */
  13.  
  14. // security - hide paths
  15. if (!defined('ADODB_DIR')) die();
  16.     
  17. define("_ADODB_ADO_LAYER");
  18. /*--------------------------------------------------------------------------------------
  19. --------------------------------------------------------------------------------------*/
  20.  
  21.     
  22. class ADODB_ado extends ADOConnection {
  23.     var $databaseType = "ado";    
  24.     var $_bindInputArray = false;
  25.     var $fmtDate = "'Y-m-d'";
  26.     var $fmtTimeStamp = "'Y-m-d, h:i:sA'";
  27.     var $replaceQuote = "''"// string to use to replace quotes
  28.     var $dataProvider = "ado";    
  29.     var $hasAffectedRows = true;
  30.     var $adoParameterType = 201// 201 = long varchar, 203=long wide varchar, 205 = long varbinary
  31.     var $_affectedRows = false;
  32.     var $_thisTransactions;
  33.     var $_cursor_type = 3// 3=adOpenStatic,0=adOpenForwardOnly,1=adOpenKeyset,2=adOpenDynamic
  34.     var $_cursor_location = 3// 2=adUseServer, 3 = adUseClient;
  35.     var $_lock_type = -1;
  36.     var $_execute_option = -1;
  37.     var $poorAffectedRows = true
  38.     var $charPage;
  39.         
  40.     function ADODB_ado(
  41.     {     
  42.         $this->_affectedRows = new VARIANT;
  43.     }
  44.  
  45.     function ServerInfo()
  46.     {
  47.         if (!empty($this->_connectionID)) $desc $this->_connectionID->provider;
  48.         return array('description' => $desc'version' => '');
  49.     }
  50.     
  51.     function _affectedrows()
  52.     {
  53.         if (PHP_VERSION >= 5return $this->_affectedRows;
  54.         
  55.         return $this->_affectedRows->value;
  56.     }
  57.     
  58.     // you can also pass a connection string like this:
  59.     //
  60.     // $DB->Connect('USER ID=sa;PASSWORD=pwd;SERVER=mangrove;DATABASE=ai',false,false,'SQLOLEDB');
  61.     function _connect($argHostname$argUsername$argPassword$argProvider'MSDASQL')
  62.     {
  63.         $u 'UID';
  64.         $p 'PWD';
  65.     
  66.         if (!empty($this->charPage))
  67.             $dbc new COM('ADODB.Connection',null,$this->charPage);
  68.         else
  69.             $dbc new COM('ADODB.Connection');
  70.             
  71.         if ($dbcreturn false;
  72.  
  73.         /* special support if provider is mssql or access */
  74.         if ($argProvider=='mssql'{
  75.             $u 'User Id';  //User parameter name for OLEDB
  76.             $p 'Password'
  77.             $argProvider "SQLOLEDB"// SQL Server Provider
  78.             
  79.             // not yet
  80.             //if ($argDatabasename) $argHostname .= ";Initial Catalog=$argDatabasename";
  81.             
  82.             //use trusted conection for SQL if username not specified
  83.             if (!$argUsername$argHostname .= ";Trusted_Connection=Yes";
  84.         else if ($argProvider=='access')
  85.             $argProvider "Microsoft.Jet.OLEDB.4.0"// Microsoft Jet Provider
  86.         
  87.         if ($argProvider$dbc->Provider $argProvider;    
  88.         
  89.         if ($argUsername$argHostname .= ";$u=$argUsername";
  90.         if ($argPassword)$argHostname .= ";$p=$argPassword";
  91.         
  92.         if ($this->debugADOConnection::outp"Host=".$argHostname."<BR>\n version=$dbc->version");
  93.         // @ added below for php 4.0.1 and earlier
  94.         @$dbc->Open((string) $argHostname);
  95.         
  96.         $this->_connectionID = $dbc;
  97.         
  98.         $dbc->CursorLocation $this->_cursor_location;
  99.         return  $dbc->State 0;
  100.     }
  101.     
  102.     // returns true or false
  103.     function _pconnect($argHostname$argUsername$argPassword$argProvider='MSDASQL')
  104.     {
  105.         return $this->_connect($argHostname,$argUsername,$argPassword,$argProvider);
  106.     }    
  107.     
  108. /*
  109.     adSchemaCatalogs    = 1,
  110.     adSchemaCharacterSets    = 2,
  111.     adSchemaCollations    = 3,
  112.     adSchemaColumns    = 4,
  113.     adSchemaCheckConstraints    = 5,
  114.     adSchemaConstraintColumnUsage    = 6,
  115.     adSchemaConstraintTableUsage    = 7,
  116.     adSchemaKeyColumnUsage    = 8,
  117.     adSchemaReferentialContraints    = 9,
  118.     adSchemaTableConstraints    = 10,
  119.     adSchemaColumnsDomainUsage    = 11,
  120.     adSchemaIndexes    = 12,
  121.     adSchemaColumnPrivileges    = 13,
  122.     adSchemaTablePrivileges    = 14,
  123.     adSchemaUsagePrivileges    = 15,
  124.     adSchemaProcedures    = 16,
  125.     adSchemaSchemata    = 17,
  126.     adSchemaSQLLanguages    = 18,
  127.     adSchemaStatistics    = 19,
  128.     adSchemaTables    = 20,
  129.     adSchemaTranslations    = 21,
  130.     adSchemaProviderTypes    = 22,
  131.     adSchemaViews    = 23,
  132.     adSchemaViewColumnUsage    = 24,
  133.     adSchemaViewTableUsage    = 25,
  134.     adSchemaProcedureParameters    = 26,
  135.     adSchemaForeignKeys    = 27,
  136.     adSchemaPrimaryKeys    = 28,
  137.     adSchemaProcedureColumns    = 29,
  138.     adSchemaDBInfoKeywords    = 30,
  139.     adSchemaDBInfoLiterals    = 31,
  140.     adSchemaCubes    = 32,
  141.     adSchemaDimensions    = 33,
  142.     adSchemaHierarchies    = 34,
  143.     adSchemaLevels    = 35,
  144.     adSchemaMeasures    = 36,
  145.     adSchemaProperties    = 37,
  146.     adSchemaMembers    = 38
  147.  
  148. */
  149.     
  150.     function &MetaTables()
  151.     {
  152.         $arrarray();
  153.         $dbc $this->_connectionID;
  154.         
  155.         $adors=@$dbc->OpenSchema(20);//tables
  156.         if ($adors){
  157.             $f $adors->Fields(2);//table/view name
  158.             $t $adors->Fields(3);//table type
  159.             while (!$adors->EOF){
  160.                 $tt=substr($t->value,0,6);
  161.                 if ($tt!='SYSTEM' && $tt !='ACCESS')
  162.                     $arr[]=$f->value;
  163.                 //print $f->value . ' ' . $t->value.'<br>';
  164.                 $adors->MoveNext();
  165.             }
  166.             $adors->Close();
  167.         }
  168.         
  169.         return $arr;
  170.     }
  171.     
  172.     function &MetaColumns($table)
  173.     {
  174.         $table strtoupper($table);
  175.         $arr array();
  176.         $dbc $this->_connectionID;
  177.         
  178.         $adors=@$dbc->OpenSchema(4);//tables
  179.     
  180.         if ($adors){
  181.             $t $adors->Fields(2);//table/view name
  182.             while (!$adors->EOF){
  183.                 
  184.                 
  185.                 if (strtoupper($t->Value== $table{
  186.                 
  187.                     $fld new ADOFieldObject();
  188.                     $c $adors->Fields(3);
  189.                     $fld->name $c->Value;
  190.                     $fld->type 'CHAR'// cannot discover type in ADO!
  191.                     $fld->max_length = -1;
  192.                     $arr[strtoupper($fld->name)]=$fld;
  193.                 }
  194.         
  195.                 $adors->MoveNext();
  196.             }
  197.             $adors->Close();
  198.         }
  199.         $false false;
  200.         return empty($arr$false $arr;
  201.     }
  202.     
  203.  
  204.  
  205.     
  206.     /* returns queryID or false */
  207.     function &_query($sql,$inputarr=false
  208.     {
  209.         
  210.         $dbc $this->_connectionID;
  211.         $false false;
  212.         
  213.     //    return rs    
  214.         if ($inputarr{
  215.             
  216.             if (!empty($this->charPage))
  217.                 $oCmd new COM('ADODB.Command',null,$this->charPage);
  218.             else
  219.                 $oCmd new COM('ADODB.Command');
  220.             $oCmd->ActiveConnection $dbc;
  221.             $oCmd->CommandText $sql;
  222.             $oCmd->CommandType 1;
  223.  
  224.             foreach($inputarr as $val{
  225.                 // name, type, direction 1 = input, len,
  226.                 $this->adoParameterType = 130;
  227.                 $p $oCmd->CreateParameter('name',$this->adoParameterType,1,strlen($val),$val);
  228.                 //print $p->Type.' '.$p->value;
  229.                 $oCmd->Parameters->Append($p);
  230.             }
  231.             $p false;
  232.             $rs $oCmd->Execute();
  233.             $e $dbc->Errors;
  234.             if ($dbc->Errors->Count 0return $false;
  235.             return $rs;
  236.         }
  237.         
  238.         $rs @$dbc->Execute($sql,$this->_affectedRows$this->_execute_option);
  239.  
  240.         if ($dbc->Errors->Count 0return $false;
  241.         if ($rsreturn $false;
  242.         
  243.         if ($rs->State == 0{
  244.             $true true;
  245.             return $true// 0 = adStateClosed means no records returned
  246.         }
  247.         return $rs;
  248.     }
  249.  
  250.     
  251.     function BeginTrans(
  252.     
  253.         if ($this->transOffreturn true;
  254.         
  255.         if (isset($this->_thisTransactions))
  256.             if (!$this->_thisTransactionsreturn false;
  257.         else {
  258.             $o $this->_connectionID->Properties("Transaction DDL");
  259.             $this->_thisTransactions = $o true false;
  260.             if (!$oreturn false;
  261.         }
  262.         @$this->_connectionID->BeginTrans();
  263.         $this->transCnt += 1;
  264.         return true;
  265.     }
  266.     
  267.     function CommitTrans($ok=true
  268.     
  269.         if (!$okreturn $this->RollbackTrans();
  270.         if ($this->transOffreturn true;
  271.         
  272.         @$this->_connectionID->CommitTrans();
  273.         if ($this->transCnt@$this->transCnt -= 1;
  274.         return true;
  275.     }
  276.     function RollbackTrans({
  277.         if ($this->transOffreturn true;
  278.         @$this->_connectionID->RollbackTrans();
  279.         if ($this->transCnt@$this->transCnt -= 1;
  280.         return true;
  281.     }
  282.     
  283.     /*    Returns: the last error message from previous database operation    */    
  284.  
  285.     function ErrorMsg(
  286.     {
  287.         if (!$this->_connectionIDreturn "No connection established";
  288.         $errc $this->_connectionID->Errors;
  289.         if (!$errcreturn "No Errors object found";
  290.         if ($errc->Count == 0return '';
  291.         $err $errc->Item($errc->Count-1);
  292.         return $err->Description;
  293.     }
  294.     
  295.     function ErrorNo(
  296.     {
  297.         $errc $this->_connectionID->Errors;
  298.         if ($errc->Count == 0return 0;
  299.         $err $errc->Item($errc->Count-1);
  300.         return $err->NativeError;
  301.     }
  302.  
  303.     // returns true or false
  304.     function _close()
  305.     {
  306.         if ($this->_connectionID$this->_connectionID->Close();
  307.         $this->_connectionID = false;
  308.         return true;
  309.     }
  310.     
  311.     
  312. }
  313.     
  314. /*--------------------------------------------------------------------------------------
  315.      Class Name: Recordset
  316. --------------------------------------------------------------------------------------*/
  317.  
  318. class ADORecordSet_ado extends ADORecordSet {    
  319.     
  320.     var $bind = false;
  321.     var $databaseType = "ado";    
  322.     var $dataProvider = "ado";    
  323.     var $_tarr = false// caches the types
  324.     var $_flds// and field objects
  325.     var $canSeek = true;
  326.       var $hideErrors = true;
  327.           
  328.     function ADORecordSet_ado($id,$mode=false)
  329.     {
  330.         if ($mode === false
  331.             global $ADODB_FETCH_MODE;
  332.             $mode $ADODB_FETCH_MODE;
  333.         }
  334.         $this->fetchMode = $mode;
  335.         return $this->ADORecordSet($id,$mode);
  336.     }
  337.  
  338.  
  339.     // returns the field object
  340.     function &FetchField($fieldOffset = -1{
  341.         $off=$fieldOffset+1// offsets begin at 1
  342.         
  343.         $onew ADOFieldObject();
  344.         $rs $this->_queryID;
  345.         $f $rs->Fields($fieldOffset);
  346.         $o->name $f->Name;
  347.         $t $f->Type;
  348.         $o->type $this->MetaType($t);
  349.         $o->max_length $f->DefinedSize;
  350.         $o->ado_type $t;    
  351.  
  352.         //print "off=$off name=$o->name type=$o->type len=$o->max_length<br>";
  353.         return $o;
  354.     }
  355.     
  356.     /* Use associative array to get fields array */
  357.     function Fields($colname)
  358.     {
  359.         if ($this->fetchMode ADODB_FETCH_ASSOCreturn $this->fields[$colname];
  360.         if (!$this->bind{
  361.             $this->bind = array();
  362.             for ($i=0$i $this->_numOfFields$i++{
  363.                 $o $this->FetchField($i);
  364.                 $this->bind[strtoupper($o->name)$i;
  365.             }
  366.         }
  367.         
  368.          return $this->fields[$this->bind[strtoupper($colname)]];
  369.     }
  370.  
  371.         
  372.     function _initrs()
  373.     {
  374.         $rs $this->_queryID;
  375.         $this->_numOfRows = $rs->RecordCount;
  376.         
  377.         $f $rs->Fields;
  378.         $this->_numOfFields = $f->Count;
  379.     }
  380.     
  381.     
  382.      // should only be used to move forward as we normally use forward-only cursors
  383.     function _seek($row)
  384.     {
  385.        $rs $this->_queryID
  386.         // absoluteposition doesn't work -- my maths is wrong ?
  387.         //    $rs->AbsolutePosition->$row-2;
  388.         //    return true;
  389.         if ($this->_currentRow > $rowreturn false;
  390.         @$rs->Move((integer)$row $this->_currentRow-1)//adBookmarkFirst
  391.         return true;
  392.     }
  393.     
  394. /*
  395.     OLEDB types
  396.     
  397.      enum DBTYPEENUM
  398.     {    DBTYPE_EMPTY    = 0,
  399.     DBTYPE_NULL    = 1,
  400.     DBTYPE_I2    = 2,
  401.     DBTYPE_I4    = 3,
  402.     DBTYPE_R4    = 4,
  403.     DBTYPE_R8    = 5,
  404.     DBTYPE_CY    = 6,
  405.     DBTYPE_DATE    = 7,
  406.     DBTYPE_BSTR    = 8,
  407.     DBTYPE_IDISPATCH    = 9,
  408.     DBTYPE_ERROR    = 10,
  409.     DBTYPE_BOOL    = 11,
  410.     DBTYPE_VARIANT    = 12,
  411.     DBTYPE_IUNKNOWN    = 13,
  412.     DBTYPE_DECIMAL    = 14,
  413.     DBTYPE_UI1    = 17,
  414.     DBTYPE_ARRAY    = 0x2000,
  415.     DBTYPE_BYREF    = 0x4000,
  416.     DBTYPE_I1    = 16,
  417.     DBTYPE_UI2    = 18,
  418.     DBTYPE_UI4    = 19,
  419.     DBTYPE_I8    = 20,
  420.     DBTYPE_UI8    = 21,
  421.     DBTYPE_GUID    = 72,
  422.     DBTYPE_VECTOR    = 0x1000,
  423.     DBTYPE_RESERVED    = 0x8000,
  424.     DBTYPE_BYTES    = 128,
  425.     DBTYPE_STR    = 129,
  426.     DBTYPE_WSTR    = 130,
  427.     DBTYPE_NUMERIC    = 131,
  428.     DBTYPE_UDT    = 132,
  429.     DBTYPE_DBDATE    = 133,
  430.     DBTYPE_DBTIME    = 134,
  431.     DBTYPE_DBTIMESTAMP    = 135
  432.     
  433.     ADO Types
  434.     
  435.        adEmpty    = 0,
  436.     adTinyInt    = 16,
  437.     adSmallInt    = 2,
  438.     adInteger    = 3,
  439.     adBigInt    = 20,
  440.     adUnsignedTinyInt    = 17,
  441.     adUnsignedSmallInt    = 18,
  442.     adUnsignedInt    = 19,
  443.     adUnsignedBigInt    = 21,
  444.     adSingle    = 4,
  445.     adDouble    = 5,
  446.     adCurrency    = 6,
  447.     adDecimal    = 14,
  448.     adNumeric    = 131,
  449.     adBoolean    = 11,
  450.     adError    = 10,
  451.     adUserDefined    = 132,
  452.     adVariant    = 12,
  453.     adIDispatch    = 9,
  454.     adIUnknown    = 13,    
  455.     adGUID    = 72,
  456.     adDate    = 7,
  457.     adDBDate    = 133,
  458.     adDBTime    = 134,
  459.     adDBTimeStamp    = 135,
  460.     adBSTR    = 8,
  461.     adChar    = 129,
  462.     adVarChar    = 200,
  463.     adLongVarChar    = 201,
  464.     adWChar    = 130,
  465.     adVarWChar    = 202,
  466.     adLongVarWChar    = 203,
  467.     adBinary    = 128,
  468.     adVarBinary    = 204,
  469.     adLongVarBinary    = 205,
  470.     adChapter    = 136,
  471.     adFileTime    = 64,
  472.     adDBFileTime    = 137,
  473.     adPropVariant    = 138,
  474.     adVarNumeric    = 139
  475. */
  476.     function MetaType($t,$len=-1,$fieldobj=false)
  477.     {
  478.         if (is_object($t)) {
  479.             $fieldobj $t;
  480.             $t $fieldobj->type;
  481.             $len $fieldobj->max_length;
  482.         }
  483.         
  484.         if (!is_numeric($t)) return $t;
  485.         
  486.         switch ($t{
  487.         case 0:
  488.         case 12// variant
  489.         case 8// bstr
  490.         case 129//char
  491.         case 130//wc
  492.         case 200// varc
  493.         case 202:// varWC
  494.         case 128// bin
  495.         case 204// varBin
  496.         case 72// guid
  497.             if ($len <= $this->blobSizereturn 'C';
  498.         
  499.         case 201:
  500.         case 203:
  501.             return 'X';
  502.         case 128:
  503.         case 204:
  504.         case 205:
  505.              return 'B';
  506.         case 7:
  507.         case 133return 'D';
  508.         
  509.         case 134:
  510.         case 135return 'T';
  511.         
  512.         case 11return 'L';
  513.         
  514.         case 16://    adTinyInt    = 16,
  515.         case 2://adSmallInt    = 2,
  516.         case 3://adInteger    = 3,
  517.         case 4://adBigInt    = 20,
  518.         case 17://adUnsignedTinyInt    = 17,
  519.         case 18://adUnsignedSmallInt    = 18,
  520.         case 19://adUnsignedInt    = 19,
  521.         case 20://adUnsignedBigInt    = 21,
  522.             return 'I';
  523.         defaultreturn 'N';
  524.         }
  525.     }
  526.     
  527.     // time stamp not supported yet
  528.     function _fetch()
  529.     {    
  530.         $rs $this->_queryID;
  531.         if (!$rs or $rs->EOF{
  532.             $this->fields = false;
  533.             return false;
  534.         }
  535.         $this->fields = array();
  536.     
  537.         if (!$this->_tarr{
  538.             $tarr array();
  539.             $flds array();
  540.             for ($i=0,$max $this->_numOfFields$i $max$i++{
  541.                 $f $rs->Fields($i);
  542.                 $flds[$f;
  543.                 $tarr[$f->Type;
  544.             }
  545.             // bind types and flds only once
  546.             $this->_tarr = $tarr
  547.             $this->_flds = $flds;
  548.         }
  549.         $t reset($this->_tarr);
  550.         $f reset($this->_flds);
  551.         
  552.         if ($this->hideErrors)  $olde error_reporting(E_ERROR|E_CORE_ERROR);// sometimes $f->value be null
  553.         for ($i=0,$max $this->_numOfFields$i $max$i++{
  554.             //echo "<p>",$t,' ';var_dump($f->value); echo '</p>';
  555.             switch($t{
  556.             case 135// timestamp
  557.                 if (!strlen((string)$f->value)) $this->fields[false;
  558.                 else {
  559.                     if (!is_numeric($f->value)) # $val = variant_date_to_timestamp($f->value);
  560.                         // VT_DATE stores dates as (float) fractional days since 1899/12/30 00:00:00
  561.                         $val=(float) variant_cast($f->value,VT_R8)*3600*24-2209161600;
  562.                     else 
  563.                         $val $f->value;
  564.                     $this->fields[adodb_date('Y-m-d H:i:s',$val);
  565.                 }
  566.                 break;            
  567.             case 133:// A date value (yyyymmdd) 
  568.                 if ($val $f->value{
  569.                     $this->fields[substr($val,0,4).'-'.substr($val,4,2).'-'.substr($val,6,2);
  570.                 else
  571.                     $this->fields[false;
  572.                 break;
  573.             case 7// adDate
  574.                 if (!strlen((string)$f->value)) $this->fields[false;
  575.                 else {
  576.                     if (!is_numeric($f->value)) $val variant_date_to_timestamp($f->value);
  577.                     else $val $f->value;
  578.                     
  579.                     if (($val 86400== 0$this->fields[adodb_date('Y-m-d',$val);
  580.                     else $this->fields[adodb_date('Y-m-d H:i:s',$val);
  581.                 }
  582.                 break;
  583.             case 1// null
  584.                 $this->fields[false;
  585.                 break;
  586.             case 6// currency is not supported properly;
  587.                 ADOConnection::outp'<b>'.$f->Name.': currency type not supported by PHP</b>');
  588.                 $this->fields[= (float) $f->value;
  589.                 break;
  590.             case 11//BIT;
  591.                 $val "";
  592.                 if(is_bool($f->value))    {
  593.                     if($f->value==true$val 1;
  594.                     else $val 0;
  595.                 }
  596.                 if(is_null($f->value)) $val null;
  597.                 
  598.                 $this->fields[$val;
  599.                 break;
  600.  
  601.             default:
  602.                 $this->fields[$f->value
  603.                 break;
  604.             }
  605.             //print " $f->value $t, ";
  606.             $f next($this->_flds);
  607.             $t next($this->_tarr);
  608.         // for
  609.         if ($this->hideErrorserror_reporting($olde);
  610.         @$rs->MoveNext()// @ needed for some versions of PHP!
  611.         
  612.         if ($this->fetchMode ADODB_FETCH_ASSOC{
  613.             $this->fields = &$this->GetRowAssoc(ADODB_ASSOC_CASE);
  614.         }
  615.         return true;
  616.     }
  617.     
  618.         function NextRecordSet()
  619.         {
  620.             $rs $this->_queryID;
  621.             $this->_queryID = $rs->NextRecordSet();
  622.             //$this->_queryID = $this->_QueryId->NextRecordSet();
  623.             if ($this->_queryID == nullreturn false;
  624.             
  625.             $this->_currentRow = -1;
  626.             $this->_currentPage = -1;
  627.             $this->bind = false;
  628.             $this->fields = false;
  629.             $this->_flds = false;
  630.             $this->_tarr = false;
  631.             
  632.             $this->_inited = false;
  633.             $this->Init();
  634.             return true;
  635.         }
  636.  
  637.     function _close({
  638.         $this->_flds = false;
  639.         @$this->_queryID->Close();// by Pete Dishman (peterd@telephonetics.co.uk)
  640.         $this->_queryID = false;    
  641.     }
  642.  
  643. }
  644.  
  645. ?>

Documentation generated on Fri, 18 Jul 2008 21:38:57 +0200 by phpDocumentor 1.4.1