Ignore:
Timestamp:
06/29/07 15:17:46 (17 years ago)
Author:
niltonneto
Message:

Versão nova do ADODB (4.5 para 4.95)

Location:
trunk/phpgwapi/inc/adodb/docs
Files:
3 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/phpgwapi/inc/adodb/docs/docs-adodb.htm

    r2 r34  
    1 <html> 
    2 <head> 
    3 <title>ADODB Manual</title> 
     1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 
     2<html><head><title>ADODB Manual</title> 
     3 
    44<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> 
    55 
     
    1212  border: 1px solid #ddd; 
    1313} 
    14 </style> 
    15 </head>  
    16 <body bgcolor="#FFFFFF"> 
     14</style></head> 
     15<body bgcolor="#ffffff" text="black"> 
    1716 
    1817<h2>ADOdb Library for PHP</h2> 
    19 <p>V4.50 6 July 2004 (c) 2000-2004 John Lim (jlim#natsoft.com)</p> 
     18<p>V4.94 23 Jan 2007 (c) 2000-2007 John Lim (jlim#natsoft.com)</p> 
    2019<p><font size="1">This software is dual licensed using BSD-Style and LGPL. This  
    2120  means you can use it in compiled proprietary and commercial products.</font></p> 
    2221   
    23    
    24   <table border=1><tr><td><font color=red>Kindly note that the ADOdb home page has moved to <a href=http://adodb.sourceforge.net/>http://adodb.sourceforge.net/</a> because of the persistent  
    25   unreliability of http://php.weblogs.com. <b>Please change your links</b>!</font></td></tr></table> 
    26         <p>Useful ADOdb links:  <a href=http://adodb.sourceforge.net/#download>Download</a> &nbsp; <a href=http://adodb.sourceforge.net/#docs>Other Docs</a> 
    27  
    28 <p><a href="#intro"><b>Introduction</b></a><b><br> 
     22 
     23        <p>Useful ADOdb links:  <a href="http://adodb.sourceforge.net/#download">Download</a> &nbsp; <a href="http://adodb.sourceforge.net/#docs">Other Docs</a> 
     24 
     25</p><p><a href="#intro"><b>Introduction</b></a><b><br> 
    2926        <a href="#features">Unique Features</a><br> 
    3027        <a href="#users">How People are using ADOdb</a><br> 
     
    3330        <a href="#mininstall">Minimum Install</a><br> 
    3431        <a href="#coding">Initializing Code and Connectioning to Databases</a><br> 
    35         </b><font size="2"> &nbsp; <a href=#dsnsupport>Data Source Name (DSN) Support</a></font>  &nbsp;  <a href=#connect_ex>Connection Examples</a></font> <br> 
     32        </b><font size="2"> &nbsp; <a href="#dsnsupport">Data Source Name (DSN) Support</a></font>  &nbsp;  <a href="#connect_ex">Connection Examples</a> <br> 
    3633        <b><a href="#speed">High Speed ADOdb - tuning tips</a></b><br> 
    3734        <b><a href="#hack">Hacking and Modifying ADOdb Safely</a><br> 
    3835        <a href="#php5">PHP5 Features</a></b><br> 
    39         <font size="2"><a href=#php5iterators>foreach iterators</a> <a href=#php5exceptions>exceptions</a></font><br> 
     36        <font size="2"><a href="#php5iterators">foreach iterators</a> <a href="#php5exceptions">exceptions</a></font><br> 
    4037        <b> <a href="#drivers">Supported Databases</a></b><br> 
    4138        <b> <a href="#quickstart">Tutorials</a></b><br> 
     
    5754        <a href="#caching">Caching</a><br> 
    5855        <a href="#pivot">Pivot Tables</a></b>  
    59 <p><a href="#ref"><b>REFERENCE</b></a> 
    60 <p> <font size="2">Variables: <a href="#adodb_countrecs">$ADODB_COUNTRECS</a> <a href=#adodb_ansi_padding_off>$ADODB_ANSI_PADDING_OFF</a> 
    61   <a href="#adodb_cache_dir">$ADODB_CACHE_DIR</a> </font><font size="2"><a href=#adodb_fetch_mode>$ADODB_FETCH_MODE</a>  
    62   <a href=#adodb_lang>$ADODB_LANG</a><br> 
    63   Constants: </font><font size="2"><a href=#adodb_assoc_case>ADODB_ASSOC_CASE</a>  
     56</p><p><a href="#ref"><b>REFERENCE</b></a> 
     57</p><p> <font size="2">Variables: <a href="#adodb_countrecs">$ADODB_COUNTRECS</a>  
     58<a href="#adodb_ansi_padding_off">$ADODB_ANSI_PADDING_OFF</a> 
     59  <a href="#adodb_cache_dir">$ADODB_CACHE_DIR</a> <br> 
     60  &nbsp; &nbsp; &nbsp; &nbsp;  <a href="#force_type">$ADODB_FORCE_TYPE</a>  
     61  <a href="#adodb_fetch_mode">$ADODB_FETCH_MODE</a>  
     62  <a href="#adodb_lang">$ADODB_LANG</a> <a href=#adodb_auto_quote>ADODB_QUOTE_FIELDNAMES</a> <br> 
     63  Constants: </font><font size="2"><a href="#adodb_assoc_case">ADODB_ASSOC_CASE</a>  
    6464  </font><br> 
    6565  <a href="#ADOConnection"><b> ADOConnection</b></a><br> 
    6666  <font size="2">Connections: <a href="#connect">Connect</a> <a href="#pconnect">PConnect</a>  
    67   <a href="#nconnect">NConnect</a> <br> 
     67  <a href="#nconnect">NConnect</a> <a href="#isconnected">IsConnected</a><br> 
    6868  Executing SQL: <a href="#execute">Execute</a> <a href="#cacheexecute"><i>CacheExecute</i></a>  
    69   <a href="#SelectLimit">SelectLimit</a> <a href="#cacheSelectLimit"><i>CacheSelectLimit</i></a>  
    70   <a href="#param">Param</a> <a href="#prepare">Prepare</a> <a href=#preparesp>PrepareSP</a>  
    71   <a href="#inparameter">InParameter</a> <a href="#outparameter">OutParameter</a> 
     69  <a href="#selectlimit">SelectLimit</a> <a href="#cacheSelectLimit"><i>CacheSelectLimit</i></a>  
     70  <a href="#param">Param</a> <a href="#prepare">Prepare</a> <a href="#preparesp">PrepareSP</a>  
     71  <a href="#inparameter">InParameter</a> <a href="#outparameter">OutParameter</a> <a href="#autoexecute">AutoExecute</a> 
    7272  <br> 
    7373  &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#getone">GetOne</a>  
     
    8080  Generates SQL strings: <a href="#getupdatesql">GetUpdateSQL</a> <a href="#getinsertsql">GetInsertSQL</a>  
    8181  <a href="#concat">Concat</a> <a href="#ifnull">IfNull</a> <a href="#length">length</a> <a href="#random">random</a> <a href="#substr">substr</a>  
    82   <a href="#qstr">qstr</a> <a href="#param">Param</a>  
    83   <a href="#prepare"></a><a href="#OffsetDate">OffsetDate</a> <a href="#SQLDate">SQLDate</a>  
    84   <a href="#dbdate">DBDate</a> <a href="#dbtimestamp"></a> <a href="#dbtimestamp">DBTimeStamp</a> 
     82  <a href="#qstr">qstr</a> <a href="#param">Param</a>  <a href="#OffsetDate">OffsetDate</a> <a href="#sqldate">SQLDate</a>  
     83  <a href="#dbdate">DBDate</a>  <a href="#dbtimestamp">DBTimeStamp</a> 
     84  <a href="#binddate">BindDate</a>  <a href="#bindtimestamp">BindTimeStamp</a> 
    8585  <br> 
    8686  Blobs: <a href="#updateblob">UpdateBlob</a> <a href="#updateclob">UpdateClob</a>  
     
    9292  <a href="#failtrans">FailTrans</a> <a href="#hasfailedtrans">HasFailedTrans</a>  
    9393  <a href="#begintrans">BeginTrans</a> <a href="#committrans">CommitTrans</a>  
    94   <a href="#rollbacktrans">RollbackTrans</a> <br> 
     94  <a href="#rollbacktrans">RollbackTrans</a> <a href=#SetTransactionMode>SetTransactionMode</a><br> 
    9595  Fetching Data: </font> <font size="2"><a href="#setfetchmode">SetFetchMode</a><br> 
    9696  Strings: <a href="#concat">concat</a> <a href="#length">length</a>  <a href="#qstr">qstr</a> <a href="#quote">quote</a> <a href="#substr">substr</a><br> 
    9797  Dates: <a href="#dbdate">DBDate</a> <a href="#dbtimestamp">DBTimeStamp</a> <a href="#unixdate">UnixDate</a>  
     98  <a href="#binddate">BindDate</a>  <a href="#bindtimestamp">BindTimeStamp</a> 
    9899  <a href="#unixtimestamp">UnixTimeStamp</a> <a href="#OffsetDate">OffsetDate</a>  
    99100  <a href="#SQLDate">SQLDate</a> <br> 
    100   Row Management: <a href="#affected_rows">Affected_Rows</a> <a href="#inserted_id">Insert_ID</a>  <a href=#rowlock>RowLock</a> 
    101   <a href="#genid">GenID</a> <a href=#createseq>CreateSequence</a> <a href=#dropseq>DropSequence</a>  
     101  Row Management: <a href="#affected_rows">Affected_Rows</a> <a href="#inserted_id">Insert_ID</a>  <a href="#rowlock">RowLock</a> 
     102  <a href="#genid">GenID</a> <a href="#createseq">CreateSequence</a> <a href="#dropseq">DropSequence</a>  
    102103  <br> 
    103104  Error Handling: <a href="#errormsg">ErrorMsg</a> <a href="#errorno">ErrorNo</a>  
    104   <a href="#metaerror">MetaError</a> <a href="#metaerrormsg">MetaErrorMsg</a><br> 
     105  <a href="#metaerror">MetaError</a> <a href="#metaerrormsg">MetaErrorMsg</a> <a href="#ignoreerrors">IgnoreErrors</a><br> 
    105106  Data Dictionary (metadata): <a href="#metadatabases">MetaDatabases</a> <a href="#metatables">MetaTables</a>  
    106107  <a href="#metacolumns">MetaColumns</a> <a href="#metacolumnames">MetaColumnNames</a>  
     
    128129  Dates:<a href="#userdate">UserDate</a> <a href="#usertimestamp">UserTimeStamp</a>  
    129130  <a href="#unixdate">UnixDate</a> <a href="#unixtimestamp">UnixTimeStamp<br> 
    130   </a>Recordset Info:<a href="#recordcount">RecordCount</a> <a href="#po_recordcount">PO_RecordSet</a>  
     131  </a>Recordset Info:<a href="#recordcount">RecordCount</a> <a href="#po_recordcount">PO_RecordCount</a>  
    131132  <a href="#nextrecordset">NextRecordSet</a><br> 
    132133  Field Info:<a href="#fieldcount">FieldCount</a> <a href="#fetchfield">FetchField</a>  
    133134  <a href="#metatype">MetaType</a><br> 
    134   Cleanup: <a href="#rsclose">Close</a></font> <font size="2"></font>  
     135  Cleanup: <a href="#rsclose">Close</a></font>   
     136</p> 
    135137<p><font size="2"><a href="#rs2html"><b>rs2html</b></a>&nbsp; <a href="#exrs2html">example</a></font><br> 
    136138  <a href="#adodiff">Differences between ADOdb and ADO</a><br> 
     
    149151<p>PHP4 supports session variables. You can store your session information using  
    150152  ADOdb for true portability and scalability. See adodb-session.php for more information.</p> 
    151 <p>Also read <a href="http://php.weblogs.com/portable_sql">http://php.weblogs.com/portable_sql</a>  
    152   (also available as tips_portable_sql.htm in the release) for tips on writing  
     153<p>Also read <a href="http://phplens.com/lens/adodb/tips_portable_sql.htm">tips_portable_sql.htm</a>  
     154 for tips on writing  
    153155  portable SQL.</p> 
    154156<h2>Unique Features of ADOdb<a name="features"></a></h2> 
     
    164166  <li><b>Easy to port</b> because all the database dependant code are stored in  
    165167        stub functions. You do not need to port the core logic of the classes.</li> 
    166   <li><b>Portable table and index creation</b> with the <a href=docs-datadict.htm>datadict</a> classes. 
    167   <li><b>Database performance monitoring and SQL tuning</b> with the <a href=docs-perf.htm>performance monitoring</a> classes. 
    168   <li><b>Database-backed sessions</b> with the <a href=docs-session.htm>session management</a> classes. Supports session expiry notification. 
    169 </ul> 
     168  <li><b>Portable table and index creation</b> with the <a href="docs-datadict.htm">datadict</a> classes. 
     169  </li><li><b>Database performance monitoring and SQL tuning</b> with the <a href="docs-perf.htm">performance monitoring</a> classes. 
     170  </li><li><b>Database-backed sessions</b> with the <a href="docs-session.htm">session management</a> classes. Supports session expiry notification. 
     171<li><b>Object-Relational Mapping</b> using <a href="docs-active-record.htm">ADOdb_Active_Record</a> classes. 
     172</li></ul> 
    170173<h2>How People are using ADOdb<a name="users"></a></h2> 
    171174Here are some examples of how people are using ADOdb (for a much longer list,  
    172 visit <a href="http://php.weblogs.com/adodb-cool-applications">http://php.weblogs.com/adodb-cool-applications</a>):  
     175visit <a href="http://phplens.com/phpeverywhere/adodb-cool-apps">adodb-cool-apps</a>):  
    173176<ul> 
    174 <li><a href="http://phplens.com/">PhpLens</a> is a commercial data grid component that allows both cool Web designers and serious unshaved programmers to develop and maintain databases on the Web easily. Developed by the author of ADOdb.<p> 
    175  
    176 <li><a href="http://www.interakt.ro/phakt/">PHAkt: PHP Extension for DreamWeaver Ultradev</a> allows you to script PHP in the popular Web page editor. Database handling provided by ADOdb.<p> 
    177  
    178 <li><a href="http://www.andrew.cmu.edu/~rdanyliw/snort/snortacid.html">Analysis Console for Intrusion Databases</a> (ACID): PHP-based analysis engine to search and process a database of security incidents generated by security-related software such as IDSes and firewalls (e.g. Snort, ipchains). By Roman Danyliw.<p> 
    179  
    180 <li><a href="http://www.postnuke.com/">PostNuke</a> is a very popular free content management 
    181  system and weblog system. It offers full CSS support, HTML 4.01 transitional compliance throughout, an advanced blocks system, and is fully multi-lingual enabled. <p> 
    182  
    183 <li><a href=http://www.auto-net.no/easypublish.php?page=index&lang_id=2>EasyPublish CMS</a>  is another free content management system for managing information and integrated modules on your internet, intranet- and extranet-sites. From Norway.<p> 
    184  
    185 <li><a href="http://nola.noguska.com/">NOLA</a> is a full featured accounting, inventory, and job tracking application. It is licensed under the GPL, and developed by Noguska. 
    186 </ul><p> 
    187  
    188 <h2>Feature Requests and Bug Reports<a name="bugs"></a></h2> 
     177<li><a href="http://phplens.com/">PhpLens</a> is a commercial data grid 
     178component that allows both cool Web designers and serious unshaved 
     179programmers to develop and maintain databases on the Web easily. 
     180Developed by the author of ADOdb.<p> 
     181 
     182</p></li><li><a href="http://www.interakt.ro/phakt/">PHAkt: PHP Extension for DreamWeaver Ultradev</a> allows you to script PHP in the popular Web page editor. Database handling provided by ADOdb.<p> 
     183 
     184</p></li><li><a href="http://www.andrew.cmu.edu/%7Erdanyliw/snort/snortacid.html">Analysis Console for Intrusion Databases</a> 
     185(ACID): PHP-based analysis engine to search and process a database of 
     186security incidents generated by security-related software such as IDSes 
     187and firewalls (e.g. Snort, ipchains). By Roman Danyliw.<p> 
     188 
     189</p></li><li><a href="http://www.postnuke.com/">PostNuke</a> is a very 
     190popular free content management system and weblog system. It offers 
     191full CSS support, HTML 4.01 transitional compliance throughout, an 
     192advanced blocks system, and is fully multi-lingual enabled. <p> 
     193 
     194</p></li><li><a href="http://www.auto-net.no/easypublish.php?page=index&amp;lang_id=2">EasyPublish CMS</a> 
     195is another free content management system for managing information and 
     196integrated modules on your internet, intranet- and extranet-sites. From 
     197Norway.<p> 
     198 
     199</p></li><li><a href="http://nola.noguska.com/">NOLA</a> is a full featured accounting, inventory, and job tracking application. It is licensed under the GPL, and developed by Noguska. 
     200</li></ul><p> 
     201 
     202</p><h2>Feature Requests and Bug Reports<a name="bugs"></a></h2> 
    189203<p>Feature requests and bug reports can be emailed to <a href="mailto:jlim#natsoft.com.my">jlim#natsoft.com.my</a>  
    190204  or posted to the ADOdb Help forums at <a href="http://phplens.com/lens/lensforum/topics.php?id=4">http://phplens.com/lens/lensforum/topics.php?id=4</a>.</p> 
     
    193207  Unpack all the files into a directory accessible by your webserver.</p> 
    194208<p>To test, try modifying some of the tutorial examples. Make sure you customize  
    195   the connection settings correctly. You can debug using <i>$db->debug = true</i> as shown below:</p> 
    196 <pre>&lt;?php 
    197         include('adodb/adodb.inc.php'); 
    198         $db = <a href="#adonewconnection">ADONewConnection</a>($dbdriver); # eg 'mysql' or 'postgres' 
    199         $db->debug = true; 
    200         $db-><a href="#connect">Connect</a>($server, $user, $password, $database); 
    201         $rs = $db-><a href="#execute">Execute</a>('select * from some_small_table'); 
    202         print &quot;&lt;pre&gt;&quot;; 
    203         print_r($rs-><a href="#getrows">GetRows</a>()); 
    204         print &quot;&lt;/pre&gt;&quot;; 
    205 ?&gt;</pre> 
    206  
    207  <h3>Minimum Install<a name=mininstall></a></h3> 
     209  the connection settings correctly. You can debug using <i>$db-&gt;debug = true</i> as shown below:</p> 
     210<pre>&lt;?php<br>       include('adodb/adodb.inc.php');<br>     $db = <a href="#adonewconnection">ADONewConnection</a>($dbdriver); # eg 'mysql' or 'postgres'<br>       $db-&gt;debug = true;<br>       $db-&gt;<a href="#connect">Connect</a>($server, $user, $password, $database);<br>       $rs = $db-&gt;<a href="#execute">Execute</a>('select * from some_small_table');<br>     print "&lt;pre&gt;";<br>        print_r($rs-&gt;<a href="#getrows">GetRows</a>());<br>  print "&lt;/pre&gt;";<br>?&gt;</pre> 
     211 
     212 <h3>Minimum Install<a name="mininstall"></a></h3> 
    208213<p>For developers who want to release a minimal install of ADOdb, you will need: 
    209 <ul> 
     214</p><ul> 
    210215<li>adodb.inc.php 
    211 <li>adodb-lib.inc.php 
    212 <li>adodb-time.inc.php 
    213 <li>drivers/adodb-$database.inc.php 
    214 <li>license.txt (for legal reasons) 
    215 <li>adodb-php4.inc.php 
    216 <li>adodb-iterator.inc.php 
    217 </ul> 
     216</li><li>adodb-lib.inc.php 
     217</li><li>adodb-time.inc.php 
     218</li><li>drivers/adodb-$database.inc.php 
     219</li><li>license.txt (for legal reasons) 
     220</li><li>adodb-php4.inc.php  
     221</li><li>adodb-iterator.inc.php  (php5 functionality) 
     222</li></ul> 
    218223Optional: 
    219224<ul> 
    220225<li>adodb-error.inc.php and lang/adodb-$lang.inc.php (if you use MetaError()) 
    221 <li>adodb-csvlib.inc.php (if you use cached recordsets - CacheExecute(), etc) 
    222 <li>adodb-exceptions.inc.php and adodb-errorhandler.inc.php (if you use adodb error handler or php5 exceptions). 
    223 </ul> 
     226</li><li>adodb-csvlib.inc.php (if you use cached recordsets - CacheExecute(), etc) 
     227</li><li>adodb-exceptions.inc.php and adodb-errorhandler.inc.php (if you use adodb error handler or php5 exceptions). 
     228<li>adodb-active-record.inc.php if you use <a href=docs-active-record.htm>Active Records</a>. 
     229</li></ul> 
    224230 
    225231<h3>Code Initialization Examples<a name="coding"></a></h3> 
     
    229235 <a name="adonewconnection"></a> 
    230236<p>For example, to connect to a mysql database:</p> 
    231 <pre> 
    232 include('/path/to/set/here/adodb.inc.php'); 
    233 $conn = &amp;ADONewConnection('mysql'); 
    234 </pre> 
     237<pre>include('/path/to/set/here/adodb.inc.php');<br>$conn = &amp;ADONewConnection('mysql');<br></pre> 
    235238<p>Whenever you need to connect to a database, you create a Connection object  
    236239  using the <b>ADONewConnection</b>($driver) function.  
    237240  <b>NewADOConnection</b>($driver) is an alternative name for the same function.</p> 
    238241 
    239 <p>At this point, you are not connected to the database (no longer true if you pass in a <a href=#dsnsupport>dsn</a>). You will first need to decide 
     242<p>At this point, you are not connected to the database (no longer true if you pass in a <a href="#dsnsupport">dsn</a>). You will first need to decide 
    240243whether to use <i>persistent</i> or <i>non-persistent</i> connections. The advantage of <i>persistent</i> 
    241244connections is that they are faster, as the database connection is never closed (even  
    242245when you call Close()). <i>Non-persistent </i>connections take up much fewer resources though, 
    243246reducing the risk of your database and your web-server becoming overloaded.  
    244 <p>For persistent connections, 
     247</p><p>For persistent connections, 
    245248use $conn-&gt;<a href="#pconnect">PConnect()</a>, 
    246249 or $conn-&gt;<a href="#connect">Connect()</a> for non-persistent connections. 
     
    248251the creation of a new connection.  
    249252 
    250 <a name=connection_gotcha></a> 
    251 <p><b>Connection Gotcha</b>:  If you create two connections, but both use the same userid and password, 
     253<a name="connection_gotcha"></a> 
     254</p><p><b>Connection Gotcha</b>:  If you create two connections, but both use the same userid and password, 
    252255PHP will share the same connection. This can cause problems if the connections are meant to  
    253256different databases. The solution is to always use different userid's for different databases, 
    254257 or use NConnect(). 
    255258 
    256  <a name=dsnsupport></a> 
    257  <h3>Data Source Name (DSN) Support</h3>  
     259 <a name="dsnsupport"></a> 
     260 </p><h3>Data Source Name (DSN) Support</h3> 
    258261 <p> Since ADOdb 4.51, you can connect to a database by passing a dsn to NewADOConnection() (or ADONewConnection, which is 
    259262 the same function). The dsn format is: 
    260 <pre> 
    261         $driver://$username:$password@hostname/$database?options[=value] 
    262 </pre><p> 
     263</p><pre>       $driver://$username:$password@hostname/$database?options[=value]<br></pre><p> 
    263264NewADOConnection() calls Connect() or PConnect() internally for you. If the connection fails, false is returned. 
    264 <pre> 
    265         <font color=#008000># non-persistent connection</font> 
     265</p><pre>       <font color="#008000"># non-persistent connection</font> 
    266266        $dsn = 'mysql://root:pwd@localhost/mydb';  
    267267        $db = NewADOConnection($dsn); 
    268268        if (!$db) die("Connection failed");    
    269269         
    270         <font color=#008000># no need to call connect/pconnect!</font> 
    271         $arr = $db->GetArray("select * from table"); 
     270        <font color="#008000"># no need to call connect/pconnect!</font> 
     271        $arr = $db-&gt;GetArray("select * from table"); 
    272272         
    273         <font color=#008000># persistent connection</font> 
     273        <font color="#008000"># persistent connection</font> 
    274274        $dsn2 = 'mysql://root:pwd@localhost/mydb?persist';  
    275275</pre> 
    276276<p> 
    277 If you have special characters such as /:? in your dsn, then you need to rawurlencode them first: 
    278 <pre> 
    279         $pwd = rawurlencode($pwd); 
    280         $dsn = "mysql://root:$pwd@localhost/mydb"; 
    281 </pre> 
     277If you have special characters such as /:?_ in your dsn, then you need to rawurlencode them first: 
     278</p><pre>       $pwd = rawurlencode($pwd);<br>  $dsn = "mysql://root:$pwd@localhost/mydb"; 
     279        $dsn2=rawurlencode("sybase_ase")."://user:pass@host/path?query";<br></pre> 
    282280<p> 
    283281Legal options are: 
    284 <p> 
    285 <table align=center border=1><tr><td>For all drivers<td> 
    286         'persist', 'persistent', 'debug', 'fetchmode' 
    287         <tr><td>Interbase/Firebird 
    288         <td> 
    289                                          'dialect', 
    290                                          'charset', 
    291                                         'buffers' 
    292         <tr><td>M'soft ADO<td> 
     282</p><p> 
     283<table align="center" border="1"><tbody><tr><td>For all drivers</td><td> 
     284        'persist', 'persistent', 'debug', 'fetchmode', 'new' 
     285        </td></tr><tr><td>Interbase/Firebird 
     286        </td><td> 
     287                                         'dialect','charset','buffers','role' 
     288        </td></tr><tr><td>M'soft ADO</td><td> 
    293289                                         'charpage' 
    294290                                         
    295                 <tr><td>MySQL<td> 
     291                </td></tr><tr><td>MySQL</td><td> 
    296292                                        'clientflags' 
    297 <tr><td>MySQLi<td> 
     293</td></tr><tr><td>MySQLi</td><td> 
    298294        'port', 'socket', 'clientflags' 
    299 </table> 
    300 <p> 
    301 For all drivers, when the options <i>persist</i> or <i>persistent</i> are set,  a persistent connection is forced. 
    302 The <i>debug</i> option enables debugging. The <i>fetchmode</i> calls <a href=#setfetchmode>SetFetchMode()</a>. 
     295</td></tr><tr><td>Oci8</td><td> 
     296 'nls_date_format','charset' 
     297</td></tr></tbody></table> 
     298</p><p> 
     299For all drivers, when the options <i>persist</i> or <i>persistent</i> are set,  a persistent connection is forced; similarly, when <i>new</i> is set, then 
     300a new connection will be created using NConnect if the underlying driver supports it.  
     301The <i>debug</i> option enables debugging. The <i>fetchmode</i> calls <a href="#setfetchmode">SetFetchMode()</a>. 
    303302If no value is defined for an option, then the value is set to 1. 
    304 <p> 
     303</p><p> 
    305304ADOdb DSN's are compatible with version 1.0 of PEAR DB's DSN format. 
    306 <a name=connect_ex> 
    307 <h3>Examples of Connecting to Databases</h3> 
    308 <h4>MySQL and Most Other Database Drivers</h4> 
    309 <p>MySQL connections are very straightforward, and the parameters are identical  
    310   to mysql_connect:</p> 
    311 <pre> 
    312         $conn = &amp;ADONewConnection('mysql');  
    313         $conn-&gt;PConnect('localhost','userid','password','database'); 
    314          
    315         <font color=#008000># or dsn </font> 
     305<a name="connect_ex"> 
     306</a></p><h3><a name="connect_ex">Examples of Connecting to Databases</a></h3> 
     307<h4><a name="connect_ex">MySQL and Most Other Database Drivers</a></h4> 
     308<p><a name="connect_ex">MySQL connections are very straightforward, and the parameters are identical  
     309  to mysql_connect:</a></p> 
     310<pre><a name="connect_ex">      $conn = &amp;ADONewConnection('mysql'); <br>    $conn-&gt;PConnect('localhost','userid','password','database');<br>     <br>    <font color="#008000"># or dsn </font> 
    316311        $dsn = 'mysql://user:pwd@localhost/mydb';  
    317312        $conn = ADONewConnection($dsn);  # no need for Connect() 
    318313         
    319         <font color=#008000># or persistent dsn</font> 
     314        <font color="#008000"># or persistent dsn</font> 
    320315        $dsn = 'mysql://user:pwd@localhost/mydb?persist';  
    321316        $conn = ADONewConnection($dsn);  # no need for PConnect() 
    322317         
    323         <font color=#008000># a more complex example:</font> 
     318        <font color="#008000"># a more complex example:</font> 
    324319        $pwd = urlencode($pwd); 
    325320        $flags =  MYSQL_CLIENT_COMPRESS; 
    326         $dsn = "mysql://user:$pwd@localhost/mydb?persist&clientflags=$flags"; 
     321        $dsn = "mysql://user:$pwd@localhost/mydb?persist&amp;clientflags=$flags"; 
    327322        $conn = ADONewConnection($dsn);  # no need for PConnect() 
    328  </pre> 
    329 <p> For most drivers, you can use the standard function: Connect($server, $user, $password, $database), or 
    330 a <a href=dsnsupport>DSN</a> since ADOdb 4.51. Exceptions to this are listed below. 
     323 </a></pre> 
     324<p><a name="connect_ex"> For most drivers, you can use the standard function: Connect($server, $user, $password, $database), or 
     325a </a><a href="dsnsupport">DSN</a> since ADOdb 4.51. Exceptions to this are listed below. 
     326</p> 
     327<a name=pdo> 
     328<h4>PDO</h4> 
     329<p>PDO, which only works with PHP5, accepts a driver specific connection string: 
     330<pre> 
     331        $conn =& NewADConnection('pdo'); 
     332        $conn->Connect('mysql:host=localhost',$user,$pwd,$mydb); 
     333        $conn->Connect('mysql:host=localhost;dbname=mydb',$user,$pwd); 
     334        $conn->Connect("mysql:host=localhost;dbname=mydb;username=$user;password=$pwd"); 
     335</pre> 
     336<p>The DSN mechanism is also supported: 
     337<pre> 
     338        $conn =& NewADConnection("pdo_mysql://user:pwd@localhost/mydb?persist"); # persist is optional 
     339</pre> 
    331340<h4>PostgreSQL</h4> 
    332 <p>PostgreSQL accepts connections using: </p> 
     341<p>PostgreSQL 7 and 8 accepts connections using: </p> 
    333342<p>a. the standard connection string:</p> 
    334 <pre> 
    335         $conn = &amp;ADONewConnection('postgres7');  
    336         $conn-&gt;PConnect('host=localhost port=5432 dbname=mary');</pre> 
     343<pre>   $conn = &amp;ADONewConnection('postgres');  <br>        $conn-&gt;PConnect('host=localhost port=5432 dbname=mary');</pre> 
    337344<p> b. the classical 4 parameters:</p> 
    338  <pre> 
    339         $conn-&gt;PConnect('localhost','userid','password','database'); 
    340  </pre> 
     345 <pre>  $conn-&gt;PConnect('localhost','userid','password','database');<br> </pre> 
    341346<p>c. dsn: 
    342 <pre> 
    343         $dsn = 'postgres7://user:pwd@localhost/mydb?persist';  # persist is optional 
    344         $conn = ADONewConnection($dsn);  # no need for Connect/PConnect 
    345 </pre> 
    346 <a name=ldap></a> 
     347</p><pre>       $dsn = 'postgres://user:pwd@localhost/mydb?persist';  # persist is optional 
     348        $conn = ADONewConnection($dsn);  # no need for Connect/PConnect<br></pre> 
     349<a name="ldap"></a> 
    347350 
    348351 <h4>LDAP</h4> 
    349352  <p>Here is an example of querying a LDAP server. Thanks to Josh Eldridge for the driver and this example: 
    350 <pre> 
    351  &lt;?php 
     353</p><pre> 
    352354require('/path/to/adodb.inc.php'); 
    353355 
     356/* Make sure to set this BEFORE calling Connect() */ 
     357$LDAP_CONNECT_OPTIONS = Array( 
     358        Array ("OPTION_NAME"=>LDAP_OPT_DEREF, "OPTION_VALUE"=>2), 
     359        Array ("OPTION_NAME"=>LDAP_OPT_SIZELIMIT,"OPTION_VALUE"=>100), 
     360        Array ("OPTION_NAME"=>LDAP_OPT_TIMELIMIT,"OPTION_VALUE"=>30), 
     361        Array ("OPTION_NAME"=>LDAP_OPT_PROTOCOL_VERSION,"OPTION_VALUE"=>3), 
     362        Array ("OPTION_NAME"=>LDAP_OPT_ERROR_NUMBER,"OPTION_VALUE"=>13), 
     363        Array ("OPTION_NAME"=>LDAP_OPT_REFERRALS,"OPTION_VALUE"=>FALSE), 
     364        Array ("OPTION_NAME"=>LDAP_OPT_RESTART,"OPTION_VALUE"=>FALSE) 
     365); 
    354366$host = 'ldap.baylor.edu'; 
    355367$ldapbase = 'ou=People,o=Baylor University,c=US'; 
     
    379391         
    380392print_r( $ldap->GetArray( $filter ) ); 
    381  
    382393print_r( $ldap->GetRow( $filter ) ); 
    383394 
    384395$ldap->Close(); 
    385396echo "&lt;/pre>"; 
    386 ?></pre> 
     397</pre> 
     398<p>Using DSN: 
     399<pre> 
     400$dsn = "ldap://ldap.baylor.edu/ou=People,o=Baylor University,c=US"; 
     401$db = NewADOConnection($dsn); 
     402</pre> 
    387403<h4>Interbase/Firebird</h4> 
    388404You define the database in the $host parameter: 
    389 <pre> 
    390         $conn = &ADONewConnection('ibase');  
    391         $conn->PConnect('localhost:c:\ibase\employee.gdb','sysdba','masterkey'); 
    392 </pre> 
     405<pre>   $conn = &amp;ADONewConnection('ibase'); <br>    $conn-&gt;PConnect('localhost:c:\ibase\employee.gdb','sysdba','masterkey');<br></pre> 
    393406<p>Or dsn: 
    394 <pre> 
    395         $dsn = 'firebird://user:pwd@localhost/mydb?persist&dialect=3';  # persist is optional 
    396         $conn = ADONewConnection($dsn);  # no need for Connect/PConnect 
    397 </pre> 
     407</p><pre>       $dsn = 'firebird://user:pwd@localhost/mydb?persist&amp;dialect=3';  # persist is optional<br>   $conn = ADONewConnection($dsn);  # no need for Connect/PConnect<br></pre> 
    398408<h4>SQLite</h4> 
    399409Sqlite will create the database file if it does not exist. 
    400 <pre> 
    401         $conn = &ADONewConnection('sqlite');  
    402         $conn->PConnect('c:\path\to\sqlite.db'); # sqlite will create if does not exist 
    403 </pre> 
     410<pre>   $conn = &amp;ADONewConnection('sqlite'); 
     411        $conn-&gt;PConnect('c:\path\to\sqlite.db'); # sqlite will create if does not exist<br></pre> 
    404412<p>Or dsn: 
    405 <pre> 
    406         $dsn = 'sqlite://user:pwd@localhost/mydb?persist';  # persist is optional 
    407         $conn = ADONewConnection($dsn);  # no need for Connect/PConnect 
    408 </pre> 
     413</p><pre>       $path = urlencode('c:\path\to\sqlite.db'); 
     414        $dsn = "sqlite://$path/?persist";  # persist is optional 
     415        $conn = ADONewConnection($dsn);  # no need for Connect/PConnect<br></pre> 
    409416<h4>Oracle (oci8)</h4> 
    410417<p>With oci8, you can connect in multiple ways. Note that oci8 works fine with  
     
    417424<pre>   $conn-&gt;PConnect('myTNS', 'scott', 'tiger');</pre> 
    418425<p>c. Host Address and SID</p> 
    419 <pre>   $conn-&gt;Connect('192.168.0.1', 'scott', 'tiger', 'SID');</pre> 
     426<pre> 
     427        $conn->connectSID = true; 
     428        $conn-&gt;Connect('192.168.0.1', 'scott', 'tiger', 'SID');</pre> 
    420429<p>d. Host Address and Service Name</p> 
    421430<pre>   $conn-&gt;Connect('192.168.0.1', 'scott', 'tiger', 'servicename');</pre> 
    422431<p>e. Oracle connection string: 
    423 <pre>   $cstr = "(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=$host)(PORT=$port)) 
    424                         (CONNECT_DATA=(SID=$sid)))"; 
    425         $conn-&gt;Connect($cstr, 'scott', 'tiger'); 
    426 </pre> 
     432</p><pre>       $cstr = "(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=$host)(PORT=$port))<br>                      (CONNECT_DATA=(SID=$sid)))";<br>        $conn-&gt;Connect($cstr, 'scott', 'tiger');<br></pre> 
    427433<p>f. ADOdb dsn: 
    428 <pre> 
    429         $dsn = 'oci8://user:pwd@tnsname?persist';  # persist is optional 
    430         $conn = ADONewConnection($dsn);  # no need for Connect/PConnect 
    431          
    432         $dsn = 'oci8://user:pwd@host/sid'; 
    433         $conn = ADONewConnection($dsn); 
    434          
    435         $dsn = 'oci8://user:pwd@/';   # oracle on local machine 
    436         $conn = ADONewConnection($dsn); 
    437 </pre> 
    438 <a name=dsnless></a> 
    439 <h4>DSN-less ODBC (access and mssql examples)</h4> 
     434</p><pre>       $dsn = 'oci8://user:pwd@tnsname/?persist';  # persist is optional<br>   $conn = ADONewConnection($dsn);  # no need for Connect/PConnect<br>     <br>    $dsn = 'oci8://user:pwd@host/sid';<br>  $conn = ADONewConnection($dsn);<br>     <br>    $dsn = 'oci8://user:pwd@/';   # oracle on local machine<br>     $conn = ADONewConnection($dsn);<br></pre> 
     435<p>You can also set the charSet for Oracle 9.2 and later, supported since PHP 4.3.2, ADOdb 4.54: 
     436</p><pre>       $conn-&gt;charSet = 'we8iso8859p1';<br> $conn-&gt;Connect(...);<br>     <br>    # or<br>        $dsn = 'oci8://user:pwd@tnsname/?charset=WE8MSWIN1252';<br>     $db = ADONewConnection($dsn);<br></pre> 
     437<a name="dsnless"></a> 
     438<h4>DSN-less ODBC ( Access, MSSQL and DB2 examples)</h4> 
    440439<p>ODBC DSN's can be created in the ODBC control panel, or you can use a DSN-less  
    441440  connection.To use DSN-less connections with ODBC you need PHP 4.3 or later.  
    442441</p> 
    443442<p>For Microsoft Access:</p> 
    444 <pre> 
    445         $db =& ADONewConnection('access'); 
    446         $dsn = <strong>"Driver=&#123;Microsoft Access Driver (*.mdb)&#125;;Dbq=d:\\northwind.mdb;Uid=Admin;Pwd=;";</strong> 
    447         $db->Connect($dsn); 
     443<pre>   $db =&amp; ADONewConnection('access');<br>      $dsn = <strong>"Driver={Microsoft Access Driver (*.mdb)};Dbq=d:\\northwind.mdb;Uid=Admin;Pwd=;";</strong> 
     444        $db-&gt;Connect($dsn); 
    448445</pre> 
    449446For Microsoft SQL Server:  
     447<pre>   $db =&amp; ADONewConnection('odbc_mssql');<br>  $dsn = <strong>"Driver={SQL Server};Server=localhost;Database=northwind;"</strong>;<br> $db-&gt;Connect($dsn,'userid','password');<br></pre> 
     448or if you prefer to use the mssql extension (which is limited to mssql 6.5 functionality): 
     449<pre>   $db =&amp; ADONewConnection('mssql');<br>       $db-&gt;Execute('localhost', 'userid', 'password', 'northwind');<br></pre> 
     450For DB2: 
    450451<pre> 
    451         $db =& ADONewConnection('odbc_mssql'); 
    452         $dsn = <strong>"Driver=&#123;SQL Server&#125;;Server=localhost;Database=northwind;"</strong>; 
    453         $db->Connect($dsn,'userid','password'); 
    454 </pre> 
    455 or if you prefer to use the mssql extension (which is limited to mssql 6.5 functionality): 
    456 <pre> 
    457         $db =& ADONewConnection('mssql'); 
    458         $db->Execute("localhost', 'userid', 'password', 'northwind'); 
     452        $dbms = 'db2'; # or 'odbc_db2' if db2 extension not available 
     453        $db =&amp; ADONewConnection($dbms); 
     454        $dsn = "driver={IBM db2 odbc DRIVER};Database=sample;hostname=localhost;port=50000;protocol=TCPIP;". 
     455                                "uid=root; pwd=secret";<br>     $db-&gt;Connect($dsn); 
    459456</pre> 
    460457<b>DSN-less Connections with ADO</b><br> 
     
    462459only work with Microsoft's ADO, which is Microsoft's COM based API. An example  
    463460using the ADOdb library and Microsoft's ADO:  
    464 <pre> 
    465 &lt;?php 
    466         include('adodb.inc.php');  
    467         $db = &ADONewConnection("ado_mssql"); 
    468         print "&lt;h1>Connecting DSN-less $db->databaseType...&lt;/h1>"; 
    469                  
    470         <b>$myDSN="PROVIDER=MSDASQL;DRIVER=&#123;SQL Server&#125;;" 
    471                 . "SERVER=flipper;DATABASE=ai;UID=sa;PWD=;"  ;</b> 
    472         $db->Connect($myDSN); 
     461<pre>&lt;?php<br>       include('adodb.inc.php'); <br>  $db = &amp;ADONewConnection("ado_mssql");<br>   print "&lt;h1&gt;Connecting DSN-less $db-&gt;databaseType...&lt;/h1&gt;";<br>           <br>    <b>$myDSN="PROVIDER=MSDASQL;DRIVER={SQL Server};"<br>           . "SERVER=flipper;DATABASE=ai;UID=sa;PWD=;"  ;</b> 
     462        $db-&gt;Connect($myDSN); 
    473463         
    474         $rs = $db->Execute("select * from table"); 
    475         $arr = $rs->GetArray(); 
     464        $rs = $db-&gt;Execute("select * from table"); 
     465        $arr = $rs-&gt;GetArray(); 
    476466        print_r($arr); 
    477 ?> 
    478 </pre><a name=speed></a> 
     467?&gt; 
     468</pre><a name="speed"></a> 
    479469<h2>High Speed ADOdb - tuning tips</h2> 
    480 <p>ADOdb is a big class library, yet it <a href=http://phplens.com/lens/adodb/>consistently beats</a> all other PHP class  
     470<p>ADOdb is a big class library, yet it <a href="http://phplens.com/lens/adodb/">consistently beats</a> all other PHP class  
    481471  libraries in performance. This is because it is designed in a layered fashion,  
    482472  like an onion, with the fastest functions in the innermost layer. Stick to the  
    483473  following functions for best performance:</p> 
    484 <table width="40%" border="1" align="center"> 
    485   <tr> 
     474<table align="center" border="1" width="40%"> 
     475  <tbody><tr> 
    486476    <td><div align="center"><b>Innermost Layer</b></div></td> 
    487477  </tr> 
     
    493483                qstr, Affected_Rows, Insert_ID</p></td> 
    494484  </tr> 
    495 </table> 
    496 <p>The fastest way to access the field data is by accessing the array $recordset->fields  
     485</tbody></table> 
     486<p>The fastest way to access the field data is by accessing the array $recordset-&gt;fields  
    497487  directly. Also set the global variables <a href="#adodb_fetch_mode">$ADODB_FETCH_MODE</a>  
    498488  = ADODB_FETCH_NUM, and (for oci8, ibase/firebird and odbc) <a href="#adodb_countrecs">$ADODB_COUNTRECS</a> = false  
     
    503493 <p>Lastly make sure you have a PHP accelerator cache installed such as APC, Turck  
    504494  MMCache, Zend Accelerator or ionCube.</p> 
     495 <p>Some examples:</p> 
     496 <table align="center" border="1"><tbody><tr><td><b>Fastest data retrieval using PHP</b></td><td><b>Fastest data retrieval using ADOdb extension</b></td></tr> 
     497<tr><td> 
     498<pre>$rs =&amp; $rs-&gt;Execute($sql);<br>while (!$rs-&gt;EOF) {<br>    var_dump($rs-&gt;fields);<br>   $rs-&gt;MoveNext();<br>}</pre></td><td> 
     499<pre>$rs =&amp; $rs-&gt;Execute($sql);<br>$array = adodb_getall($rs);<br>var_dump($array);<br><br><br></pre></td></tr></tbody></table> 
    505500 <p><b>Advanced Tips</b> 
    506  <p>If you have the <a href=http://adodb.sourceforge.net/#extension>ADOdb C extension</a> installed,  
    507  you can replace your calls to $rs->MoveNext() with adodb_movenext($rs).  
     501 </p><p>If you have the <a href="http://adodb.sourceforge.net/#extension">ADOdb C extension</a> installed,  
     502 you can replace your calls to $rs-&gt;MoveNext() with adodb_movenext($rs).  
    508503 This doubles the speed of this operation. For retrieving entire recordsets at once, 
    509504use GetArray(), which uses the high speed extension function adodb_getall($rs) internally. 
    510  <p>Execute() is the default way to run queries. You can use the low-level functions _Execute() and _query() 
     505 </p><p>Execute() is the default way to run queries. You can use the low-level functions _Execute() and _query() 
    511506to reduce query overhead.  Both these functions share the same parameters as Execute(). 
    512 <p>If you do not have any bind parameters or your database supports binding (without emulation), 
    513 then you can call _Execute() directly. Calling this function bypasses bind emulation. Debugging is still supported in _Execute(). 
    514 <p>If you do not require debugging facilities nor emulated binding, and do not require a recordset to be returned, then you can call _query. This is great for inserts, updates and deletes. Calling this function 
    515 bypasses emulated binding, debugging, and recordset handling. Either the resultid, true or false are returned by _query(). 
    516  <p>For Informix, you can disable scrollable cursors with $db->cursorType = 0. 
    517 <p><a name=hack></a> </p> 
     507</p><p>If you do not have any bind parameters or your database supports 
     508binding (without emulation), 
     509then you can call _Execute() directly. Calling this function bypasses 
     510bind emulation. Debugging is still supported in _Execute(). 
     511</p><p>If you do not require debugging facilities nor emulated 
     512binding, and do not require a recordset to be returned, then you can 
     513call _query. This is great for inserts, updates and deletes. Calling 
     514this function 
     515bypasses emulated binding, debugging, and recordset handling. Either 
     516the resultid, true or false are returned by _query(). </p><p>For Informix, you can disable scrollable cursors with $db-&gt;cursorType = 0. 
     517</p><p><a name="hack"></a> </p> 
    518518<h2>Hacking ADOdb Safely</h2> 
    519519<p>You might want to modify ADOdb for your own purposes. Luckily you can 
     
    522522ADOConnection() checks for this variable and will call 
    523523the function-name stored in this variable if it is defined. 
    524 <p>In the following example, new functionality for the connection object  
     524</p><p>In the following example, new functionality for the connection object  
    525525is placed in the <i>hack_mysql</i> and <i>hack_postgres7</i> classes. The recordset class naming convention 
    526526can be controlled using $rsPrefix. Here we set it to 'hack_rs_', which will make ADOdb use 
     
    528528 
    529529 
    530 <pre> 
    531 class hack_mysql extends adodb_mysql { 
    532 var $rsPrefix = 'hack_rs_'; 
    533   /* Your mods here */ 
    534 } 
    535  
    536 class hack_rs_mysql extends ADORecordSet_mysql { 
    537          /* Your mods here */ 
    538 } 
    539  
    540 class hack_postgres7 extends adodb_postgres7 { 
    541 var $rsPrefix = 'hack_rs_'; 
    542   /* Your mods here */ 
    543 } 
    544  
    545 class hack_rs_postgres7 extends ADORecordSet_postgres7 { 
    546  /* Your mods here */ 
    547 } 
    548  
    549 $ADODB_NEWCONNECTION = 'hack_factory'; 
    550  
    551 function& hack_factory($driver) 
    552 { 
    553         if ($driver !== 'mysql' && $driver !== 'postgres7') return false; 
    554          
    555         $driver = 'hack_'.$driver; 
    556         $obj = new $driver(); 
    557         return $obj; 
    558 } 
    559  
    560 include_once('adodb.inc.php'); 
    561 </pre> 
    562 <p><p>Don't forget to call the constructor of the parent class in your constructor. If you want to use the default ADOdb drivers return false in the above hack_factory() function. 
     530</p><pre>class hack_mysql extends adodb_mysql {<br>var $rsPrefix = 'hack_rs_';<br>  /* Your mods here */<br>}<br><br>class hack_rs_mysql extends ADORecordSet_mysql {<br>        /* Your mods here */<br>}<br><br>class hack_postgres7 extends adodb_postgres7 {<br>var $rsPrefix = 'hack_rs_';<br>  /* Your mods here */<br>}<br><br>class hack_rs_postgres7 extends ADORecordSet_postgres7 {<br> /* Your mods here */<br>}<br><br>$ADODB_NEWCONNECTION = 'hack_factory';<br><br>function&amp; hack_factory($driver)<br>{<br>  if ($driver !== 'mysql' &amp;&amp; $driver !== 'postgres7') return false;<br>   <br>    $driver = 'hack_'.$driver;<br>  $obj = new $driver();<br>       return $obj;<br>}<br><br>include_once('adodb.inc.php');<br></pre> 
     531<p></p><p>Don't forget to call the constructor of the parent class in 
     532your constructor. If you want to use the default ADOdb drivers return 
     533false in the above hack_factory() function. 
    563534<a name="php5"></a> 
    564 <h2>PHP5 Features</h2> 
     535</p><h2>PHP5 Features</h2> 
    565536 ADOdb 4.02 or later will transparently determine which version of PHP you are using. 
    566537If PHP5 is detected, the following features become available: 
    567538<ul> 
     539 
     540<li><b>PDO</b>: PDO drivers are available. See the <a href=#pdo>connection examples</a>. Currently PDO drivers are 
     541 not as powerful as native drivers, and should be treated as experimental.<br><br> 
    568542<a name="php5iterators"></a> 
    569543<li><b>Foreach iterators</b>: This is a very natural way of going through a recordset: 
    570 <pre> 
    571         $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 
    572         $rs = $db->Execute($sql); 
    573         foreach($rs as $k => $row) { 
    574                 echo "r1=".$row[0]." r2=".$row[1]."&lt;br>"; 
    575         } 
    576 </pre> 
     544<pre>   $ADODB_FETCH_MODE = ADODB_FETCH_NUM;<br>        $rs = $db-&gt;Execute($sql);<br>        foreach($rs as $k =&gt; $row) {<br>             echo "r1=".$row[0]." r2=".$row[1]."&lt;br&gt;";<br>     }<br></pre> 
    577545<p> 
    578546<a name="php5exceptions"></a> 
    579 <li><b>Exceptions</b>: Just include <i>adodb-exceptions.inc.php</i> and you can now  
     547</p></li><li><b>Exceptions</b>: Just include <i>adodb-exceptions.inc.php</i> and you can now  
    580548catch exceptions on errors as they occur. 
    581 <pre> 
    582         <b>include("../adodb-exceptions.inc.php");</b>  
    583         include("../adodb.inc.php");      
    584         try {  
    585                 $db = NewADOConnection("oci8");  
    586                 $db->Connect('','scott','bad-password');  
    587         } catch (exception $e) {  
    588                 var_dump($e);  
    589         }  
    590 </pre> 
     549<pre>   <b>include("../adodb-exceptions.inc.php");</b> <br>     include("../adodb.inc.php");     <br>   try { <br>              $db = NewADOConnection("oci8"); <br>            $db-&gt;Connect('','scott','bad-password'); <br>        } catch (exception $e) { <br>           var_dump($e); <br>              adodb_backtrace($e-&gt;gettrace());<br> } <br></pre> 
    591550<p>Note that reaching EOF is <b>not</b> considered an error nor an exception. 
    592 If you want to use the default ADOdb drivers return false. 
    593 </ul>  
     551</p></li></ul>  
    594552<h3><a name="drivers"></a>Databases Supported</h3> 
    595553The <i>name</i> below is the value you pass to NewADOConnection($name) to create a  connection object for that database. 
    596554<p> 
    597 <table width="100%" border="1"> 
    598   <tr valign="top">  
     555</p><p>  
     556</p><table border="1" width="100%"> 
     557  <tbody><tr valign="top">  
    599558    <td><b>Name</b></td> 
    600559    <td><b>Tested</b></td> 
     
    641600    <td><font size="2">Windows only</font></td> 
    642601  </tr> 
     602    <tr valign="top">  
     603    <td height="54"><b><font size="2">db2</font></b></td> 
     604    <td height="54"><font size="2">C</font></td> 
     605    <td height="54"><font size="2">Uses PHP's db2-specific extension for better performance.</font></td> 
     606    <td height="54"><font size="2">Y/N</font></td> 
     607    <td height="54"><font size="2">DB2 CLI/ODBC interface</font></td> 
     608    <td height="54"> <p><font size="2">Unix and Windows. Requires IBM DB2 Universal Database client.</font></p></td> 
     609  </tr> 
    643610  <tr valign="top">  
    644     <td height="54"><b><font size="2">db2</font></b></td> 
    645     <td height="54"><font size="2">A</font></td> 
    646     <td height="54"><font size="2">DB2. Should work reliably as based on ODBC  
    647       driver.</font></td> 
     611    <td height="54"><b><font size="2">odbc_db2</font></b></td> 
     612    <td height="54"><font size="2">C</font></td> 
     613    <td height="54"><font size="2">Connects to DB2 using generic ODBC extension.</font></td> 
    648614    <td height="54"><font size="2">Y/N</font></td> 
    649615    <td height="54"><font size="2">DB2 CLI/ODBC interface</font></td> 
     
    672638    <td><font size="2">Interbase 6 or earlier. Some users report you might need  
    673639      to use this<br> 
    674       $db->PConnect('localhost:c:/ibase/employee.gdb', "sysdba", "masterkey")  
     640      $db-&gt;PConnect('localhost:c:/ibase/employee.gdb', "sysdba", "masterkey")  
    675641      to connect. Lacks Affected_Rows currently.<br> 
    676642      <br> 
    677       You can set $db->dialect, $db-&gt;buffers and $db->charSet before connecting.</font></td> 
     643      You can set $db-&gt;role, $db-&gt;dialect, $db-&gt;buffers and $db-&gt;charSet before connecting.</font></td> 
    678644    <td><font size="2">Y/N</font></td> 
    679645    <td><font size="2">Interbase client</font></td> 
     
    734700    <td height="73"> <p><font size="2">Unix and Windows. <br> 
    735701        <a href="http://phpbuilder.com/columns/alberto20000919.php3">Unix install  
    736         howto</a> and <a href=http://linuxjournal.com/article.php?sid=6636&mode=thread&order=0>another  
     702        howto</a> and <a href="http://linuxjournal.com/article.php?sid=6636&amp;mode=thread&amp;order=0">another  
    737703        one</a>. </font></p></td> 
    738704  </tr> 
     
    779745        or using an entry in TNSNAMES.ORA or ONAMES or HOSTNAMES: <br> 
    780746        <i>PConnect(false, 'scott', 'tiger', $oraname)</i>. </font>  
    781       <p><font size="2">Since 2.31, we support Oracle REF cursor variables directly  
    782         (see <a href="#executecursor">ExecuteCursor</a>).</font> </td> 
     747      </p><p><font size="2">Since 2.31, we support Oracle REF cursor variables directly  
     748        (see <a href="#executecursor">ExecuteCursor</a>).</font> </p></td> 
    783749    <td><font size="2">Y/N</font></td> 
    784750    <td><font size="2">Oracle client</font></td> 
     
    802768      of lowercase names. </font> <p><font size="2">Use this driver if porting  
    803769        from other databases is important. Otherwise the oci8 driver offers better  
    804         performance. </font> </td> 
     770        performance. </font> </p></td> 
    805771    <td><font size="2">Y/N</font></td> 
    806772    <td><font size="2">Oracle client</font></td> 
     
    839805    <td><b><font size="2">odbtp</font></b></td> 
    840806    <td><font size="2">C</font></td> 
    841     <td><font size="2">Generic odbtp driver. <a href=http://odbtp.sourceforge.net/>Odbtp</a> is a software for 
     807    <td><font size="2">Generic odbtp driver. <a href="http://odbtp.sourceforge.net/">Odbtp</a> is a software for 
    842808        accessing Windows ODBC data sources from other operating systems.</font></td> 
    843809    <td><font size="2">Y/N</font></td> 
     
    870836    <td height="34"><font size="2">?</font></td> 
    871837  </tr> 
     838     <tr valign="top">  
     839    <td><b><font size="2">pdo</font></b></td> 
     840    <td><font size="2">C</font></td> 
     841    <td><font size="2">Generic PDO driver for PHP5. </font></td> 
     842    <td><font size="2">Y</font></td> 
     843    <td><font size="2">PDO extension and database specific drivers</font></td> 
     844    <td><font size="2">Unix and Windows. </font></td> 
     845  </tr> 
    872846  <tr valign="top">  
    873847    <td><b><font size="2">postgres</font></b></td> 
    874848    <td><font size="2">A</font></td> 
    875849    <td><font size="2">Generic PostgreSQL driver. Currently identical to postgres7  
    876       driver. </font></td> 
     850      driver.</font></td> 
    877851    <td><font size="2">Y</font></td> 
    878852    <td><font size="2">PostgreSQL client</font></td> 
     
    896870    <td><font size="2">Unix and Windows. </font></td> 
    897871  </tr> 
     872    <tr valign="top">  
     873    <td><b><font size="2">postgres8</font></b></td> 
     874    <td><font size="2">A</font></td> 
     875    <td><font size="2">PostgreSQL which supports version 8 functionality.</font></td> 
     876    <td><font size="2">Y</font></td> 
     877    <td><font size="2">PostgreSQL client</font></td> 
     878    <td><font size="2">Unix and Windows. </font></td> 
     879  </tr> 
    898880  <tr valign="top">  
    899881    <td><b><font size="2">sapdb</font></b></td> 
     
    926908    <td height="54"><font size="2">Portable SQLite driver.  This is because assoc mode does not work like other drivers in sqlite. 
    927909   Namely, when selecting (joining) multiple tables, the table 
    928           names are included in the assoc keys in the "sqlite" driver.<p> 
    929           In "sqlitepo" driver, the table names are stripped from the returned column names.  
     910          names are included in the assoc keys in the "sqlite" driver.</font><p> 
     911<font size="2">   In "sqlitepo" driver, the table names are stripped from the returned column names.  
    930912          When this results in a conflict,  the first field get preference. 
    931           </font></td> 
     913          </font></p></td> 
    932914    <td height="54"><font size="2">Y</font></td> 
    933915    <td height="54"><font size="2">-</font></td> 
     
    944926    <td> <p><font size="2">Unix and Windows.</font></p></td> 
    945927  </tr> 
    946   <p>  
    947 </table> 
    948  
    949 <p>The &quot;Tested&quot; column indicates how extensively the code has been tested  
     928   
     929    <tr valign="top">  
     930    <td><b><font size="2">sybase_ase</font></b></td> 
     931    <td><font size="2">C</font></td> 
     932    <td><font size="2">Sybase ASE. </font></td> 
     933    <td><font size="2">Y/N</font></td> 
     934    <td><font size="2">Sybase client</font></td> 
     935    <td> <p><font size="2">Unix and Windows.</font></p></td> 
     936  </tr> 
     937  </tbody></table> 
     938 
     939<p></p><p>The "Tested" column indicates how extensively the code has been tested  
    950940  and used. <br> 
    951941  A = well tested and used by many people<br> 
     
    953943  C = user contributed or experimental driver. Might not fully support all of  
    954944  the latest features of ADOdb. </p> 
    955 <p>The column &quot;RecordCount() usable&quot; indicates whether RecordCount()  
     945<p>The column "RecordCount() usable" indicates whether RecordCount()  
    956946  return the number of rows, or returns -1 when a SELECT statement is executed.  
    957947  If this column displays Y/N then the RecordCount() is emulated when the global  
     
    963953  is executed, so you can selectively choose which recordsets to count.</p> 
    964954<p>  
    965 <hr> 
     955</p><hr /> 
    966956<h1>Tutorials<a name="quickstart"></a></h1> 
    967957<h3>Example 1: Select Statement<a name="ex1"></a></h3> 
     
    978968<p>NB: A useful function that is not used in this example is <font face="Courier New, Courier, mono"><a href="#selectlimit">SelectLimit</a></font>,  
    979969  which allows us to limit the number of rows shown.  
    980 <pre> 
    981 &lt;? 
    982 <font face="Courier New, Courier, mono"><b>include</b>('adodb.inc.php');           # load code common to ADOdb 
    983 $<font color="#660000">conn</font> = &amp;ADONewConnection('access');   # create a connection 
    984 $<font color="#660000">conn</font>->PConnect('northwind');   # connect to MS-Access, northwind DSN 
    985 $<font color="#660000">recordSet</font> = &amp;$<font color="#660000">conn</font>->Execute('select * from products'); 
    986 if (!$<font color="#660000">recordSet</font>)  
    987         print $<font color="#660000">conn</font>-&gt;ErrorMsg(); 
    988 else 
    989 <b>while</b> (!$<font color="#660000">recordSet</font>-&gt;EOF) &#123; 
    990         <b>print</b> $<font color="#660000">recordSet</font>->fields[0].' '.$<font color="#660000">recordSet</font>->fields[1].'&lt;BR&gt;'; 
    991         $<font color="#660000">recordSet</font>-&gt;MoveNext(); 
    992 &#125;</font><font face="Courier New, Courier, mono"> 
    993  
    994 $<font color="#660000">recordSet</font>->Close(); # optional 
    995 $<font color="#660000">conn</font>->Close(); # optional 
    996 </font> 
    997 ?> 
     970</p><pre>&lt;?<br><font face="Courier New, Courier, mono"><b>include</b>('adodb.inc.php');         # load code common to ADOdb<br>$<font color="#660000">conn</font> = &amp;ADONewConnection('access'); # create a connection<br>$<font color="#660000">conn</font>-&gt;PConnect('northwind');   # connect to MS-Access, northwind DSN<br>$<font color="#660000">recordSet</font> = &amp;$<font color="#660000">conn</font>-&gt;Execute('select * from products');<br>if (!$<font color="#660000">recordSet</font>) <br>        print $<font color="#660000">conn</font>-&gt;ErrorMsg();<br>else<br><b>while</b> (!$<font color="#660000">recordSet</font>-&gt;EOF) {<br>       <b>print</b> $<font color="#660000">recordSet</font>-&gt;fields[0].' '.$<font color="#660000">recordSet</font>-&gt;fields[1].'&lt;BR&gt;';<br>  $<font color="#660000">recordSet</font>-&gt;MoveNext();<br>}</font><font face="Courier New, Courier, mono"> 
     971 
     972$<font color="#660000">recordSet</font>-&gt;Close(); # optional<br>$<font color="#660000">conn</font>-&gt;Close(); # optional<br></font> 
     973?&gt; 
    998974</pre> 
    999975<p>The $<font face="Courier New, Courier, mono">recordSet</font> returned stores  
     
    1008984  - use the SetFetchMode function. Each recordset saves and uses whatever fetch  
    1009985  mode was set when the recordset was created in Execute() or SelectLimit().  
    1010 <pre> 
    1011         $db->SetFetchMode(ADODB_FETCH_NUM); 
    1012         $rs1 = $db->Execute('select * from table'); 
    1013         $db->SetFetchMode(ADODB_FETCH_ASSOC); 
    1014         $rs2 = $db->Execute('select * from table'); 
    1015         print_r($rs1->fields); # shows <i>array([0]=>'v0',[1] =>'v1')</i> 
    1016         print_r($rs2->fields); # shows <i>array(['col1']=>'v0',['col2'] =>'v1')</i> 
     986</p><pre>       $db-&gt;SetFetchMode(ADODB_FETCH_NUM);<br>      $rs1 = $db-&gt;Execute('select * from table');<br>      $db-&gt;SetFetchMode(ADODB_FETCH_ASSOC);<br>    $rs2 = $db-&gt;Execute('select * from table');<br>      print_r($rs1-&gt;fields); # shows <i>array([0]=&gt;'v0',[1] =&gt;'v1')</i> 
     987        print_r($rs2-&gt;fields); # shows <i>array(['col1']=&gt;'v0',['col2'] =&gt;'v1')</i> 
    1017988</pre> 
    1018989<p> </p> 
     
    1022993<p>Select a table, display the first two columns. If the second column is a date  
    1023994  or timestamp, reformat the date to US format.</p> 
    1024 <pre> 
    1025 &lt;? 
    1026 <font face="Courier New, Courier, mono"><b>include</b>('adodb.inc.php');           # load code common to ADOdb 
    1027 $<font color="#660000">conn</font> = &amp;ADONewConnection('access');   # create a connection 
    1028 $<font color="#660000">conn</font>->PConnect('northwind');   # connect to MS-Access, northwind dsn 
    1029 $<font color="#660000">recordSet</font> = &amp;$<font color="#660000">conn</font>->Execute('select CustomerID,OrderDate from Orders'); 
    1030 if (!$<font color="#660000">recordSet</font>)  
    1031         print $<font color="#660000">conn</font>-&gt;ErrorMsg(); 
    1032 else 
    1033 <b>while</b> (!$<font color="#660000">recordSet</font>-&gt;EOF) &#123; 
    1034         $<font color="#660000">fld</font> = <font color="#336600"><b>$</b><font color="#660000">recordSet</font><b>-&gt;FetchField</b></font><font color="#006600">(</font>1<font color="#006600">);</font> 
    1035         $<font color="#660000">type</font> = <font color="#336600"><b>$</b><font color="#660000">recordSet</font><b>-&gt;MetaType</b></font>($fld-&gt;type); 
    1036  
    1037         <b>if</b> ( $<font color="#660000">type</font> == 'D' || $<font color="#660000">type</font> == 'T')  
    1038                 <b>print</b> $<font color="#660000">recordSet</font>-&gt;fields[0].' '. 
    1039                         <b><font color="#336600">$</font></b><font color="#660000">recordSet</font><b><font color="#336600">-&gt;UserDate</font></b>($<font color="#660000">recordSet</font>-&gt;fields[1],'<b>m/d/Y</b>').'&lt;BR&gt;'; 
    1040         <b>else </b> 
    1041                 <b>print</b> $<font color="#660000">recordSet</font>->fields[0].' '.$<font color="#660000">recordSet</font>->fields[1].'&lt;BR&gt;'; 
    1042  
    1043         $<font color="#660000">recordSet</font>-&gt;MoveNext(); 
    1044 &#125;</font><font face="Courier New, Courier, mono"> 
    1045 $<font color="#660000">recordSet</font>->Close(); # optional 
    1046 $<font color="#660000">conn</font>->Close(); # optional 
    1047 </font> 
    1048 ?> 
     995<pre>&lt;?<br><font face="Courier New, Courier, mono"><b>include</b>('adodb.inc.php');     # load code common to ADOdb<br>$<font color="#660000">conn</font> = &amp;ADONewConnection('access'); # create a connection<br>$<font color="#660000">conn</font>-&gt;PConnect('northwind');   # connect to MS-Access, northwind dsn<br>$<font color="#660000">recordSet</font> = &amp;$<font color="#660000">conn</font>-&gt;Execute('select CustomerID,OrderDate from Orders');<br>if (!$<font color="#660000">recordSet</font>) <br>       print $<font color="#660000">conn</font>-&gt;ErrorMsg();<br>else<br><b>while</b> (!$<font color="#660000">recordSet</font>-&gt;EOF) {<br>       $<font color="#660000">fld</font> = <font color="#336600"><b>$</b><font color="#660000">recordSet</font><b>-&gt;FetchField</b></font><font color="#006600">(</font>1<font color="#006600">);</font> 
     996        $<font color="#660000">type</font> = <font color="#336600"><b>$</b><font color="#660000">recordSet</font><b>-&gt;MetaType</b></font>($fld-&gt;type);<br><br>    <b>if</b> ( $<font color="#660000">type</font> == 'D' || $<font color="#660000">type</font> == 'T') <br>                <b>print</b> $<font color="#660000">recordSet</font>-&gt;fields[0].' '.<br>                     <b><font color="#336600">$</font></b><font color="#660000">recordSet</font><b><font color="#336600">-&gt;UserDate</font></b>($<font color="#660000">recordSet</font>-&gt;fields[1],'<b>m/d/Y</b>').'&lt;BR&gt;';<br>    <b>else </b> 
     997                <b>print</b> $<font color="#660000">recordSet</font>-&gt;fields[0].' '.$<font color="#660000">recordSet</font>-&gt;fields[1].'&lt;BR&gt;';<br><br>      $<font color="#660000">recordSet</font>-&gt;MoveNext();<br>}</font><font face="Courier New, Courier, mono"> 
     998$<font color="#660000">recordSet</font>-&gt;Close(); # optional<br>$<font color="#660000">conn</font>-&gt;Close(); # optional<br></font> 
     999?&gt; 
    10491000</pre> 
    10501001<p>In this example, we check the field type of the second column using <font face="Courier New, Courier, mono"><a href="#fetchfield">FetchField</a>().</font>  
     
    10611012  <i>generic</i> types are defined:</p> 
    10621013<ul> 
    1063   <li><b>C</b>: character fields that should be shown in a &lt;input type=&quot;text&quot;&gt;  
     1014  <li><b>C</b>: character fields that should be shown in a &lt;input type="text"&gt;  
    10641015    tag.</li> 
    10651016  <li><b>X</b>: TeXt, large text fields that should be shown in a &lt;textarea&gt;</li> 
    10661017  <li><b>B</b>: Blobs, or Binary Large Objects. Typically images.  
    1067   <li><b>D</b>: Date field</li> 
     1018  </li><li><b>D</b>: Date field</li> 
    10681019  <li><b>T</b>: Timestamp field</li> 
    10691020  <li><b>L</b>: Logical field (boolean or bit-field)</li> 
     
    10831034  be quoted before they can be accepted by the database, eg: the single-quote  
    10841035  in the word <i>John's</i>.</p> 
    1085 <pre> 
    1086 &lt;? 
    1087 <b>include</b>('adodb.inc.php');           # load code common to ADOdb 
    1088 $<font color="#660000">conn</font> = &amp;ADONewConnection('access');   # create a connection 
    1089  
    1090 $<font color="#660000">conn</font>->PConnect('northwind');   # connect to MS-Access, northwind dsn 
    1091 $<font color="#660000">shipto</font> = <font color="#006600"><b>$conn-&gt;qstr</b></font>(&quot;<i>John's Old Shoppe</i>&quot;); 
    1092  
    1093 $<font color="#660000">sql</font> = &quot;insert into orders (customerID,EmployeeID,OrderDate,ShipName) &quot;; 
    1094 $<font color="#660000">sql</font> .= &quot;values ('ANATR',2,&quot;.<b><font color="#006600">$conn-&gt;DBDate(</font>time()<font color="#006600">)</font></b><font color="#006600">.</font>&quot;,$<font color="#660000">shipto</font>)&quot;; 
    1095  
    1096 <b>if</b> ($<font color="#660000">conn</font>->Execute($<font color="#660000">sql</font>) <font color="#336600"><b>=== false</b></font>) &#123; 
    1097         <b>print</b> 'error inserting: '.<font color="#336600"><b>$conn-&gt;ErrorMsg()</b></font>.'&lt;BR&gt;'; 
    1098 &#125; 
    1099 ?> 
    1100 </pre> 
     1036<pre>&lt;?<br><b>include</b>('adodb.inc.php');     # load code common to ADOdb<br>$<font color="#660000">conn</font> = &amp;ADONewConnection('access'); # create a connection<br><br>$<font color="#660000">conn</font>-&gt;PConnect('northwind');   # connect to MS-Access, northwind dsn<br>$<font color="#660000">shipto</font> = <font color="#006600"><b>$conn-&gt;qstr</b></font>("<i>John's Old Shoppe</i>");<br><br>$<font color="#660000">sql</font> = "insert into orders (customerID,EmployeeID,OrderDate,ShipName) ";<br>$<font color="#660000">sql</font> .= "values ('ANATR',2,".<b><font color="#006600">$conn-&gt;DBDate(</font>time()<font color="#006600">)</font></b><font color="#006600">.</font>",$<font color="#660000">shipto</font>)";<br><br><b>if</b> ($<font color="#660000">conn</font>-&gt;Execute($<font color="#660000">sql</font>) <font color="#336600"><b>=== false</b></font>) {<br>        <b>print</b> 'error inserting: '.<font color="#336600"><b>$conn-&gt;ErrorMsg()</b></font>.'&lt;BR&gt;';<br>}<br>?&gt;<br></pre> 
    11011037<p>In this example, we see the advanced date and quote handling facilities of  
    11021038  ADOdb. The unix timestamp (which is a long integer) is appropriately formated  
     
    11121048  be saved.</p> 
    11131049<h3> Example 4: Debugging<a name="ex4"></a></h3> 
    1114 <pre>&lt;? 
    1115 <b>include</b>('adodb.inc.php');           # load code common to ADOdb 
    1116 $<font color="#663300">conn</font> = &amp;ADONewConnection('access');   # create a connection 
    1117 $<font color="#663300">conn</font>->PConnect('northwind');   # connect to MS-Access, northwind dsn 
    1118 <font color="#000000">$<font color="#663300">shipto</font> = <b>$conn-&gt;qstr</b>(&quot;John's Old Shoppe&quot;); 
    1119 $<font color="#663300">sql</font> = &quot;insert into orders (customerID,EmployeeID,OrderDate,ShipName) &quot;; 
    1120 $<font color="#663300">sql</font> .= &quot;values ('ANATR',2,&quot;.$<font color="#663300">conn</font>-&gt;FormatDate(time()).&quot;,$shipto)&quot;; 
    1121 <b><font color="#336600">$<font color="#663300">conn</font>-&gt;debug = true;</font></b> 
    1122 <b>if</b> ($<font color="#663300">conn</font>->Execute($sql) <b>=== false</b>) <b>print</b> 'error inserting';</font> 
     1050<pre>&lt;?<br><b>include</b>('adodb.inc.php');     # load code common to ADOdb<br>$<font color="#663300">conn</font> = &amp;ADONewConnection('access'); # create a connection<br>$<font color="#663300">conn</font>-&gt;PConnect('northwind');   # connect to MS-Access, northwind dsn<br><font>$<font color="#663300">shipto</font> = <b>$conn-&gt;qstr</b>("John's Old Shoppe");<br>$<font color="#663300">sql</font> = "insert into orders (customerID,EmployeeID,OrderDate,ShipName) ";<br>$<font color="#663300">sql</font> .= "values ('ANATR',2,".$<font color="#663300">conn</font>-&gt;FormatDate(time()).",$shipto)";<br><b><font color="#336600">$<font color="#663300">conn</font>-&gt;debug = true;</font></b> 
     1051<b>if</b> ($<font color="#663300">conn</font>-&gt;Execute($sql) <b>=== false</b>) <b>print</b> 'error inserting';</font> 
    11231052?&gt; 
    11241053</pre> 
     
    11281057  in this case. For displaying the recordset, see the <font face="Courier New, Courier, mono"><a href="#exrs2html">rs2html</a>()  
    11291058  </font>example.</p> 
    1130 <p>Also see the section on <a href=#errorhandling>Custom Error Handlers</a>.</p> 
     1059<p>Also see the section on <a href="#errorhandling">Custom Error Handlers</a>.</p> 
    11311060<h3>Example 5: MySQL and Menus<a name="ex5"></a></h3> 
    11321061<p>Connect to MySQL database <i>agora</i>, and generate a &lt;select&gt; menu  
    11331062  from an SQL statement where the &lt;option&gt; captions are in the 1st column,  
    11341063  and the value to send back to the server is in the 2nd column.</p> 
    1135 <pre>&lt;? 
    1136 <b>include</b>('adodb.inc.php'); # load code common to ADOdb 
    1137 $<font color="#663300">conn</font> = &amp;ADONewConnection('mysql');  # create a connection 
    1138 $<font color="#663300">conn</font>->PConnect('localhost','userid','','agora');# connect to MySQL, agora db 
    1139 <font color="#000000">$<font color="#663300">sql</font> = 'select CustomerName, CustomerID from customers'; 
    1140 $<font color="#663300">rs</font> = $<font color="#663300">conn</font>->Execute($sql); 
    1141 <b>print</b> <b><font color="#336600">$<font color="#663300">rs</font>-&gt;GetMenu('GetCust','Mary Rosli'); 
    1142 ?&gt;</font></b></font></pre> 
     1064<pre>&lt;?<br><b>include</b>('adodb.inc.php'); # load code common to ADOdb<br>$<font color="#663300">conn</font> = &amp;ADONewConnection('mysql');  # create a connection<br>$<font color="#663300">conn</font>-&gt;PConnect('localhost','userid','','agora');# connect to MySQL, agora db<br><font>$<font color="#663300">sql</font> = 'select CustomerName, CustomerID from customers';<br>$<font color="#663300">rs</font> = $<font color="#663300">conn</font>-&gt;Execute($sql);<br><b>print</b> <b><font color="#336600">$<font color="#663300">rs</font>-&gt;GetMenu('GetCust','Mary Rosli');<br>?&gt;</font></b></font></pre> 
    11431065<p>Here we define a menu named GetCust, with the menu option 'Mary Rosli' selected.  
    11441066  See <a href="#getmenu"><font face="Courier New, Courier, mono">GetMenu</font></a><font face="Courier New, Courier, mono">()</font>.  
     
    11461068  and as an associative array with the key being the first column: <a href="#getassoc1">GetAssoc</a>().</p> 
    11471069<h3>Example 6: Connecting to 2 Databases At Once<a name="ex6"></a></h3> 
    1148 <pre>&lt;? 
    1149 <b>include</b>('adodb.inc.php');         # load code common to ADOdb 
    1150 $<font color="#663300">conn1</font> = &amp;ADONewConnection('mysql');  # create a mysql connection 
    1151 $<font color="#663300">conn2</font> = &amp;ADONewConnection('oracle');  # create a oracle connection 
    1152  
    1153 $conn1-&gt;PConnect($server, $userid, $password, $database); 
    1154 $conn2-&gt;PConnect(false, $ora_userid, $ora_pwd, $oraname); 
    1155  
    1156 $conn1-&gt;Execute('insert ...'); 
    1157 $conn2-&gt;Execute('update ...'); 
    1158 ?&gt;</pre> 
     1070<pre>&lt;?<br><b>include</b>('adodb.inc.php');   # load code common to ADOdb<br>$<font color="#663300">conn1</font> = &amp;ADONewConnection('mysql');  # create a mysql connection<br>$<font color="#663300">conn2</font> = &amp;ADONewConnection('oracle');  # create a oracle connection<br><br>$conn1-&gt;PConnect($server, $userid, $password, $database);<br>$conn2-&gt;PConnect(false, $ora_userid, $ora_pwd, $oraname);<br><br>$conn1-&gt;Execute('insert ...');<br>$conn2-&gt;Execute('update ...');<br>?&gt;</pre> 
    11591071<p>  
    1160 <h3>Example 7: Generating Update and Insert SQL<a name="ex7"></a></h3> 
    1161 ADOdb 1.31 and later supports two new recordset functions: GetUpdateSQL( ) and  
     1072</p><h3>Example 7: Generating Update and Insert SQL<a name="ex7"></a></h3> 
     1073<p>Since ADOdb 4.56, we support <a href="reference.functions.getupdatesql.html#autoexecute">AutoExecute()</a>,  
     1074which simplifies things by providing an advanced wrapper for GetInsertSQL() and GetUpdateSQL(). For example, 
     1075an INSERT can be carried out with: 
     1076 
     1077<pre> 
     1078    $record["firstname"] = "Bob";  
     1079    $record["lastname"] = "Smith";  
     1080    $record["created"] = time();  
     1081    $insertSQL = $conn->AutoExecute($rs, $record, 'INSERT');  
     1082</pre> 
     1083 
     1084and an UPDATE with: 
     1085<pre> 
     1086    $record["firstname"] = "Caroline";  
     1087    $record["lastname"] = "Smith"; # Update Caroline's lastname from Miranda to Smith  
     1088    $insertSQL = $conn->AutoExecute($rs, $record, 'UPDATE', 'id = 1');  
     1089</pre> 
     1090<p> 
     1091The rest of this section is out-of-date: 
     1092<p>ADOdb 1.31 and later supports two new recordset functions: GetUpdateSQL( ) and  
    11621093GetInsertSQL( ). This allow you to perform a "SELECT * FROM table query WHERE...",  
    1163 make a copy of the $rs->fields, modify the fields, and then generate the SQL to  
     1094make a copy of the $rs-&gt;fields, modify the fields, and then generate the SQL to  
    11641095update or insert into the table automatically.  
    11651096<p> We show how the functions can be used when accessing a table with the following  
    11661097  fields: (ID, FirstName, LastName, Created).  
    1167 <p> Before these functions can be called, you need to initialize the recordset  
     1098</p><p> Before these functions can be called, you need to initialize the recordset  
    11681099  by performing a select on the table. Idea and code by Jonathan Younger jyounger#unilab.com.  
    11691100 Since ADOdb 2.42, you can pass a  table name instead of a recordset into  
    11701101GetInsertSQL (in $rs), and it will generate an insert statement for that table. 
    1171 <p>  
    1172 <pre>&lt;? 
    1173 #============================================== 
    1174 # SAMPLE GetUpdateSQL() and GetInsertSQL() code 
    1175 #============================================== 
    1176 include('adodb.inc.php'); 
    1177 include('tohtml.inc.php'); 
    1178  
    1179 #========================== 
    1180 # This code tests an insert 
    1181  
    1182 $sql = "SELECT * FROM ADOXYZ WHERE id = -1";  
    1183 # Select an empty record from the database 
    1184  
    1185 $conn = &ADONewConnection("mysql");  # create a connection 
    1186 $conn->debug=1; 
    1187 $conn->PConnect("localhost", "admin", "", "test"); # connect to MySQL, testdb 
    1188 $rs = $conn->Execute($sql); # Execute the query and get the empty recordset 
    1189  
    1190 $record = array(); # Initialize an array to hold the record data to insert 
    1191  
    1192 # Set the values for the fields in the record 
    1193 # Note that field names are case-insensitive 
    1194 $record["firstname"] = "Bob"; 
    1195 $record["lastNamE"] = "Smith"; 
    1196 $record["creaTed"] = time(); 
    1197  
    1198 # Pass the empty recordset and the array containing the data to insert 
    1199 # into the GetInsertSQL function. The function will process the data and return 
    1200 # a fully formatted insert sql statement. 
    1201 $insertSQL = $conn->GetInsertSQL($rs, $record); 
    1202  
    1203 $conn->Execute($insertSQL); # Insert the record into the database 
    1204  
    1205 #========================== 
    1206 # This code tests an update 
    1207  
    1208 $sql = "SELECT * FROM ADOXYZ WHERE id = 1";  
    1209 # Select a record to update 
    1210  
    1211 $rs = $conn->Execute($sql); # Execute the query and get the existing record to update 
    1212  
    1213 $record = array(); # Initialize an array to hold the record data to update 
    1214  
    1215 # Set the values for the fields in the record 
    1216 # Note that field names are case-insensitive 
    1217 $record["firstname"] = "Caroline"; 
    1218 $record["LasTnAme"] = "Smith"; # Update Caroline's lastname from Miranda to Smith 
    1219  
    1220 # Pass the single record recordset and the array containing the data to update 
    1221 # into the GetUpdateSQL function. The function will process the data and return 
    1222 # a fully formatted update sql statement with the correct WHERE clause. 
    1223 # If the data has not changed, no recordset is returned 
    1224 $updateSQL = $conn->GetUpdateSQL($rs, $record); 
    1225  
    1226 $conn->Execute($updateSQL); # Update the record in the database 
    1227 $conn->Close(); 
    1228 ?> 
    1229 </pre> 
    1230 GetInsertSQL/GetUpdateSQL ignore all empty fields (they are not added to the SQL generated).  
    1231 To explicitly force a field to be set to "null", set the constant define('ADODB_FORCE_NULLS',1) before 
    1232 you call the functions. 
     1102</p><p>  
     1103</p><pre>&lt;?<br>#==============================================<br># SAMPLE GetUpdateSQL() and GetInsertSQL() code<br>#==============================================<br>include('adodb.inc.php');<br>include('tohtml.inc.php');<br><br>#==========================<br># This code tests an insert<br><br>$sql = "SELECT * FROM ADOXYZ WHERE id = -1"; <br># Select an empty record from the database<br><br>$conn = &amp;ADONewConnection("mysql");  # create a connection<br>$conn-&gt;debug=1;<br>$conn-&gt;PConnect("localhost", "admin", "", "test"); # connect to MySQL, testdb<br>$rs = $conn-&gt;Execute($sql); # Execute the query and get the empty recordset<br><br>$record = array(); # Initialize an array to hold the record data to insert<br><br># Set the values for the fields in the record<br># Note that field names are case-insensitive<br>$record["firstname"] = "Bob";<br>$record["lastNamE"] = "Smith";<br>$record["creaTed"] = time();<br><br># Pass the empty recordset and the array containing the data to insert<br># into the GetInsertSQL function. The function will process the data and return<br># a fully formatted insert sql statement.<br>$insertSQL = $conn-&gt;GetInsertSQL($rs, $record);<br><br>$conn-&gt;Execute($insertSQL); # Insert the record into the database<br><br>#==========================<br># This code tests an update<br><br>$sql = "SELECT * FROM ADOXYZ WHERE id = 1"; <br># Select a record to update<br><br>$rs = $conn-&gt;Execute($sql); # Execute the query and get the existing record to update<br><br>$record = array(); # Initialize an array to hold the record data to update<br><br># Set the values for the fields in the record<br># Note that field names are case-insensitive<br>$record["firstname"] = "Caroline";<br>$record["LasTnAme"] = "Smith"; # Update Caroline's lastname from Miranda to Smith<br><br># Pass the single record recordset and the array containing the data to update<br># into the GetUpdateSQL function. The function will process the data and return<br># a fully formatted update sql statement with the correct WHERE clause.<br># If the data has not changed, no recordset is returned<br>$updateSQL = $conn-&gt;GetUpdateSQL($rs, $record);<br><br>$conn-&gt;Execute($updateSQL); # Update the record in the database<br>$conn-&gt;Close();<br>?&gt;<br></pre> 
     1104<a name="ADODB_FORCE_TYPE"></a> 
     1105<b>$ADODB_FORCE_TYPE</b><p> 
     1106The behaviour of AutoExecute(), GetUpdateSQL() and GetInsertSQL()   
     1107when converting empty or null PHP variables to SQL is controlled by the 
     1108 global $ADODB_FORCE_TYPE variable. Set it to one of the values below. Default 
     1109  is ADODB_FORCE_VALUE (3): 
     1110</p><pre>0 = ignore empty fields. All empty fields in array are ignored.<br>1 = force null. All empty, php null and string 'null' fields are changed to sql NULL values.<br>2 = force empty. All empty, php null and string 'null' fields are changed to sql empty '' or 0 values.<br>3 = force value. Value is left as it is. Php null and string 'null' are set to sql NULL values and <br>    empty fields '' are set to empty '' sql values.<br><br>define('ADODB_FORCE_IGNORE',0);<br>define('ADODB_FORCE_NULL',1);<br>define('ADODB_FORCE_EMPTY',2);<br>define('ADODB_FORCE_VALUE',3);<br></pre> 
    12331111<p> 
    1234 <h3>Example 8: Implementing Scrolling with Next and Previous<a name="ex8"></a></h3> 
     1112Thanks to Niko (nuko#mbnet.fi) for the $ADODB_FORCE_TYPE code. 
     1113</p><p> 
     1114Note: the constant ADODB_FORCE_NULLS is obsolete since 4.52 and is ignored. Set $ADODB_FORCE_TYPE = ADODB_FORCE_NULL 
     1115for equivalent behaviour. 
     1116<p>Since 4.62, the table name to be used can be overridden by setting $rs->tableName before AutoExecute(), GetInsertSQL() or GetUpdateSQL() is called. 
     1117</p><h3>Example 8: Implementing Scrolling with Next and Previous<a name="ex8"></a></h3> 
    12351118<p> The following code creates a very simple recordset pager, where you can scroll  
    12361119  from page to page of a recordset.</p> 
    1237 <pre> 
    1238 include_once('../adodb.inc.php'); 
    1239 include_once('../adodb-pager.inc.php'); 
    1240 session_start(); 
    1241  
    1242 $db = NewADOConnection('mysql'); 
    1243  
    1244 $db->Connect('localhost','root','','xphplens'); 
    1245  
    1246 $sql = "select * from adoxyz "; 
    1247  
    1248 $pager = new ADODB_Pager($db,$sql); 
    1249 $pager->Render($rows_per_page=5);</pre> 
     1120<pre>include_once('../adodb.inc.php');<br>include_once('../adodb-pager.inc.php');<br>session_start();<br><br>$db = NewADOConnection('mysql');<br><br>$db-&gt;Connect('localhost','root','','xphplens');<br><br>$sql = "select * from adoxyz ";<br><br>$pager = new ADODB_Pager($db,$sql);<br>$pager-&gt;Render($rows_per_page=5);</pre> 
    12501121<p>This will create a basic record pager that looks like this: <a name="scr"></a>  
    1251 <p>  
    1252 <table border=1 bgcolor=beige> 
    1253   <tr>  
     1122</p><p>  
     1123<table bgcolor="beige" border="1"> 
     1124  <tbody><tr>  
    12541125    <td> <a href="#scr"><code>|&lt;</code></a> &nbsp; <a href="#scr"><code>&lt;&lt;</code></a>  
    1255       &nbsp; <a href="#scr"><code>>></code></a> &nbsp; <a href="#scr"><code>>|</code></a>  
     1126      &nbsp; <a href="#scr"><code>&gt;&gt;</code></a> &nbsp; <a href="#scr"><code>&gt;|</code></a>  
    12561127      &nbsp; </td> 
    12571128  </tr> 
    12581129  <tr> 
    1259     <td><TABLE COLS=4 width=100% border=1 bgcolor=white> 
    1260         <TH>ID</TH> 
    1261         <TH>First Name</TH> 
    1262         <TH>Last Name</TH> 
    1263         <TH>Date Created</TH> 
    1264         <TR>  
    1265           <TD align=right>36&nbsp;</TD> 
    1266           <TD>Alan&nbsp;</TD> 
    1267           <TD>Turing&nbsp;</TD> 
    1268           <TD>Sat 06, Oct 2001&nbsp;</TD> 
    1269         </TR> 
    1270         <TR>  
    1271           <TD align=right>37&nbsp;</TD> 
    1272           <TD>Serena&nbsp;</TD> 
    1273           <TD>Williams&nbsp;</TD> 
    1274           <TD>Sat 06, Oct 2001&nbsp;</TD> 
    1275         </TR> 
    1276         <TR>  
    1277           <TD align=right>38&nbsp;</TD> 
    1278           <TD>Yat Sun&nbsp;</TD> 
    1279           <TD>Sun&nbsp;</TD> 
    1280           <TD>Sat 06, Oct 2001&nbsp;</TD> 
    1281         </TR> 
    1282         <TR>  
    1283           <TD align=right>39&nbsp;</TD> 
    1284           <TD>Wai Hun&nbsp;</TD> 
    1285           <TD>See&nbsp;</TD> 
    1286           <TD>Sat 06, Oct 2001&nbsp;</TD> 
    1287         </TR> 
    1288         <TR>  
    1289           <TD align=right>40&nbsp;</TD> 
    1290           <TD>Steven&nbsp;</TD> 
    1291           <TD>Oey&nbsp;</TD> 
    1292           <TD>Sat 06, Oct 2001&nbsp;</TD> 
    1293         </TR> 
    1294       </TABLE></td> 
     1130    <td><table bgcolor="white" border="1" cols="4" width="100%"> 
     1131        <tbody><tr><th>ID</th> 
     1132        <th>First Name</th> 
     1133        <th>Last Name</th> 
     1134        <th>Date Created</th> 
     1135        </tr><tr>  
     1136          <td align="right">36&nbsp;</td> 
     1137          <td>Alan&nbsp;</td> 
     1138          <td>Turing&nbsp;</td> 
     1139          <td>Sat 06, Oct 2001&nbsp;</td> 
     1140        </tr> 
     1141        <tr>  
     1142          <td align="right">37&nbsp;</td> 
     1143          <td>Serena&nbsp;</td> 
     1144          <td>Williams&nbsp;</td> 
     1145          <td>Sat 06, Oct 2001&nbsp;</td> 
     1146        </tr> 
     1147        <tr>  
     1148          <td align="right">38&nbsp;</td> 
     1149          <td>Yat Sun&nbsp;</td> 
     1150          <td>Sun&nbsp;</td> 
     1151          <td>Sat 06, Oct 2001&nbsp;</td> 
     1152        </tr> 
     1153        <tr>  
     1154          <td align="right">39&nbsp;</td> 
     1155          <td>Wai Hun&nbsp;</td> 
     1156          <td>See&nbsp;</td> 
     1157          <td>Sat 06, Oct 2001&nbsp;</td> 
     1158        </tr> 
     1159        <tr>  
     1160          <td align="right">40&nbsp;</td> 
     1161          <td>Steven&nbsp;</td> 
     1162          <td>Oey&nbsp;</td> 
     1163          <td>Sat 06, Oct 2001&nbsp;</td> 
     1164        </tr> 
     1165      </tbody></table></td> 
    12951166  </tr> 
    12961167  <tr> 
    1297     <td><font size=-1>Page 8/10</font></td> 
    1298   </tr> 
    1299 </table> 
    1300 <p>The number of rows to display at one time is controled by the Render($rows)  
     1168    <td><font size="-1">Page 8/10</font></td> 
     1169  </tr> 
     1170</tbody></table> 
     1171</p><p>The number of rows to display at one time is controled by the Render($rows)  
    13011172  method. If you do not pass any value to Render(), ADODB_Pager will default to  
    13021173  10 records per page.  
    1303 <p>You can control the column titles by modifying your SQL (supported by most  
     1174</p><p>You can control the column titles by modifying your SQL (supported by most  
    13041175  databases):  
    1305 <pre>$sql = 'select id as &quot;ID&quot;, firstname as &quot;First Name&quot;,  
    1306                   lastname as &quot;Last Name&quot;, created as &quot;Date Created&quot; <br>           from adoxyz';</pre> 
     1176</p><pre>$sql = 'select id as "ID", firstname as "First Name", <br>               lastname as "Last Name", created as "Date Created" <br>               from adoxyz';</pre> 
    13071177<p>The above code can be found in the <i>adodb/tests/testpaging.php</i> example  
    13081178  included with this release, and the class ADODB_Pager in <i>adodb/adodb-pager.inc.php</i>.  
     
    13101180  be replaced by images, and the dull white background be replaced with more interesting  
    13111181  colors.  
    1312 <p>You can also allow display of html by setting $pager->htmlSpecialChars = false.  
    1313 <p>Some of the code used here was contributed by Iv&aacute;n Oliva and Cornel  
     1182</p><p>You can also allow display of html by setting $pager-&gt;htmlSpecialChars = false.  
     1183</p><p>Some of the code used here was contributed by Iv&aacute;n Oliva and Cornel  
    13141184  G. </p> 
    13151185<h3><a name="ex9"></a>Example 9: Exporting in CSV or Tab-Delimited Format</h3> 
     
    13171187  tab-delimited formats:</p> 
    13181188<pre><b>include_once('/path/to/adodb/toexport.inc.php');</b><br>include_once('/path/to/adodb/adodb.inc.php');<br> 
    1319 $db = &amp;NewADOConnection('mysql');<br>$db-&gt;Connect($server, $userid, $password, $database);<br><br>$rs = $db-&gt;Execute('select fname as &quot;First Name&quot;, surname as &quot;Surname&quot; from table'); 
    1320  
    1321 print &quot;&lt;pre&gt;&quot;;<br>print <b>rs2csv</b>($rs); # return a string, CSV format<p>print '&lt;hr&gt;'; 
    1322 <br>$rs-&gt;MoveFirst(); # note, some databases do not support MoveFirst<br>print <b>rs2tab</b>($rs,<i>false</i>); # return a string, tab-delimited 
    1323                                                  # false == suppress field names in first line</p>print '&lt;hr&gt;';<br>$rs-&gt;MoveFirst();<br><b>rs2tabout</b>($rs); # send to stdout directly (there is also an rs2csvout function) 
    1324 print &quot;&lt;/pre&gt;&quot;; 
    1325  
    1326 $rs-&gt;MoveFirst();<br><b></b>$fp = fopen($path, &quot;w&quot;); 
    1327 if ($fp) {<br>  <b>rs2csvfile</b>($rs, $fp); # write to file (there is also an rs2tabfile function) 
    1328   fclose($fp);<br>} 
    1329 </pre> 
     1189$db = &amp;NewADOConnection('mysql');<br>$db-&gt;Connect($server, $userid, $password, $database);<br><br>$rs = $db-&gt;Execute('select fname as "First Name", surname as "Surname" from table');<br><br>print "&lt;pre&gt;";<br>print <b>rs2csv</b>($rs); # return a string, CSV format<p>print '&lt;hr&gt;';<br><br>$rs-&gt;MoveFirst(); # note, some databases do not support MoveFirst<br>print <b>rs2tab</b>($rs,<i>false</i>); # return a string, tab-delimited<br>                                                 # false == suppress field names in first line</p>print '&lt;hr&gt;';<br>$rs-&gt;MoveFirst();<br><b>rs2tabout</b>($rs); # send to stdout directly (there is also an rs2csvout function)<br>print "&lt;/pre&gt;";<br><br>$rs-&gt;MoveFirst();<br>$fp = fopen($path, "w");<br>if ($fp) {<br>  <b>rs2csvfile</b>($rs, $fp); # write to file (there is also an rs2tabfile function)<br>  fclose($fp);<br>}<br></pre> 
    13301190<p> Carriage-returns or newlines are converted to spaces. Field names are returned  
    13311191  in the first line of text. Strings containing the delimiter character are quoted  
    13321192  with double-quotes. Double-quotes are double-quoted again. This conforms to  
    13331193  Excel import and export guide-lines.  
    1334 <p>All the above functions take as an optional last parameter, $addtitles which  
     1194</p><p>All the above functions take as an optional last parameter, $addtitles which  
    13351195  defaults to <i>true</i>. When set to <i>false</i> field names in the first line  
    13361196  are suppressed. <br> 
    1337 <h3>Example 10: Recordset Filters<a name="ex10"></a></h3> 
     1197</p><h3>Example 10: Recordset Filters<a name="ex10"></a></h3> 
    13381198<p>Sometimes we want to pre-process all rows in a recordset before we use it.  
    13391199  For example, we want to ucwords all text in recordset.  
    1340 <pre> 
    1341 include_once('adodb/rsfilter.inc.php'); 
    1342 include_once('adodb/adodb.inc.php'); 
    1343  
    1344 // ucwords() every element in the recordset 
    1345 function do_ucwords(&$arr,$rs) 
    1346 &#123; 
    1347         foreach($arr as $k => $v) &#123; 
    1348                 $arr[$k] = ucwords($v); 
    1349         &#125; 
    1350 &#125; 
    1351  
    1352 $db = NewADOConnection('mysql'); 
    1353 $db->PConnect('server','user','pwd','db'); 
    1354  
    1355 $rs = $db->Execute('select ... from table'); 
    1356 $rs = <b>RSFilter</b>($rs,'do_ucwords'); 
    1357 </pre> 
     1200</p><pre>include_once('adodb/rsfilter.inc.php');<br>include_once('adodb/adodb.inc.php');<br><br>// ucwords() every element in the recordset<br>function do_ucwords(&amp;$arr,$rs)<br>{<br>      foreach($arr as $k =&gt; $v) {<br>              $arr[$k] = ucwords($v);<br>     }<br>}<br><br>$db = NewADOConnection('mysql');<br>$db-&gt;PConnect('server','user','pwd','db');<br><br>$rs = $db-&gt;Execute('select ... from table');<br>$rs = <b>RSFilter</b>($rs,'do_ucwords');<br></pre> 
    13581201<p>The <i>RSFilter</i> function takes 2 parameters, the recordset, and the name  
    13591202  of the <i>filter</i> function. It returns the processed recordset scrolled to  
     
    13631206<h3>Example 11:<a name="ex11"></a> Smart Transactions</h3> 
    13641207The old way of doing transactions required you to use  
    1365 <pre> 
    1366 $conn-><b>BeginTrans</b>(); 
    1367 $ok = $conn->Execute($sql); 
    1368 if ($ok) $ok = $conn->Execute($sql2); 
    1369 if (!$ok) $conn-><b>RollbackTrans</b>(); 
    1370 else $conn-><b>CommitTrans</b>(); 
    1371 </pre> 
     1208<pre>$conn-&gt;<b>BeginTrans</b>();<br>$ok = $conn-&gt;Execute($sql);<br>if ($ok) $ok = $conn-&gt;Execute($sql2);<br>if (!$ok) $conn-&gt;<b>RollbackTrans</b>();<br>else $conn-&gt;<b>CommitTrans</b>();<br></pre> 
    13721209This is very complicated for large projects because you have to track the error  
    13731210status. Smart Transactions is much simpler. You start a smart transaction by calling  
    13741211StartTrans():  
    1375 <pre> 
    1376 $conn-><b>StartTrans</b>(); 
    1377 $conn->Execute($sql); 
    1378 $conn->Execute($Sql2); 
    1379 $conn-><b>CompleteTrans</b>(); 
    1380 </pre> 
     1212<pre>$conn-&gt;<b>StartTrans</b>();<br>$conn-&gt;Execute($sql);<br>$conn-&gt;Execute($Sql2);<br>$conn-&gt;<b>CompleteTrans</b>();<br></pre> 
    13811213CompleteTrans() detects when an SQL error occurs, and will Rollback/Commit as  
    13821214appropriate. To specificly force a rollback even if no error occured, use FailTrans().  
    13831215Note that the rollback is done in CompleteTrans(), and not in FailTrans().  
    1384 <pre> 
    1385 $conn-><b>StartTrans</b>(); 
    1386 $conn->Execute($sql); 
    1387 if (!CheckRecords()) $conn-><strong>FailTrans</strong>(); 
    1388 $conn->Execute($Sql2); 
    1389 $conn-><b>CompleteTrans</b>(); 
    1390 </pre> 
     1216<pre>$conn-&gt;<b>StartTrans</b>();<br>$conn-&gt;Execute($sql);<br>if (!CheckRecords()) $conn-&gt;<strong>FailTrans</strong>();<br>$conn-&gt;Execute($Sql2);<br>$conn-&gt;<b>CompleteTrans</b>();<br></pre> 
    13911217<p>You can also check if a transaction has failed, using HasFailedTrans(), which  
    13921218  returns true if FailTrans() was called, or there was an error in the SQL execution.  
    13931219  Make sure you call HasFailedTrans() before you call CompleteTrans(), as it is  
    13941220  only works between StartTrans/CompleteTrans. 
    1395 <p>Lastly, StartTrans/CompleteTrans is nestable, and only the outermost block  
     1221</p><p>Lastly, StartTrans/CompleteTrans is nestable, and only the outermost block  
    13961222  is executed. In contrast, BeginTrans/CommitTrans/RollbackTrans is NOT nestable.  
    1397 <pre> 
    1398 $conn-><strong>StartTrans</strong>(); 
    1399 $conn->Execute($sql); 
    1400   $conn-><strong>StartTrans</strong>();    <font color="#006600"># ignored</font> 
    1401   if (!CheckRecords()) $conn->FailTrans(); 
    1402   $conn-><strong>CompleteTrans</strong>(); <font color="#006600"># ignored</font> 
    1403 $conn->Execute($Sql2); 
    1404 $conn-><strong>CompleteTrans</strong>(); 
    1405 </pre> 
     1223</p><pre>$conn-&gt;<strong>StartTrans</strong>();<br>$conn-&gt;Execute($sql);<br>  $conn-&gt;<strong>StartTrans</strong>();    <font color="#006600"># ignored</font> 
     1224  if (!CheckRecords()) $conn-&gt;FailTrans(); 
     1225  $conn-&gt;<strong>CompleteTrans</strong>(); <font color="#006600"># ignored</font> 
     1226$conn-&gt;Execute($Sql2); 
     1227$conn-&gt;<strong>CompleteTrans</strong>();<br></pre> 
    14061228<p>Note: Savepoints are currently not supported.  
    1407 <h2><a name="errorhandling"></a>Using Custom Error Handlers and PEAR_Error</h2> 
    1408 Apart from the old $con->debug = true; way of debugging, ADOdb 1.50 onwards provides  
    1409 another way of handling errors using ADOdb's custom error handlers.  
    1410 <p> ADOdb provides two custom handlers which you can modify for your needs. The  
     1229</p><h2><a name="errorhandling"></a>Using Custom Error Handlers and PEAR_Error</h2> 
     1230<p>ADOdb supports PHP5 exceptions.  Just include <i>adodb-exceptions.inc.php</i> and you can now  
     1231catch exceptions on errors as they occur. 
     1232</p><pre>       <b>include("../adodb-exceptions.inc.php");</b> <br>     include("../adodb.inc.php");     <br>   try { <br>              $db = NewADOConnection("oci8://scott:bad-password@mytns/"); <br>        } catch (exception $e) { <br>           var_dump($e); <br>              adodb_backtrace($e-&gt;gettrace());<br> } <br></pre> 
     1233<p> ADOdb also provides two custom handlers which you can modify for your needs. The  
    14111234  first one is in the <b>adodb-errorhandler.inc.php</b> file. This makes use of  
    1412   the standard PHP functions <a href=http://php.net/error_reporting>error_reporting</a>  
    1413   to control what error messages types to display, and <a href=http://php.net/trigger_error>trigger_error</a>  
     1235  the standard PHP functions <a href="http://php.net/error_reporting">error_reporting</a>  
     1236  to control what error messages types to display, and <a href="http://php.net/trigger_error">trigger_error</a>  
    14141237  which invokes the default PHP error handler.  
    1415 <p> Including the above file will cause <i>trigger_error($errorstring,E_USER_ERROR)</i>  
     1238</p><p> Including the above file will cause <i>trigger_error($errorstring,E_USER_ERROR)</i>  
    14161239  to be called when<br> 
    14171240  (a) Connect() or PConnect() fails, or <br> 
     
    14191242  has an error.<br> 
    14201243  (c) GenID() appears to go into an infinite loop.  
    1421 <p> The $errorstring is generated by ADOdb and will contain useful debugging information  
     1244</p><p> The $errorstring is generated by ADOdb and will contain useful debugging information  
    14221245  similar to the error.log data generated below. This file adodb-errorhandler.inc.php  
    14231246  should be included before you create any ADOConnection objects.  
    1424 <p> If you define error_reporting(0), no errors will be passed to the error handler.  
     1247</p><p> If you define error_reporting(0), no errors will be passed to the error handler.  
    14251248  If you set error_reporting(E_ALL), all errors will be passed to the error handler.  
    14261249  You still need to use <b>ini_set("display_errors", "0" or "1")</b> to control  
    14271250  the display of errors.  
    1428 <pre> 
    1429 &lt;?php 
    1430 <b>error_reporting(E_ALL); # pass any error messages triggered to error handler 
    1431 include('adodb-errorhandler.inc.php');</b> 
     1251</p><pre>&lt;?php<br><b>error_reporting(E_ALL); # pass any error messages triggered to error handler<br>include('adodb-errorhandler.inc.php');</b> 
    14321252include('adodb.inc.php'); 
    14331253include('tohtml.inc.php'); 
    14341254$c = NewADOConnection('mysql'); 
    1435 $c->PConnect('localhost','root','','northwind'); 
    1436 $rs=$c->Execute('select * from productsz'); #invalid table productsz'); 
     1255$c-&gt;PConnect('localhost','root','','northwind'); 
     1256$rs=$c-&gt;Execute('select * from productsz'); #invalid table productsz'); 
    14371257if ($rs) rs2html($rs); 
    1438 ?> 
     1258?&gt; 
    14391259</pre> 
    14401260<p> If you want to log the error message, you can do so by defining the following  
    14411261  optional constants ADODB_ERROR_LOG_TYPE and ADODB_ERROR_LOG_DEST. ADODB_ERROR_LOG_TYPE  
    1442   is the error log message type (see <a href=http://php.net/error_log>error_log</a>  
     1262  is the error log message type (see <a href="http://php.net/error_log">error_log</a>  
    14431263  in the PHP manual). In this case we set it to 3, which means log to the file  
    14441264  defined by the constant ADODB_ERROR_LOG_DEST.  
    1445 <pre> 
    1446 &lt;?php 
    1447 <b>error_reporting(E_ALL); # report all errors 
    1448 ini_set("display_errors", "0"); # but do not echo the errors 
    1449 define('ADODB_ERROR_LOG_TYPE',3); 
    1450 define('ADODB_ERROR_LOG_DEST','C:/errors.log'); 
    1451 include('adodb-errorhandler.inc.php');</b> 
     1265</p><pre>&lt;?php<br><b>error_reporting(E_ALL); # report all errors<br>ini_set("display_errors", "0"); # but do not echo the errors<br>define('ADODB_ERROR_LOG_TYPE',3);<br>define('ADODB_ERROR_LOG_DEST','C:/errors.log');<br>include('adodb-errorhandler.inc.php');</b> 
    14521266include('adodb.inc.php'); 
    14531267include('tohtml.inc.php'); 
    14541268 
    14551269$c = NewADOConnection('mysql'); 
    1456 $c->PConnect('localhost','root','','northwind'); 
    1457 $rs=$c->Execute('select * from productsz'); ## invalid table productsz 
     1270$c-&gt;PConnect('localhost','root','','northwind'); 
     1271$rs=$c-&gt;Execute('select * from productsz'); ## invalid table productsz 
    14581272if ($rs) rs2html($rs); 
    1459 ?> 
     1273?&gt; 
    14601274</pre> 
    14611275The following message will be logged in the error.log file:  
    1462 <pre> 
    1463 (2001-10-28 14:20:38) mysql error: [1146: Table 'northwind.productsz' doesn't exist] in 
    1464  EXECUTE("select * from productsz") 
    1465 </pre> 
     1276<pre>(2001-10-28 14:20:38) mysql error: [1146: Table 'northwind.productsz' doesn't exist] in<br> EXECUTE("select * from productsz")<br></pre> 
     1277<h3>PEAR_ERROR</h3> 
    14661278The second error handler is <b>adodb-errorpear.inc.php</b>. This will create a  
    14671279PEAR_Error derived object whenever an error occurs. The last PEAR_Error object  
    14681280created can be retrieved using ADODB_Pear_Error().  
    1469 <pre> 
    1470 &lt;?php 
    1471 <b>include('adodb-errorpear.inc.php');</b> 
     1281<pre>&lt;?php<br><b>include('adodb-errorpear.inc.php');</b> 
    14721282include('adodb.inc.php'); 
    14731283include('tohtml.inc.php'); 
    14741284$c = NewADOConnection('mysql'); 
    1475 $c->PConnect('localhost','root','','northwind'); 
    1476 $rs=$c->Execute('select * from productsz'); #invalid table productsz'); 
     1285$c-&gt;PConnect('localhost','root','','northwind'); 
     1286$rs=$c-&gt;Execute('select * from productsz'); #invalid table productsz'); 
    14771287if ($rs) rs2html($rs); 
    1478 else &#123; 
    1479         <b>$e = ADODB_Pear_Error(); 
    1480         echo '&lt;p>',$e->message,'&lt;/p>';</b> 
    1481 &#125; 
    1482 ?> 
     1288else { 
     1289        <b>$e = ADODB_Pear_Error();<br> echo '&lt;p&gt;',$e-&gt;message,'&lt;/p&gt;';</b> 
     1290} 
     1291?&gt; 
    14831292</pre> 
    14841293<p> You can use a PEAR_Error derived class by defining the constant ADODB_PEAR_ERROR_CLASS  
     
    14861295  can set the default error handler in the beginning of the PHP script to PEAR_ERROR_DIE,  
    14871296  which will cause an error message to be printed, then halt script execution:  
    1488 <pre> 
    1489 include('PEAR.php'); 
    1490 PEAR::setErrorHandling('PEAR_ERROR_DIE'); 
    1491 </pre> 
     1297</p><pre>include('PEAR.php');<br>PEAR::setErrorHandling('PEAR_ERROR_DIE');<br></pre> 
    14921298<p> Note that we do not explicitly return a PEAR_Error object to you when an error  
    14931299  occurs. We return false instead. You have to call ADODB_Pear_Error() to get  
    14941300  the last error or use the PEAR_ERROR_DIE technique.  
     1301</p> 
     1302<h3>MetaError and MetaErrMsg</h3> 
     1303 <p>If you need error messages that work across multiple databases, then use <a href="#metaerror">MetaError()</a>, which returns a virtualized error number, based on PEAR DB's error number system, and <a href=<a href="#metaerrmsg">MetaErrMsg()</a>. 
     1304 
    14951305<h4>Error Messages</h4> 
    14961306<p>Error messages are outputted using the static method ADOConnnection::outp($msg,$newline=true).  
    14971307  By default, it sends the messages to the client. You can override this to perform  
    14981308  error-logging.  
    1499 <h2><a name="dsn"></a> Data Source Names</h2> 
     1309</p><h2><a name="dsn"></a> Data Source Names</h2> 
    15001310<p>We now support connecting using PEAR style DSN's. A DSN is a connection string  
    15011311  of the form:</p> 
    1502 <p>$dsn = <i>&quot;$driver://$username:$password@$hostname/$databasename&quot;</i>;</p> 
     1312<p>$dsn = <i>"$driver://$username:$password@$hostname/$databasename"</i>;</p> 
    15031313<p>An example:</p> 
    1504 <pre> 
    1505    $username = 'root'; 
    1506    $password = ''; 
    1507    $hostname = 'localhost'; 
    1508    $databasename = 'xphplens'; 
    1509    $driver = 'mysql'; 
    1510    $dsn = &quot;$driver://$username:$password@$hostname/$databasename&quot; 
    1511    $db = NewADOConnection();  
    1512    # DB::Connect($dsn) also works if you include 'adodb/adodb-pear.inc.php' at the top 
    1513    $rs = $db-&gt;query('select firstname,lastname from adoxyz'); 
    1514    $cnt = 0; 
    1515    while ($arr = $rs-&gt;fetchRow()) { 
    1516                 print_r($arr); print &quot;&lt;br&gt;&quot;; 
    1517    }</pre> 
    1518    </p> 
     1314<pre>   $username = 'root';<br>   $password = '';<br>   $hostname = 'localhost';<br>   $databasename = 'xphplens';<br>   $driver = 'mysql';<br>   $dsn = "$driver://$username:$password@$hostname/$databasename"<br>   $db = NewADOConnection(); <br>   # DB::Connect($dsn) also works if you include 'adodb/adodb-pear.inc.php' at the top<br>   $rs = $db-&gt;query('select firstname,lastname from adoxyz');<br>   $cnt = 0;<br>   while ($arr = $rs-&gt;fetchRow()) {<br>           print_r($arr); print "&lt;br&gt;";<br>   }</pre> 
     1315   <p></p> 
    15191316<p>   <a href="#dsnsupport">More info and connection examples</a> on the DSN format. 
    15201317 
    1521  <h2><a name="pear"></a>PEAR Compatibility</h2> 
     1318</p><h2><a name="pear"></a>PEAR Compatibility</h2> 
    15221319  We support DSN's (see above), and the following functions: 
    1523  <pre> 
    1524 <b> DB_Common</b> 
     1320 <pre><b> DB_Common</b> 
    15251321        query - returns PEAR_Error on error 
    15261322        limitQuery - return PEAR_Error on error 
     
    15491345  ) and CacheSelectLimit( ) functions. There are similar to the non-cache functions,  
    15501346  except that they take a new first parameter, $secs2cache.  
    1551 <p> An example:  
    1552 <pre> 
    1553 <b>include</b>('adodb.inc.php'); # load code common to ADOdb 
    1554 $ADODB_CACHE_DIR = '/usr/ADODB_cache'; 
    1555 $<font color="#663300">conn</font> = &amp;ADONewConnection('mysql');  # create a connection 
    1556 $<font color="#663300">conn</font>->PConnect('localhost','userid','','agora');# connect to MySQL, agora db 
    1557 <font color="#000000">$<font color="#663300">sql</font> = 'select CustomerName, CustomerID from customers'; 
    1558 $<font color="#663300">rs</font> = $<font color="#663300">conn</font>->CacheExecute(15,$sql);</font></pre> 
    1559 <p><font color="#000000"> The first parameter is the number of seconds to cache  
     1347</p><p> An example:  
     1348</p><pre><b>include</b>('adodb.inc.php'); # load code common to ADOdb<br>$ADODB_CACHE_DIR = '/usr/ADODB_cache';<br>$<font color="#663300">conn</font> = &amp;ADONewConnection('mysql');  # create a connection<br>$<font color="#663300">conn</font>-&gt;PConnect('localhost','userid','','agora');# connect to MySQL, agora db<br><font>$<font color="#663300">sql</font> = 'select CustomerName, CustomerID from customers';<br>$<font color="#663300">rs</font> = $<font color="#663300">conn</font>-&gt;CacheExecute(15,$sql);</font></pre> 
     1349<p><font> The first parameter is the number of seconds to cache  
    15601350  the query. Subsequent calls to that query will used the cached version stored  
    15611351  in $ADODB_CACHE_DIR. To force a query to execute and flush the cache, call CacheExecute()  
    15621352  with the first parameter set to zero. Alternatively, use the CacheFlush($sql)  
    15631353  call. </font></p> 
    1564 <p><font color="#000000">For the sake of security, we recommend you set <i>register_globals=off</i>  
     1354<p><font>For the sake of security, we recommend you set <i>register_globals=off</i>  
    15651355  in php.ini if you are using $ADODB_CACHE_DIR.</font></p> 
    15661356<p>In ADOdb 1.80 onwards, the secs2cache parameter is optional in CacheSelectLimit()  
    1567   and CacheExecute(). If you leave it out, it will use the $connection->cacheSecs  
     1357  and CacheExecute(). If you leave it out, it will use the $connection-&gt;cacheSecs  
    15681358  parameter, which defaults to 60 minutes.  
    1569 <pre> 
    1570         $conn->Connect(...); 
    1571         $conn->cacheSecs = 3600*24; # cache 24 hours 
    1572         $rs = $conn->CacheExecute('select * from table'); 
    1573 </pre> 
    1574 <p>Please note that magic_quotes_runtime should be turned off. <a href=http://phplens.com/lens/lensforum/msgs.php?LeNs#LensBM_forummsg>More  
     1359</p><pre>       $conn-&gt;Connect(...);<br>     $conn-&gt;cacheSecs = 3600*24; # cache 24 hours<br>     $rs = $conn-&gt;CacheExecute('select * from table');<br></pre> 
     1360<p>Please note that magic_quotes_runtime should be turned off. <a href="http://phplens.com/lens/lensforum/msgs.php?LeNs#LensBM_forummsg">More  
    15751361  info</a>, and do not change $ADODB_FETCH_MODE (or SetFetchMode)  
    1576   as the cached recordset will use the $ADODB_FETCH_MODE set when the query was executed. <font color="#000000">  
     1362  as the cached recordset will use the $ADODB_FETCH_MODE set when the query was executed. <font>  
    15771363<h2><a name="pivot"></a>Pivot Tables</h2> 
    1578 </font> <p><font color="#000000">Since ADOdb 2.30, we support the generation of  
     1364</font> </p><p><font>Since ADOdb 2.30, we support the generation of  
    15791365SQL to create pivot tables, also known as cross-tabulations. For further explanation  
    1580 read this DevShed <a href=http://www.devshed.com/Server_Side/MySQL/MySQLWiz/>Cross-Tabulation  
     1366read this DevShed <a href="http://www.devshed.com/Server_Side/MySQL/MySQLWiz/">Cross-Tabulation  
    15811367tutorial</a>. We assume that your database supports the SQL case-when expression. </font></p>  
    1582 <font color="#000000">  
     1368<font>  
    15831369<p>In this example, we will use the Northwind database from Microsoft. In the  
    15841370  database, we have a products table, and we want to analyze this table by <i>suppliers  
     
    15871373  on the right:</p> 
    15881374</font>  
    1589 <table border="0" cellspacing="2" cellpadding="2" align="center"> 
    1590   <tr> 
     1375<table align="center" border="0" cellpadding="2" cellspacing="2"> 
     1376  <tbody><tr> 
    15911377        <td> 
    1592           <table border="1" cellspacing="2" cellpadding="2" align="center" width="142"> 
    1593                 <tr>  
     1378          <table align="center" border="1" cellpadding="2" cellspacing="2" width="142"> 
     1379                <tbody><tr>  
    15941380                  <td><i>Supplier</i></td> 
    15951381                  <td><i>Category</i></td> 
     
    16071393                  <td>category2</td> 
    16081394                </tr> 
    1609           </table> 
     1395          </tbody></table> 
    16101396        </td> 
    16111397        <td> <font face="Courier New, Courier, mono">--&gt;</font></td> 
    16121398        <td> 
    1613           <table border="1" cellspacing="2" cellpadding="2" align="center"> 
    1614                 <tr>  
     1399          <table align="center" border="1" cellpadding="2" cellspacing="2"> 
     1400                <tbody><tr>  
    16151401                  <td>&nbsp;</td> 
    16161402                  <td><i>category1</i></td> 
     
    16301416                  <td align="right">2</td> 
    16311417                </tr> 
    1632           </table> 
     1418          </tbody></table> 
    16331419        </td> 
    16341420  </tr> 
    1635 </table> 
    1636 <font color="#000000">  
    1637 <p>The following code will generate the SQL for a cross-tabulation:  
    1638 <pre> 
    1639 # Query the main "product" table 
    1640 # Set the rows to CompanyName 
    1641 # and the columns to the values of Categories 
    1642 # and define the joins to link to lookup tables  
    1643 # "categories" and "suppliers" 
    1644 # 
    1645  include &quot;adodb/pivottable.php&quot;; 
    1646  $sql = PivotTableSQL( 
    1647         $gDB,                                      # adodb connection 
    1648         'products p ,categories c ,suppliers s',   # tables 
    1649         'CompanyName',                             # rows (multiple fields allowed) 
    1650         'CategoryName',                            # column to pivot on  
    1651         'p.CategoryID = c.CategoryID and s.SupplierID= p.SupplierID' # joins/where 
    1652 ); 
    1653 </pre> 
    1654 </font>  
    1655 <p><font color="#000000"> This will generate the following SQL:</font></p> 
    1656 <p><code><font size="2">SELECT CompanyName, <br> 
    1657   SUM(CASE WHEN CategoryName='Beverages' THEN 1 ELSE 0 END) AS &quot;Beverages&quot;,  
     1421</tbody></table> 
     1422<font>  
     1423</font><p><font>The following code will generate the SQL for a cross-tabulation:  
     1424</font></p><pre><font># Query the main "product" table<br># Set the rows to SupplierName<br># and the columns to the values of Categories<br># and define the joins to link to lookup tables <br># "categories" and "suppliers"<br>#<br> include "adodb/pivottable.inc.php";<br> $sql = PivotTableSQL(<br>      $gDB,                                      # adodb connection<br>       'products p ,categories c ,suppliers s',   # tables<br> 'SupplierName',                             # rows (multiple fields allowed)<br>        'CategoryName',                            # column to pivot on <br>    'p.CategoryID = c.CategoryID and s.SupplierID= p.SupplierID' # joins/where<br>);<br></font></pre> 
     1425  
     1426<p><font> This will generate the following SQL:</font></p> 
     1427<p><code><font size="2">SELECT SupplierName, <br> 
     1428  SUM(CASE WHEN CategoryName='Beverages' THEN 1 ELSE 0 END) AS "Beverages",  
    16581429  <br> 
    1659   SUM(CASE WHEN CategoryName='Condiments' THEN 1 ELSE 0 END) AS &quot;Condiments&quot;,  
     1430  SUM(CASE WHEN CategoryName='Condiments' THEN 1 ELSE 0 END) AS "Condiments",  
    16601431  <br> 
    1661   SUM(CASE WHEN CategoryName='Confections' THEN 1 ELSE 0 END) AS &quot;Confections&quot;,  
     1432  SUM(CASE WHEN CategoryName='Confections' THEN 1 ELSE 0 END) AS "Confections",  
    16621433  <br> 
    1663   SUM(CASE WHEN CategoryName='Dairy Products' THEN 1 ELSE 0 END) AS &quot;Dairy  
    1664   Products&quot;, <br> 
    1665   SUM(CASE WHEN CategoryName='Grains/Cereals' THEN 1 ELSE 0 END) AS &quot;Grains/Cereals&quot;,  
     1434  SUM(CASE WHEN CategoryName='Dairy Products' THEN 1 ELSE 0 END) AS "Dairy  
     1435  Products", <br> 
     1436  SUM(CASE WHEN CategoryName='Grains/Cereals' THEN 1 ELSE 0 END) AS "Grains/Cereals",  
    16661437  <br> 
    1667   SUM(CASE WHEN CategoryName='Meat/Poultry' THEN 1 ELSE 0 END) AS &quot;Meat/Poultry&quot;,  
     1438  SUM(CASE WHEN CategoryName='Meat/Poultry' THEN 1 ELSE 0 END) AS "Meat/Poultry",  
    16681439  <br> 
    1669   SUM(CASE WHEN CategoryName='Produce' THEN 1 ELSE 0 END) AS &quot;Produce&quot;,  
     1440  SUM(CASE WHEN CategoryName='Produce' THEN 1 ELSE 0 END) AS "Produce",  
    16701441  <br> 
    1671   SUM(CASE WHEN CategoryName='Seafood' THEN 1 ELSE 0 END) AS &quot;Seafood&quot;,  
     1442  SUM(CASE WHEN CategoryName='Seafood' THEN 1 ELSE 0 END) AS "Seafood",  
    16721443  <br> 
    16731444  SUM(1) as Total <br> 
    16741445  FROM products p ,categories c ,suppliers s WHERE p.CategoryID = c.CategoryID  
    16751446  and s.SupplierID= p.SupplierID <br> 
    1676   GROUP BY CompanyName</font></code></p> 
     1447  GROUP BY SupplierName</font></code></p> 
    16771448<p> You can also pivot on <i>numerical columns</i> and <i>generate totals</i>  
    1678         by using ranges. <font color="#000000">This code was revised in ADODB 2.41  
     1449        by using ranges. <font>This code was revised in ADODB 2.41  
    16791450        and is not backward compatible.</font> The second example shows this:</p> 
    1680 <pre> 
    1681  $sql = PivotTableSQL( 
    1682         $gDB,                                       # adodb connection 
    1683         'products p ,categories c ,suppliers s',    # tables 
    1684         'CompanyName',                              #<font color="#000000"> rows (multiple fields allowed)</font> 
     1451<pre> $sql = PivotTableSQL(<br>         $gDB,                                       # adodb connection<br>      'products p ,categories c ,suppliers s',    # tables<br>        'SupplierName',                              #<font> rows (multiple fields allowed)</font> 
    16851452   array(                                       # column ranges 
    1686         ' 0 '      => 'UnitsInStock <= 0', 
    1687         "1 to 5"   => '0 < UnitsInStock and UnitsInStock <= 5', 
    1688         "6 to 10"  => '5 < UnitsInStock and UnitsInStock <= 10', 
    1689         "11 to 15" => '10 < UnitsInStock and UnitsInStock <= 15', 
    1690         "16+"      => '15 < UnitsInStock' 
     1453        ' 0 '      =&gt; 'UnitsInStock &lt;= 0', 
     1454        "1 to 5"   =&gt; '0 &lt; UnitsInStock and UnitsInStock &lt;= 5', 
     1455        "6 to 10"  =&gt; '5 &lt; UnitsInStock and UnitsInStock &lt;= 10', 
     1456        "11 to 15" =&gt; '10 &lt; UnitsInStock and UnitsInStock &lt;= 15', 
     1457        "16+"      =&gt; '15 &lt; UnitsInStock' 
    16911458        ), 
    16921459        ' p.CategoryID = c.CategoryID and s.SupplierID= p.SupplierID', # joins/where 
     
    16961463</pre>  
    16971464<p>Which generates: </p> 
    1698 <p> <code> <font size="2">SELECT CompanyName, <br> 
    1699         SUM(CASE WHEN UnitsInStock &lt;= 0 THEN UnitsInStock ELSE 0 END) AS &quot;Sum  
    1700         0 &quot;, <br> 
     1465<p> <code> <font size="2">SELECT SupplierName, <br> 
     1466        SUM(CASE WHEN UnitsInStock &lt;= 0 THEN UnitsInStock ELSE 0 END) AS "Sum  
     1467        0 ", <br> 
    17011468        SUM(CASE WHEN 0 &lt; UnitsInStock and UnitsInStock &lt;= 5 THEN UnitsInStock  
    1702         ELSE 0 END) AS &quot;Sum 1 to 5&quot;,<br> 
     1469        ELSE 0 END) AS "Sum 1 to 5",<br> 
    17031470        SUM(CASE WHEN 5 &lt; UnitsInStock and UnitsInStock &lt;= 10 THEN UnitsInStock  
    1704         ELSE 0 END) AS &quot;Sum 6 to 10&quot;,<br> 
     1471        ELSE 0 END) AS "Sum 6 to 10",<br> 
    17051472        SUM(CASE WHEN 10 &lt; UnitsInStock and UnitsInStock &lt;= 15 THEN UnitsInStock  
    1706         ELSE 0 END) AS &quot;Sum 11 to 15&quot;, <br> 
    1707         SUM(CASE WHEN 15 &lt; UnitsInStock THEN UnitsInStock ELSE 0 END) AS &quot;Sum  
    1708         16+&quot;, <br> 
     1473        ELSE 0 END) AS "Sum 11 to 15", <br> 
     1474        SUM(CASE WHEN 15 &lt; UnitsInStock THEN UnitsInStock ELSE 0 END) AS "Sum  
     1475        16+", <br> 
    17091476        SUM(UnitsInStock) AS "Sum UnitsInStock", <br> 
    17101477        SUM(1) as Total,<br> 
    17111478        FROM products p ,categories c ,suppliers s WHERE p.CategoryID = c.CategoryID  
    17121479        and s.SupplierID= p.SupplierID <br> 
    1713         GROUP BY CompanyName</font></code><font size="2"><br> 
     1480        GROUP BY SupplierName</font></code><font size="2"><br> 
    17141481        </font> </p> 
    1715 <font color="#000000"><hr> 
     1482<font><hr /> 
    17161483<h1>Class Reference<a name="ref"></a></h1> 
    17171484<p>Function parameters with [ ] around them are optional.</p> 
    17181485</font>  
    17191486<h2>Global Variables</h2> 
    1720 <h3><font color="#000000"><a name="adodb_countrecs"></a></font>$ADODB_COUNTRECS</h3> 
     1487<h3><font><a name="adodb_countrecs"></a></font>$ADODB_COUNTRECS</h3> 
    17211488<p>If the database driver API does not support counting the number of records  
    17221489        returned in a SELECT statement, the function RecordCount() is emulated when  
     
    17261493        This variable is checked every time a query is executed, so you can selectively  
    17271494        choose which recordsets to count.</p> 
    1728 <h3><font color="#000000"><a name="adodb_cache_dir"></a>$ADODB_CACHE_DIR</font></h3> 
    1729 <font color="#000000">  
     1495<h3><font><a name="adodb_cache_dir"></a>$ADODB_CACHE_DIR</font></h3> 
     1496<font>  
    17301497<p>If you are using recordset caching, this is the directory to save your recordsets  
    17311498  in. Define this before you call any caching functions such as CacheExecute(  
     
    17371504<p>chown -R apache /path/to/adodb/cache<br> 
    17381505  chgrp -R apache /path/to/adodb/cache </p> 
    1739 <font color="#000000"> 
    1740 <h3><a name="adodb_ansi_padding_off"></a>$ADODB_ANSI_PADDING_OFF</h3> 
    1741 <p>Determines whether to right trim CHAR fields (and also VARCHAR for ibase/firebird). 
     1506<h3><font><a name="adodb_ansi_padding_off"></a>$ADODB_ANSI_PADDING_OFF</font></h3> 
     1507<p><font>Determines whether to right trim CHAR fields (and also VARCHAR for ibase/firebird). 
    17421508Set to true to trim. Default is false. Currently works for oci8po, ibase and firebird  
    17431509drivers. Added in ADOdb 4.01. 
    1744 <h3><font color="#000000"><a name="adodb_lang"></a></font>$ADODB_LANG</h3> 
    1745 <p>Determines the language used in MetaErrorMsg(). The default is 'en', for English.  
     1510</font></p><h3><font><a name="adodb_lang"></a>$ADODB_LANG</font></h3> 
     1511<p><font>Determines the language used in MetaErrorMsg(). The default is 'en', for English.  
    17461512To find out what languages are supported, see the files  
    17471513in adodb/lang/adodb-$lang.inc.php, where $lang is the supported langauge. 
    1748 <h3><a name="adodb_fetch_mode"></a>$ADODB_FETCH_MODE</h3> 
    1749 <p>This is a global variable that determines how arrays are retrieved by recordsets.  
     1514</font></p><h3><font><a name="adodb_fetch_mode"></a>$ADODB_FETCH_MODE</font></h3> 
     1515<p><font>This is a global variable that determines how arrays are retrieved by recordsets.  
    17501516  The recordset saves this value on creation (eg. in Execute( ) or SelectLimit(  
    17511517  )), and any subsequent changes to $ADODB_FETCH_MODE have no affect on existing  
    1752   recordsets, only on recordsets created in the future.</p> 
    1753 <p>The following constants are defined:</p> 
    1754 </font>  
    1755 <p><font color="#000000">define('ADODB_FETCH_DEFAULT',0);<br> 
     1518  recordsets, only on recordsets created in the future.</font></p> 
     1519 <p><font>The following constants are defined:</font></p> 
     1520 <p><font>define('ADODB_FETCH_DEFAULT',0);<br> 
    17561521  define('ADODB_FETCH_NUM',1);<br> 
    17571522  define('ADODB_FETCH_ASSOC',2);<br> 
    17581523  define('ADODB_FETCH_BOTH',3); </font></p> 
    1759 <font color="#000000">  
    1760 <p> An example:  
    1761 <pre> 
    1762         $ADODB_<b>FETCH_MODE</b> = ADODB_FETCH_NUM; 
    1763         $rs1 = $db->Execute('select * from table'); 
    1764         $ADODB_<b>FETCH_MODE</b> = ADODB_FETCH_ASSOC; 
    1765         $rs2 = $db->Execute('select * from table'); 
    1766         print_r($rs1->fields); # shows <i>array([0]=>'v0',[1] =>'v1')</i> 
    1767         print_r($rs2->fields); # shows <i>array(['col1']=>'v0',['col2'] =>'v1')</i> 
    1768 </pre> 
    1769 <p> As you can see in the above example, both recordsets store and use different  
     1524<font>  
     1525</font><p><font> An example:  
     1526</font></p><pre><font>  $ADODB_<b>FETCH_MODE</b> = ADODB_FETCH_NUM;<br> $rs1 = $db-&gt;Execute('select * from table');<br>      $ADODB_<b>FETCH_MODE</b> = ADODB_FETCH_ASSOC;<br>       $rs2 = $db-&gt;Execute('select * from table');<br>      print_r($rs1-&gt;fields); # shows <i>array([0]=&gt;'v0',[1] =&gt;'v1')</i> 
     1527        print_r($rs2-&gt;fields); # shows <i>array(['col1']=&gt;'v0',['col2'] =&gt;'v1')</i> 
     1528</font></pre> 
     1529<p><font> As you can see in the above example, both recordsets store and use different  
    17701530        fetch modes based on the $ADODB_FETCH_MODE setting when the recordset was  
    1771         created by Execute().</p> 
    1772 <p>If no fetch mode is predefined, the fetch mode defaults to ADODB_FETCH_DEFAULT.  
     1531        created by Execute().</font></p> 
     1532<p><font>If no fetch mode is predefined, the fetch mode defaults to ADODB_FETCH_DEFAULT.  
    17731533        The behaviour of this default mode varies from driver to driver, so do not  
    17741534        rely on ADODB_FETCH_DEFAULT. For portability, we recommend sticking to ADODB_FETCH_NUM  
    1775         or ADODB_FETCH_ASSOC. Many drivers do not support ADODB_FETCH_BOTH.</p> 
    1776 <p><strong>SetFetchMode Function</strong></p> 
    1777 <p>Some programmers prefer to use a more object-oriented solution, where the fetch  
    1778         mode is set by a object function, <a href="#setfetchmode">SetFetchMode</a>.  
     1535        or ADODB_FETCH_ASSOC. Many drivers do not support ADODB_FETCH_BOTH.</font></p> 
     1536<p><font><strong>SetFetchMode Function</strong></font></p> 
     1537<p><font>If you have multiple connection objects, and want to have different fetch modes for each  
     1538connection, then use <a href="#setfetchmode">SetFetchMode</a>.  
    17791539        Once this function is called for a connection object, that connection object  
    17801540        will ignore the global variable $ADODB_FETCH_MODE and will use the internal  
    1781         fetchMode property exclusively.</p> 
    1782 <pre> 
    1783         $db->SetFetchMode(ADODB_FETCH_NUM); 
    1784         $rs1 = $db->Execute('select * from table'); 
    1785         $db->SetFetchMode(ADODB_FETCH_ASSOC); 
    1786         $rs2 = $db->Execute('select * from table'); 
    1787         print_r($rs1->fields); # shows <i>array([0]=>'v0',[1] =>'v1')</i> 
    1788         print_r($rs2->fields); # shows <i>array(['col1']=>'v0',['col2'] =>'v1')</i></pre> 
    1789 <p>To retrieve the previous fetch mode, you can use check the $db-&gt;fetchMode  
     1541        fetchMode property exclusively.</font></p> 
     1542<pre><font>     $db-&gt;SetFetchMode(ADODB_FETCH_NUM);<br>      $rs1 = $db-&gt;Execute('select * from table');<br>      $db-&gt;SetFetchMode(ADODB_FETCH_ASSOC);<br>    $rs2 = $db-&gt;Execute('select * from table');<br>      print_r($rs1-&gt;fields); # shows <i>array([0]=&gt;'v0',[1] =&gt;'v1')</i> 
     1543        print_r($rs2-&gt;fields); # shows <i>array(['col1']=&gt;'v0',['col2'] =&gt;'v1')</i></font></pre> 
     1544<p><font>To retrieve the previous fetch mode, you can use check the $db-&gt;fetchMode  
    17901545        property, or use the return value of SetFetchMode( ).  
    1791 <p><strong><a name="adodb_assoc_case"></a>ADODB_ASSOC_CASE</strong></p> 
    1792 <p>You can control the associative fetch case for certain drivers which behave  
     1546</font></p><p><font><strong><a name="adodb_assoc_case"></a>ADODB_ASSOC_CASE</strong></font></p> 
     1547<p><font>You can control the associative fetch case for certain drivers which behave  
    17931548        differently. For the sybase, oci8po, mssql, odbc and ibase drivers and all  
    17941549        drivers derived from them, ADODB_ASSOC_CASE will by default generate recordsets  
    17951550        where the field name keys are lower-cased. Use the constant ADODB_ASSOC_CASE  
    1796         to change the case of the keys. There are 3 possible values:</p> 
    1797 <p>0 = assoc lowercase field names. $rs-&gt;fields['orderid']<br> 
     1551        to change the case of the keys. There are 3 possible values:</font></p> 
     1552<p><font>0 = assoc lowercase field names. $rs-&gt;fields['orderid']<br> 
    17981553        1 = assoc uppercase field names. $rs-&gt;fields['ORDERID']<br> 
    17991554        2 = use native-case field names. $rs-&gt;fields['OrderID'] -- this is the  
    1800         default since ADOdb 2.90</p> 
    1801 <p>To use it, declare it before you incldue adodb.inc.php.</p> 
    1802 <p>define('ADODB_ASSOC_CASE', 2); # use native-case for ADODB_FETCH_ASSOC<br> 
    1803         include('adodb.inc.php'); </p> 
    1804 <hr> 
    1805 <h2>ADOConnection<a name="adoconnection"></a></h2> 
    1806 <p>Object that performs the connection to the database, executes SQL statements  
     1555        default since ADOdb 2.90</font></p> 
     1556<p><font>To use it, declare it before you incldue adodb.inc.php.</font></p> 
     1557<p><font>define('ADODB_ASSOC_CASE', 2); # use native-case for ADODB_FETCH_ASSOC<br> 
     1558        include('adodb.inc.php'); </font></p> 
     1559<h3><font><a name="force_type"></a>$ADODB_FORCE_TYPE</font></h3> 
     1560<p><font>See the <a href="#ADODB_FORCE_TYPE">GetUpdateSQL tutorial</a>. 
     1561</font></p> 
     1562<h3><font><a name="adodb_auto_quote"></a>$ADODB_QUOTE_FIELDNAMES</font></h3> 
     1563<p><font>Auto-quotes field names when using AutoExecute() when set to true. </font> 
     1564<p>&nbsp;</p> 
     1565<hr /> 
     1566<h2><font>ADOConnection<a name="adoconnection"></a></font></h2> 
     1567<p><font>Object that performs the connection to the database, executes SQL statements  
    18071568        and has a set of utility functions for standardising the format of SQL statements  
    1808         for issues such as concatenation and date formats.</p> 
    1809 <h3>ADOConnection Fields</h3> 
    1810 <p><b>databaseType</b>: Name of the database system we are connecting to. Eg.  
    1811         <b>odbc</b> or <b>mssql</b> or <b>mysql</b>.</p> 
    1812 <p><b>dataProvider</b>: The underlying mechanism used to connect to the database.  
    1813         Normally set to <b>native</b>, unless using <b>odbc</b> or <b>ado</b>.</p> 
    1814 <p><b>host: </b>Name of server or data source name (DSN) to connect to.</p> 
    1815 <p><b>database</b>: Name of the database or to connect to. If ado is used, it  
    1816         will hold the ado data provider.</p> 
    1817 <p><b>user</b>: Login id to connect to database. Password is not saved for security  
    1818         reasons.</p> 
    1819 <p><b>raiseErrorFn</b>: Allows you to define an error handling function. See adodb-errorhandler.inc.php  
    1820         for an example.</p> 
    1821 <p><b>debug</b>: Set to <i>true</i> to make debug statements to appear.</p> 
    1822 <p><b>concat_operator</b>: Set to '+' or '||' normally. The operator used to concatenate  
    1823         strings in SQL. Used by the <b><a href="#concat">Concat</a></b> function.</p> 
    1824 <p><b>fmtDate</b>: The format used by the <b><a href="#dbdate">DBDate</a></b>  
     1569        for issues such as concatenation and date formats.</font></p> 
     1570<h3><font>ADOConnection Fields</font></h3> 
     1571<p><font><b>databaseType</b>: Name of the database system we are connecting to. Eg.  
     1572        <b>odbc</b> or <b>mssql</b> or <b>mysql</b>.</font></p> 
     1573<p><font><b>dataProvider</b>: The underlying mechanism used to connect to the database.  
     1574        Normally set to <b>native</b>, unless using <b>odbc</b> or <b>ado</b>.</font></p> 
     1575<p><font><b>host: </b>Name of server or data source name (DSN) to connect to.</font></p> 
     1576<p><font><b>database</b>: Name of the database or to connect to. If ado is used, it  
     1577        will hold the ado data provider.</font></p> 
     1578<p><font><b>user</b>: Login id to connect to database. Password is not saved for security  
     1579        reasons.</font></p> 
     1580<p><font><b>raiseErrorFn</b>: Allows you to define an error handling function. See adodb-errorhandler.inc.php  
     1581        for an example.</font></p> 
     1582<p><font><b>debug</b>: Set to <i>true</i> to make debug statements to appear.</font></p> 
     1583<p><font><b>concat_operator</b>: Set to '+' or '||' normally. The operator used to concatenate  
     1584        strings in SQL. Used by the <b><a href="#concat">Concat</a></b> function.</font></p> 
     1585<p><font><b>fmtDate</b>: The format used by the <b><a href="#dbdate">DBDate</a></b>  
    18251586        function to send dates to the database. is '#Y-m-d#' for Microsoft Access,  
    1826         and ''Y-m-d'' for MySQL.</p> 
    1827 <p><b>fmtTimeStamp: </b>The format used by the <b><a href="#dbtimestamp">DBTimeStamp</a></b>  
    1828         function to send timestamps to the database. </p> 
    1829 <p><b>true</b>: The value used to represent true.Eg. '.T.'. for Foxpro, '1' for  
    1830         Microsoft SQL.</p> 
    1831 <p><b>false: </b> The value used to represent false. Eg. '.F.'. for Foxpro, '0'  
    1832         for Microsoft SQL.</p> 
    1833 <p><b>replaceQuote</b>: The string used to escape quotes. Eg. double single-quotes  
    1834         for Microsoft SQL, and backslash-quote for MySQL. Used by <a href="#qstr">qstr</a>.</p> 
    1835 <p><b>autoCommit</b>: indicates whether automatic commit is enabled. Default is  
    1836         true.</p> 
    1837 <p><b>charSet</b>: set the default charset to use. Currently only interbase supports  
    1838         this.</p> 
    1839 <p><b>dialect</b>: set the default sql dialect to use. Currently only interbase  
    1840         supports this.</p> 
    1841 <p><b>metaTablesSQL</b>: SQL statement to return a list of available tables. Eg.  
    1842         <i>SHOW TABLES</i> in MySQL.</p> 
    1843 <p><b>genID</b>: The latest id generated by GenID() if supported by the database.</p> 
    1844 <p><b>cacheSecs</b>: The number of seconds to cache recordsets if CacheExecute()  
    1845         or CacheSelectLimit() omit the $secs2cache parameter. Defaults to 60 minutes.</p> 
    1846 <p><b>sysDate</b>: String that holds the name of the database function to call  
    1847         to get the current date. Useful for inserts and updates.</p> 
    1848 <p><b>sysTimeStamp</b>: String that holds the name of the database function to  
    1849         call to get the current timestamp/datetime value.</p> 
    1850 <p><b>leftOuter</b>: String that holds operator for left outer join, if known.  
    1851         Otherwise set to false.</p> 
    1852 <p><b>rightOuter</b>: String that holds operator for left outer join, if known.  
    1853         Otherwise set to false.</p> 
    1854 <p><b>ansiOuter</b>: Boolean that if true indicates that ANSI style outer joins  
    1855         are permitted. Eg. <i>select * from table1 left join table2 on p1=p2.</i></p> 
    1856 <p><b>connectSID</b>: Boolean that indicates whether to treat the $database parameter  
     1587        and ''Y-m-d'' for MySQL.</font></p> 
     1588<p><font><b>fmtTimeStamp: </b>The format used by the <b><a href="#dbtimestamp">DBTimeStamp</a></b>  
     1589        function to send timestamps to the database. </font></p> 
     1590<p><font><b>true</b>: The value used to represent true.Eg. '.T.'. for Foxpro, '1' for  
     1591        Microsoft SQL.</font></p> 
     1592<p><font><b>false: </b> The value used to represent false. Eg. '.F.'. for Foxpro, '0'  
     1593        for Microsoft SQL.</font></p> 
     1594<p><font><b>replaceQuote</b>: The string used to escape quotes. Eg. double single-quotes  
     1595        for Microsoft SQL, and backslash-quote for MySQL. Used by <a href="#qstr">qstr</a>.</font></p> 
     1596<p><font><b>autoCommit</b>: indicates whether automatic commit is enabled. Default is  
     1597        true.</font></p> 
     1598<p><font><b>charSet</b>: set the default charset to use. Currently only interbase/firebird supports  
     1599        this.</font></p> 
     1600<p><font><b>dialect</b>: set the default sql dialect to use. Currently only interbase/firebird  
     1601        supports this.</font></p> 
     1602        <p><font><b>role</b>: set the role. Currently only interbase/firebird  
     1603        supports this.</font></p> 
     1604<p><font><b>metaTablesSQL</b>: SQL statement to return a list of available tables. Eg.  
     1605        <i>SHOW TABLES</i> in MySQL.</font></p> 
     1606<p><font><b>genID</b>: The latest id generated by GenID() if supported by the database.</font></p> 
     1607<p><font><b>cacheSecs</b>: The number of seconds to cache recordsets if CacheExecute()  
     1608        or CacheSelectLimit() omit the $secs2cache parameter. Defaults to 60 minutes.</font></p> 
     1609<p><font><b>sysDate</b>: String that holds the name of the database function to call  
     1610        to get the current date. Useful for inserts and updates.</font></p> 
     1611<p><font><b>sysTimeStamp</b>: String that holds the name of the database function to  
     1612        call to get the current timestamp/datetime value.</font></p> 
     1613<p><font><b>leftOuter</b>: String that holds operator for left outer join, if known.  
     1614        Otherwise set to false.</font></p> 
     1615<p><font><b>rightOuter</b>: String that holds operator for left outer join, if known.  
     1616        Otherwise set to false.</font></p> 
     1617<p><font><b>ansiOuter</b>: Boolean that if true indicates that ANSI style outer joins  
     1618        are permitted. Eg. <i>select * from table1 left join table2 on p1=p2.</i></font></p> 
     1619<p><font><b>connectSID</b>: Boolean that indicates whether to treat the $database parameter  
    18571620        in connects as the SID for the oci8 driver. Defaults to false. Useful for  
    1858         Oracle 8.0.5 and earlier.</p> 
    1859 <p><b>autoRollback</b>: Persistent connections are auto-rollbacked in PConnect(  
    1860         ) if this is set to true. Default is false.</p> 
    1861 <hr> 
    1862 <h3>ADOConnection Main Functions</h3> 
    1863 <p><b>ADOConnection( )</b></p> 
    1864 <p>Constructor function. Do not call this directly. Use ADONewConnection( ) instead.</p> 
    1865 <p><b>Connect<a name="connect"></a>($host,[$user],[$password],[$database])</b></p> 
    1866 <p>Non-persistent connect to data source or server $<b>host</b>, using userid  
     1621        Oracle 8.0.5 and earlier.</font></p> 
     1622<p><font><b>autoRollback</b>: Persistent connections are auto-rollbacked in PConnect(  
     1623        ) if this is set to true. Default is false.</font></p> 
     1624<hr /> 
     1625<h3><font>ADOConnection Main Functions</font></h3> 
     1626<p><font><b>ADOConnection( )</b></font></p> 
     1627<p><font>Constructor function. Do not call this directly. Use ADONewConnection( ) instead.</font></p> 
     1628<p><font><b>Connect<a name="connect"></a>($host,[$user],[$password],[$database])</b></font></p> 
     1629<p><font>Non-persistent connect to data source or server $<b>host</b>, using userid  
    18671630        $<b>user </b>and password $<b>password</b>. If the server supports multiple  
    1868         databases, connect to database $<b>database</b>. </p> 
    1869 <p>Returns true/false depending on connection success. Since 4.23, null is returned if the extension is not loaded.</p> 
    1870 <p>ADO Note: If you are using a Microsoft ADO and not OLEDB, you can set the $database  
    1871         parameter to the OLEDB data provider you are using.</p> 
    1872 <p>PostgreSQL: An alternative way of connecting to the database is to pass the  
     1631        databases, connect to database $<b>database</b>. </font></p> 
     1632<p><font>Returns true/false depending on connection success. Since 4.23, null is returned if the extension is not loaded.</font></p> 
     1633<p><font>ADO Note: If you are using a Microsoft ADO and not OLEDB, you can set the $database  
     1634        parameter to the OLEDB data provider you are using.</font></p> 
     1635<p><font>PostgreSQL: An alternative way of connecting to the database is to pass the  
    18731636        standard PostgreSQL connection string in the first parameter $host, and the  
    1874         other parameters will be ignored.</p> 
    1875 <p>For Oracle and Oci8, there are two ways to connect. First is to use the TNS  
     1637        other parameters will be ignored.</font></p> 
     1638<p><font>For Oracle and Oci8, there are two ways to connect. First is to use the TNS  
    18761639        name defined in your local tnsnames.ora (or ONAMES or HOSTNAMES). Place the  
    18771640        name in the $database field, and set the $host field to false. Alternatively,  
    18781641        set $host to the server, and $database to the database SID, this bypassed  
    18791642        tnsnames.ora.  
    1880 <p>Examples:  
    1881 <pre> # $oraname in tnsnames.ora/ONAMES/HOSTNAMES 
    1882  $conn->Connect(false, 'scott', 'tiger', $oraname);  
    1883  $conn->Connect('server:1521', 'scott', 'tiger', 'ServiceName'); # bypass tnsnames.ora</pre> 
    1884 <p>There are many examples of connecting to a database. 
    1885 See  <a href=#connect_ex>Connection Examples</a>, <a href="http://php.weblogs.com/adodb">php.weblogs.com/ADOdb</a>,  
    1886         and in the testdatabases.inc.php file included in the release.</p> 
    1887  
    1888 <p><b>PConnect<a name="pconnect"></a>($host,[$user],[$password],[$database])</b></p> 
    1889 <p>Persistent connect to data source or server $<b>host</b>, using userid $<b>user</b>  
     1643</font></p><p><font>Examples:  
     1644</font></p><pre><font> # $oraname in tnsnames.ora/ONAMES/HOSTNAMES<br> $conn-&gt;Connect(false, 'scott', 'tiger', $oraname); <br> $conn-&gt;Connect('server:1521', 'scott', 'tiger', 'ServiceName'); # bypass tnsnames.ora</font></pre> 
     1645<p><font>There are many examples of connecting to a database. 
     1646See  <a href="#connect_ex">Connection Examples</a> for many examples. 
     1647 
     1648</font></p><p><font><b>PConnect<a name="pconnect"></a>($host,[$user],[$password],[$database])</b></font></p> 
     1649<p><font>Persistent connect to data source or server $<b>host</b>, using userid $<b>user</b>  
    18901650        and password $<b>password</b>. If the server supports multiple databases,  
    1891         connect to database $<b>database</b>.</p> 
    1892 <p>We now perform a rollback on persistent connection for selected databases since  
     1651        connect to database $<b>database</b>.</font></p> 
     1652<p><font>We now perform a rollback on persistent connection for selected databases since  
    18931653        2.21, as advised in the PHP manual. See change log or source code for which  
    18941654        databases are affected.  
    1895 <p>Returns true/false depending on connection. Since 4.23, null is returned if the extension is not loaded. 
    1896 See Connect( ) above for more info.</p> 
    1897 <p>Since ADOdb 2.21, we also support autoRollback. If you set:</p> 
    1898 </font>  
    1899 <pre> $conn = &amp;NewADOConnection('mysql'); 
    1900  $conn-&gt;autoRollback = true; # default is false 
    1901  $conn-&gt;PConnect(...); # rollback here</pre> 
     1655</font></p><p><font>Returns true/false depending on connection. Since 4.23, 0 is returned if the extension is not loaded. 
     1656See Connect( ) above for more info.</font></p> 
     1657<p><font>Since ADOdb 2.21, we also support autoRollback. If you set:</font></p> 
     1658  
     1659<pre> $conn = &amp;NewADOConnection('mysql');<br> $conn-&gt;autoRollback = true; # default is false<br> $conn-&gt;PConnect(...); # rollback here</pre> 
    19021660<p> Then when doing a persistent connection with PConnect( ), ADOdb will  
    19031661  perform a rollback first. This is because it is documented that PHP is  
     
    19051663  persistent connections are used. This is implemented in Oracle,  
    19061664  MySQL, PgSQL, MSSQL, ODBC currently.  
    1907 <p>Since ADOdb 3.11, you can force non-persistent  
     1665</p><p>Since ADOdb 3.11, you can force non-persistent  
    19081666connections even if PConnect is called by defining the constant  
    19091667ADODB_NEVER_PERSIST  before you call PConnect. 
    1910 <p> 
     1668</p><p> 
    19111669Since 4.23, null is returned if the extension is not loaded. 
    1912 <p><b>NConnect<a name="nconnect"></a>($host,[$user],[$password],[$database])</b></p> 
     1670</p><p><b>NConnect<a name="nconnect"></a>($host,[$user],[$password],[$database])</b></p> 
    19131671<p>Always force a new connection. In contrast, PHP sometimes reuses connections  
    19141672        when you use Connect() or PConnect(). Currently works only on mysql (PHP 4.3.0  
    19151673        or later), postgresql and oci8-derived drivers. For other drivers, NConnect() works like  
    1916         Connect().  
    1917 <font color="#000000">  
    1918 <p><b>Execute<a name="execute"></a>($sql,$inputarr=false)</b></p> 
    1919 <p>Execute SQL statement $<b>sql</b> and return derived class of ADORecordSet  
     1674        Connect().</p> 
     1675<p><font><b>IsConnected( )<a name="isconnected"></a></b></font></p> 
     1676<p> 
     1677<font>Returns true if connected to database. Added in 4.53. 
     1678 
     1679</font></p><p><font><b>Execute<a name="execute"></a>($sql,$inputarr=false)</b></font></p> 
     1680<p><font>Execute SQL statement $<b>sql</b> and return derived class of ADORecordSet  
    19201681        if successful. Note that a record set is always returned on success, even  
    19211682        if we are executing an insert or update statement. You can also pass in $sql a statement prepared  
    1922         in <a href=#prepare>Prepare()</a>.</p> 
    1923 <p>Returns derived class of ADORecordSet. Eg. if connecting via mysql, then ADORecordSet_mysql  
     1683        in <a href="#prepare">Prepare()</a>.</font></p> 
     1684<p><font>Returns derived class of ADORecordSet. Eg. if connecting via mysql, then ADORecordSet_mysql  
    19241685        would be returned. False is returned if there was an error in executing the  
    1925         sql.</p> 
    1926 <p>The $inputarr parameter can be used for binding variables to parameters. Below  
    1927         is an Oracle example:</p> 
    1928 <pre> 
    1929  $conn->Execute("SELECT * FROM TABLE WHERE COND=:val", array('val'=> $val)); 
    1930  </pre> 
    1931 <p>Another example, using ODBC,which uses the ? convention:</p> 
    1932 <pre> 
    1933   $conn->Execute("SELECT * FROM TABLE WHERE COND=?", array($val)); 
    1934 </pre> 
    1935 <a name="binding"></a> 
    1936 <i>Binding variables</i><p> 
    1937 Variable binding speeds the compilation and caching of SQL statements, leading  
     1686        sql.</font></p> 
     1687<p><font>The $inputarr parameter can be used for binding variables to parameters. Below  
     1688        is an Oracle example:</font></p> 
     1689<pre><font> $conn-&gt;Execute("SELECT * FROM TABLE WHERE COND=:val", array('val'=&gt; $val));<br> </font></pre> 
     1690<p><font>Another example, using ODBC,which uses the ? convention:</font></p> 
     1691<pre><font>  $conn-&gt;Execute("SELECT * FROM TABLE WHERE COND=?", array($val));<br></font></pre> 
     1692<font><a name="binding"></a> 
     1693<i>Binding variables</i></font><p> 
     1694<font>Variable binding speeds the compilation and caching of SQL statements, leading  
    19381695to higher performance. Currently Oracle, Interbase and ODBC supports variable binding.  
    19391696Interbase/ODBC style ? binding is emulated in databases that do not support binding.  
    19401697Note that you do not have to quote strings if you use binding. 
    1941 <p> Variable binding in the odbc, interbase and oci8po drivers.  
    1942 <pre> 
    1943 $rs = $db->Execute('select * from table where val=?', array('10')); 
    1944 </pre> 
    1945 Variable binding in the oci8 driver:  
    1946 <pre> 
    1947 $rs = $db->Execute('select name from table where val=:key',  
    1948   array('key' => 10)); 
    1949 </pre> 
    1950 <a name="bulkbind"></a> 
     1698</font></p><p><font> Variable binding in the odbc, interbase and oci8po drivers.  
     1699</font></p><pre><font>$rs = $db-&gt;Execute('select * from table where val=?', array('10'));<br></font></pre> 
     1700<font>Variable binding in the oci8 driver:  
     1701</font><pre><font>$rs = $db-&gt;Execute('select name from table where val=:key', <br>  array('key' =&gt; 10));<br></font></pre> 
     1702<font><a name="bulkbind"></a> 
    19511703<i>Bulk binding</i> 
    1952 <p>Since ADOdb 3.80, we support bulk binding in Execute(), in which you pass in a 2-dimensional array to 
     1704</font><p><font>Since ADOdb 3.80, we support bulk binding in Execute(), in which you pass in a 2-dimensional array to 
    19531705be bound to an INSERT/UPDATE or DELETE statement. 
    1954 <pre> 
    1955 $arr = array( 
    1956         array('Ahmad',32), 
    1957         array('Zulkifli', 24), 
    1958         array('Rosnah', 21) 
    1959         ); 
    1960 $ok = $db->Execute('insert into table (name,age) values (?,?)',$arr); 
    1961 </pre> 
    1962 <p>This provides very high performance as the SQL statement is prepared first.  
     1706</font></p><pre><font>$arr = array(<br> array('Ahmad',32),<br>  array('Zulkifli', 24),<br>      array('Rosnah', 21)<br> );<br>$ok = $db-&gt;Execute('insert into table (name,age) values (?,?)',$arr);<br></font></pre> 
     1707<p><font>This provides very high performance as the SQL statement is prepared first.  
    19631708The prepared statement is executed repeatedly for each array row until all rows are completed,  
    19641709or until the first error. Very useful for importing data. 
    19651710 
    1966 <p><b>CacheExecute<a name="cacheexecute"></a>([$secs2cache,]$sql,$inputarr=false)</b></p> 
    1967 <p>Similar to Execute, except that the recordset is cached for $secs2cache seconds  
     1711</font></p><p><font><b>CacheExecute<a name="cacheexecute"></a>([$secs2cache,]$sql,$inputarr=false)</b></font></p> 
     1712<p><font>Similar to Execute, except that the recordset is cached for $secs2cache seconds  
    19681713        in the $ADODB_CACHE_DIR directory, and $inputarr only accepts 1-dimensional arrays.  
    19691714        If CacheExecute() is called again with the same $sql, $inputarr,  
    19701715        and also the same database, same userid, and the cached recordset  
    19711716        has not expired, the cached recordset is returned.  
    1972 <pre> 
    1973   include('adodb.inc.php');  
    1974   include('tohtml.inc.php'); 
    1975   $ADODB_<b>CACHE_DIR</b> = '/usr/local/ADOdbcache'; 
    1976   $conn = &ADONewConnection('mysql');  
    1977   $conn->PConnect('localhost','userid','password','database'); 
    1978   $rs = $conn-><b>CacheExecute</b>(15, 'select * from table'); # cache 15 secs 
    1979   rs2html($rs); /* recordset to html table */   
    1980 </pre> 
    1981 <p> Alternatively, since ADOdb 1.80, the $secs2cache parameter is optional:</p> 
    1982 <pre>   $conn-&gt;Connect(...); 
    1983         $conn-&gt;cacheSecs = 3600*24; // cache 24 hours 
    1984         $rs = $conn-&gt;CacheExecute('select * from table'); 
    1985 </pre> 
    1986 If $secs2cache is omitted, we use the value  
     1717</font></p><pre><font>  include('adodb.inc.php'); <br>  include('tohtml.inc.php');<br>  $ADODB_<b>CACHE_DIR</b> = '/usr/local/ADOdbcache';<br>  $conn = &amp;ADONewConnection('mysql'); <br>  $conn-&gt;PConnect('localhost','userid','password','database');<br>  $rs = $conn-&gt;<b>CacheExecute</b>(15, 'select * from table'); # cache 15 secs<br>  rs2html($rs); /* recordset to html table */  <br></font></pre> 
     1718<p><font> Alternatively, since ADOdb 1.80, the $secs2cache parameter is optional:</font></p> 
     1719<pre><font>     $conn-&gt;Connect(...);<br>     $conn-&gt;cacheSecs = 3600*24; // cache 24 hours<br>    $rs = $conn-&gt;CacheExecute('select * from table');<br></font></pre> 
     1720<font>If $secs2cache is omitted, we use the value  
    19871721in $connection-&gt;cacheSecs (default is 3600 seconds, or 1 hour). Use CacheExecute()  
    19881722only with SELECT statements.  
    1989 <p>Performance note: I have done some benchmarks and found that they vary so greatly  
     1723</font><p><font>Performance note: I have done some benchmarks and found that they vary so greatly  
    19901724        that it's better to talk about when caching is of benefit. When your database  
    19911725        server is <i>much slower </i>than your Web server or the database is <i>very  
    19921726        overloaded </i>then ADOdb's caching is good because it reduces the load on  
    19931727        your database server. If your database server is lightly loaded or much faster  
    1994         than your Web server, then caching could actually reduce performance. </p> 
    1995 <p><b>ExecuteCursor<a name="executecursor"></a>($sql,$cursorName='rs',$parameters=false)</b></p> 
    1996 <p>Execute an Oracle stored procedure, and returns an Oracle REF cursor variable as  
     1728        than your Web server, then caching could actually reduce performance. </font></p> 
     1729<p><font><b>ExecuteCursor<a name="executecursor"></a>($sql,$cursorName='rs',$parameters=false)</b></font></p> 
     1730<p><font>Execute an Oracle stored procedure, and returns an Oracle REF cursor variable as  
    19971731        a regular ADOdb recordset. Does not work with any other database except oci8.  
    19981732        Thanks to Robert Tuttle for the design. 
     1733</font></p><pre><font>    $db = ADONewConnection("oci8"); <br>    $db-&gt;Connect("foo.com:1521", "uid", "pwd", "FOO"); <br>    $rs = $db-&gt;ExecuteCursor("begin :cursorvar := getdata(:param1); end;", <br>                                  'cursorvar',<br>                                        array('param1'=&gt;10)); <br>    # $rs is now just like any other ADOdb recordset object<br>    rs2html($rs);</font></pre> 
     1734<p><font>ExecuteCursor() is a helper function that does the following internally:  
     1735</font></p><pre><font>  $stmt = $db-&gt;Prepare("begin :cursorvar := getdata(:param1); end;", true); <br>       $db-&gt;Parameter($stmt, $cur, 'cursorvar', false, -1, OCI_B_CURSOR);<br>       $rs = $db-&gt;Execute($stmt,$bindarr);<br></font></pre> 
     1736<p><font>ExecuteCursor only accepts 1 out parameter. So if you have 2 out parameters, use: 
     1737</font></p><pre><font>  $vv = 'A%';<br> $stmt = $db-&gt;PrepareSP("BEGIN list_tabs(:crsr,:tt); END;");<br>      $db-&gt;OutParameter($stmt, $cur, 'crsr', -1, OCI_B_CURSOR);<br>        $db-&gt;OutParameter($stmt, $vv, 'tt', 32); # return varchar(32)<br>    $arr = $db-&gt;GetArray($stmt);<br>     print_r($arr);<br>      echo " val = $vv"; ## outputs 'TEST'<br></font></pre> 
     1738<font>for the following PL/SQL: 
     1739</font><pre><font>      TYPE TabType IS REF CURSOR RETURN TAB%ROWTYPE;<br><br>  PROCEDURE list_tabs(tabcursor IN OUT TabType,tablenames IN OUT VARCHAR) IS<br>  BEGIN<br>               OPEN tabcursor FOR SELECT * FROM TAB WHERE tname LIKE tablenames;<br>           tablenames := 'TEST';<br>       END list_tabs;<br></font></pre> 
     1740<p><font><b>SelectLimit<a name="selectlimit"></a>($sql,$numrows=-1,$offset=-1,$inputarr=false)</b></font></p> 
     1741<p><font>Returns a recordset if successful. Returns false otherwise. Performs a select  
     1742        statement, simulating PostgreSQL's SELECT statement, LIMIT $numrows OFFSET  
     1743        $offset clause.</font></p> 
     1744<p><font>In PostgreSQL, SELECT * FROM TABLE LIMIT 3 will return the first 3 records  
     1745        only. The equivalent is <code>$connection-&gt;SelectLimit('SELECT * FROM TABLE',3)</code>.  
     1746        This functionality is simulated for databases that do not possess this feature.</font></p> 
     1747<p><font>And SELECT * FROM TABLE LIMIT 3 OFFSET 2 will return records 3, 4 and 5 (eg.  
     1748        after record 2, return 3 rows). The equivalent in ADOdb is <code>$connection-&gt;SelectLimit('SELECT  
     1749        * FROM TABLE',3,2)</code>.</font></p> 
     1750<p><font>Note that this is the <i>opposite</i> of MySQL's LIMIT clause. You can also  
     1751        set <code>$connection-&gt;SelectLimit('SELECT * FROM TABLE',-1,10)</code> to  
     1752        get rows 11 to the last row.</font></p> 
     1753<p><font>The last parameter $inputarr is for databases that support variable binding  
     1754        such as Oracle oci8. This substantially reduces SQL compilation overhead.  
     1755        Below is an Oracle example:</font></p> 
     1756<pre><font> $conn-&gt;SelectLimit("SELECT * FROM TABLE WHERE COND=:val", 100,-1,array('val'=&gt; $val));<br> </font></pre> 
     1757<p><font>The oci8po driver (oracle portable driver) uses the more standard bind variable  
     1758        of ?:  
     1759</font></p><pre><font> $conn-&gt;SelectLimit("SELECT * FROM TABLE WHERE COND=?", 100,-1,array('val'=&gt; $val));<br></font></pre> 
     1760<p><font>  
     1761</font></p><p><font>Ron Wilson reports that SelectLimit does not work with UNIONs.  
     1762</font></p><p><font><b>CacheSelectLimit<a name="cacheselectlimit"></a>([$secs2cache,] $sql, $numrows=-1,$offset=-1,$inputarr=false)</b></font></p> 
     1763<p><font>Similar to SelectLimit, except that the recordset returned is cached for $secs2cache  
     1764        seconds in the $ADODB_CACHE_DIR directory. </font></p> 
     1765<p><font>Since 1.80, $secs2cache has been optional, and you can define the caching time  
     1766        in $connection-&gt;cacheSecs.</font></p> 
     1767  
     1768<pre><font>     $conn-&gt;Connect(...);<br>   $conn-&gt;cacheSecs = 3600*24; // cache 24 hours<br>      $rs = $conn-&gt;CacheSelectLimit('select * from table',10);</font></pre> 
     1769<font>  
     1770</font><p><font><b>CacheFlush<a name="cacheflush"></a>($sql=false,$inputarr=false)</b></font></p> 
     1771<p><font>Flush (delete) any cached recordsets for the SQL statement $sql in $ADODB_CACHE_DIR.  
     1772</font></p><p><font>If no parameter is passed in, then all adodb_*.cache files are deleted.  
     1773</font></p> 
     1774  <p>CacheSelectLimit() rewrites the SQL query, so you won't be able to pass the SQL to CacheFlush. In this case, 
     1775   to flush the cached SQL recordset returned by CacheSelectLimit(), set $secs2cache to -1: 
    19991776<pre> 
    2000     $db = ADONewConnection("oci8");  
    2001     $db->Connect("foo.com:1521", "uid", "pwd", "FOO");  
    2002     $rs = $db->ExecuteCursor("begin :cursorvar := getdata(:param1); end;",  
    2003                                         'cursorvar', 
    2004                                         array('param1'=>10));  
    2005     # $rs is now just like any other ADOdb recordset object<br>    rs2html($rs);</pre> 
    2006 <p>ExecuteCursor() is a helper function that does the following internally:  
    2007 <pre> 
    2008         $stmt = $db->Prepare("begin :cursorvar := getdata(:param1); end;", true);  
    2009         $db->Parameter($stmt, $cur, 'cursorvar', false, -1, OCI_B_CURSOR); 
    2010         $rs = $db->Execute($stmt,$bindarr); 
     1777        $db->CacheSelectLimit(-1, $sql, $nrows); 
    20111778</pre> 
    2012 <p>ExecuteCursor only accepts 1 out parameter. So if you have 2 out parameters, use: 
    2013 <pre> 
    2014         $vv = 'A%'; 
    2015         $stmt = $db->PrepareSP("BEGIN list_tabs(:crsr,:tt); END;"); 
    2016         $db->OutParameter($stmt, $cur, 'crsr', -1, OCI_B_CURSOR); 
    2017         $db->OutParameter($stmt, $vv, 'tt', 32); # return varchar(32) 
    2018         $arr = $db->GetArray($stmt); 
    2019         print_r($arr); 
    2020         echo " val = $vv"; ## outputs 'TEST' 
    2021 </pre> 
    2022 for the following PL/SQL: 
    2023 <pre> 
    2024         TYPE TabType IS REF CURSOR RETURN TAB%ROWTYPE; 
    2025  
    2026         PROCEDURE list_tabs(tabcursor IN OUT TabType,tablenames IN OUT VARCHAR) IS 
    2027         BEGIN 
    2028                 OPEN tabcursor FOR SELECT * FROM TAB WHERE tname LIKE tablenames; 
    2029                 tablenames := 'TEST'; 
    2030         END list_tabs; 
    2031 </pre> 
    2032 <p><b>SelectLimit<a name="selectlimit"></a>($sql,$numrows=-1,$offset=-1,$inputarr=false)</b></p> 
    2033 <p>Returns a recordset if successful. Returns false otherwise. Performs a select  
    2034         statement, simulating PostgreSQL's SELECT statement, LIMIT $numrows OFFSET  
    2035         $offset clause.</p> 
    2036 <p>In PostgreSQL, SELECT * FROM TABLE LIMIT 3 will return the first 3 records  
    2037         only. The equivalent is <code>$connection->SelectLimit('SELECT * FROM TABLE',3)</code>.  
    2038         This functionality is simulated for databases that do not possess this feature.</p> 
    2039 <p>And SELECT * FROM TABLE LIMIT 3 OFFSET 2 will return records 3, 4 and 5 (eg.  
    2040         after record 2, return 3 rows). The equivalent in ADOdb is <code>$connection->SelectLimit('SELECT  
    2041         * FROM TABLE',3,2)</code>.</p> 
    2042 <p>Note that this is the <i>opposite</i> of MySQL's LIMIT clause. You can also  
    2043         set <code>$connection->SelectLimit('SELECT * FROM TABLE',-1,10)</code> to  
    2044         get rows 11 to the last row.</p> 
    2045 <p>The last parameter $inputarr is for databases that support variable binding  
    2046         such as Oracle oci8. This substantially reduces SQL compilation overhead.  
    2047         Below is an Oracle example:</p> 
    2048 <pre> 
    2049  $conn->SelectLimit("SELECT * FROM TABLE WHERE COND=:val", 100,-1,array('val'=> $val)); 
    2050  </pre> 
    2051 <p>The oci8po driver (oracle portable driver) uses the more standard bind variable  
    2052         of ?:  
    2053 <pre> 
    2054  $conn->SelectLimit("SELECT * FROM TABLE WHERE COND=?", 100,-1,array('val'=> $val)); 
    2055 </pre> 
    2056 <p>  
    2057 <p>Ron Wilson reports that SelectLimit does not work with UNIONs.  
    2058 <p><b>CacheSelectLimit<a name="cacheselectlimit"></a>([$secs2cache,] $sql, $numrows=-1,$offset=-1,$inputarr=false)</b></p> 
    2059 <p>Similar to SelectLimit, except that the recordset returned is cached for $secs2cache  
    2060         seconds in the $ADODB_CACHE_DIR directory. </p> 
    2061 <p>Since 1.80, $secs2cache has been optional, and you can define the caching time  
    2062         in $connection-&gt;cacheSecs.</p> 
    2063 </font>  
    2064 <pre><font color="#000000">     $conn-&gt;Connect(...); 
    2065    $conn-&gt;cacheSecs = 3600*24; // cache 24 hours 
    2066         $rs = $conn-&gt;CacheSelectLimit('select * from table',10);</font></pre> 
    2067 <font color="#000000">  
    2068 <p><b>CacheFlush<a name="cacheflush"></a>($sql=false,$inputarr=false)</b></p> 
    2069 <p>Flush (delete) any cached recordsets for the SQL statement $sql in $ADODB_CACHE_DIR.  
    2070 <p>If no parameter is passed in, then all adodb_*.cache files are deleted.  
    2071 <p> If you want to flush all cached recordsets manually, execute the following  
     1779<p><font> If you want to flush all cached recordsets manually, execute the following  
    20721780        PHP code (works only under Unix): <br> 
    2073         <code> &nbsp; system(&quot;rm -f `find &quot;.$ADODB_CACHE_DIR.&quot; -name  
    2074         adodb_*.cache`&quot;);</code></p> 
    2075 <p>For general cleanup of all expired files, you should use <a href="http://www.superscripts.com/tutorial/crontab.html">crontab</a>  
     1781        <code> &nbsp; system("rm -f `find ".$ADODB_CACHE_DIR." -name  
     1782        adodb_*.cache`");</code></font></p> 
     1783<p><font>For general cleanup of all expired files, you should use <a href="http://www.superscripts.com/tutorial/crontab.html">crontab</a>  
    20761784        on Unix, or at.exe on Windows, and a shell script similar to the following:<font face="Courier New, Courier, mono"><br> 
    20771785        #------------------------------------------------------ <br> 
    20781786        # This particular example deletes files in the TMPPATH <br> 
    2079         # directory with the string &quot;.cache&quot; in their name that <br> 
     1787        # directory with the string ".cache" in their name that <br> 
    20801788        # are more than 7 days old. <br> 
    20811789        #------------------------------------------------------ <br> 
    20821790        AGED=7 <br> 
    2083         find ${TMPPATH} -mtime +$AGED | grep &quot;\.cache&quot; | xargs rm -f <br> 
    2084         </font> </p> 
    2085 <p><b>MetaError<a name="metaerror"></a>($errno=false)</b></p> 
    2086 <p>Returns a virtualized error number, based on PEAR DB's error number system. You might 
     1791        find ${TMPPATH} -mtime +$AGED | grep "\.cache" | xargs rm -f <br> 
     1792        </font> </font></p> 
     1793<p><font><b>MetaError<a name="metaerror"></a>($errno=false)</b></font></p> 
     1794<p><font>Returns a virtualized error number, based on PEAR DB's error number system. You might 
    20871795need to include adodb-error.inc.php before you call this function. The parameter $errno 
    20881796is the native error number you want to convert. If you do not pass any parameter, MetaError 
    20891797will call ErrorNo() for you and convert it. If the error number cannot be virtualized, MetaError  
    2090 will return -1 (DB_ERROR).</p> 
    2091  
    2092 <p><b>MetaErrorMsg<a name="metaerrormsg"></a>($errno)</b></p> 
    2093 <p>Pass the error number returned by MetaError() for the equivalent textual error message.</p> 
    2094 <p><b>ErrorMsg<a name="errormsg"></a>()</b></p> 
    2095 <p>Returns the last status or error message. The error message is reset after every  
     1798will return -1 (DB_ERROR).</font></p> 
     1799 
     1800<p><font><b>MetaErrorMsg<a name="metaerrormsg"></a>($errno)</b></font></p> 
     1801<p><font>Pass the error number returned by MetaError() for the equivalent textual error message.</font></p> 
     1802<p><font><b>ErrorMsg<a name="errormsg"></a>()</b></font></p> 
     1803<p><font>Returns the last status or error message. The error message is reset after every  
    20961804call to Execute().  
    2097 <p> 
    2098 This can return a string even if  
     1805</font></p><p> 
     1806<font>This can return a string even if  
    20991807        no error occurs. In general you do not need to call this function unless an  
    2100         ADOdb function returns false on an error. </p> 
    2101 <p>Note: If <b>debug</b> is enabled, the SQL error message is always displayed  
    2102         when the <b>Execute</b> function is called.</p> 
    2103 <p><b>ErrorNo<a name="errorno"></a>()</b></p> 
    2104 <p>Returns the last error number. The error number is reset after every call to Execute().  
     1808        ADOdb function returns false on an error. </font></p> 
     1809<p><font>Note: If <b>debug</b> is enabled, the SQL error message is always displayed  
     1810        when the <b>Execute</b> function is called.</font></p> 
     1811<p><font><b>ErrorNo<a name="errorno"></a>()</b></font></p> 
     1812<p><font>Returns the last error number. The error number is reset after every call to Execute().  
    21051813If 0 is returned, no error occurred. 
    2106 <p> 
    2107 Note that old versions of PHP (pre 4.0.6) do  
     1814</font></p><p> 
     1815<font>Note that old versions of PHP (pre 4.0.6) do  
    21081816        not support error number for ODBC. In general you do not need to call this  
    2109         function unless an ADOdb function returns false on an error.</p> 
    2110 </font> 
    2111 <p><font color="#000000"><b>SetFetchMode<a name="setfetchmode"></a>($mode)</b></font></p> 
    2112 <p><font color="#000000">Sets the current fetch mode for the connection and stores  
     1817        function unless an ADOdb function returns false on an error.</font></p> 
     1818<p><font><b>IgnoreErrors<a name="ignoreerrors"></a>($saveErrHandlers)</b></font></p> 
     1819<p>Allows you to ignore errors so that StartTrans()/CompleteTrans() is not affected, nor is the default error handler called if an error occurs. 
     1820Useful when you want to check if a field or table exists in a database without invoking an error if it does not exist. 
     1821<p>Usage: 
     1822<pre> 
     1823$saveErrHandlers = $conn->IgnoreErrors(); 
     1824$rs = $conn->Execute("select field from some_table_that_might_not_exist"); 
     1825$conn->IgnoreErrors($saveErrHandlers); 
     1826</pre> 
     1827<p>Warning: do not call StartTrans()/CompleteTrans() inside a code block that is using IgnoreErrors(). 
     1828<p><font><b>SetFetchMode<a name="setfetchmode"></a>($mode)</b></font></p> 
     1829<p><font>Sets the current fetch mode for the connection and stores  
    21131830        it in $db-&gt;fetchMode. Legal modes are ADODB_FETCH_ASSOC and ADODB_FETCH_NUM.  
    21141831        For more info, see <a href="#adodb_fetch_mode">$ADODB_FETCH_MODE</a>.</font></p> 
    2115 <p><font color="#000000">Returns the previous fetch mode, which could be false  
     1832<p><font>Returns the previous fetch mode, which could be false  
    21161833        if SetFetchMode( ) has not been called before.</font></p> 
    2117 <font color="#000000">  
    2118 <p><b>CreateSequence<a name="createseq"></a>($seqName = 'adodbseq',$startID=1)</b></p> 
    2119 <p>Create a sequence. The next time GenID( ) is called, the value returned will  
     1834<font>  
     1835</font><p><font><b>CreateSequence<a name="createseq"></a>($seqName = 'adodbseq',$startID=1)</b></font></p> 
     1836<p><font>Create a sequence. The next time GenID( ) is called, the value returned will  
    21201837        be $startID. Added in 2.60.  
    2121 <p><b>DropSequenceD<a name="dropseq"></a>($seqName = 'adodbseq')</b></p> 
    2122 <p>Delete a sequence. Added in 2.60.  
    2123 <p><b>GenID<a name="genid"></a>($seqName = 'adodbseq',$startID=1)</b></p> 
    2124 <p>Generate a sequence number . Works for interbase,  
     1838</font></p><p><font><b>DropSequence<a name="dropseq"></a>($seqName = 'adodbseq')</b></font></p> 
     1839<p><font>Delete a sequence. Added in 2.60.  
     1840</font></p><p><font><b>GenID<a name="genid"></a>($seqName = 'adodbseq',$startID=1)</b></font></p> 
     1841<p><font>Generate a sequence number . Works for interbase,  
    21251842        mysql, postgresql, oci8, oci8po, mssql, ODBC based (access,vfp,db2,etc) drivers  
    21261843        currently. Uses $seqName as the name of the sequence. GenID() will automatically  
    21271844        create the sequence for you if it does not exist (provided the userid has  
    21281845        permission to do so). Otherwise you will have to create the sequence yourself.  
    2129 <p> If your database driver emulates sequences, the name of the table is the sequence  
     1846</font></p><p><font> If your database driver emulates sequences, the name of the table is the sequence  
    21301847        name. The table has one column, "id" which should be of type integer, or if  
    21311848        you need something larger - numeric(16).  
    2132 <p> For ODBC and databases that do not support sequences natively (eg mssql, mysql),  
     1849</font></p><p><font> For ODBC and databases that do not support sequences natively (eg mssql, mysql),  
    21331850        we create a table for each sequence. If the sequence has not been defined  
    2134         earlier, it is created with the starting value set in $startID.</p> 
    2135 <p>Note that the mssql driver's GenID() before 1.90 used to generate 16 byte GUID's.</p> 
    2136 <p><b>UpdateBlob<a name="updateblob"></a>($table,$column,$val,$where)</b></p> 
    2137 Allows you to store a blob (in $val) into $table into $column in a row at $where.  
    2138 <p> Usage:  
    2139 <p>  
    2140 <pre> 
    2141         # for oracle 
    2142         $conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, empty_blob())'); 
    2143         $conn->UpdateBlob('blobtable','blobcol',$blobvalue,'id=1'); 
    2144          
    2145         # non oracle databases 
    2146         $conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, null)'); 
    2147         $conn->UpdateBlob('blobtable','blobcol',$blobvalue,'id=1'); 
    2148 </pre> 
    2149 <p> Returns true if succesful, false otherwise. Supported by MySQL, PostgreSQL,  
     1851        earlier, it is created with the starting value set in $startID.</font></p> 
     1852<p><font>Note that the mssql driver's GenID() before 1.90 used to generate 16 byte GUID's.</font></p> 
     1853<p><font><b>UpdateBlob<a name="updateblob"></a>($table,$column,$val,$where)</b></font></p> 
     1854<font>Allows you to store a blob (in $val) into $table into $column in a row at $where.  
     1855</font><p><font> Usage:  
     1856</font></p><p><font>  
     1857</font></p><pre><font>  # for oracle<br>        $conn-&gt;Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, empty_blob())');<br>  $conn-&gt;UpdateBlob('blobtable','blobcol',$blobvalue,'id=1');<br>      <br>    # non oracle databases<br>      $conn-&gt;Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, null)');<br>  $conn-&gt;UpdateBlob('blobtable','blobcol',$blobvalue,'id=1');<br></font></pre> 
     1858<p><font> Returns true if succesful, false otherwise. Supported by MySQL, PostgreSQL,  
    21501859        Oci8, Oci8po and Interbase drivers. Other drivers might work, depending on  
    2151         the state of development.</p> 
    2152 <p>Note that when an Interbase blob is retrieved using SELECT, it still needs  
    2153         to be decoded using $connection->DecodeBlob($blob); to derive the original  
     1860        the state of development.</font></p> 
     1861<p><font>Note that when an Interbase blob is retrieved using SELECT, it still needs  
     1862        to be decoded using $connection-&gt;DecodeBlob($blob); to derive the original  
    21541863        value in versions of PHP before 4.1.0.  
    2155 <p>For PostgreSQL, you can store your blob using blob oid's or as a bytea field.  
     1864</font></p><p><font>For PostgreSQL, you can store your blob using blob oid's or as a bytea field.  
    21561865        You can use bytea fields but not blob oid's currently with UpdateBlob( ).  
    21571866        Conversely UpdateBlobFile( ) supports oid's, but not bytea data.<br> 
     
    21591868        If you do not pass in an oid, then UpdateBlob() assumes that you are storing  
    21601869        in bytea fields. 
    2161 <p><b>UpdateClob<a name="updateclob"></a>($table,$column,$val,$where)</b></p> 
    2162 Allows you to store a clob (in $val) into $table into $column in a row at $where.  
     1870        <p>If you do not have any blob fields, you can improve you can improve general SQL query performance by disabling blob handling with $connection->disableBlobs = true. 
     1871</p></font><p><font><b>UpdateClob<a name="updateclob"></a>($table,$column,$val,$where)</b></font></p> 
     1872<font>Allows you to store a clob (in $val) into $table into $column in a row at $where.  
    21631873Similar to UpdateBlob (see above), but for Character Large OBjects.  
    2164 <p> Usage: 
    2165 <pre> 
    2166         # for oracle 
    2167         $conn->Execute('INSERT INTO clobtable (id, clobcol) VALUES (1, empty_clob())'); 
    2168         $conn->UpdateBlob('clobtable','clobcol',$clobvalue,'id=1'); 
    2169          
    2170         # non oracle databases 
    2171         $conn->Execute('INSERT INTO clobtable (id, clobcol) VALUES (1, null)'); 
    2172         $conn->UpdateBlob('clobtable','clobcol',$clobvalue,'id=1'); 
    2173 </pre> 
    2174 <p><b>UpdateBlobFile<a name="updateblobfile"></a>($table,$column,$path,$where,$blobtype='BLOB')</b></p> 
    2175 <p>Similar to UpdateBlob, except that we pass in a file path to where the blob  
     1874</font><p><font> Usage: 
     1875</font></p><pre><font>  # for oracle<br>        $conn-&gt;Execute('INSERT INTO clobtable (id, clobcol) VALUES (1, empty_clob())');<br>  $conn-&gt;UpdateBlob('clobtable','clobcol',$clobvalue,'id=1');<br>      <br>    # non oracle databases<br>      $conn-&gt;Execute('INSERT INTO clobtable (id, clobcol) VALUES (1, null)');<br>  $conn-&gt;UpdateBlob('clobtable','clobcol',$clobvalue,'id=1');<br></font></pre> 
     1876<p><font><b>UpdateBlobFile<a name="updateblobfile"></a>($table,$column,$path,$where,$blobtype='BLOB')</b></font></p> 
     1877<p><font>Similar to UpdateBlob, except that we pass in a file path to where the blob  
    21761878        resides. 
    2177 <p>For PostgreSQL, if you are using blob oid's, use this interface. This interface  
     1879</font></p><p><font>For PostgreSQL, if you are using blob oid's, use this interface. This interface  
    21781880        does not support bytea fields. 
    2179 <p>Returns true if successful, false otherwise.  
    2180 <p><b>BlobEncode<a name="blobencode" id="blobencode"></a>($blob)</b>  
    2181 <p>Some databases require blob's to be encoded manually before upload. Note if  
     1881</font></p><p><font>Returns true if successful, false otherwise.  
     1882</font></p><p><font><b>BlobEncode<a name="blobencode" id="blobencode"></a>($blob)</b>  
     1883</font></p><p><font>Some databases require blob's to be encoded manually before upload. Note if  
    21821884        you use UpdateBlob( ) or UpdateBlobFile( ) the conversion is done automatically  
    21831885        for you and you do not have to call this function. For PostgreSQL, currently,  
    21841886        BlobEncode() can only be used for bytea fields. 
    2185 <p>Returns the encoded blob value. 
    2186 <p>Note that there is a connection property called <em>blobEncodeType</em> which  
     1887</font></p><p><font>Returns the encoded blob value. 
     1888</font></p><p><font>Note that there is a connection property called <em>blobEncodeType</em> which  
    21871889        has 3 legal values:  
    2188 <p>false - no need to perform encoding or decoding.<br> 
     1890</font></p><p><font>false - no need to perform encoding or decoding.<br> 
    21891891        'I' - blob encoding required, and returned encoded blob is a numeric value  
    21901892        (no need to quote).<br> 
    21911893        'C' - blob encoding required, and returned encoded blob is a character value  
    21921894        (requires quoting). 
    2193 <p>This is purely for documentation purposes, so that programs that accept multiple  
     1895</font></p><p><font>This is purely for documentation purposes, so that programs that accept multiple  
    21941896        database drivers know what is the right thing to do when processing blobs. 
    2195 <p><strong>BlobDecode<a name="blobdecode"></a>($blob)</strong>  
    2196 </font><p><font color="#000000">Some databases require blob's to be decoded manually after doing a select statement.  
     1897</font></p><p><font><strong>BlobDecode<a name="blobdecode"></a>($blob, $maxblobsize = false)</strong>  
     1898</font></p><p><font>Some databases require blob's to be decoded manually after doing a select statement.  
    21971899        If the database does not require decoding, then this function will return  
    21981900        the blob unchanged. Currently BlobDecode is only required for one database,  
    21991901        PostgreSQL, and only if you are using blob oid's (if you are using bytea fields,  
    2200         we auto-decode for you).</font><font color="#000000"> 
    2201 <pre>$rs = $db-&gt;Execute(&quot;select bloboid from postgres_table where id=$key&quot;); 
    2202 $blob = $db-&gt;BlobDecode( reset($rs-&gt;fields) );</pre> 
    2203 <p><b>Replace<a name="replace"></a>($table, $arrFields, $keyCols,$autoQuote=false)</b></p> 
    2204 <p>Try to update a record, and if the record is not found, an insert statement  
     1902        we auto-decode for you).</font> The default maxblobsize is set in $connection-&gt;maxblobsize, which  
     1903        is set to 256K in adodb 4.54. </p><p> 
     1904        In ADOdb 4.54 and later, the blob is the return value. In earlier versions, the blob data is sent to stdout.</p><font> 
     1905</font><p></p><pre><font>$rs = $db-&gt;Execute("select bloboid from postgres_table where id=$key");<br>$blob = $db-&gt;BlobDecode( reset($rs-&gt;fields) );</font></pre> 
     1906<p><font><b>Replace<a name="replace"></a>($table, $arrFields, $keyCols,$autoQuote=false)</b></font></p> 
     1907<p><font>Try to update a record, and if the record is not found, an insert statement  
    22051908        is generated and executed. Returns 0 on failure, 1 if update statement worked,  
    22061909        2 if no record was found and the insert was executed successfully. This differs  
     
    22091912        Interbase and its derivitives, which uses delete and insert because of some  
    22101913        Interbase API limitations.  
    2211 <p>The parameters are $table which is the table name, the $keyCols which is an  
    2212         associative array where the keys are the field names, and keyCols is the name  
     1914</font></p><p><font>The parameters are $table which is the table name, the $arrFields which is an  
     1915        associative array where the keys are the field names, and $keyCols is the name  
    22131916        of the primary key, or an array of field names if it is a compound key. If  
    22141917        $autoQuote is set to true, then Replace() will quote all values that are non-numeric;  
    22151918        auto-quoting will not quote nulls. Note that auto-quoting will not work if  
    22161919        you use SQL functions or operators.  
    2217 <p>Examples:  
     1920</font></p><p><font>Examples:  
     1921</font></p><pre><font># single field primary key<br>$ret = $db-&gt;Replace('atable', <br>       array('id'=&gt;1000,'firstname'=&gt;'Harun','lastname'=&gt;'Al-Rashid'),<br>    'id',$autoquote = true);        <br># generates UPDATE atable SET firstname='Harun',lastname='Al-Rashid' WHERE id=1000<br># or INSERT INTO atable (id,firstname,lastname) VALUES (1000,'Harun','Al-Rashid')<br><br># compound key<br>$ret = $db-&gt;Replace('atable2', <br>     array('firstname'=&gt;'Harun','lastname'=&gt;'Al-Rashid', 'age' =&gt; 33, 'birthday' =&gt; 'null'),<br> array('lastname','firstname'),<br>      $autoquote = true);<br><br># no auto-quoting<br>$ret = $db-&gt;Replace('atable2', <br>  array('firstname'=&gt;"'Harun'",'lastname'=&gt;"'Al-Rashid'", 'age' =&gt; 'null'),<br>  array('lastname','firstname')); <br></font></pre> 
     1922<p><font><b>AutoExecute<a name="autoexecute"></a>($table, $arrFields, $mode, $where=false, $forceUpdate=true,$magicq=false)</b></font></p> 
     1923<p>Since ADOdb 4.56, you can automatically generate and execute INSERTs and UPDATEs on a given table with this 
     1924function, which is a wrapper for GetInsertSQL() and GetUpdateSQL(). 
     1925<p>AutoExecute() inserts or updates $table given an array of $arrFields, where the keys are the field names and the array values are the  
     1926field values to store. Note that there is some overhead because the table is first queried to extract key information  
     1927before the SQL is generated. We generate an INSERT or UPDATE based on $mode (see below). 
     1928<p> 
     1929Legal values for $mode are  
     1930<ul> 
     1931<li>'INSERT' or 1 or DB_AUTOQUERY_INSERT 
     1932<li>'UPDATE' or 2 or DB_AUTOQUERY_UPDATE 
     1933</ul> 
     1934<p>You have to define the constants DB_AUTOQUERY_UPDATE and DB_AUTOQUERY_INSERT yourself or include adodb-pear.inc.php. 
     1935<p>The $where clause is required if $mode == 'UPDATE'. If $forceUpdate=false then we will query the  
     1936database first and check if the field value returned by the query matches the current field value; only if they differ do we update that field. 
     1937<p>Returns true on success, false on error. 
     1938<p>An example of its use is: 
    22181939<pre> 
    2219 # single field primary key 
    2220 $ret = $db->Replace('atable',  
    2221         array('id'=>1000,'firstname'=>'Harun','lastname'=>'Al-Rashid'), 
    2222         'id',$autoquote = true);         
    2223 # generates UPDATE atable SET firstname='Harun',lastname='Al-Rashid' WHERE id=1000 
    2224 # or INSERT INTO atable (id,firstname,lastname) VALUES (1000,'Harun','Al-Rashid') 
    2225  
    2226 # compound key 
    2227 $ret = $db->Replace('atable2',  
    2228         array('firstname'=>'Harun','lastname'=>'Al-Rashid', 'age' => 33, 'birthday' => 'null'), 
    2229         array('lastname','firstname'), 
    2230         $autoquote = true); 
    2231  
    2232 # no auto-quoting 
    2233 $ret = $db->Replace('atable2',  
    2234         array('firstname'=>"'Harun'",'lastname'=>"'Al-Rashid'", 'age' => 'null'), 
    2235         array('lastname','firstname'));  
     1940$record["firstName"] = "Carol"; 
     1941$record["lasTname"] = "Smith";  
     1942$conn->AutoExecute($table,$record,'INSERT'); 
     1943# executes <i>"INSERT INTO $table (firstName,lasTname) values ('Carol',Smith')"</i>; 
     1944 
     1945$record["firstName"] = "Carol"; 
     1946$record["lasTname"] = "Jones";  
     1947$conn->AutoExecute($table,$record,'UPDATE', "lastname like 'Sm%'"); 
     1948# executes <i>"UPDATE $table SET firstName='Carol',lasTname='Jones' WHERE lastname like 'Sm%'"</i>; 
    22361949</pre> 
    2237 <p><b>GetUpdateSQL<a name="getupdatesql"></a>(&$rs, $arrFields, $forceUpdate=false,$magicq=false, $forcenulls=false)</b></p> 
    2238 <p>Generate SQL to update a table given a recordset $rs, and the modified fields  
     1950<p>Note: One of the strengths of ADOdb's AutoExecute() is that only valid field names for $table are updated. If $arrFields 
     1951contains keys that are invalid field names for $table, they are ignored. There is some overhead in doing this as we have to  
     1952query the database to get the field names, but given that you are not directly coding the SQL yourself, you probably aren't interested in 
     1953speed at all, but convenience. 
     1954<p>Since 4.62, the table name to be used can be overridden by setting $rs->tableName before AutoExecute(), GetInsertSQL() or GetUpdateSQL() is called. 
     1955<p>Since 4.94, setting the global variable $ADODB_QUOTE_FIELDNAMES to true will force field names to be auto-quoted in AutoExecute(), GetInsertSQL() and GetUpdateSQL(). </p> 
     1956<p><font><b>GetUpdateSQL<a name="getupdatesql"></a>(&amp;$rs, $arrFields, $forceUpdate=false,$magicq=false, $force=null)</b></font></p> 
     1957<p><font>Generate SQL to update a table given a recordset $rs, and the modified fields  
    22391958        of the array $arrFields (which must be an associative array holding the column  
    22401959        names and the new values) are compared with the current recordset. If $forceUpdate  
     
    22421961        $rs-&gt;fields. Requires the recordset to be associative. $magicq is used  
    22431962        to indicate whether magic quotes are enabled (see qstr()). The field names in the array  
    2244         are case-insensitive.</p> 
    2245         <p>Since 3.61, define('ADODB_FORCE_NULLS',1) and all PHP nulls will be auto-converted to SQL nulls. 
    2246         Since 4.24, we allow you to pass in $forcenulls as a parameter. This overrides the ADODB_FORCE_NULLS 
    2247         constant. 
    2248 <p><b>GetInsertSQL<a name="getinsertsql"></a>(&$rs, $arrFields,$magicq=false,$forcenulls=false)</b></p> 
    2249 <p>Generate SQL to insert into a table given a recordset $rs. Requires the query  
     1963        are case-insensitive.</font></p> 
     1964<font>  </font><p><font>Since 4.52, we allow you to pass the $force type parameter, and this overrides the <a href="#ADODB_FORCE_TYPE">$ADODB_FORCE_TYPE</a> 
     1965        global variable. 
     1966<p>Since 4.62, the table name to be used can be overridden by setting $rs->tableName before AutoExecute(), GetInsertSQL() or GetUpdateSQL() is called. 
     1967</p></font><p><font><b>GetInsertSQL<a name="getinsertsql"></a>(&amp;$rs, $arrFields,$magicq=false,$force_type=false)</b></font></p> 
     1968<p><font>Generate SQL to insert into a table given a recordset $rs. Requires the query  
    22501969        to be associative. $magicq is used to indicate whether magic quotes are enabled  
    2251         (for qstr()). The field names in the array are case-insensitive.</p> 
     1970        (for qstr()). The field names in the array are case-insensitive.</font></p> 
    22521971<p> 
    2253   Since 2.42, you can pass a  table name instead of a recordset into  
     1972<font>  Since 2.42, you can pass a  table name instead of a recordset into  
    22541973GetInsertSQL (in $rs), and it will generate an insert statement for that table. 
    2255 <p>Since 3.61, define('ADODB_FORCE_NULLS',1) and all PHP nulls will be auto-converted  
    2256   to SQL nulls.  
    2257 Since 4.24, we allow you to pass in $forcenulls as a parameter. This overrides the ADODB_FORCE_NULLS 
    2258         constant. 
    2259 <p><b>PageExecute<a name="pageexecute"></a>($sql, $nrows, $page, $inputarr=false)</b>  
    2260 <p>Used for pagination of recordset. $page is 1-based. See <a href="#ex8">Example  
    2261   8</a>.</p> 
    2262 </font>  
    2263 <p><font color="#000000"><b>CachePageExecute<a name="cachepageexecute"></a>($secs2cache,  
     1974</font></p><p><font>Since 4.52, we allow you to pass the $force_type parameter, and this overrides the <a href="#ADODB_FORCE_TYPE">$ADODB_FORCE_TYPE</a> 
     1975        global variable. 
     1976<p>Since 4.62, the table name to be used can be overridden by setting $rs->tableName before AutoExecute(), GetInsertSQL() or GetUpdateSQL() is called. 
     1977</p></font><p><font><b>PageExecute<a name="pageexecute"></a>($sql, $nrows, $page, $inputarr=false)</b>  
     1978</font></p><p><font>Used for pagination of recordset. $page is 1-based. See <a href="#ex8">Example  
     1979  8</a>.</font></p> 
     1980  
     1981<p><font><b>CachePageExecute<a name="cachepageexecute"></a>($secs2cache,  
    22641982  $sql, $nrows, $page, $inputarr=false)</b> </font></p> 
    2265 <p><font color="#000000">Used for pagination of recordset. $page is 1-based. See  
     1983<p><font>Used for pagination of recordset. $page is 1-based. See  
    22661984  <a href="#ex8">Example 8</a>. Caching version of PageExecute.</font></p> 
    2267 <font color="#000000">  
    2268 <p></p> 
    2269 <p><b>Close<a name="close"></a>( )</b></p> 
    2270 <p>Close the database connection. PHP4 proudly states that we no longer have to  
     1985<font>  
     1986</font><p></p> 
     1987<p><font><b>Close<a name="close"></a>( )</b></font></p> 
     1988<p><font>Close the database connection. PHP4 proudly states that we no longer have to  
    22711989  clean up at the end of the connection because the reference counting mechanism  
    2272   of PHP4 will automatically clean up for us.</p> 
    2273   <p><b>StartTrans<a name="starttrans"></a>( )</b></p> 
    2274   <p>Start a monitored transaction. As SQL statements are executed, ADOdb will monitor 
     1990  of PHP4 will automatically clean up for us.</font></p> 
     1991<font>  </font><p><font><b>StartTrans<a name="starttrans"></a>( )</b></font></p> 
     1992<font>  </font><p><font>Start a monitored transaction. As SQL statements are executed, ADOdb will monitor 
    22751993  for SQL errors, and if any are detected, when CompleteTrans() is called, we auto-rollback. 
    2276   <p> 
    2277   <p> To understand why StartTrans() is superior to BeginTrans(),  
     1994  </font></p><p> 
     1995<font>  </font></p><p><font> To understand why StartTrans() is superior to BeginTrans(),  
    22781996  let us examine a few ways of using BeginTrans(). 
    22791997  The following is the wrong way to use transactions:  
    2280 <pre> 
    2281 $DB->BeginTrans(); 
    2282 $DB->Execute("update table1 set val=$val1 where id=$id"); 
    2283 $DB->Execute("update table2 set val=$val2 where id=$id"); 
    2284 $DB->CommitTrans(); 
    2285 </pre> 
    2286 <p>because you perform no error checking. It is possible to update table1 and  
     1998</font></p><pre><font>$DB-&gt;BeginTrans();<br>$DB-&gt;Execute("update table1 set val=$val1 where id=$id");<br>$DB-&gt;Execute("update table2 set val=$val2 where id=$id");<br>$DB-&gt;CommitTrans();<br></font></pre> 
     1999<p><font>because you perform no error checking. It is possible to update table1 and  
    22872000  for the update on table2 to fail. Here is a better way:  
    2288 <pre> 
    2289 $DB->BeginTrans(); 
    2290 $ok = $DB->Execute("update table1 set val=$val1 where id=$id"); 
    2291 if ($ok) $ok = $DB->Execute("update table2 set val=$val2 where id=$id"); 
    2292 if ($ok) $DB->CommitTrans(); 
    2293 else $DB->RollbackTrans(); 
    2294 </pre> 
    2295 <p>Another way is (since ADOdb 2.0):  
    2296 <pre> 
    2297 $DB->BeginTrans(); 
    2298 $ok = $DB->Execute("update table1 set val=$val1 where id=$id"); 
    2299 if ($ok) $ok = $DB->Execute("update table2 set val=$val2 where id=$id"); 
    2300 $DB->CommitTrans($ok); 
    2301 </pre> 
    2302 <p> Now it is a headache monitoring $ok all over the place. StartTrans() is an 
     2001</font></p><pre><font>$DB-&gt;BeginTrans();<br>$ok = $DB-&gt;Execute("update table1 set val=$val1 where id=$id");<br>if ($ok) $ok = $DB-&gt;Execute("update table2 set val=$val2 where id=$id");<br>if ($ok) $DB-&gt;CommitTrans();<br>else $DB-&gt;RollbackTrans();<br></font></pre> 
     2002<p><font>Another way is (since ADOdb 2.0):  
     2003</font></p><pre><font>$DB-&gt;BeginTrans();<br>$ok = $DB-&gt;Execute("update table1 set val=$val1 where id=$id");<br>if ($ok) $ok = $DB-&gt;Execute("update table2 set val=$val2 where id=$id");<br>$DB-&gt;CommitTrans($ok);<br></font></pre> 
     2004<p><font> Now it is a headache monitoring $ok all over the place. StartTrans() is an 
    23032005improvement because it monitors all SQL errors for you. This is particularly 
    23042006useful if you are calling black-box functions in which SQL queries might be executed. 
    23052007 Also all BeginTrans, CommitTrans and RollbackTrans calls inside a StartTrans block  
    23062008  will be disabled, so even if the black box function does a commit, it will be ignored. 
    2307 <pre> 
    2308 $DB->StartTrans(); 
    2309 CallBlackBox(); 
    2310 $DB->Execute("update table1 set val=$val1 where id=$id"); 
    2311 $DB->Execute("update table2 set val=$val2 where id=$id"); 
    2312 $DB->CompleteTrans($ok); 
    2313 </pre> 
    2314 <p>Note that a StartTrans blocks are nestable, the inner blocks are ignored. 
    2315  <p><b>CompleteTrans<a name="completetrans"></a>($autoComplete=true)</b></p> 
    2316   <p>Complete a transaction called with StartTrans(). This function monitors 
     2009</font></p><pre><font>$DB-&gt;StartTrans();<br>CallBlackBox();<br>$DB-&gt;Execute("update table1 set val=$val1 where id=$id");<br>$DB-&gt;Execute("update table2 set val=$val2 where id=$id");<br>$DB-&gt;CompleteTrans();<br></font></pre> 
     2010<p><font>Note that a StartTrans blocks are nestable, the inner blocks are ignored. 
     2011 </font></p><p><font><b>CompleteTrans<a name="completetrans"></a>($autoComplete=true)</b></font></p> 
     2012<font>  </font><p><font>Complete a transaction called with StartTrans(). This function monitors 
    23172013  for SQL errors, and will commit if no errors have occured, otherwise it will rollback.  
    23182014  Returns true on commit, false on rollback. If the parameter $autoComplete is true 
    23192015  monitor sql errors and commit and rollback as appropriate. Set $autoComplete to false  
    23202016  to force rollback even if no SQL error detected. 
    2321   <p><b>FailTrans<a name="failtrans"></a>( )</b></p> 
    2322   <p>Fail a transaction started with StartTrans(). The rollback will only occur when 
     2017  </font></p><p><font><b>FailTrans<a name="failtrans"></a>( )</b></font></p> 
     2018<font>  </font><p><font>Fail a transaction started with StartTrans(). The rollback will only occur when 
    23232019  CompleteTrans() is called. 
    2324     <p><b>HasFailedTrans<a name="hasfailedtrans"></a>( )</b></p> 
    2325         <p>Check whether smart transaction has failed,  
     2020    </font></p><p><font><b>HasFailedTrans<a name="hasfailedtrans"></a>( )</b></font></p> 
     2021<font>  </font><p><font>Check whether smart transaction has failed,  
    23262022        eg. returns true if there was an error in SQL execution or FailTrans() was called. 
    23272023        If not within smart transaction, returns false. 
    2328 <p><b>BeginTrans<a name="begintrans"></a>( )</b></p> 
    2329 <p>Begin a transaction. Turns off autoCommit. Returns true if successful. Some  
     2024</font></p><p><font><b>BeginTrans<a name="begintrans"></a>( )</b></font></p> 
     2025<p><font>Begin a transaction. Turns off autoCommit. Returns true if successful. Some  
    23302026  databases will always return false if transaction support is not available.  
    23312027   Any open transactions will be rolled back when the connection is closed. Among the 
    23322028   databases that support transactions are Oracle, PostgreSQL, Interbase, MSSQL, certain 
    2333     versions of MySQL, DB2, Informix, Sybase, etc.</p> 
    2334  <p>Note that <a href=#starttrans>StartTrans()</a> and CompleteTrans() is a superior method of  
    2335  handling transactions, available since ADOdb 3.40. For a explanation, see the <a href=#starttrans>StartTrans()</a> documentation. 
    2336  
    2337 <p>You can also use the ADOdb <a href=#errorhandling>error handler</a> to die  
     2029    versions of MySQL, DB2, Informix, Sybase, etc.</font></p> 
     2030<font> </font><p><font>Note that <a href="#starttrans">StartTrans()</a> and CompleteTrans() is a superior method of  
     2031 handling transactions, available since ADOdb 3.40. For a explanation, see the <a href="#starttrans">StartTrans()</a> documentation. 
     2032 
     2033</font></p><p><font>You can also use the ADOdb <a href="#errorhandling">error handler</a> to die  
    23382034  and rollback your transactions for you transparently. Some buggy database extensions  
    23392035  are known to commit all outstanding tranasactions, so you might want to explicitly  
    2340   do a $DB->RollbackTrans() in your error handler for safety.  
    2341  <h4>Detecting Transactions</h4> 
    2342  <p>Since ADOdb 2.50, you are able to detect when you are inside a transaction. Check 
    2343  that $connection->transCnt > 0. This variable is incremented whenever BeginTrans() is called, 
     2036  do a $DB-&gt;RollbackTrans() in your error handler for safety.  
     2037 </font></p><h4><font>Detecting Transactions</font></h4> 
     2038<font> </font><p><font>Since ADOdb 2.50, you are able to detect when you are inside a transaction. Check 
     2039 that $connection-&gt;transCnt &gt; 0. This variable is incremented whenever BeginTrans() is called, 
    23442040 and decremented whenever RollbackTrans() or CommitTrans() is called. 
    2345 <p><b>CommitTrans<a name="committrans"></a>($ok=true)</b></p> 
    2346 <p>End a transaction successfully. Returns true if successful. If the database  
     2041</font></p><p><font><b>CommitTrans<a name="committrans"></a>($ok=true)</b></font></p> 
     2042<p><font>End a transaction successfully. Returns true if successful. If the database  
    23472043  does not support transactions, will return true also as data is always committed.  
    2348 </p> 
    2349 <p>If you pass the parameter $ok=false, the data is rolled back. See example in  
    2350   BeginTrans().</p> 
    2351 <p><b>RollbackTrans<a name="rollbacktrans"></a>( )</b></p> 
    2352 <p>End a transaction, rollback all changes. Returns true if successful. If the  
     2044</font></p> 
     2045<p><font>If you pass the parameter $ok=false, the data is rolled back. See example in  
     2046  BeginTrans().</font></p> 
     2047<p><font><b>RollbackTrans<a name="rollbacktrans"></a>( )</b></font></p> 
     2048<p><font>End a transaction, rollback all changes. Returns true if successful. If the  
    23532049  database does not support transactions, will return false as data is never rollbacked.  
    2354 </p> 
    2355 </font><font color="#000000">  
    2356 <p><b>GetAssoc<a name=getassoc1></a>($sql,$inputarr=false,$force_array=false,$first2cols=false)</b></p> 
    2357 <p>Returns an associative array for the given query $sql with optional bind parameters  
     2050</font></p> 
     2051  
     2052<p><font><b>SetTransactionMode<a name="SetTransactionMode"></a>($mode )</b></font></p> 
     2053<p>SetTransactionMode allows you to pass in the transaction mode to use for all subsequent transactions.  
     2054Note: if you have persistent connections and using mssql or mysql, you might have to explicitly reset your transaction mode at the beginning of each page request.  
     2055This is only supported in postgresql, mssql, mysql with InnoDB and oci8 currently. For example: 
     2056<pre> 
     2057$db->SetTransactionMode("SERIALIZABLE"); 
     2058$db->BeginTrans(); 
     2059$db->Execute(...); $db->Execute(...); 
     2060$db->CommiTrans(); 
     2061 
     2062$db->SetTransactionMode(""); // restore to default 
     2063$db->StartTrans(); 
     2064$db->Execute(...); $db->Execute(...); 
     2065$db->CompleteTrans(); 
     2066</pre> 
     2067 
     2068<p>Supported values to pass in: 
     2069<ul> 
     2070<li>READ UNCOMMITTED (allows dirty reads, but fastest) 
     2071<li>READ COMMITTED (default postgres, mssql and oci8) 
     2072<li>REPEATABLE READ (default mysql) 
     2073<li>SERIALIZABLE (slowest and most restrictive) 
     2074</ul> 
     2075<p>You can also pass in database specific values such as 'SNAPSHOT' for mssql or 'READ ONLY' for oci8/postgres. 
     2076<p>See transaction levels for <a href=http://www.postgresql.org/docs/8.1/interactive/sql-set-transaction.html>PostgreSQL</a>, 
     2077<a href=http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_10005.htm>Oracle</a>, 
     2078<a href=http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html>MySQL</a>, and 
     2079<a href=http://msdn2.microsoft.com/en-US/ms173763.aspx>MS SQL Server</a>. 
     2080<p><font><b>GetAssoc<a name="getassoc1"></a>($sql,$inputarr=false,$force_array=false,$first2cols=false)</b></font></p> 
     2081<p><font>Returns an associative array for the given query $sql with optional bind parameters  
    23582082  in $inputarr. If the number of columns returned is greater to two, a 2-dimensional  
    23592083  array is returned, with the first column of the recordset becomes the keys  
     
    23612085  is created, where the the keys directly map to the values (unless $force_array  
    23622086  is set to true, when an array is created for each value). 
    2363 <p> <font color="#000000">Examples:<a name=getassocex></a></font></p> 
    2364 </font> 
    2365 <p><font color="#000000">We have the following data in a recordset:</font></p> 
    2366 <p><font color="#000000">row1: Apple, Fruit, Edible<br> 
     2087</font></p><p><font> Examples:<a name="getassocex"></a></font></p> 
     2088 
     2089<p><font>We have the following data in a recordset:</font></p> 
     2090<p><font>row1: Apple, Fruit, Edible<br> 
    23672091  row2: Cactus, Plant, Inedible<br> 
    23682092  row3: Rose, Flower, Edible</font></p> 
    2369 <p><font color="#000000">GetAssoc will generate the following 2-dimensional associative  
     2093<p><font>GetAssoc will generate the following 2-dimensional associative  
    23702094  array:</font></p> 
    2371 <p><font color="#000000">Apple =&gt; array[Fruit, Edible]<br> 
     2095<p><font>Apple =&gt; array[Fruit, Edible]<br> 
    23722096  Cactus =&gt; array[Plant, Inedible]<br> 
    23732097  Rose =&gt; array[Flower,Edible]</font></p> 
    2374 <p><font color="#000000">If the dataset is:</font></p> 
    2375 <p><font color="#000000"><font color="#000000"><font color="#000000">row1: Apple,  
    2376   Fruit<br> 
    2377   row2: Cactus, Plant<br> 
    2378   row3: Rose, Flower</font> </font></font></p> 
    2379 <p><font color="#000000"><font color="#000000">GetAssoc will generate the following  
    2380   1-dimensional associative array (with $force_array==false):</font></font></p> 
    2381 <p><font color="#000000">Apple =&gt; Fruit</font><br> 
     2098<p><font>If the dataset is:</font></p> 
     2099<p><font>row1: Apple, Fruit<br> 
     2100row2: Cactus, Plant<br> 
     2101row3: Rose, Flower </font></p> 
     2102<p><font>GetAssoc will generate the following 1-dimensional associative 
     2103  array (with $force_array==false):</font></p> 
     2104<p><font>Apple =&gt; Fruit</font><br> 
    23822105  Cactus=&gt;Plant<br> 
    2383   Rose=&gt;Flower <font color="#000000"><font color="#000000"> </font></font><font color="#000000"><font color="#000000"></font></font></p> 
    2384 <p><font color="#000000">The function returns:</font></p> 
    2385 <p><font color="#000000">The associative array, or false if an error occurs.</font></p> 
    2386 <font color="#000000"> 
     2106  Rose=&gt;Flower </p> 
     2107<p><font>The function returns:</font></p> 
     2108<p><font>The associative array, or false if an error occurs.</font></p> 
     2109<font> 
    23872110<p><b>CacheGetAssoc<a name="cachegetassoc"></a>([$secs2cache,] $sql,$inputarr=false,$force_array=false,$first2cols=false)</b></p> 
    2388 </font><font color="#000000">  
    2389 <p>Caching version of <a href=#getassoc1>GetAssoc</a> function above. 
    2390 <p><b>GetOne<a name="getone"></a>($sql,$inputarr=false)</b></p> 
    2391 <p>Executes the SQL and returns the first field of the first row. The recordset  
     2111</font> 
     2112<p><font>Caching version of <a href="#getassoc1">GetAssoc</a> function above. 
     2113</font></p><p><font><b>GetOne<a name="getone"></a>($sql,$inputarr=false)</b></font></p> 
     2114<p><font>Executes the SQL and returns the first field of the first row. The recordset  
    23922115  and remaining rows are discarded for you automatically. If an error occur, false  
    2393   is returned.</p> 
    2394 <p><b>GetRow<a name="getrow"></a>($sql,$inputarr=false)</b></p> 
    2395 <p>Executes the SQL and returns the first row as an array. The recordset and remaining  
    2396   rows are discarded for you automatically. If an error occurs, false is returned.</p> 
    2397 <p><b>GetAll<a name="getall"></a>($sql)</b></p> 
    2398 </font> 
    2399 <p><font color="#000000">Executes the SQL and returns the all the rows as a 2-dimensional  
     2116  is returned.</font></p> 
     2117<p><font><b>GetRow<a name="getrow"></a>($sql,$inputarr=false)</b></font></p> 
     2118<p><font>Executes the SQL and returns the first row as an array. The recordset and remaining  
     2119  rows are discarded for you automatically. If an error occurs, false is returned.</font></p> 
     2120<p><font><b>GetAll<a name="getall"></a>($sql,$inputarr=false)</b></font></p> 
     2121 
     2122<p>Executes the SQL and returns the all the rows as a 2-dimensional  
    24002123  array. The recordset is discarded for you automatically. If an error occurs,  
    2401   false is returned.</font></p> 
     2124  false is returned. <i>GetArray</i> is a synonym for <i>GetAll</i>.</p> 
    24022125 <p><b>GetCol<a name="getcol"></a>($sql,$inputarr=false,$trim=false)</b></p> 
    24032126 
    2404 <p><font color="#000000">Executes the SQL and returns all elements of the first column as a  
     2127<p><font>Executes the SQL and returns all elements of the first column as a  
    240521281-dimensional array. The recordset is discarded for you automatically. If an error occurs,  
    24062129  false is returned.</font></p> 
    2407 <p><font color="#000000"><b>CacheGetOne<a name="cachegetone"></a>([$secs2cache,]  
     2130<p><font><b>CacheGetOne<a name="cachegetone"></a>([$secs2cache,]  
    24082131  $sql,$inputarr=false), CacheGetRow<a name="cachegetrow"></a>([$secs2cache,] $sql,$inputarr=false), CacheGetAll<a name="cachegetall"></a>([$secs2cache,]  
    24092132  $sql,$inputarr=false), CacheGetCol<a name="cachegetcol"></a>([$secs2cache,]  
    24102133  $sql,$inputarr=false,$trim=false)</b></font></p> 
    2411 <font color="#000000">  
    2412 <p>Similar to above Get* functions, except that the recordset is serialized and  
     2134<font>  
     2135</font><p><font>Similar to above Get* functions, except that the recordset is serialized and  
    24132136  cached in the $ADODB_CACHE_DIR directory for $secs2cache seconds. Good for speeding  
    24142137  up queries on rarely changing data. Note that the $secs2cache parameter is optional.  
    24152138  If omitted, we use the value in $connection-&gt;cacheSecs (default is 3600 seconds,  
    2416   or 1 hour).</p> 
    2417 <p><b>Prepare<a name="prepare"></a>($sql )</b></p> 
    2418 </font>  
    2419 <p><font color="#000000">Prepares (compiles) an SQL query for repeated execution. Bind parameters 
     2139  or 1 hour).</font></p> 
     2140<p><font><b>Prepare<a name="prepare"></a>($sql )</b></font></p> 
     2141  
     2142<p><font>Prepares (compiles) an SQL query for repeated execution. Bind parameters 
    24202143are denoted by ?, except for the oci8 driver, which uses the traditional Oracle :varname 
    24212144convention.  
    24222145  </font></p> 
    2423 <p><font color="#000000">Returns an array containing the original sql statement  
     2146<p><font>Returns an array containing the original sql statement  
    24242147  in the first array element; the remaining elements of the array are driver dependent.  
    24252148  If there is an error, or we are emulating Prepare( ), we return the original  
    24262149  $sql string. This is because all error-handling has been centralized in Execute(  
    24272150  ).</font></p> 
    2428 <p><font color="#000000">Prepare( ) cannot be used with functions that use SQL  
     2151<p><font>Prepare( ) cannot be used with functions that use SQL  
    24292152  query rewriting techniques, e.g. PageExecute( ) and SelectLimit( ).</font></p> 
    24302153<p>Example:</p> 
    2431 <pre><font color="#000000">$stmt = $DB-&gt;Prepare('insert into table (col1,col2) values (?,?)'); 
    2432 for ($i=0; $i &lt; $max; $i++)<br></font>       $DB-&gt;<font color="#000000">Execute($stmt,array((string) rand(), $i)); 
    2433 </font></pre> 
    2434 <font color="#000000">  
    2435 <p>Also see InParameter(), OutParameter() and PrepareSP() below. Only supported internally by interbase,  
     2154<pre><font>$stmt = $DB-&gt;Prepare('insert into table (col1,col2) values (?,?)');<br>for ($i=0; $i &lt; $max; $i++)<br></font>  $DB-&gt;<font>Execute($stmt,array((string) rand(), $i));<br></font></pre> 
     2155<font>  
     2156</font><p><font>Also see InParameter(), OutParameter() and PrepareSP() below. Only supported internally by interbase,  
    24362157  oci8 and selected ODBC-based drivers, otherwise it is emulated. There is no  
    24372158  performance advantage to using Prepare() with emulation.  
    2438 <p> Important: Due to limitations or bugs in PHP, if you are getting errors when  
     2159</font></p><p><font> Important: Due to limitations or bugs in PHP, if you are getting errors when  
    24392160  you using prepared queries, try setting $ADODB_COUNTRECS = false before preparing.  
    24402161  This behaviour has been observed with ODBC.  
    2441 <p><b>IfNull<a name="ifnull"></a>($field, $nullReplacementValue)</b></p> 
    2442 <p>Portable IFNULL function (NVL in Oracle). Returns a string that represents  
     2162</font></p><p><font><b>IfNull<a name="ifnull"></a>($field, $nullReplacementValue)</b></font></p> 
     2163<p><font>Portable IFNULL function (NVL in Oracle). Returns a string that represents  
    24432164  the function that checks whether a $field is null for the given database, and  
    2444   if null, change the value returned to $nullReplacementValue. Eg.</p> 
    2445 <pre>$sql = <font color="#993300">'SELECT '</font>.$db-&gt;IfNull('name', <font color="#993300">&quot;'- unknown -'&quot;</font>).<font color="#993300"> ' FROM table'</font>;</pre> 
    2446  
    2447 <p><b>length<a name="length"></a></b></p> 
    2448 <p>This is not a function, but a property. Some databases have "length" and others "len" 
     2165  if null, change the value returned to $nullReplacementValue. Eg.</font></p> 
     2166<pre><font>$sql = <font color="#993300">'SELECT '</font>.$db-&gt;IfNull('name', <font color="#993300">"'- unknown -'"</font>).<font color="#993300"> ' FROM table'</font>;</font></pre> 
     2167 
     2168<p><font><b>length<a name="length"></a></b></font></p> 
     2169<p><font>This is not a function, but a property. Some databases have "length" and others "len" 
    24492170as the function to measure the length of a string. To use this property: 
    2450 <pre> 
    2451   $sql = <font color="#993300">"SELECT "</font>.$db->length.<font color="#993300">"(field) from table"</font>; 
    2452   $rs = $db->Execute($sql); 
    2453 </pre> 
    2454  
    2455 <p><b>random<a name="random"></a></b></p> 
    2456 <p>This is not a function, but a property. This is a string that holds the sql to 
     2171</font></p><pre><font>  $sql = <font color="#993300">"SELECT "</font>.$db-&gt;length.<font color="#993300">"(field) from table"</font>;<br>  $rs = $db-&gt;Execute($sql);<br></font></pre> 
     2172 
     2173<p><font><b>random<a name="random"></a></b></font></p> 
     2174<p><font>This is not a function, but a property. This is a string that holds the sql to 
    24572175generate a random number between 0.0 and 1.0 inclusive. 
    24582176 
    2459 <p><b>substr<a name="substr"></a></b></p> 
    2460 <p>This is not a function, but a property. Some databases have "substr" and others "substring" 
     2177</font></p><p><font><b>substr<a name="substr"></a></b></font></p> 
     2178<p><font>This is not a function, but a property. Some databases have "substr" and others "substring" 
    24612179as the function to retrieve a sub-string. To use this property: 
    2462 <pre> 
    2463   $sql = <font color="#993300">"SELECT "</font>.$db->substr.<font color="#993300">"(field, $offset, $length) from table"</font>; 
    2464   $rs = $db->Execute($sql); 
    2465 </pre> 
    2466 <p>For all databases, the 1st parameter of <i>substr</i> is the field, the 2nd is the 
     2180</font></p><pre><font>  $sql = <font color="#993300">"SELECT "</font>.$db-&gt;substr.<font color="#993300">"(field, $offset, $length) from table"</font>;<br>  $rs = $db-&gt;Execute($sql);<br></font></pre> 
     2181<p><font>For all databases, the 1st parameter of <i>substr</i> is the field, the 2nd is the 
    24672182offset (1-based) to the beginning of the sub-string, and the 3rd is the length of the sub-string. 
    24682183 
    24692184 
    2470 <p><b>Param<a name="param"></a>($name)</b></p> 
    2471 <p>Generates a bind placeholder portably. For most databases, the bind placeholder  
     2185</font></p><p><font><b>Param<a name="param"></a>($name)</b></font></p> 
     2186<p><font>Generates a bind placeholder portably. For most databases, the bind placeholder  
    24722187  is "?". However some databases use named bind parameters such as Oracle, eg  
    24732188  ":somevar". This allows us to portably define an SQL statement with bind parameters:  
    2474 <pre><font color="#000000">$sql = <font color="#993300">'insert into table (col1,col2) values ('</font>.$DB-&gt;Param('a').<font color="#993300">','</font>.$DB-&gt;Param('b').<font color="#993300">')'</font>; 
    2475 <font color="#006600"># generates 'insert into table (col1,col2) values (?,?)' 
    2476 # or        'insert into table (col1,col2) values (:a,:b)</font>' 
    2477 $stmt = $DB-&gt;Prepare($sql); 
    2478 $stmt = $DB-&gt;Execute($stmt,array('one','two')); 
    2479 </font></pre> 
    2480 <font color="#000000">  
     2189</font></p><pre><font>$sql = <font color="#993300">'insert into table (col1,col2) values ('</font>.$DB-&gt;Param('a').<font color="#993300">','</font>.$DB-&gt;Param('b').<font color="#993300">')'</font>;<br><font color="#006600"># generates 'insert into table (col1,col2) values (?,?)'<br># or        'insert into table (col1,col2) values (:a,:b)</font>'<br>$stmt = $DB-&gt;Prepare($sql);<br>$stmt = $DB-&gt;Execute($stmt,array('one','two'));<br></font></pre> 
     2190<font> </font> 
    24812191<p></p> 
    2482 <p><b>PrepareSP</b><b><a name="preparesp"></a></b><b>($sql, $cursor=false )</b></p> 
    2483 <p>When calling stored procedures in mssql and oci8 (oracle), and you might want  
    2484   to directly bind to parameters that return values, or for special LOB handling.  
    2485   PrepareSP() allows you to do so.  
    2486 <p>Returns the same array or $sql string as Prepare( ) above. If you do not need  
    2487   to bind to return values, you should use Prepare( ) instead.</p> 
    2488 <p>The 2nd parameter, $cursor is not used except with oci8. Setting it to true will 
    2489 force OCINewCursor to be called; this is to support output REF CURSORs. 
    2490 <p>For examples of usage of PrepareSP( ), see InParameter( ) below.  
    2491 <p>Note: in the mssql driver, preparing stored procedures requires a special function  
    2492   call, mssql_init( ), which is called by this function. PrepareSP( ) is available  
    2493   in all other drivers, and is emulated by calling Prepare( ). </p> 
    2494 <p><b> InParameter<a name="inparameter"></a>($stmt, $var, $name, 
    2495   $maxLen = 4000, $type = false )</b></p> 
    2496 Binds a PHP variable as input to a stored procedure variable. The parameter <i>$stmt</i> 
    2497  is the value returned by PrepareSP(), <i>$var</i> is the PHP variable you want to bind, $name 
    2498  is the name of the stored procedure variable. Optional is <i>$maxLen</i>, the maximum length of the 
    2499  data to bind, and $type which is database dependant.  
    2500  Consult <a href=http://php.net/mssql_bind>mssql_bind</a> and <a href=http://php.net/ocibindbyname>ocibindbyname</a> docs 
    2501   at php.net for more info on legal values for $type.  
    2502  <p> 
    2503 InParameter() is a wrapper function that calls Parameter() with $isOutput=false.  
    2504 The advantage of this function is that it is self-documenting, because 
    2505 the $isOutput parameter is no longer needed.  Only for mssql  
    2506   and oci8 currently. 
    2507   <p>Here is an example using oci8: 
    2508   <pre><font color="green"># For oracle, Prepare and PrepareSP are identical</font> 
     2192<p><font><b>PrepareSP</b><b><a name="preparesp"></a></b><b>($sql, 
     2193$cursor=false )</b></font></p> 
     2194<p><font>When calling stored procedures in mssql and oci8 (oracle), 
     2195    and you might want to directly bind to parameters that return values, or 
     2196for special LOB handling. PrepareSP() allows you to do so. </font></p> 
     2197<p><font>Returns the same array or $sql string as Prepare( ) 
     2198    above. If you do not need to bind to return values, you should use Prepare( 
     2199  ) instead.</font></p> 
     2200<p><font>The 2nd parameter, $cursor is not used except with oci8. 
     2201    Setting it to true will force OCINewCursor to be called; this is to support 
     2202output REF CURSORs. </font></p> 
     2203<p><font>For examples of usage of PrepareSP( ), see InParameter( 
     2204) below. </font></p> 
     2205<p><font>Note: in the mssql driver, preparing stored procedures 
     2206    requires a special function call, mssql_init( ), which is called by this 
     2207    function. PrepareSP( ) is available in all other drivers, and is emulated 
     2208  by calling Prepare( ). </font></p> 
     2209<p><font><b> InParameter<a name="inparameter"></a>($stmt, $var, 
     2210  $name, $maxLen = 4000, $type = false )</b></font></p> 
     2211<font>Binds a PHP variable as input to a stored procedure variable. 
     2212The parameter <i>$stmt</i> is the value returned by PrepareSP(), <i>$var</i> is 
     2213the PHP variable you want to bind, $name is the name of the stored procedure 
     2214variable. Optional is <i>$maxLen</i>, the maximum length of the data to bind, 
     2215and $type which is database dependant. Consult <a href="http://php.net/mssql_bind">mssql_bind</a> and <a href="http://php.net/ocibindbyname">ocibindbyname</a> docs 
     2216at php.net for more info on legal values for $type. </font> 
     2217<p> 
     2218<font>InParameter() is a wrapper function that calls Parameter() 
     2219with $isOutput=false. The advantage of this function is that it is self-documenting, 
     2220because the $isOutput parameter is no longer needed. Only for mssql and oci8 
     2221currently. </font></p> 
     2222<p><font>Here is an example using oci8: </font></p> 
     2223<pre><font><font color="green"># For oracle, Prepare and PrepareSP are identical</font> 
    25092224$stmt = $db-&gt;PrepareSP( 
    2510         <font color="#993300">&quot;declare RETVAL integer;  
    2511         begin 
    2512         :RETVAL := </font><font color="#993300">SP_RUNSOMETHING</font><font color="#993300">(:myid,:group); 
    2513         end;&quot;</font>); 
    2514 $db-&gt;InParameter($stmt,$id,'myid'); 
    2515 $db-&gt;InParameter($stmt,$group,'group',64); 
    2516 $db-&gt;OutParameter($stmt,$ret,'RETVAL');<br>$db-&gt;Execute($stmt); 
    2517 </pre> 
    2518 <p> The same example using mssql:</p> 
    2519 </font>  
    2520 <pre><font color="#000000"><font color="green"># @RETVAL = SP_RUNSOMETHING @myid,@group</font> 
     2225        <font color="#993300">"declare RETVAL integer; <br>     begin<br>       :RETVAL := </font><font color="#993300">SP_RUNSOMETHING</font><font color="#993300">(:myid,:group);<br> end;"</font>);<br>$db-&gt;InParameter($stmt,$id,'myid');<br>$db-&gt;InParameter($stmt,$group,'group',64);<br>$db-&gt;OutParameter($stmt,$ret,'RETVAL');<br>$db-&gt;Execute($stmt);<br></font></pre> 
     2226<p><font> The same example using mssql:</font></p> 
     2227<font>  
     2228</font><pre><font><font color="green"># @RETVAL = SP_RUNSOMETHING @myid,@group</font> 
    25212229$stmt = $db-&gt;PrepareSP(<font color="#993333">'<font color="#993300">SP_RUNSOMETHING</font>'</font>); <br><font color="green"># note that the parameter name does not have @ in front!</font> 
    25222230$db-&gt;InParameter($stmt,$id,'myid'); 
    25232231$db-&gt;InParameter($stmt,$group,'group',64); 
    2524 <font color="green"># return value in mssql - RETVAL is hard-coded name</font>  
    2525 $db-&gt;OutParameter($stmt,$ret,'RETVAL'); 
    2526 $db-&gt;Execute($stmt); </font></pre> 
    2527  
    2528 <p>Note that the only difference between the oci8 and mssql implementations is $sql.</p> 
    2529   <p> 
    2530  If $type parameter is set to false, in mssql, $type will be dynamicly determined  
     2232<font color="green"># return value in mssql - RETVAL is hard-coded name</font> <br>$db-&gt;OutParameter($stmt,$ret,'RETVAL');<br>$db-&gt;Execute($stmt); </font></pre> 
     2233 
     2234<p><font>Note that the only difference between the oci8 and mssql implementations is $sql.</font></p> 
     2235<p> 
     2236<font> If $type parameter is set to false, in mssql, $type will be dynamicly determined  
    25312237based on the type of the PHP variable passed <font face="Courier New, Courier, mono">(string  
    25322238=&gt; SQLCHAR, boolean =&gt;SQLINT1, integer =&gt;SQLINT4 or float/double=&gt;SQLFLT8)</font>. 
    2533 <p>  
     2239</font></p><p><font>  
    25342240In oci8, $type can be set to OCI_B_FILE (Binary-File), OCI_B_CFILE (Character-File),  
    25352241OCI_B_CLOB (Character-LOB), OCI_B_BLOB (Binary-LOB) and OCI_B_ROWID (ROWID). To  
    25362242pass in a null, use<font face="Courier New, Courier, mono"> $db-&gt;Parameter($stmt,  
    25372243$null=null, 'param')</font>.  
    2538   <p><b> OutParameter<a name="outparameter"></a>($stmt, $var, $name,  
    2539   $maxLen = 4000, $type = false )</b></p> 
    2540   Binds a PHP variable as output from a stored procedure variable. The parameter <i>$stmt</i> 
     2244  </font></p><p><font><b> OutParameter<a name="outparameter"></a>($stmt, $var, $name,  
     2245  $maxLen = 4000, $type = false )</b></font></p> 
     2246<font>  Binds a PHP variable as output from a stored procedure variable. The parameter <i>$stmt</i> 
    25412247 is the value returned by PrepareSP(), <i>$var</i> is the PHP variable you want to bind, <i>$name</i> 
    25422248 is the name of the stored procedure variable. Optional is <i>$maxLen</i>, the maximum length of the 
    25432249 data to bind, and <i>$type</i> which is database dependant.  
    2544   <p> 
    2545   OutParameter() is a wrapper function that calls Parameter() with $isOutput=true.  
     2250</font><p> 
     2251<font>  OutParameter() is a wrapper function that calls Parameter() with $isOutput=true.  
    25462252  The advantage of this function is that it is self-documenting, because 
    25472253the $isOutput parameter is no longer needed.  Only for mssql  
    25482254  and oci8 currently. 
    2549 <p> 
    2550 For an example, see <a href=#inparameter>InParameter</a>. 
    2551  
    2552 <p><b> Parameter<a name="parameter"></a>($stmt, $var, $name, $isOutput=false,  
    2553   $maxLen = 4000, $type = false )</b></p> 
    2554 <p>Note: This function is deprecated, because of the new InParameter() and OutParameter() functions. 
     2255</font></p><p> 
     2256<font>For an example, see <a href="#inparameter">InParameter</a>. 
     2257 
     2258</font></p><p><font><b> Parameter<a name="parameter"></a>($stmt, $var, $name, $isOutput=false,  
     2259  $maxLen = 4000, $type = false )</b></font></p> 
     2260<p><font>Note: This function is deprecated, because of the new InParameter() and OutParameter() functions. 
    25552261These are superior because they are self-documenting, unlike Parameter(). 
    2556 <p>Adds a bind parameter suitable for return values or special data handling (eg.  
     2262</font></p><p><font>Adds a bind parameter suitable for return values or special data handling (eg.  
    25572263  LOBs) after a statement has been prepared using PrepareSP(). Only for mssql  
    25582264  and oci8 currently. The parameters are:<br> 
     
    25662272  [$<b>type</b>] Consult <a href="http://php.net/mssql_bind">mssql_bind</a> and  
    25672273  <a href="http://php.net/ocibindbyname">ocibindbyname</a> docs at php.net for  
    2568   more info on legal values for type.</p> 
    2569 <p>Lastly, in oci8, bind parameters can be reused without calling PrepareSP( )  
    2570   or Parameters again. This is not possible with mssql. An oci8 example:</p> 
    2571 <pre>$id = 0; $i = 0; 
    2572 $stmt = $db-&gt;PrepareSP( <font color="#993300">&quot;update table set val=:i where id=:id&quot;</font>); 
    2573 $db-&gt;Parameter($stmt,$id,'id'); 
    2574 $db-&gt;Parameter($stmt,$i, 'i'); 
    2575 for ($cnt=0; $cnt &lt; 1000; $cnt++) { 
    2576         $id = $cnt; <br>        $i = $cnt * $cnt; <font color="green"># works with oci8!</font> 
    2577         $db-&gt;Execute($stmt); <br>}</pre> 
    2578 <p><b>Bind<a name="bind"></a>($stmt, $var, $size=4001, $type=false, $name=false)</b></p> 
    2579 </font>  
    2580 <p><font color="#000000">This is a low-level function supported only by the oci8  
     2274  more info on legal values for type.</font></p> 
     2275<p><font>Lastly, in oci8, bind parameters can be reused without calling PrepareSP( )  
     2276  or Parameters again. This is not possible with mssql. An oci8 example:</font></p> 
     2277<pre><font>$id = 0; $i = 0;<br>$stmt = $db-&gt;PrepareSP( <font color="#993300">"update table set val=:i where id=:id"</font>);<br>$db-&gt;Parameter($stmt,$id,'id');<br>$db-&gt;Parameter($stmt,$i, 'i');<br>for ($cnt=0; $cnt &lt; 1000; $cnt++) {<br>        $id = $cnt; <br>        $i = $cnt * $cnt; <font color="green"># works with oci8!</font> 
     2278        $db-&gt;Execute($stmt); <br>}</font></pre> 
     2279<p><font><b>Bind<a name="bind"></a>($stmt, $var, $size=4001, $type=false, $name=false)</b></font></p> 
     2280  
     2281<p><font>This is a low-level function supported only by the oci8  
    25812282  driver. <b>Avoid using</b> unless you only want to support Oracle. The Parameter(  
    25822283  ) function is the recommended way to go with bind variables.</font></p> 
    2583 <p><font color="#000000">Bind( ) allows you to use bind variables in your sql  
     2284<p><font>Bind( ) allows you to use bind variables in your sql  
    25842285  statement. This binds a PHP variable to a name defined in an Oracle sql statement  
    25852286  that was previously prepared using Prepare(). Oracle named variables begin with  
     
    25932294  Lastly, instead of using the default :0, :1, etc names, you can define your  
    25942295  own bind-name using $name.  
    2595 <p><font color="#000000">The following example shows 3 bind variables being used:  
     2296</p><p><font>The following example shows 3 bind variables being used:  
    25962297  p1, p2 and p3. These variables are bound to :0, :1 and :2.</font></p> 
    2597 <pre>$stmt = $DB-&gt;Prepare(&quot;insert into table (col0, col1, col2) values (:0, :1, :2)&quot;); 
    2598 $DB-&gt;Bind($stmt, $p1); 
    2599 $DB-&gt;Bind($stmt, $p2); 
    2600 $DB-&gt;Bind($stmt, $p3); 
    2601 for ($i = 0; $i &lt; $max; $i++) {  
    2602    $p1 = ?; $p2 = ?; $p3 = ?; 
    2603    $DB-&gt;Execute($stmt); 
    2604 }</pre> 
     2298<pre>$stmt = $DB-&gt;Prepare("insert into table (col0, col1, col2) values (:0, :1, :2)");<br>$DB-&gt;Bind($stmt, $p1);<br>$DB-&gt;Bind($stmt, $p2);<br>$DB-&gt;Bind($stmt, $p3);<br>for ($i = 0; $i &lt; $max; $i++) { <br>   $p1 = ?; $p2 = ?; $p3 = ?;<br>   $DB-&gt;Execute($stmt);<br>}</pre> 
    26052299<p>You can also use named variables:</p> 
    2606 <pre> 
    2607 $stmt = $DB-&gt;Prepare(&quot;insert into table (col0, col1, col2) values (:name0, :name1, :name2)&quot;); 
    2608 $DB-&gt;Bind($stmt, $p1, &quot;name0&quot;); 
    2609 $DB-&gt;Bind($stmt, $p2, &quot;name1&quot;); 
    2610 $DB-&gt;Bind($stmt, $p3, &quot;name2&quot;); 
    2611 for ($i = 0; $i &lt; $max; $i++) {  
    2612    $p1 = ?; $p2 = ?; $p3 = ?; 
    2613    $DB-&gt;Execute($stmt); 
    2614 }</pre> 
    2615 <p><b>LogSQL($enable=true)<a name=logsql></a></b></p> 
     2300<pre>$stmt = $DB-&gt;Prepare("insert into table (col0, col1, col2) values (:name0, :name1, :name2)");<br>$DB-&gt;Bind($stmt, $p1, "name0");<br>$DB-&gt;Bind($stmt, $p2, "name1");<br>$DB-&gt;Bind($stmt, $p3, "name2");<br>for ($i = 0; $i &lt; $max; $i++) { <br>   $p1 = ?; $p2 = ?; $p3 = ?;<br>   $DB-&gt;Execute($stmt);<br>}</pre> 
     2301<p><b>LogSQL($enable=true)<a name="logsql"></a></b></p> 
    26162302Call this method to install a SQL logging and timing function (using fnExecute).  
    26172303Then all SQL statements are logged into an adodb_logsql table in a database. If  
     
    26202306false for disabled). Here are samples of the DDL for selected databases:  
    26212307<p>  
    2622 <pre> 
    2623                 <b>mysql:</b> 
     2308</p><pre>               <b>mysql:</b> 
    26242309                CREATE TABLE adodb_logsql ( 
    26252310                  created datetime NOT NULL, 
     
    26622347</pre> 
    26632348Usage:  
    2664 <pre> 
    2665         $conn->LogSQL(); // turn on logging 
    2666           : 
    2667         $conn->Execute(...); 
    2668           : 
    2669         $conn->LogSQL(false); // turn off logging 
    2670          
    2671         # output summary of SQL logging results 
    2672         $perf = NewPerfMonitor($conn); 
    2673         echo $perf->SuspiciousSQL(); 
    2674         echo $perf->ExpensiveSQL(); 
    2675 </pre> 
     2349<pre>   $conn-&gt;LogSQL(); // turn on logging<br>        :<br> $conn-&gt;Execute(...);<br>       :<br> $conn-&gt;LogSQL(false); // turn off logging<br>        <br>    # output summary of SQL logging results<br>     $perf = NewPerfMonitor($conn);<br>      echo $perf-&gt;SuspiciousSQL();<br>     echo $perf-&gt;ExpensiveSQL();<br></pre> 
    26762350<p>One limitation of logging is that rollback also prevents SQL from being logged. 
    2677 <p> 
     2351</p><p> 
    26782352If you prefer to use another name for the table used to store the SQL, you can override it by calling  
    26792353adodb_perf::table($tablename), where $tablename is the new table name (you will still need to manually 
    26802354create the table yourself). An example: 
    2681 <pre> 
    2682         include('adodb.inc.php'); 
    2683         include('adodb-perf.inc.php'); 
    2684         adodb_perf::table('my_logsql_table'); 
    2685 </pre> 
    2686 Also see <a href=docs-perf.htm>Performance Monitor</a>.  
    2687 <p><font color="#000000"><b>fnExecute and fnCacheExecute properties<a name="fnexecute" id="fnexecute"></a></b></font></p> 
     2355</p><pre>       include('adodb.inc.php');<br>   include('adodb-perf.inc.php');<br>      adodb_perf::table('my_logsql_table');<br></pre> 
     2356Also see <a href="docs-perf.htm">Performance Monitor</a>.  
     2357<p><font><b>fnExecute and fnCacheExecute properties<a name="fnexecute" id="fnexecute"></a></b></font></p> 
    26882358<p>These two properties allow you to define bottleneck functions for all sql statements  
    26892359  processed by ADOdb. This allows you to perform statistical analysis and query-rewriting  
    26902360  of your sql.  
    2691 <p><b>Examples of fnExecute</b></p> 
     2361</p><p><b>Examples of fnExecute</b></p> 
    26922362<p>Here is an example of using fnExecute, to count all cached queries and non-cached  
    26932363  queries, you can do this:</p> 
    26942364<pre><font color="#006600"># $db is the connection object</font> 
    2695 function CountExecs($db, $sql, $inputarray) 
     2365function &CountExecs($db, $sql, $inputarray) 
    26962366{ 
    26972367global $EXECS; 
    26982368 
    2699 if (!is_array(inputarray)) $EXECS++; 
    2700 <font color="#006600"># handle 2-dimensional input arrays</font> 
    2701 else if (is_array(reset($inputarray))) $EXECS += sizeof($inputarray); 
    2702 else $EXECS++; 
     2369        if (!is_array(inputarray)) $EXECS++; 
     2370        <font color="#006600"># handle 2-dimensional input arrays</font> 
     2371        else if (is_array(reset($inputarray))) $EXECS += sizeof($inputarray); 
     2372        else $EXECS++; 
     2373         
     2374        <font color="#006600"># in PHP4.4 and PHP5, we need to return a value by reference</font> 
     2375        $null = null; 
     2376        return $null; 
    27032377} 
    27042378 
    27052379<font color="#006600"># $db is the connection object</font> 
    27062380function CountCachedExecs($db, $secs2cache, $sql, $inputarray) 
    2707 {<br>global $CACHED; $CACHED++; 
    2708 } 
    2709 <br>$db = NewADOConnection('mysql'); 
    2710 $db-&gt;Connect(...); 
    2711 $db-&gt;<strong>fnExecute</strong> = 'CountExecs'; 
    2712 $db-&gt;<strong>fnCacheExecute</strong> = 'CountCachedExecs'; 
    2713  : 
    2714  :<br><font color="#006600"># After many sql statements:</font>` 
    2715 printf(&quot;&lt;p&gt;Total queries=%d; total cached=%d&lt;/p&gt;&quot;,$EXECS+$CACHED, $CACHED); 
    2716 </pre> 
     2381{<br>global $CACHED; $CACHED++;<br>}<br><br>$db = NewADOConnection('mysql');<br>$db-&gt;Connect(...);<br>$db-&gt;<strong>fnExecute</strong> = 'CountExecs';<br>$db-&gt;<strong>fnCacheExecute</strong> = 'CountCachedExecs';<br> :<br> :<br><font color="#006600"># After many sql statements:</font>`<br>printf("&lt;p&gt;Total queries=%d; total cached=%d&lt;/p&gt;",$EXECS+$CACHED, $CACHED);<br></pre> 
    27172382<p>The fnExecute function is called before the sql is parsed and executed, so  
    27182383  you can perform a query rewrite. If you are passing in a prepared statement,  
    27192384  then $sql is an array (see <a href="#prepare">Prepare</a>). The fnCacheExecute  
    2720   function is only called if the recordset returned was cached.<font color="#000000">  
     2385  function is only called if the recordset returned was cached.<font>  
    27212386  The function parameters match the Execute and CacheExecute functions respectively,  
    27222387  except that $this (the connection object) is passed as the first parameter.</font></p> 
     
    27242389  defined function returns a value. If it does not return a value, then the $sql  
    27252390  is executed as before. This is useful for query rewriting or counting sql queries.  
    2726 <p> On the other hand, you might want to replace the Execute function with one  
     2391</p><p> On the other hand, you might want to replace the Execute function with one  
    27272392  of your own design. If this is the case, then have your function return a value.  
    27282393  If a value is returned, that value is returned immediately, without any further  
    27292394  processing. This is used internally by ADOdb to implement LogSQL() functionality.  
    2730 <p> <font color="#000000">  
    2731 <hr> 
    2732 <h3>ADOConnection Utility Functions</h3> 
    2733 <p><b>BlankRecordSet<a name="blankrecordset"></a>([$queryid])</b></p> 
    2734 <p>No longer available - removed since 1.99.</p> 
    2735 <p><b>Concat<a name="concat"></a>($s1,$s2,....)</b></p> 
    2736 <p>Generates the sql string used to concatenate $s1, $s2, etc together. Uses the  
     2395</p> 
     2396<p> 
     2397</p><hr /> 
     2398<h3><font>ADOConnection Utility Functions</font></h3> 
     2399<p><font><b>BlankRecordSet<a name="blankrecordset"></a>([$queryid])</b></font></p> 
     2400<p><font>No longer available - removed since 1.99.</font></p> 
     2401<p><font><b>Concat<a name="concat"></a>($s1,$s2,....)</b></font></p> 
     2402<p><font>Generates the sql string used to concatenate $s1, $s2, etc together. Uses the  
    27372403  string in the concat_operator field to generate the concatenation. Override  
    2738   this function if a concatenation operator is not used, eg. MySQL.</p> 
    2739 <p>Returns the concatenated string.</p> 
    2740 <p><b>DBDate<a name="dbdate"></a>($date)</b></p> 
    2741 <p>Format the $<b>date</b> in the format the database accepts. This is used in  
    2742   INSERT/UPDATE statements; for SELECT statements, use <a href="#sqldate">SQLDate</a>.  
     2404  this function if a concatenation operator is not used, eg. MySQL.</font></p> 
     2405<p><font>Returns the concatenated string.</font></p> 
     2406<p><font><b>DBDate<a name="dbdate"></a>($date)</b></font></p> 
     2407<p><font>Format the $<b>date</b> in the format the database accepts - the return string is also quoted. This is used 
     2408when you are sending dates to the database (eg INSERT, UPDATE or where clause of SELECT statement).  
    27432409  The $<b>date</b> parameter can be a Unix integer timestamp or an ISO format  
    27442410  Y-m-d. Uses the fmtDate field, which holds the format to use. If null or false  
    2745   or '' is passed in, it will be converted to an SQL null.</p> 
    2746 <p>Returns the date as a quoted string.</p> 
    2747 <p><b>DBTimeStamp<a name="dbtimestamp"></a>($ts)</b></p> 
    2748 <p>Format the timestamp $<b>ts</b> in the format the database accepts; this can  
     2411  or '' is passed in, it will be converted to an SQL null.</font></p> 
     2412<p><font>Returns the date as a quoted string.</font></p> 
     2413<pre> 
     2414        $sql = "select * from atable where created > ".$db->DBDate("$year-$month-$day"); 
     2415        $db->Execute($sql); 
     2416</pre> 
     2417<p>Note to retrieve a date column in a specific format,  use <a href="#sqldate">SQLDate</a>. </p> 
     2418<p><font><b>BindDate<a name="binddate"></a>($date)</b></font></p> 
     2419<p><font>Format the $<b>date</b> in the bind format the database accepts. Normally 
     2420 this means that the date string is not quoted, unlike DBDate, which quotes the string. 
     2421<pre> 
     2422        $sql = "select * from atable where created > ".$db->Param('0'); 
     2423        // or 
     2424        $sql = "select * from atable where created > ?"; 
     2425        $db->Execute($sql,array($db->BindDate("$year-$month-$day")); 
     2426</pre> 
     2427<p><font><b>DBTimeStamp<a name="dbtimestamp"></a>($ts)</b></font></p> 
     2428<p><font>Format the timestamp $<b>ts</b> in the format the database accepts; this can  
    27492429  be a Unix integer timestamp or an ISO format Y-m-d H:i:s. Uses the fmtTimeStamp  
    27502430  field, which holds the format to use. If null or false or '' is passed in, it  
    2751   will be converted to an SQL null.</p> 
    2752 <p>Returns the timestamp as a quoted string.</p> 
    2753 <p><b>qstr<a name="qstr"></a>($s,[$magic_quotes_enabled</b>=false]<b>)</b></p> 
    2754 <p>Quotes a string to be sent to the database. The $<b>magic_quotes_enabled</b>  
     2431  will be converted to an SQL null.</font></p> 
     2432<p><font>Returns the timestamp as a quoted string.</font></p> 
     2433<pre> 
     2434        $sql = "select * from atable where created > ".$db->DBTimeStamp("$year-$month-$day $hr:$min:$secs"); 
     2435        $db->Execute($sql); 
     2436</pre> 
     2437<p><font><b>BindTimeStamp<a name="bindtimestamp"></a>($ts)</b></font></p> 
     2438<p><font>Format the timestamp $<b>ts</b> in the bind format the database accepts. Normally 
     2439 this means that the timestamp string is not quoted, unlike DBTimeStamp, which quotes the string. 
     2440<pre> 
     2441        $sql = "select * from atable where created > ".$db->Param('0'); 
     2442        // or 
     2443        $sql = "select * from atable where created > ?"; 
     2444        $db->Execute($sql,array($db->BindTimeStamp("$year-$month-$day $hr:$min:$secs")); 
     2445</pre> 
     2446<p><font><b>qstr<a name="qstr"></a>($s,[$magic_quotes_enabled</b>=false]<b>)</b></font></p> 
     2447<p><font>Quotes a string to be sent to the database. The $<b>magic_quotes_enabled</b>  
    27552448  parameter may look funny, but the idea is if you are quoting a string extracted  
    27562449  from a POST/GET variable, then pass get_magic_quotes_gpc() as the second parameter.  
    27572450  This will ensure that the variable is not quoted twice, once by <i>qstr</i>  
    2758   and once by the <i>magic_quotes_gpc</i>.</p> 
    2759 <p>Eg.<font face="Courier New, Courier, mono"> $s = $db-&gt;qstr(HTTP_GET_VARS['name'],get_magic_quotes_gpc());</font></p> 
    2760 <p>Returns the quoted string.</p> 
    2761 <p><b>Quote<a name="quote"></a>($s)</b></p> 
    2762 <p>Quotes the string $s, escaping the database specific quote character as appropriate.  
     2451  and once by the <i>magic_quotes_gpc</i>.</font></p> 
     2452<p><font>Eg.<font face="Courier New, Courier, mono"> $s = $db-&gt;qstr(HTTP_GET_VARS['name'],get_magic_quotes_gpc());</font></font></p> 
     2453<p><font>Returns the quoted string.</font></p> 
     2454<p><font><b>Quote<a name="quote"></a>($s)</b></font></p> 
     2455<p><font>Quotes the string $s, escaping the database specific quote character as appropriate.  
    27632456  Formerly checked magic quotes setting, but this was disabled since 3.31 for  
    27642457  compatibility with PEAR DB.  
    2765 <p><b>Affected_Rows<a name="affected_rows"></a>( )</b></p> 
    2766 <p>Returns the number of rows affected by a update or delete statement. Returns  
    2767   false if function not supported.</p> 
    2768 <p>Not supported by interbase/firebird currently. </p> 
    2769 <p><b>Insert_ID<a name="inserted_id"></a>( )</b></p> 
    2770 <p>Returns the last autonumbering ID inserted. Returns false if function not supported.  
    2771 </p> 
    2772 <p>Only supported by databases that support auto-increment or object id's, such  
     2458</font></p><p><font><b>Affected_Rows<a name="affected_rows"></a>( )</b></font></p> 
     2459<p><font>Returns the number of rows affected by a update or delete statement. Returns  
     2460  false if function not supported.</font></p> 
     2461<p><font>Not supported by interbase/firebird currently. </font></p> 
     2462<p><font><b>Insert_ID<a name="inserted_id"></a>( )</b></font></p> 
     2463<p><font>Returns the last autonumbering ID inserted. Returns false if function not supported.  
     2464</font></p> 
     2465<p><font>Only supported by databases that support auto-increment or object id's, such  
    27732466  as PostgreSQL, MySQL and MS SQL Server currently. PostgreSQL returns the OID, which  
    2774   can change on a database reload.</p> 
    2775 <p><b>RowLock<a name="rowlock"></a>($table,$where)</b></p> 
    2776 <p>Lock a table row for the duration of a transaction. For example to lock record $id in table1: 
    2777 <pre> 
    2778         $DB->StartTrans(); 
    2779         $DB->RowLock("table1","rowid=$id"); 
    2780         $DB->Execute($sql1); 
    2781         $DB->Execute($sql2); 
    2782         $DB->CompleteTrans(); 
    2783 </pre> 
    2784 <p>Supported in db2, interbase, informix, mssql, oci8, postgres, sybase. 
    2785 <p><b>MetaDatabases<a name="metadatabases"></a>()</b></p> 
    2786 <p>Returns a list of databases available on the server as an array. You have to  
    2787   connect to the server first. Only available for ODBC, MySQL and ADO.</p> 
    2788 <p><b>MetaTables<a name="metatables"></a>($ttype = false, $showSchema = false,  
    2789   $mask=false)</b></p> 
    2790 <p>Returns an array of tables and views for the current database as an array.  
     2467  can change on a database reload.</font></p> 
     2468<p><font><b>RowLock<a name="rowlock"></a>($table,$where)</b></font></p> 
     2469<p><font>Lock a table row for the duration of a transaction. For example to lock record $id in table1: 
     2470</font></p><pre><font>  $DB-&gt;StartTrans();<br>       $DB-&gt;RowLock("table1","rowid=$id");<br>      $DB-&gt;Execute($sql1);<br>     $DB-&gt;Execute($sql2);<br>     $DB-&gt;CompleteTrans();<br></font></pre> 
     2471<p><font>Supported in db2, interbase, informix, mssql, oci8, postgres, sybase. 
     2472</font></p><p><font><b>MetaDatabases<a name="metadatabases"></a>()</b></font></p> 
     2473<p><font>Returns a list of databases available on the server as an array. You have to  
     2474  connect to the server first. Only available for ODBC, MySQL and ADO.</font></p> 
     2475<p><font><b>MetaTables<a name="metatables"></a>($ttype = false, $showSchema = false,  
     2476  $mask=false)</b></font></p> 
     2477<p><font>Returns an array of tables and views for the current database as an array.  
    27912478  The array should exclude system catalog tables if possible. To only show tables,  
    2792   use $db->MetaTables('TABLES'). To show only views, use $db->MetaTables('VIEWS').  
     2479  use $db-&gt;MetaTables('TABLES'). To show only views, use $db-&gt;MetaTables('VIEWS').  
    27932480  The $showSchema parameter currently works only for DB2, and when set to true,  
    2794   will add the schema name to the table, eg. "SCHEMA.TABLE". </p> 
    2795 <p>You can define a mask for matching. For example, setting $mask = 'TMP%' will  
     2481  will add the schema name to the table, eg. "SCHEMA.TABLE". </font></p> 
     2482<p><font>You can define a mask for matching. For example, setting $mask = 'TMP%' will  
    27962483  match all tables that begin with 'TMP'. Currently only mssql, oci8, odbc_mssql  
    27972484  and postgres* support $mask.  
    2798 <p><b>MetaColumns<a name="metacolumns"></a>($table,$toupper=true)</b></p> 
    2799 <p>Returns an array of ADOFieldObject's, one field object for every column of  
     2485</font></p><p><font><b>MetaColumns<a name="metacolumns"></a>($table,$notcasesensitive=true)</b></font></p> 
     2486<p><font>Returns an array of ADOFieldObject's, one field object for every column of  
    28002487  $table. A field object is a class instance with (name, type, max_length) defined. 
    28012488  Currently Sybase does not recognise date types, and ADO cannot identify  
    28022489  the correct data type (so we default to varchar).    
    2803  <p> The $toupper parameter determines whether we uppercase the table name  
    2804  (required for some databases). 
    2805  <p>For schema support, pass in the $table parameter, "$schema.$tablename". This is only 
     2490 </font></p><p><font> The $notcasesensitive parameter determines whether we uppercase or lowercase the table name to normalize it 
     2491 (required for some databases). Does not work with MySQL ISAM tables. 
     2492 </font></p><p><font>For schema support, pass in the $table parameter, "$schema.$tablename". This is only 
    28062493 supported for selected databases. 
    2807 <p><b>MetaColumnNames<a name="metacolumnames"></a>($table,$numericIndex=false)</b></p> 
    2808 <p>Returns an array of column names for $table. Since ADOdb 4.22, this is an associative array, with the 
     2494</font></p><p><font><b>MetaColumnNames<a name="metacolumnames"></a>($table,$numericIndex=false)</b></font></p> 
     2495<p><font>Returns an array of column names for $table. Since ADOdb 4.22, this is an associative array, with the 
    28092496keys in uppercase. Set $numericIndex=true if you want the old behaviour of numeric indexes (since 4.23). 
    2810 <p> 
    2811 e.g. array('FIELD1' => 'Field1', 'FIELD2'=>'Field2') 
    2812 <p> 
    2813 <p><font color="#000000"><b>MetaPrimaryKeys<a name="metaprimarykeys"></a>($table,  
    2814   $owner=false)</b></font></font>  
    2815 <p><font color="#000000">Returns an array containing column names that are the  
     2497</font></p><p> 
     2498<font>e.g. array('FIELD1' =&gt; 'Field1', 'FIELD2'=&gt;'Field2') 
     2499</font></p><p> 
     2500</p><p><font><b>MetaPrimaryKeys<a name="metaprimarykeys"></a>($table, 
     2501      $owner=false)</b></font>  
     2502</p> 
     2503<p><font>Returns an array containing column names that are the  
    28162504  primary keys of $table. Supported by mysql, odbc (including db2, odbc_mssql,  
    2817   etc), mssql, postgres, interbase/firebird, oci8 currently. </font><font color="#000000">  
    2818 <p>Views (and some tables) have primary keys, but sometimes this information is not available from the 
     2505etc), mssql, postgres, interbase/firebird, oci8 currently. </font></p> 
     2506<p><font>Views (and some tables) have primary keys, but sometimes this information is not available from the 
    28192507database. You can define a function  ADODB_View_PrimaryKeys($databaseType, $database, $view, $owner) that 
    28202508should return an array containing the fields that make up the primary key. If that function exists, 
    28212509it will be called when MetaPrimaryKeys() cannot find a primary key for a table or view. 
    2822 <pre> 
    2823 // In this example: dbtype = 'oci8', $db = 'mydb', $view = 'dataView', $owner = false  
    2824 function ADODB_View_PrimaryKeys($dbtype,$db,$view,$owner) 
    2825 { 
    2826         switch(strtoupper($view)) { 
    2827         case 'DATAVIEW': return array('DATAID'); 
    2828         default: return false; 
    2829         } 
    2830 } 
    2831  
    2832 $db = NewADOConnection('oci8'); 
    2833 $db->Connect('localhost','root','','mydb');  
    2834 $db->MetaPrimaryKeys('dataView'); 
    2835 </pre> 
    2836 <p><font color="#000000"><b>ServerInfo<a name="serverinfo" id="serverinfo"></a>($table)</b></font></font>  
    2837 <p><font color="#000000">Returns an array of containing two elements 'description'  
     2510</font></p><pre><font>// In this example: dbtype = 'oci8', $db = 'mydb', $view = 'dataView', $owner = false <br>function ADODB_View_PrimaryKeys($dbtype,$db,$view,$owner)<br>{<br>      switch(strtoupper($view)) {<br> case 'DATAVIEW': return array('DATAID');<br>    default: return false;<br>      }<br>}<br><br>$db = NewADOConnection('oci8');<br>$db-&gt;Connect('localhost','root','','mydb'); <br>$db-&gt;MetaPrimaryKeys('dataView');<br></font></pre> 
     2511<p><font><b>ServerInfo<a name="serverinfo" id="serverinfo"></a>()</b></font>  
     2512</p> 
     2513<p><font>Returns an array of containing two elements 'description'  
    28382514  and 'version'. The 'description' element contains the string description of  
    28392515  the database. The 'version' naturally holds the version number (which is also  
    2840   a string).</font><font color="#000000">  
    2841 <p><b>MetaForeignKeys<a name="metaforeignkeys"></a>($table, $owner=false, $upper=false)</b>  
    2842 <p>Returns an associate array of foreign keys, or false if not supported. For  
     2516a string).</font></p> 
     2517<p><font><b>MetaForeignKeys<a name="metaforeignkeys"></a>($table, $owner=false, $upper=false)</b>  
     2518</font></p><p><font>Returns an associate array of foreign keys, or false if not supported. For  
    28432519  example, if table employee has a foreign key where employee.deptkey points to  
    28442520  dept_table.deptid, and employee.posn=posn_table.postionid and employee.poscategory=posn_table.category,  
    2845   then $conn->MetaForeignKeys('employee') will return  
    2846 <pre> 
    2847         array( 
    2848                 'dept_table' => array('deptkey=deptid'), 
    2849                 'posn_table' => array('posn=positionid','poscategory=category') 
    2850         ) 
    2851 </pre> 
    2852 <p>The optional schema or owner can be defined in $owner. If $upper is true, then  
     2521  then $conn-&gt;MetaForeignKeys('employee') will return  
     2522</font></p><pre><font>  array(<br>              'dept_table' =&gt; array('deptkey=deptid'),<br>         'posn_table' =&gt; array('posn=positionid','poscategory=category')<br>  )<br></font></pre> 
     2523<p><font>The optional schema or owner can be defined in $owner. If $upper is true, then  
    28532524  the table names (array keys) are upper-cased.  
    2854 <hr> 
    2855 <h2>ADORecordSet<a name="adorecordset"></a></h2> 
    2856 <p>When an SQL statement successfully is executed by <font face="Courier New, Courier, mono">ADOConnection-&gt;Execute($sql),</font>an  
     2525</font></p><hr /> 
     2526<h2><font>ADORecordSet<a name="adorecordset"></a></font></h2> 
     2527<p><font>When an SQL statement successfully is executed by <font face="Courier New, Courier, mono">ADOConnection-&gt;Execute($sql),</font>an  
    28572528  ADORecordSet object is returned. This object contains a virtual cursor so we  
    28582529  can move from row to row, functions to obtain information about the columns  
    28592530  and column types, and helper functions to deal with formating the results to  
    2860   show to the user.</p> 
    2861 <h3>ADORecordSet Fields</h3> 
    2862 <p><b>fields: </b>Array containing the current row. This is not associative, but  
     2531  show to the user.</font></p> 
     2532<h3><font>ADORecordSet Fields</font></h3> 
     2533<p><font><b>fields: </b>Array containing the current row. This is not associative, but  
    28632534  is an indexed array from 0 to columns-1. See also the function <b><a href="#fields">Fields</a></b>,  
    2864   which behaves like an associative array.</p> 
    2865 <p><b>dataProvider</b>: The underlying mechanism used to connect to the database.  
    2866   Normally set to <b>native</b>, unless using <b>odbc</b> or <b>ado</b>.</p> 
    2867 <p><b>blobSize</b>: Maximum size of a char, string or varchar object before it  
     2535  which behaves like an associative array.</font></p> 
     2536<p><font><b>dataProvider</b>: The underlying mechanism used to connect to the database.  
     2537  Normally set to <b>native</b>, unless using <b>odbc</b> or <b>ado</b>.</font></p> 
     2538<p><font><b>blobSize</b>: Maximum size of a char, string or varchar object before it  
    28682539  is treated as a Blob (Blob's should be shown with textarea's). See the <a href="#metatype">MetaType</a>  
    2869   function.</p> 
    2870 <p><b>sql</b>: Holds the sql statement used to generate this record set.</p> 
    2871 <p><b>canSeek</b>: Set to true if Move( ) function works.</p> 
    2872 <p><b>EOF</b>: True if we have scrolled the cursor past the last record.</p> 
    2873 <h3>ADORecordSet Functions</h3> 
    2874 <p><b>ADORecordSet( )</b></p> 
    2875 <p>Constructer. Normally you never call this function yourself.</p> 
    2876 <p><b>GetAssoc<a name="getassoc"></a>([$force_array])</b></p> 
    2877 <p>Generates an associative array from the recordset. Note that is this function  
     2540  function.</font></p> 
     2541<p><font><b>sql</b>: Holds the sql statement used to generate this record set.</font></p> 
     2542<p><font><b>canSeek</b>: Set to true if Move( ) function works.</font></p> 
     2543<p><font><b>EOF</b>: True if we have scrolled the cursor past the last record.</font></p> 
     2544<h3><font>ADORecordSet Functions</font></h3> 
     2545<p><font><b>ADORecordSet( )</b></font></p> 
     2546<p><font>Constructer. Normally you never call this function yourself.</font></p> 
     2547<p><font><b>GetAssoc<a name="getassoc"></a>([$force_array])</b></font></p> 
     2548<p><font>Generates an associative array from the recordset. Note that is this function  
    28782549  is also <a href="#getassoc1">available</a> in the connection object. More details  
    2879   can be found there.</p> 
    2880 </font></font><font color="#000000"><font color="#000000"> </font></font><font color="#000000"><font color="#000000"> 
    2881 <p><b>GetArray<a name="getarray"></a>([$number_of_rows])</b></p> 
    2882 <p>Generate a 2-dimensional array of records from the current cursor position,  
    2883   indexed from 0 to $number_of_rows - 1. If $number_of_rows is undefined, till  
    2884   EOF.</p> 
    2885 <p><b>GetRows<a name="getrows"></a>([$number_of_rows])</b></p> 
    2886 Generate a 2-dimensional array of records from the current cursor position. Synonym  
    2887 for GetArray() for compatibility with Microsoft ADO.  
    2888 <p> <b>GetMenu<a name="getmenu"></a>($name, [$default_str=''], [$blank1stItem=true],  
    2889   [$multiple_select=false], [$size=0], [$moreAttr=''])</b></p> 
    2890 <p>Generate a HTML menu (&lt;select&gt;&lt;option&gt;&lt;option&gt;&lt;/select&gt;).  
    2891   The first column of the recordset (fields[0]) will hold the string to display  
    2892   in the option tags. If the recordset has more than 1 column, the second column  
    2893   (fields[1]) is the value to send back to the web server.. The menu will be given  
    2894   the name $<i>name</i>.  
    2895 <p> If $<i>default_str</i> is defined, then if $<i>default_str</i> == fields[0],  
    2896   that field is selected. If $<i>blank1stItem</i> is true, the first option is  
    2897   empty. You can also set the first option strings by setting $blank1stItem =  
    2898   "$value:$text".</p> 
    2899 <p>$<i>Default_str</i> can be array for a multiple select listbox.</p> 
    2900 <p>To get a listbox, set the $<i>size</i> to a non-zero value (or pass $default_str  
    2901   as an array). If $<i>multiple_select</i> is true then a listbox will be generated  
    2902   with $<i>size</i> items (or if $size==0, then 5 items) visible, and we will  
    2903   return an array to a server. Lastly use $<i>moreAttr </i> to add additional  
    2904   attributes such as javascript or styles. </p> 
    2905 <p>Menu Example 1: <code>GetMenu('menu1','A',true)</code> will generate a menu:  
    2906   <select name='menu1'> 
    2907     <option>  
    2908     <option value=1 selected>A  
    2909     <option value=2>B  
    2910     <option value=3>C  
    2911   </select> 
    2912   for the data (A,1), (B,2), (C,3). Also see <a href="#ex5">example 5</a>.</p> 
    2913 <p>Menu Example 2: For the same data, <code>GetMenu('menu1',array('A','B'),false)</code>  
    2914   will generate a menu with both A and B selected: <br> 
    2915   <select name='menu1' multiple size=3> 
    2916     <option value=1 selected>A  
    2917     <option value=2 selected>B  
    2918     <option value=3>C  
    2919   </select> 
    2920 <p> <b>GetMenu2<a name="getmenu2"></a>($name, [$default_str=''], [$blank1stItem=true],  
    2921   [$multiple_select=false], [$size=0], [$moreAttr=''])</b></p> 
    2922 <p>This is nearly identical to GetMenu, except that the $<i>default_str</i> is  
    2923   matched to fields[1] (the option values).</p> 
    2924 <p>Menu Example 3: Given the data in menu example 2, <code>GetMenu2('menu1',array('1','2'),false)</code>  
    2925   will generate a menu with both A and B selected in menu example 2, but this  
    2926   time the selection is based on the 2nd column, which holds the values to return  
    2927   to the Web server.  
    2928 <p><b>UserDate<a name="userdate"></a>($str, [$fmt])</b></p> 
    2929 <p>Converts the date string $<i>str</i> to another format. The date format is Y-m-d, 
    2930 or Unix timestamp format. The default $<i>fmt</i> is Y-m-d.</p> 
    2931 <p><b>UserTimeStamp<a name="usertimestamp"></a>($str, [$fmt])</b></p> 
    2932 <p>Converts the timestamp string $<b>str</b> to another format. The timestamp  
    2933   format is Y-m-d H:i:s, as in '2002-02-28 23:00:12', or Unix timestamp format. 
    2934    UserTimeStamp calls UnixTimeStamp to parse $<i>str</i>, and $<i>fmt</i> defaults to Y-m-d H:i:s if not defined.  
    2935 </p> 
    2936 <p><b>UnixDate<a name="unixdate"></a>($str)</b></p> 
    2937 <p>Parses the date string $<b>str</b> and returns it in unix mktime format (eg.  
    2938   a number indicating the seconds after January 1st, 1970). Expects the date to  
    2939   be in Y-m-d H:i:s format, except for Sybase and Microsoft SQL Server, where  
    2940   M d Y is also accepted (the 3 letter month strings are controlled by a global  
    2941   array, which might need localisation).</p> 
    2942 <p>This function is available in both ADORecordSet and ADOConnection since 1.91.</p> 
    2943 <p><b>UnixTimeStamp<a name="unixtimestamp"></a>($str)</b></p> 
    2944 <p>Parses the timestamp string $<b>str</b> and returns it in unix mktime format  
    2945   (eg. a number indicating the seconds after January 1st, 1970). Expects the date  
    2946   to be in "Y-m-d, H:i:s" (1970-12-24, 00:00:00) or "Y-m-d H:i:s" (1970-12-24 00:00:00) or "YmdHis" (19701225000000) format, except for Sybase and Microsoft SQL Server, where  
    2947   "M d Y h:i:sA" (Dec 25 1970 00:00:00AM) is also accepted (the 3 letter month strings are controlled by  
    2948   a global array, which might need localisation).</p> 
    2949 </font>  
    2950 <p><font color="#000000">This function is available in both ADORecordSet and ADOConnection  
    2951   since 1.91. </font></p> 
    2952 <p><font color="#000000"><b>OffsetDate<a name="offsetdate"></a>($dayFraction,  
     2550  can be found there.</font></p> 
     2551<font> </font> 
     2552<p><font><b>GetArray<a name="getarray"></a>([$number_of_rows])</b></font></p> 
     2553<p><font>Generate a 2-dimensional array of records from the current 
     2554    cursor position, indexed from 0 to $number_of_rows - 1. If $number_of_rows 
     2555  is undefined, till EOF.</font></p> 
     2556<p><font><b>GetRows<a name="getrows"></a>([$number_of_rows])</b></font></p> 
     2557<font>Generate a 2-dimensional array of records from the current 
     2558cursor position. Synonym for GetArray() for compatibility with Microsoft ADO. </font> 
     2559<p><font> <b>GetMenu<a name="getmenu"></a>($name, [$default_str=''], 
     2560  [$blank1stItem=true], [$multiple_select=false], [$size=0], [$moreAttr=''])</b></font></p> 
     2561<p><font>Generate a HTML menu (&lt;select&gt;&lt;option&gt;&lt;option&gt;&lt;/select&gt;). 
     2562    The first column of the recordset (fields[0]) will hold the string to display 
     2563    in the option tags. If the recordset has more than 1 column, the second column 
     2564    (fields[1]) is the value to send back to the web server.. The menu will be 
     2565given the name $<i>name</i>. </font></p> 
     2566<p><font> If $<i>default_str</i> is defined, then if $<i>default_str</i> == 
     2567    fields[0], that field is selected. If $<i>blank1stItem</i> is true, the first 
     2568    option is empty. You can also set the first option strings by setting $blank1stItem 
     2569  = "$value:$text".</font></p> 
     2570<p><font>$<i>Default_str</i> can be array for a multiple select 
     2571listbox.</font></p> 
     2572<p><font>To get a listbox, set the $<i>size</i> to a non-zero 
     2573    value (or pass $default_str as an array). If $<i>multiple_select</i> is true 
     2574    then a listbox will be generated with $<i>size</i> items (or if $size==0, 
     2575    then 5 items) visible, and we will return an array to a server. Lastly use 
     2576  $<i>moreAttr </i> to add additional attributes such as javascript or styles. </font></p> 
     2577<p><font>Menu Example 1: <code>GetMenu('menu1','A',true)</code> will 
     2578    generate a menu: 
     2579    <select name="menu1"><option> </option><option value="1" selected="selected">A </option><option value="2">B </option><option value="3">C </option></select> 
     2580for the data (A,1), (B,2), (C,3). Also see <a href="#ex5">example 5</a>.</font></p> 
     2581<p><font>Menu Example 2: For the same data, <code>GetMenu('menu1',array('A','B'),false)</code> will 
     2582    generate a menu with both A and B selected: <br> 
     2583    <select name="menu1" multiple="multiple" size="3"><option value="1" selected="selected">A </option><option value="2" selected="selected">B </option><option value="3">C </option></select> 
     2584</font></p> 
     2585<p><font> <b>GetMenu2<a name="getmenu2"></a>($name, [$default_str=''], 
     2586  [$blank1stItem=true], [$multiple_select=false], [$size=0], [$moreAttr=''])</b></font></p> 
     2587<p><font>This is nearly identical to GetMenu, except that the 
     2588  $<i>default_str</i> is matched to fields[1] (the option values).</font></p> 
     2589<p><font>Menu Example 3: Given the data in menu example 2, <code>GetMenu2('menu1',array('1','2'),false)</code> will 
     2590    generate a menu with both A and B selected in menu example 2, but this time 
     2591    the selection is based on the 2nd column, which holds the values to return 
     2592to the Web server. </font></p> 
     2593<p><font><b>UserDate<a name="userdate"></a>($str, [$fmt])</b></font></p> 
     2594<p><font>Converts the date string $<i>str</i> to another format. 
     2595    The date format is Y-m-d, or Unix timestamp format. The default $<i>fmt</i> is 
     2596Y-m-d.</font></p> 
     2597<p><font><b>UserTimeStamp<a name="usertimestamp"></a>($str, [$fmt])</b></font></p> 
     2598<p><font>Converts the timestamp string $<b>str</b> to another 
     2599    format. The timestamp format is Y-m-d H:i:s, as in '2002-02-28 23:00:12', 
     2600    or Unix timestamp format. UserTimeStamp calls UnixTimeStamp to parse $<i>str</i>, 
     2601and $<i>fmt</i> defaults to Y-m-d H:i:s if not defined. </font></p> 
     2602<p><font><b>UnixDate<a name="unixdate"></a>($str)</b></font></p> 
     2603<p><font>Parses the date string $<b>str</b> and returns it in 
     2604    unix mktime format (eg. a number indicating the seconds after January 1st, 
     2605    1970). Expects the date to be in Y-m-d H:i:s format, except for Sybase and 
     2606    Microsoft SQL Server, where M d Y is also accepted (the 3 letter month strings 
     2607  are controlled by a global array, which might need localisation).</font></p> 
     2608<p><font>This function is available in both ADORecordSet and 
     2609ADOConnection since 1.91.</font></p> 
     2610<p><font><b>UnixTimeStamp<a name="unixtimestamp"></a>($str)</b></font></p> 
     2611<p><font>Parses the timestamp string $<b>str</b> and returns 
     2612    it in unix mktime format (eg. a number indicating the seconds after January 
     2613    1st, 1970). Expects the date to be in "Y-m-d, H:i:s" (1970-12-24, 00:00:00) 
     2614    or "Y-m-d H:i:s" (1970-12-24 00:00:00) or "YmdHis" (19701225000000) format, 
     2615    except for Sybase and Microsoft SQL Server, where "M d Y h:i:sA" (Dec 25 
     2616    1970 00:00:00AM) is also accepted (the 3 letter month strings are controlled 
     2617by a global array, which might need localisation).</font></p> 
     2618<font>  
     2619</font><p><font>This function is available in both ADORecordSet 
     2620    and ADOConnection since 1.91. </font></p> 
     2621<p><font><b>OffsetDate<a name="OffsetDate"></a>($dayFraction, 
    29532622  $basedate=false)</b></font></p> 
    2954 <p><font color="#000000"><font color="#000000">Returns a string </font>with the  
    2955   native SQL functions to calculate future and past dates based on $basedate in  
    2956   a portable fashion. If $basedate is not defined, then the current date (at 12  
    2957   midnight) is used. Returns the SQL string that performs the calculation when  
    2958   passed to Execute(). </font></p> 
    2959 <p><font color="#000000">For example, in Oracle, to find the date and time that  
     2623<p><font>Returns a string with the native SQL functions to calculate 
     2624    future and past dates based on $basedate in a portable fashion. If $basedate 
     2625    is not defined, then the current date (at 12 midnight) is used. Returns the 
     2626  SQL string that performs the calculation when passed to Execute(). </font></p> 
     2627<p><font>For example, in Oracle, to find the date and time that 
    29602628  is 2.5 days from today, you can use:</font></p> 
    2961 <pre><font color="#000000"># get date one week from now 
    2962 $fld = $conn-&gt;OffsetDate(7); // returns &quot;(trunc(sysdate)+7&quot;)</font></pre> 
    2963 <pre><font color="#000000"># get date and time that is 60 hours from current date and time 
    2964 $fld = $conn-&gt;OffsetDate(2.5, $conn-&gt;sysTimeStamp);       // returns &quot;(sysdate+2.5)&quot;</font> 
    2965  
    2966 $conn-&gt;Execute(&quot;UPDATE TABLE SET dodate=$fld WHERE ID=$id&quot;);</pre> 
    2967 <p> This function is available for mysql, mssql, oracle, oci8 and postgresql drivers  
    2968   since 2.13. It might work with other drivers<font color="#000000"> provided  
    2969   they allow performing numeric day arithmetic on dates.</font></p> 
    2970 <font color="#000000">  
    2971 <p><font color="#000000"><b>SQLDate<a name="sqldate"></a>($dateFormat, $basedate=false)</b></font></p> 
    2972 Returns a string which contains the native SQL functions to format a date or date  
    2973 column $basedate. This is used in SELECT statements. For INSERT/UPDATE statements,  
    2974 use <a href="#dbdate">DBDate</a>. It uses a case-sensitive $dateFormat, which  
    2975 supports:  
    2976 <pre> 
    2977  Y: 4-digit Year 
    2978  Q: Quarter (1-4) 
    2979  M: Month (Jan-Dec) 
    2980  m: Month (01-12) 
    2981  d: Day (01-31) 
    2982  H: Hour (00-23) 
    2983  h: Hour (1-12) 
    2984  i: Minute (00-59) 
    2985  s: Second (00-60) 
    2986  A: AM/PM indicator</pre> 
    2987 <p>All other characters are treated as strings. You can also use \ to escape characters.  
    2988   Available on selected databases, including mysql, postgresql, mssql, oci8 and  
    2989   DB2.  
    2990 <p>This is useful in writing portable sql statements that GROUP BY on dates. For  
    2991   example to display total cost of goods sold broken by quarter (dates are stored  
    2992   in a field called postdate):  
    2993 <pre> 
    2994  $sqlfn = $db->SQLDate('Y-\QQ','postdate'); # get sql that formats postdate to output 2002-Q1 
    2995  $sql = "SELECT $sqlfn,SUM(cogs) FROM table GROUP BY $sqlfn ORDER BY 1 desc"; 
    2996  </pre> 
    2997 <p><b>MoveNext<a name="movenext"></a>( )</b></p> 
    2998 <p>Move the internal cursor to the next row. The <i>$this->fields</i> array is  
    2999   automatically updated. Returns false if unable to do so (normally because EOF  
    3000   has been reached), otherwise true.  
    3001 <p> If EOF is reached, then the $this->fields array is set to false (this was  
    3002   only implemented consistently in ADOdb 3.30). For the pre-3.30 behaviour of  
    3003   $this->fields (at EOF), set the global variable $ADODB_COMPAT_FETCH = true.</p> 
    3004 <p>Example:</p> 
    3005 <pre>$rs = $db-&gt;Execute($sql); 
    3006 if ($rs)  
    3007         while (!$rs-&gt;EOF) { 
    3008                 ProcessArray($rs->fields);       
    3009                 $rs->MoveNext(); 
    3010         } </pre> 
    3011 <p><b>Move<a name="move"></a>($to)</b></p> 
    3012 <p>Moves the internal cursor to a specific row $<b>to</b>. Rows are zero-based  
    3013   eg. 0 is the first row. The <b>fields</b> array is automatically updated. For  
    3014   databases that do not support scrolling internally, ADOdb will simulate forward  
    3015   scrolling. Some databases do not support backward scrolling. If the $<b>to</b>  
    3016   position is after the EOF, $<b>to</b> will move to the end of the RecordSet  
    3017   for most databases. Some obscure databases using odbc might not behave this  
    3018   way.</p> 
    3019 <p>Note: This function uses <i>absolute positioning</i>, unlike Microsoft's ADO.</p> 
    3020 <p>Returns true or false. If false, the internal cursor is not moved in most implementations,  
    3021   so AbsolutePosition( ) will return the last cursor position before the Move(  
    3022   ). </p> 
    3023 <p><b>MoveFirst<a name="movefirst"></a>()</b></p> 
    3024 <p>Internally calls Move(0). Note that some databases do not support this function.</p> 
    3025 <p><b>MoveLast<a name="movelast"></a>()</b></p> 
    3026 <p>Internally calls Move(RecordCount()-1). Note that some databases do not support  
    3027   this function.</p> 
    3028 <p><b>GetRowAssoc</b><a name="getrowassoc"></a>($toUpper=true)</p> 
    3029 <p>Returns an associative array containing the current row. The keys to the array  
    3030   are the column names. The column names are upper-cased for easy access. To get  
    3031   the next row, you will still need to call MoveNext(). </p> 
    3032 <p>For example:<br> 
    3033   Array ( [ID] => 1 [FIRSTNAME] => Caroline [LASTNAME] => Miranda [CREATED] =>  
    3034   2001-07-05 ) </p> 
    3035 <p>Note: do not use GetRowAssoc() with $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC.  
    3036   Because they have the same functionality, they will interfere with each other.</p> 
    3037 </font>  
    3038 <p><font color="#000000"><b>AbsolutePage<a name="absolutepage"></a>($page=-1)  
    3039   </b></font></p> 
    3040 <p>Returns the current page. Requires PageExecute()/CachePageExecute() to be called.  
    3041   See <a href=#ex8>Example 8</a>.</p> 
    3042 <font color="#000000">  
     2629<pre><font># get date one week from now<br>$fld = $conn-&gt;OffsetDate(7); // returns "(trunc(sysdate)+7")</font></pre> 
     2630<pre><font># get date and time that is 60 hours from current date and time<br>$fld = $conn-&gt;OffsetDate(2.5, $conn-&gt;sysTimeStamp); // returns "(sysdate+2.5)"<br><br>$conn-&gt;Execute("UPDATE TABLE SET dodate=$fld WHERE ID=$id");</font></pre> 
     2631<p><font> This function is available for mysql, mssql, oracle, oci8 and postgresql drivers  
     2632  since 2.13. It might work with other drivers provided they allow performing 
     2633  numeric day arithmetic on dates.</font></p> 
     2634<font> </font> 
     2635<p><font><b>SQLDate<a name="sqldate"></a>($dateFormat, $basedate=false)</b></font></p> 
     2636<font>Returns a string which contains the native SQL functions 
     2637to format a date or date column $basedate. This is used when retrieving date columns in SELECT statements. 
     2638For sending dates to the database (eg. in UPDATE, INSERT or the where clause of SELECT statements)  
     2639use <a href="#dbdate">DBDate</a>. It uses a case-sensitive 
     2640$dateFormat, which supports: </font> 
     2641<pre><font>  
     2642  Y: 4-digit Year 
     2643  Q: Quarter (1-4) 
     2644  M: Month (Jan-Dec) 
     2645  m: Month (01-12) 
     2646  d: Day (01-31) 
     2647  H: Hour (00-23) 
     2648  h: Hour (1-12) 
     2649  i: Minute (00-59) 
     2650  s: Second (00-60) 
     2651  A: AM/PM indicator 
     2652  w: day of week (0-6 or 1-7 depending on DB) 
     2653  l: day of week (as string - lowercase L) 
     2654  W: week in year (0..53 for MySQL, 1..53 for PostgreSQL and Oracle) 
     2655  </font></pre> 
     2656<p><font>All other characters are treated as strings. You can 
     2657    also use \ to escape characters. Available on selected databases, including 
     2658mysql, postgresql, mssql, oci8 and DB2. </font></p> 
     2659<p><font>This is useful in writing portable sql statements that 
     2660    GROUP BY on dates. For example to display total cost of goods sold broken 
     2661by quarter (dates are stored in a field called postdate): </font></p> 
     2662<pre><font> $sqlfn = $db-&gt;SQLDate('Y-\QQ','postdate'); # get sql that formats postdate to output 2002-Q1<br> $sql = "SELECT $sqlfn,SUM(cogs) FROM table GROUP BY $sqlfn ORDER BY 1 desc";<br> </font></pre> 
     2663<p><font><b>MoveNext<a name="movenext"></a>( )</b></font></p> 
     2664<p><font>Move the internal cursor to the next row. The <i>$this-&gt;fields</i> array 
     2665    is automatically updated. Returns false if unable to do so (normally because 
     2666EOF has been reached), otherwise true. </font></p> 
     2667<p><font> If EOF is reached, then the $this-&gt;fields array 
     2668    is set to false (this was only implemented consistently in ADOdb 3.30). For 
     2669    the pre-3.30 behaviour of $this-&gt;fields (at EOF), set the global variable 
     2670  $ADODB_COMPAT_FETCH = true.</font></p> 
     2671<p><font>Example:</font></p> 
     2672<pre><font>$rs = $db-&gt;Execute($sql);<br>if ($rs) <br>        while (!$rs-&gt;EOF) {<br>              ProcessArray($rs-&gt;fields);   <br>            $rs-&gt;MoveNext();<br> } </font></pre> 
     2673<p><font><b>Move<a name="move"></a>($to)</b></font></p> 
     2674<p><font>Moves the internal cursor to a specific row $<b>to</b>. 
     2675    Rows are zero-based eg. 0 is the first row. The <b>fields</b> array is automatically 
     2676    updated. For databases that do not support scrolling internally, ADOdb will 
     2677    simulate forward scrolling. Some databases do not support backward scrolling. 
     2678    If the $<b>to</b> position is after the EOF, $<b>to</b> will move to the 
     2679    end of the RecordSet for most databases. Some obscure databases using odbc 
     2680  might not behave this way.</font></p> 
     2681<p><font>Note: This function uses <i>absolute positioning</i>, 
     2682unlike Microsoft's ADO.</font></p> 
     2683<p><font>Returns true or false. If false, the internal cursor 
     2684    is not moved in most implementations, so AbsolutePosition( ) will return 
     2685  the last cursor position before the Move( ). </font></p> 
     2686<p><font><b>MoveFirst<a name="movefirst"></a>()</b></font></p> 
     2687<p><font>Internally calls Move(0). Note that some databases do 
     2688not support this function.</font></p> 
     2689<p><font><b>MoveLast<a name="movelast"></a>()</b></font></p> 
     2690<p><font>Internally calls Move(RecordCount()-1). Note that some 
     2691  databases do not support this function.</font></p> 
     2692<p><font><b>GetRowAssoc</b><a name="getrowassoc"></a>($toUpper=true)</font></p> 
     2693<p><font>Returns an associative array containing the current 
     2694    row. The keys to the array are the column names. The column names are upper-cased 
     2695  for easy access. To get the next row, you will still need to call MoveNext(). </font></p> 
     2696<p><font>For example:<br> 
     2697Array ( [ID] =&gt; 1 [FIRSTNAME] =&gt; Caroline [LASTNAME] =&gt; Miranda [CREATED] 
     2698=&gt; 2001-07-05 ) </font></p> 
     2699<p><font>Note: do not use GetRowAssoc() with $ADODB_FETCH_MODE 
     2700    = ADODB_FETCH_ASSOC. Because they have the same functionality, they will 
     2701  interfere with each other.</font></p> 
     2702<font>  
     2703</font><p><font><b>AbsolutePage<a name="absolutepage"></a>($page=-1) </b></font></p> 
     2704<p><font>Returns the current page. Requires PageExecute()/CachePageExecute() to be called.  
     2705  See <a href="#ex8">Example 8</a>.</font></p> 
     2706<font> 
    30432707<p><b>AtFirstPage<a name="atfirstpage">($status='')</a></b></p> 
    3044 <p>Returns true if at first page (1-based). Requires PageExecute()/CachePageExecute()  
    3045   to be called. See <a href=#ex8>Example 8</a>.</p> 
     2708<p>Returns true if at first page (1-based). Requires PageExecute()/CachePageExecute() 
     2709  to be called. See <a href="#ex8">Example 8</a>.</p> 
    30462710<p><b>AtLastPage<a name="atlastpage">($status='')</a></b></p> 
    3047 <p>Returns true if at last page (1-based). Requires PageExecute()/CachePageExecute()  
    3048   to be called. See <a href=#ex8>Example 8</a>.</p> 
     2711<p>Returns true if at last page (1-based). Requires PageExecute()/CachePageExecute() 
     2712  to be called. See <a href="#ex8">Example 8</a>.</p> 
    30492713<p><b>Fields</b><a name="fields"></a>(<b>$colname</b>)</p> 
    3050 <p>Returns the value of the  
    3051   associated column $<b>colname</b> for the current row. The column name is case-insensitive.</p> 
     2714<p>Returns the value of the associated column $<b>colname</b> for the current 
     2715  row. The column name is case-insensitive.</p> 
    30522716<p>This is a convenience function. For higher performance, use <a href="#adodb_fetch_mode">$ADODB_FETCH_MODE</a>. </p> 
    3053 <p><b>FetchRow</b><a name="fetchrow"></a>()</p> 
    3054 </font>  
    3055 <p><font color="#000000">Returns array containing current row, or false if EOF.  
    3056   FetchRow( ) internally moves to the next record after returning the current  
    3057   row. </font></p> 
    3058 <p><font color="#000000">Warning: Do not mix using FetchRow() with MoveNext().</font></p> 
    3059 <p><font color="#000000">Usage:</font></p> 
    3060 <pre><font color="#000000">$rs = $db-&gt;Execute($sql); 
    3061 if ($rs) 
    3062         while ($arr = $rs-&gt;FetchRow()) &#123; 
    3063            &nbsp;&nbsp;# process $arr    
    3064 </font><font color="#000000">   &#125;</font></pre> 
    3065 <p><font color="#000000"><b>FetchInto</b><a name="fetchinto"></a>(<b>&amp;$array</b>)</font></p> 
    3066 <p><font color="#000000"> Sets $array to the current row. Returns PEAR_Error object  
    3067   if EOF, 1 if ok (DB_OK constant). If PEAR is undefined, false is returned when  
    3068   EOF. </font><font color="#000000">FetchInto( ) internally moves to the next  
    3069   record after returning the current row. </font></p> 
    3070 <p><font color="#000000"> FetchRow() is easier to use. See above.</font></p> 
    3071 <font color="#000000">  
    3072 <p><b>FetchField<a name="fetchfield"></a>($column_number)</b></p> 
    3073 <p>Returns an object containing the <b>name</b>, <b>type</b> and <b>max_length</b>  
    3074   of the associated field. If the max_length cannot be determined reliably, it  
    3075   will be set to -1. The column numbers are zero-based. See <a href="#ex2">example  
    3076   2.</a></p> 
    3077 <p><b>FieldCount<a name="fieldcount"></a>( )</b></p> 
    3078 <p>Returns the number of fields (columns) in the record set.</p> 
    3079 <p><b>RecordCount<a name="recordcount"></a>( )</b></p> 
    3080 <p>Returns the number of rows in the record set. If the number of records returned  
    3081   cannot be determined from the database driver API, we will buffer all rows and  
    3082   return a count of the rows after all the records have been retrieved. This buffering  
    3083   can be disabled (for performance reasons) by setting the global variable $ADODB_COUNTRECS  
    3084   = false. When disabled, RecordCount( ) will return -1 for certain databases.  
    3085   See the supported databases list above for more details. </p> 
    3086 <p> RowCount is a synonym for RecordCount.</p> 
    3087 <p><b>PO_RecordCount<a name="po_recordcount"></a>($table, $where)</b></p> 
    3088 <p>Returns the number of rows in the record set. If the database does not support  
    3089   this, it will perform a SELECT COUNT(*) on the table $table, with the given  
    3090   $where condition to return an estimate of the recordset size.</p> 
    3091 <p>$numrows = $rs-&gt;PO_RecordCount(&quot;articles_table&quot;, &quot;group=$group&quot;);</p> 
    3092 <b> NextRecordSet<a name="nextrecordset" id="nextrecordset"></a>()</b>  
    3093 <p>For databases that allow multiple recordsets to be returned in one query, this  
    3094   function allows you to switch to the next recordset. Currently only supported  
    3095   by mssql driver.</p> 
    3096 <pre> 
    3097 $rs = $db-&gt;Execute('execute return_multiple_rs'); 
    3098 $arr1 = $rs-&gt;GetArray(); 
    3099 $rs-&gt;NextRecordSet(); 
    3100 $arr2 = $rs-&gt;GetArray();</pre> 
    3101 <p><b>FetchObject<a name="fetchobject"></a>($toupper=true)</b></p> 
    3102 <p>Returns the current row as an object. If you set $toupper to true, then the  
    3103   object fields are set to upper-case. Note: The newer FetchNextObject() is the  
    3104   recommended way of accessing rows as objects. See below.</p> 
    3105 <p><b>FetchNextObject<a name="fetchnextobject"></a>($toupper=true)</b></p> 
    3106 <p>Gets the current row as an object and moves to the next row automatically.  
    3107   Returns false if at end-of-file. If you set $toupper to true, then the object  
    3108   fields are set to upper-case.</p> 
    3109 <pre> 
    3110 $rs = $db->Execute('select firstname,lastname from table'); 
    3111 if ($rs) &#123; 
    3112         while ($o = $rs->FetchNextObject()) &#123; 
    3113                 print "$o->FIRSTNAME, $o->LASTNAME&lt;BR>"; 
    3114         &#125; 
    3115 &#125; 
    3116 </pre> 
    3117 <p>There is some trade-off in speed in using FetchNextObject(). If performance  
    3118   is important, you should access rows with the <code>fields[]</code> array. <b>FetchObj<a name="fetchobj" id="fetchobj"></a>()</b>  
    3119 <p>Returns the current record as an object. Fields are not upper-cased, unlike  
    3120   FetchObject. </font>  
    3121 <p><font color="#000000"><b>FetchNextObj<a name="fetchnextobj" id="fetchnextobj"></a>()</b>  
    3122   </font></p> 
    3123 <p><font color="#000000">Returns the current record as an object and moves to  
    3124   the next record. If EOF, false is returned. Fields are not upper-cased, unlike  
     2717<p><b>FetchRow</b><a name="fetchrow"></a>()</p>  
     2718</font><p><font>Returns array containing current row, or false 
     2719    if EOF. FetchRow( ) internally moves to the next record after returning the 
     2720    current row. </font></p> 
     2721<p><font>Warning: Do not mix using FetchRow() with MoveNext().</font></p> 
     2722<p><font>Usage:</font></p> 
     2723<pre><font>$rs = $db-&gt;Execute($sql);<br>if ($rs)<br> while ($arr = $rs-&gt;FetchRow()) {<br>    &nbsp;&nbsp;# process $arr   <br>    }</font></pre> 
     2724<p><font><b>FetchInto</b><a name="fetchinto"></a>(<b>&amp;$array</b>)</font></p> 
     2725<p><font> Sets $array to the current row. Returns PEAR_Error 
     2726    object if EOF, 1 if ok (DB_OK constant). If PEAR is undefined, false is returned 
     2727    when EOF. FetchInto( ) internally moves to the next record after returning 
     2728  the current row. </font></p> 
     2729<p><font> FetchRow() is easier to use. See above.</font></p> 
     2730<font> </font> 
     2731<p><font><b>FetchField<a name="fetchfield"></a>($column_number)</b></font></p> 
     2732<p><font>Returns an object containing the <b>name</b>, <b>type</b> and <b>max_length</b> of 
     2733    the associated field. If the max_length cannot be determined reliably, it 
     2734    will be set to -1. The column numbers are zero-based. See <a href="#ex2">example 
     2735  2.</a></font></p> 
     2736<p><font><b>FieldCount<a name="fieldcount"></a>( )</b></font></p> 
     2737<p><font>Returns the number of fields (columns) in the record 
     2738set.</font></p> 
     2739<p><font><b>RecordCount<a name="recordcount"></a>( )</b></font></p> 
     2740<p><font>Returns the number of rows in the record set. If the 
     2741    number of records returned cannot be determined from the database driver 
     2742    API, we will buffer all rows and return a count of the rows after all the 
     2743    records have been retrieved. This buffering can be disabled (for performance 
     2744    reasons) by setting the global variable $ADODB_COUNTRECS = false. When disabled, 
     2745    RecordCount( ) will return -1 for certain databases. See the supported databases 
     2746  list above for more details. </font></p> 
     2747<p><font> RowCount is a synonym for RecordCount.</font></p> 
     2748<p><font><b>PO_RecordCount<a name="po_recordcount"></a>($table, 
     2749$where)</b></font></p> 
     2750<p><font>Returns the number of rows in the record set. If the 
     2751    database does not support this, it will perform a SELECT COUNT(*) on the 
     2752    table $table, with the given $where condition to return an estimate of the 
     2753  recordset size.</font></p> 
     2754<p><font>$numrows = $rs-&gt;PO_RecordCount("articles_table", "group=$group");</font></p> 
     2755<font><b> NextRecordSet<a name="nextrecordset" id="nextrecordset"></a>()</b> </font> 
     2756<p><font>For databases that allow multiple recordsets to be returned 
     2757    in one query, this function allows you to switch to the next recordset. Currently 
     2758  only supported by mssql driver.</font></p> 
     2759<pre><font>$rs = $db-&gt;Execute('execute return_multiple_rs');<br>$arr1 = $rs-&gt;GetArray();<br>$rs-&gt;NextRecordSet();<br>$arr2 = $rs-&gt;GetArray();</font></pre> 
     2760<p><font><b>FetchObject<a name="fetchobject"></a>($toupper=true)</b></font></p> 
     2761<p><font>Returns the current row as an object. If you set $toupper 
     2762    to true, then the object fields are set to upper-case. Note: The newer FetchNextObject() 
     2763  is the recommended way of accessing rows as objects. See below.</font></p> 
     2764<p><font><b>FetchNextObject<a name="fetchnextobject"></a>($toupper=true)</b></font></p> 
     2765<p><font>Gets the current row as an object and moves to the next 
     2766    row automatically. Returns false if at end-of-file. If you set $toupper to 
     2767  true, then the object fields are set to upper-case. Note that for some drivers such as mssql, you need to SetFetchMode(ADODB_FETCH_ASSOC) or SetFetchMode(ADODB_FETCH_BOTH).</font></p> 
     2768<pre><font>$rs = $db-&gt;Execute('select firstname,lastname from table');<br>if ($rs) {<br>     while ($o = $rs-&gt;FetchNextObject()) {<br>            print "$o-&gt;FIRSTNAME, $o-&gt;LASTNAME&lt;BR&gt;";<br>        }<br>}<br></font></pre> 
     2769<p><font>There is some trade-off in speed in using FetchNextObject(). 
     2770If performance is important, you should access rows with the <code>fields[]</code> array. <b>FetchObj<a name="fetchobj" id="fetchobj"></a>()</b> </font></p> 
     2771<p><font>Returns the current record as an object. Fields are 
     2772    not upper-cased, unlike FetchObject.   
     2773</font></p> 
     2774<p><font><b>FetchNextObj<a name="fetchnextobj" id="fetchnextobj"></a>()</b> </font></p> 
     2775<p><font>Returns the current record as an object and moves to 
     2776    the next record. If EOF, false is returned. Fields are not upper-cased, unlike 
    31252777  FetctNextObject. </font></p> 
    3126 <font color="#000000">  
     2778<font> 
    31272779<p><b>CurrentRow<a name="currentrow"></a>( )</b></p> 
    31282780<p>Returns the current row of the record set. 0 is the first row.</p> 
    31292781<p><b>AbsolutePosition<a name="abspos"></a>( )</b></p> 
    3130 <p>Synonym for <b>CurrentRow</b> for compatibility with ADO. Returns the current  
     2782<p>Synonym for <b>CurrentRow</b> for compatibility with ADO. Returns the current 
    31312783  row of the record set. 0 is the first row.</p> 
    31322784<p><b>MetaType<a name="metatype"></a>($nativeDBType[,$field_max_length],[$fieldobj])</b></p> 
    3133 <p>Determine what <i>generic</i> meta type a database field type is given its  
    3134   native type $<b>nativeDBType</b> as a string and the length of the field $<b>field_max_length</b>.  
    3135   Note that field_max_length can be -1 if it is not known. The field object returned  
    3136   by FetchField() can be passed in $<b>fieldobj</b> or as the 1st parameter <b>$nativeDBType</b>.  
    3137   This is useful for databases such as <i>mysql</i> which has additional properties  
     2785<p>Determine what <i>generic</i> meta type a database field type is given its 
     2786  native type $<b>nativeDBType</b> as a string and the length of the field $<b>field_max_length</b>. 
     2787  Note that field_max_length can be -1 if it is not known. The field object returned 
     2788  by FetchField() can be passed in $<b>fieldobj</b> or as the 1st parameter <b>$nativeDBType</b>. 
     2789  This is useful for databases such as <i>mysql</i> which has additional properties 
    31382790  in the field object such as <i>primary_key</i>. </p> 
    3139 <p>Uses the field <b>blobSize</b> and compares it with $<b>field_max_length</b>  
    3140   to determine whether the character field is actually a blob.</p> 
    3141 For example, $db-&gt;MetaType('char') will return 'C'.  
     2791<p>Uses the field <b>blobSize</b> and compares it with $<b>field_max_length</b> to 
     2792  determine whether the character field is actually a blob.</p> 
     2793For example, $db-&gt;MetaType('char') will return 'C'. 
    31422794<p>Returns:</p> 
    31432795<ul> 
    3144   <li><b>C</b>: Character fields that should be shown in a &lt;input type=&quot;text&quot;&gt;  
    3145     tag. </li> 
    3146   <li><b>X</b>: Clob (character large objects), or large text fields that should  
     2796  <li><b>C</b>: Character fields that should be shown in a &lt;input type="text"&gt; tag. </li> 
     2797  <li><b>X</b>: Clob (character large objects), or large text fields that should 
    31472798    be shown in a &lt;textarea&gt;</li> 
    31482799  <li><b>D</b>: Date field</li> 
    31492800  <li><b>T</b>: Timestamp field</li> 
    31502801  <li><b>L</b>: Logical field (boolean or bit-field)</li> 
    3151   <li><b>N</b>: Numeric field. Includes decimal, numeric, floating point, and  
     2802  <li><b>N</b>: Numeric field. Includes decimal, numeric, floating point, and 
    31522803    real. </li> 
    31532804  <li><b>I</b>:&nbsp; Integer field. </li> 
    31542805  <li><b>R</b>: Counter or Autoincrement field. Must be numeric.</li> 
    3155   <li><b>B</b>: Blob, or binary large objects.<font color="#000000"> </font></li> 
    3156 </ul> 
    3157 </font>  
    3158 <p><font color="#000000"> Since ADOdb 3.0, MetaType accepts $fieldobj as the first  
    3159   parameter, instead of $nativeDBType. </font></p> 
    3160 <font color="#000000">  
    3161 <p><b>Close( )<a name="rsclose"></a></b></p> 
    3162 <p>Closes the recordset, cleaning all memory and resources associated with the recordset.  
     2806  <li><b>B</b>: Blob, or binary large objects. </li> 
     2807</ul>  
     2808</font><p><font> Since ADOdb 3.0, MetaType accepts $fieldobj 
     2809    as the first parameter, instead of $nativeDBType. </font></p> 
     2810<font> </font> 
     2811<p><font><b>Close( )<a name="rsclose"></a></b></font></p> 
     2812<p><font>Closes the recordset, cleaning all memory and resources 
     2813associated with the recordset. </font></p> 
    31632814<p> 
    3164 If memory management is not an issue, you do not need to call this function as recordsets 
    3165 are closed for you by PHP at the end of the script.  
    3166 SQL statements such as INSERT/UPDATE/DELETE do not really return a recordset, so you do not have to call Close() 
    3167 for such SQL statements.</p> 
    3168 <hr> 
    3169 <h3>function rs2html<a name="rs2html"></a>($adorecordset,[$tableheader_attributes],  
    3170   [$col_titles])</h3> 
    3171 <p>This is a standalone function (rs2html = recordset to html) that is similar  
    3172   to PHP's <i>odbc_result_all</i> function, it prints a ADORecordSet, $<b>adorecordset</b>  
    3173   as a HTML table. $<b>tableheader_attributes</b> allow you to control the table  
    3174   <i>cellpadding</i>, <i>cellspacing</i> and <i>border</i> attributes. Lastly  
    3175   you can replace the database column names with your own column titles with the  
    3176   array $<b>col_titles</b>. This is designed more as a quick debugging mechanism,  
    3177   not a production table recordset viewer.</p> 
    3178 <p>You will need to include the file <i>tohtml.inc.php</i>.</p> 
    3179 <p>Example of rs2html:<b><font color="#336600"><a name="exrs2html"></a></font></b></p> 
    3180 <pre><b><font color="#336600">&lt;? 
    3181 include('tohtml.inc.php')</font></b>; # load code common to ADOdb  
    3182 <b>include</b>('adodb.inc.php'); # load code common to ADOdb  
    3183 $<font color="#663300">conn</font> = &amp;ADONewConnection('mysql');   # create a connection  
    3184 $<font color="#663300">conn</font>->PConnect('localhost','userid','','agora');# connect to MySQL, agora db 
    3185 $<font color="#663300">sql</font> = 'select CustomerName, CustomerID from customers';  
    3186 $<font color="#663300">rs</font>   = $<font color="#663300">conn</font>->Execute($sql);  
    3187 <font color="#336600"><b>rs2html</b></font><b>($<font color="#663300">rs</font>,'<i>border=2 cellpadding=3</i>',array('<i>Customer Name','Customer ID</i>')); 
    3188 ?&gt;</b></pre> 
    3189 <hr> 
    3190 <h3>Differences between this ADOdb library and Microsoft ADO<a name="adodiff"></a></h3> 
     2815<font>If memory management is not an issue, you do not need to 
     2816call this function as recordsets are closed for you by PHP at the end of the 
     2817script. SQL statements such as INSERT/UPDATE/DELETE do not really return a recordset, 
     2818so you do not have to call Close() for such SQL statements.</font></p> 
     2819<hr /> 
     2820<h3><font>function rs2html<a name="rs2html"></a>($adorecordset,[$tableheader_attributes], 
     2821  [$col_titles])</font></h3> 
     2822<p><font>This is a standalone function (rs2html = recordset to 
     2823    html) that is similar to PHP's <i>odbc_result_all</i> function, it prints 
     2824    a ADORecordSet, $<b>adorecordset</b> as a HTML table. $<b>tableheader_attributes</b> allow 
     2825    you to control the table <i>cellpadding</i>, <i>cellspacing</i> and <i>border</i> attributes. 
     2826    Lastly you can replace the database column names with your own column titles 
     2827    with the array $<b>col_titles</b>. This is designed more as a quick debugging 
     2828  mechanism, not a production table recordset viewer.</font></p> 
     2829<p><font>You will need to include the file <i>tohtml.inc.php</i>.</font></p> 
     2830<p><font>Example of rs2html:<b><font color="#336600"><a name="exrs2html"></a></font></b></font></p> 
     2831<pre><font><b><font color="#336600">&lt;?<br>include('tohtml.inc.php')</font></b>; # load code common to ADOdb <br><b>include</b>('adodb.inc.php'); # load code common to ADOdb <br>$<font color="#663300">conn</font> = &amp;ADONewConnection('mysql');   # create a connection <br>$<font color="#663300">conn</font>-&gt;PConnect('localhost','userid','','agora');# connect to MySQL, agora db<br>$<font color="#663300">sql</font> = 'select CustomerName, CustomerID from customers'; <br>$<font color="#663300">rs</font>   = $<font color="#663300">conn</font>-&gt;Execute($sql); <br><font color="#336600"><b>rs2html</b></font><b>($<font color="#663300">rs</font>,'<i>border=2 cellpadding=3</i>',array('<i>Customer Name','Customer ID</i>'));<br>?&gt;</b></font></pre> 
     2832<hr /> 
     2833<h3><font>Differences between this ADOdb library and Microsoft 
     2834ADO<a name="adodiff"></a></font></h3> 
    31912835<ol> 
    3192   <li>ADOdb only supports recordsets created by a connection object. Recordsets  
    3193     cannot be created independently.</li> 
    3194   <li>ADO properties are implemented as functions in ADOdb. This makes it easier  
    3195     to implement any enhanced ADO functionality in the future.</li> 
    3196   <li>ADOdb's <font face="Courier New, Courier, mono">ADORecordSet-&gt;Move()</font>  
    3197     uses absolute positioning, not relative. Bookmarks are not supported.</li> 
    3198   <li><font face="Courier New, Courier, mono">ADORecordSet-&gt;AbsolutePosition()  
    3199     </font>cannot be used to move the record cursor.</li> 
    3200   <li>ADO Parameter objects are not supported. Instead we have the ADOConnection::<a href="#parameter">Parameter</a>(  
    3201     ) function, which provides a simpler interface for calling preparing parameters  
    3202     and calling stored procedures.</li> 
    3203   <li>Recordset properties for paging records are available, but implemented as  
    3204     in <a href=#ex8>Example 8</a>.</li> 
    3205 </ol> 
    3206 <hr> 
    3207 <h1>Database Driver Guide<a name="driverguide"></a></h1> 
    3208 <p>This describes how to create a class to connect to a new database. To ensure  
    3209   there is no duplication of work, kindly email me at jlim#natsoft.com.my if you  
    3210   decide to create such a class.</p> 
    3211 <p>First decide on a name in lower case to call the database type. Let's say we  
    3212   call it xbase. </p> 
    3213 <p>Then we need to create two classes ADODB_xbase and ADORecordSet_xbase in the  
    3214   file adodb-xbase.inc.php.</p> 
    3215 <p>The simplest form of database driver is an adaptation of an existing ODBC driver.  
    3216   Then we just need to create the class <i>ADODB_xbase extends ADODB_odbc</i>  
    3217   to support the new <b>date</b> and <b>timestamp</b> formats, the <b>concatenation</b>  
    3218   operator used, <b>true</b> and <b>false</b>. For the<i> ADORecordSet_xbase extends  
    3219   ADORecordSet_odbc </i>we need to change the <b>MetaType</b> function. See<b>  
    3220   adodb-vfp.inc.php</b> as an example.</p> 
    3221 <p>More complicated is a totally new database driver that connects to a new PHP  
    3222   extension. Then you will need to implement several functions. Fortunately, you  
    3223   do not have to modify most of the complex code. You only need to override a  
    3224   few stub functions. See <b>adodb-mysql.inc.php</b> for example.</p> 
    3225 <p>The default date format of ADOdb internally is YYYY-MM-DD (Ansi-92). All dates  
    3226   should be converted to that format when passing to an ADOdb date function. See  
    3227   Oracle for an example how we use ALTER SESSION to change the default date format  
    3228   in _pconnect _connect.</p> 
    3229 <p><b>ADOConnection Functions to Override</b></p> 
    3230 <p>Defining a constructor for your ADOConnection derived function is optional.  
    3231   There is no need to call the base class constructor.</p> 
    3232 <p>_<b>connect</b>: Low level implementation of Connect. Returns true or false.  
    3233   Should set the _<b>connectionID</b>.</p> 
    3234 <p>_<b>pconnect:</b> Low level implemention of PConnect. Returns true or false.  
    3235   Should set the _<b>connectionID</b>.</p> 
    3236 <p>_<b>query</b>: Execute a query. Returns the queryID, or false.</p> 
    3237 <p>_<b>close: </b>Close the connection -- PHP should clean up all recordsets.  
     2836<font> 
     2837<li>ADOdb only supports recordsets created by a connection object. Recordsets 
     2838  cannot be created independently.</li> 
     2839<li>ADO properties are implemented as functions in ADOdb. This makes it easier 
     2840  to implement any enhanced ADO functionality in the future.</li> 
     2841<li>ADOdb's <font face="Courier New, Courier, mono">ADORecordSet-&gt;Move()</font> uses 
     2842  absolute positioning, not relative. Bookmarks are not supported.</li> 
     2843<li><font face="Courier New, Courier, mono">ADORecordSet-&gt;AbsolutePosition() </font>cannot 
     2844  be used to move the record cursor.</li> 
     2845<li>ADO Parameter objects are not supported. Instead we have the ADOConnection::<a href="#parameter">Parameter</a>( 
     2846  ) function, which provides a simpler interface for calling preparing parameters 
     2847  and calling stored procedures.</li> 
     2848<li>Recordset properties for paging records are available, but implemented as 
     2849  in <a href="#ex8">Example 8</a>.</li> 
     2850</font></ol> 
     2851<hr /> 
     2852<h1><font>Database Driver Guide<a name="driverguide"></a></font></h1> 
     2853<p><font>This describes how to create a class to connect to a 
     2854    new database. To ensure there is no duplication of work, kindly email me 
     2855  at jlim#natsoft.com.my if you decide to create such a class.</font></p> 
     2856<p><font>First decide on a name in lower case to call the database 
     2857  type. Let's say we call it xbase. </font></p> 
     2858<p><font>Then we need to create two classes ADODB_xbase and ADORecordSet_xbase 
     2859  in the file adodb-xbase.inc.php.</font></p> 
     2860<p><font>The simplest form of database driver is an adaptation 
     2861    of an existing ODBC driver. Then we just need to create the class <i>ADODB_xbase 
     2862    extends ADODB_odbc</i> to support the new <b>date</b> and <b>timestamp</b> formats, 
     2863    the <b>concatenation</b> operator used, <b>true</b> and <b>false</b>. For 
     2864    the<i> ADORecordSet_xbase extends ADORecordSet_odbc </i>we need to change 
     2865  the <b>MetaType</b> function. See<b> adodb-vfp.inc.php</b> as an example.</font></p> 
     2866<p><font>More complicated is a totally new database driver that 
     2867    connects to a new PHP extension. Then you will need to implement several 
     2868    functions. Fortunately, you do not have to modify most of the complex code. 
     2869    You only need to override a few stub functions. See <b>adodb-mysql.inc.php</b> for 
     2870  example.</font></p> 
     2871<p><font>The default date format of ADOdb internally is YYYY-MM-DD 
     2872    (Ansi-92). All dates should be converted to that format when passing to an 
     2873    ADOdb date function. See Oracle for an example how we use ALTER SESSION to 
     2874  change the default date format in _pconnect _connect.</font></p> 
     2875<p><font><b>ADOConnection Functions to Override</b></font></p> 
     2876<p><font>Defining a constructor for your ADOConnection derived 
     2877  function is optional. There is no need to call the base class constructor.</font></p> 
     2878<p><font>_<b>connect</b>: Low level implementation of Connect. 
     2879  Returns true or false. Should set the _<b>connectionID</b>.</font></p> 
     2880<p><font>_<b>pconnect:</b> Low level implemention of PConnect. 
     2881  Returns true or false. Should set the _<b>connectionID</b>.</font></p> 
     2882<p><font>_<b>query</b>: Execute a query. Returns the queryID, 
     2883or false.</font></p> 
     2884<p><font>_<b>close: </b>Close the connection -- PHP should clean 
     2885up all recordsets. </font></p> 
     2886<p><font><b>ErrorMsg</b>: Stores the error message in the private 
     2887variable _errorMsg. </font></p> 
     2888<p><font><b>ADOConnection Fields to Set</b></font></p> 
     2889<p><font>_<b>bindInputArray</b>: Set to true if binding of parameters 
     2890  for SQL inserts and updates is allowed using ?, eg. as with ODBC.</font></p> 
     2891<p><font><b>fmtDate</b></font></p> 
     2892<p><font><b>fmtTimeStamp</b></font></p> 
     2893<p><font><b>true</b></font></p> 
     2894<p><font><b>false</b></font></p> 
     2895<p><font><b>concat_operator</b></font></p> 
     2896<p><font><b>replaceQuote</b></font></p> 
     2897<p><font><b>hasLimit</b> support SELECT * FROM TABLE LIMIT 10 
     2898of MySQL.</font></p> 
     2899<p><font><b>hasTop</b> support Microsoft style SELECT TOP 10 
     2900* FROM TABLE.</font></p> 
     2901<p><font><b>ADORecordSet Functions to Override</b></font></p> 
     2902<p><font>You will need to define a constructor for your ADORecordSet 
     2903  derived class that calls the parent class constructor.</font></p> 
     2904<p><font><b>FetchField: </b> as documented above in ADORecordSet</font></p> 
     2905<p><font>_<b>initrs</b>: low level initialization of the recordset: 
     2906    setup the _<b>numOfRows</b> and _<b>numOfFields</b> fields -- called by the 
     2907  constructor.</font></p> 
     2908<p><font>_<b>seek</b>: seek to a particular row. Do not load 
     2909    the data into the fields array. This is done by _fetch. Returns true or false. 
     2910    Note that some implementations such as Interbase do not support seek. Set 
     2911  canSeek to false.</font></p> 
     2912<p><font>_<b>fetch</b>: fetch a row using the database extension 
     2913    function and then move to the next row. Sets the <b>fields</b> array. If 
     2914    the parameter $ignore_fields is true then there is no need to populate the <b>fields</b> array, 
     2915  just move to the next row. then Returns true or false.</font></p> 
     2916<p><font>_<b>close</b>: close the recordset</font></p> 
     2917<p><font><b>Fields</b>: If the array row returned by the PHP 
     2918    extension is not an associative one, you will have to override this. See 
     2919    adodb-odbc.inc.php for an example. For databases such as MySQL and MSSQL 
     2920    where an associative array is returned, there is no need to override this 
     2921  function.</font></p> 
     2922<p><font><b>ADOConnection Fields to Set</b></font></p> 
     2923<p><font>canSeek: Set to true if the _seek function works.</font></p> 
     2924<h2><font>Optimizing PHP</font></h2> 
     2925    For info on tuning PHP, read this article on <a href="http://phplens.com/lens/php-book/optimizing-debugging-php.php">Optimizing 
     2926  PHP</a>. </font></p> 
     2927 
     2928<h2><font>Change Log<a name="Changes"></a><a name="changes"></a><a name="changelog"></a></font></h2> 
     2929 
     2930<p><a name="4.95"></a><b>4.95/5.01 17 May 2007</b> 
     2931<p>CacheFlush debug outp() passed in invalid parameters. Fixed. 
     2932<p>Added Thai language file for adodb. Thx Trirat Petchsingh rosskouk#gmail.com and Marcos Pont</p> 
     2933<p>Added zerofill checking support to MetaColumns for mysql and mysqli. 
     2934<p>CacheFlush no longer deletes all files/directories. Only *.cache files deleted.</p> 
     2935<p>DB2 timestamp format changed to var $fmtTimeStamp = "'Y-m-d-H:i:s'";</p> 
     2936<p>Added some code sanitization to AutoExecute in adodb-lib.inc.php.</p> 
     2937<p>Due to typo, all connections in adodb-oracle.inc.php would become persistent, even non-persistent ones. Fixed.</p> 
     2938<P>Oci8 DBTimeStamp uses 24 hour time for input now, so you can perform string comparisons between 2 DBTimeStamp values.</P> 
     2939<p>Some PHP4.4 compat issues fixed in adodb-session2.inc.php</p> 
     2940<p>For ADOdb 5.01, fixed some adodb-datadict.inc.php MetaType compat issues with PHP5. 
     2941<p>The $argHostname was wiped out in adodb-ado5.inc.php. Fixed. 
     2942<p>Adodb5 version, added iterator support for adodb_recordset_empty. 
     2943 
     2944<p><a name="4.94"></a><b>4.94 23 Jan 2007</b> 
     2945<p>Active Record: $ADODB_ASSOC_CASE=2 did not work properly. Fixed. Thx gmane#auxbuss.com. 
     2946<p>mysqli had bugs in BeginTrans() and EndTrans(). Fixed.</p> 
     2947<p>Improved error handling when no database is connected for oci8. Thx Andy Hassall.</p> 
     2948<p>Names longer than 30 chars in oci8 datadict will be changed to random name. Thx Eugenio. http://phplens.com/lens/lensforum/msgs.php?id=16182 
     2949<p>Added var $upperCase = 'ucase' to access and ado_access drivers. Thx Renato De Giovanni renato#cria.org.br</p> 
     2950<p>Postgres64 driver, if preparing plan failed in _query, did not handle error properly. Fixed. See http://phplens.com/lens/lensforum/msgs.php?id=16131. 
     2951<p>Fixed  GetActiveRecordsClass() reference bug. See http://phplens.com/lens/lensforum/msgs.php?id=16120 
     2952<p> 
     2953 
     2954Added handling of nulls in adodb-ado_mssql.inc.php for qstr(). Thx to Felix Rabinovich. 
     2955<p> 
     2956 
     2957Adodb-dict contributions by Gaetano: 
     2958<br> 
     2959+ Support for INDEX in data-dict. Example: 
     2960idx_ev1. The ability to define indexes using the INDEX keyword was added in ADOdb 4.94. The following example features mutiple indexes, including a compound index idx_ev1.  
     2961<pre> 
     2962  event_id I(11) NOTNULL AUTOINCREMENT PRIMARY, 
     2963  event_type I(4) NOTNULL  <b>INDEX idx_evt</b>, 
     2964  event_start_date T DEFAULT NULL <b>INDEX id_esd</b>, 
     2965  event_end_date T DEFAULT '0000-00-00 00:00:00' <b>INDEX id_eted</b>, 
     2966  event_parent I(11) UNSIGNED NOTNULL DEFAULT 0 <b>INDEX id_evp</b>, 
     2967  event_owner I(11) DEFAULT 0 <b>INDEX idx_ev1</b>, 
     2968  event_project I(11) DEFAULT 0 <b>INDEX idx_ev1</b>, 
     2969  event_times_recuring I(11) UNSIGNED NOTNULL DEFAULT 0, 
     2970  event_icon C(20) DEFAULT 'obj/event', 
     2971  event_description X 
     2972</pre> 
     2973<br> 
     2974+ Prevents the generated SQL from including double drop-sequence statements for REPLACE case of tables with autoincrement columns (on those dbs that emulate it via sequences) 
     2975<br> 
     2976+ makes any date defined as DEFAULT value for D and T columns work cross-database, not just the "sysdate" value (as long as it is specified using adodb standard format). See above example. 
     2977<p>Fixed pdo's GetInsertID() support. Thx Ricky Su. 
     2978<p>oci8 Prepare() now sets error messages if an error occurs. 
     2979<p>Added 'PT_BR' to SetDateLocale() -- brazilian portugese. 
     2980<p>charset in oci8 was not set correctly on *Connect() 
     2981<p>ADOConnection::Transpose() now appends as first column the field names. 
     2982<p>Added $ADODB_QUOTE_FIELDNAMES. If set to true, will autoquote field names in AutoExecute(),GetInsertSQL(), GetUpdateSQL(). 
     2983<p>Transpose now adds the field names as the first column after transposition. 
     2984<p>Added === check in ADODB_SetDatabaseAdapter for $db, adodb-active-record.inc.php. Thx Christian Affolter. 
     2985<p>Added ErrorNo() to adodb-active-record.inc.php. Thx ante#novisplet.com. 
     2986 
     2987 
     2988 
     2989<p><a name="4.93"></a><b>4.93 10 Oct 2006</b> 
     2990<p>Added support for multiple database connections in performance monitoring code (adodb-perf.inc.php). Now all sql in multiple database connections can be saved into one database ($ADODB_LOG_CONN). 
     2991<p>Added MetaIndexes() to odbc_mssql. 
     2992<p>Added connection property $db->null2null = 'null'. In autoexecute/getinsertsql/getupdatesql, this value will be converted to a null. Set this to a funny invalid value if you do not want null conversion. See http://phplens.com/lens/lensforum/msgs.php?id=15902. 
     2993<p>Path disclosure problem in mysqli fixed. Thx Andy. 
     2994<p>Fixed typo in session_schema2.xml. 
     2995<p>Changed INT in oci8 to return correct precision in $fld->max_length, MetaColumns(). Thx Eloy Lafuente Plaza. 
     2996<p>Patched postgres64 _connect to handle serverinfo(). see http://phplens.com/lens/lensforum/msgs.php?id=15887. 
     2997<p>Added pdo fix for null columns. See http://phplens.com/lens/lensforum/msgs.php?id=15889 
     2998<p>For stored procedures, missing connection id now passed into mssql_query(). Thx Ecsy (ecsy#freemail.hu). 
     2999 
     3000<p><a name="4.92a"></a><b>4.92a 30 Aug 2006</b> 
     3001<p>Syntax error in postgres7 driver. Thx Eloy Lafuente Plaza.  
     3002<p>Minor bug fixes - adodb informix 10 types added to adodb.inc.php. Thx Fernando Ortiz. 
     3003 
     3004<p><a name="4.92"></a><b>4.92 29 Aug 2006</b> 
     3005 
     3006<p>Better odbtp date support. 
     3007<P>Added IgnoreErrors() to bypass default error handling. 
     3008<p>The _adodb_getcount() function in adodb-lib.inc.php, some ORDER BY bug fixes. 
     3009<p>For ibase and firebird, set  $sysTimeStamp = "CURRENT_TIMESTAMP". 
     3010<p>Fixed postgres connection bug: http://phplens.com/lens/lensforum/msgs.php?id=11057. 
     3011<p>Changed CacheSelectLimit() to flush cache when $secs2cache==-1 due to complaints from other users.  
     3012<p>Added support for using memcached with CacheExecute/CacheSelectLimit. Requires memcache module PECL extension. Usage: 
     3013<pre> 
     3014$db = NewADOConnection($driver); 
     3015$db->memCache = true; /// should we use memCache instead of caching in files 
     3016$db->memCacheHost = 126.0.1.1; /// memCache host 
     3017$db->memCachePort = 11211; /// this is default memCache port 
     3018$db->memCacheCompress = false; /// Use 'true' to store the item compressed (uses zlib) 
     3019 
     3020$db->Connect(...); 
     3021$db->CacheExecute($sql); 
     3022</pre> 
     3023<p>Implemented Transpose() for recordsets. Recordset must be retrieved using ADODB_FETCH_NUM. First column becomes the  
     3024column name. 
     3025<pre> 
     3026$DB = NewADOConnection('mysql'); 
     3027$DB->Connect(...); 
     3028$DB->SetFetchMode(ADODB_FETCH_NUM); 
     3029$rs = $DB->Execute('select productname,productid,unitprice from products limit 10'); 
     3030$rs2 = $DB->Transpose($rs); 
     3031rs2html($rs2); 
     3032</pre> 
     3033<p><a name="4.91"></a><b>4.91 2 Aug 2006</b> 
     3034<p>Major session code rewrite .... See session docs. 
     3035<p>PDO bindinputarray was not set properly for MySQL (changed from true to false). 
     3036<p>Changed CacheSelectLimit() to re-cache when $secs2cache==0. This is one way to flush the cache when SelectLimit is called. 
     3037<p>Added to quotes to mysql  and mysqli: "SHOW COLUMNS FROM `%s`"; 
     3038<p>Removed accidental optgroup handling in GetMenu(). 
     3039<a>Fixed ibase _BlobDecode for php5 compat, and also mem alloc issues for small blobs, thx salvatori#interia.pl 
     3040<p>Mysql driver OffsetDate() speedup, useful for adodb-sessions. 
     3041<p>Fix for GetAssoc() PHP5 compat. See http://phplens.com/lens/lensforum/msgs.php?id=15425 
     3042<p>Active Record - If inserting a record and the value of a primary key field is null, then we do not insert that field in as we assume it is an auto-increment field. Needed by mssql. 
     3043<p>Changed postgres7 MetaForeignKeys() see http://phplens.com/lens/lensforum/msgs.php?id=15531 
     3044<p>DB2 will now return db2_conn_errormsg() when it is a connection error.  
     3045<p><a name="4.90"></a><b>4.90 8 June 2006</b> 
     3046<p>Changed adodb_countrec() in adodb-lib.inc.php to allow LIMIT to be used as a speedup to reduce no of records counted. 
     3047<p>Added support for transaction modes for postgres and oci8 with SetTransactionMode().  
     3048These transaction modes affect all subsequent transactions of that connection. 
     3049<p>Thanks to Halmai Csongor for suggestion. 
     3050<p>Removed $off = $fieldOffset - 1 line in db2 driver, FetchField(). Tx Larry Menard. 
     3051<p>Added support for PHP5 objects as Execute() bind parameters using __toString (eg. Simple-XML). Thx Carl-Christian Salvesen. 
     3052<p>Rounding in tohtml.inc.php did not work properly. Fixed. 
     3053<p>MetaIndexes in postgres fails when fields are deleted then added in again because the attnum has gaps in it.  
     3054See http://sourceforge.net/tracker/index.php?func=detail&aid=1451245&group_id=42718&atid=433976. Fixed. 
     3055<p>MetaForeignkeys in mysql and mysqli did not work when fetchMode==ADODB_FETCH_ASSOC used. Fixed. 
     3056<p>Reference error in AutoExecute() fixed. 
     3057<p>Added macaddr postgres type to MetaType. Maps to 'C'. 
     3058<p>Added to _connect() in adodb-ado5.inc.php support for $database and $dataProvider parameters.  Thx Larry Menard. 
     3059<p>Added support for sequences in adodb-ado_mssql.inc.php. Thx Larry Menard. 
     3060<p>Added ADODB_SESSION_READONLY. 
     3061<p>Added session expiryref support to crc32 mode, and in LOB code. 
     3062<p>Clear _errorMsg in postgres7 driver, so that ErrorMsg() displays properly when no error occurs. 
     3063<p>Added BindDate and BindTimeStamp 
     3064<p><a name="4.81"></a><b>4.81 3 May 2006</b> 
     3065<p>Fixed variable ref errors in adodb-ado5.inc.php in _query(). 
     3066<p>Mysqli setcharset fix using method_exists(). 
     3067<p>The adodb-perf.inc.php CreateLogTable() code now works for user-defined table names. 
     3068<p>Error in ibase_blob_open() fixed. See http://phplens.com/lens/lensforum/msgs.php?id=14997 
     3069<p><a name="4.80"></a><b>4.80 8 Mar 2006</b> 
     3070<p>Added activerecord support. 
     3071<p>Added mysql $conn->compat323 = true if you want MySQL 3.23 compat enabled. Fixes GetOne() Select-Limit problems. 
     3072<p>Added adodb-xmlschema03.inc.php to support XML Schema version 3 and updated adodb-datadict.htm docs. 
     3073<p>Better memory management in Execute. Thx Mike Fedyk. 
     3074<p><a name="4.72"></a><b>4.72 21 Feb 2006</b> 
     3075<p>Added 'new' DSN parameter for NConnect(). 
     3076<p>Pager now sanitizes $PHP_SELF to protect against XSS. Thx to James Bercegay and others. 
     3077<p>ADOConnection::MetaType changed to setup $rs->connection correctly.  
     3078<p>New native DB2 driver contributed by Larry Menard, Dan Scott, Andy Staudacher, Bharat Mediratta. 
     3079<p>The mssql CreateSequence() did not BEGIN TRANSACTION correctly. Fixed. Thx Sean Lee. 
     3080<p>The _adodb_countrecs() function in adodb-lib.inc.php has been revised to handle more ORDER BY variations. 
     3081<p><a name="4.71"></a><b>4.71 24 Jan 2006</b> 
     3082<p>Fixes postgresql security issue related to binary strings. Thx to Andy Staudacher. 
     3083<p>Several DSN bugs found: 
     3084<p>1. Fix bugs in DSN connections introduced in 4.70 when underscores are found in the DSN.  
     3085<p>2. DSN with _ did not work properly in PHP5 (fine in PHP4). Fixed. 
     3086<p>3. Added support for PDO DSN connections in NewADOConnection(), and database parameter in PDO::Connect(). 
     3087<p>The oci8 datetime flag not correctly implemented in ADORecordSet_array. Fixed. 
     3088<p>Added BlobDelete() to postgres, as a counterpoint to UpdateBlobFile(). 
     3089<p>Fixed GetInsertSQL() to support oci8po. 
     3090<p>Fixed qstr() issue with postgresql with \0 in strings. 
     3091<p>Fixed some datadict driver loading issues in _adodb_getdriver().  
     3092<p>Added register shutdown function session_write_close in adodb-session.inc.php for PHP 5 compat. See http://phplens.com/lens/lensforum/msgs.php?id=14200. 
     3093<p><a name="4.70"></a><b>4.70 6 Jan 2006</b> 
     3094<p>Many fixes from Danila Ulyanov  to ibase, oci8, postgres, mssql, odbc_oracle, odbtp, etc drivers. 
     3095<p>Changed usage of binary hint in adodb-session.inc.php for mysql. See  
     3096http://phplens.com/lens/lensforum/msgs.php?id=14160 
     3097<p>Fixed invalid variable reference problem in undomq(), adodb-perf.inc.php. 
     3098<p>Fixed http://phplens.com/lens/lensforum/msgs.php?id=14254 in adodb-perf.inc.php, _DBParameter() settings of fetchmode was wrong. 
     3099<p>Fixed security issues in server.php and tmssql.php discussed by Andreas Sandblad in a Secunia security advisory. Added $ACCEPTIP = 127.0.0.1 
     3100and changed suggested root password to something more secure. 
     3101<p>Changed pager to close recordset after RenderLayout(). 
     3102<p><a name="4.68"></a><b>4.68 25 Nov  2005</b> 
     3103<p>PHP 5 compat for mysqli. MetaForeignKeys repeated twice and MYSQLI_BINARY_FLAG missing. 
     3104<p>PHP 5.1 support for postgresql bind parameters using ? did not work if >= 10 parameters. Fixed. Thx to Stanislav Shramko. 
     3105<p>Lots of PDO improvements. 
     3106<p>Spelling error fixed in mysql MetaForeignKeys, $associative parameter. 
     3107<p><a name="4.67"></a><b>4.67 16 Nov  2005</b> 
     3108<p>Postgresql not_null flag not set to false correctly. Thx Cristian MARIN. 
     3109<p>We now check in Replace() if key is in fieldArray. Thx Sébastien Vanvelthem. 
     3110<p>_file_get_contents() function was missing in xmlschema. fixed. 
     3111<p>Added week in year support to SQLDate(), using 'W' flag. Thx Spider. 
     3112<p>In sqlite metacolumns was repeated twice, causing PHP 5 problems. Fixed. 
     3113<p>Made debug output XHTML compliant.  
     3114<p><a name="4.66"></a><b>4.66 28 Sept  2005</b> 
     3115<p>ExecuteCursor() in oci8 did not clean up properly on failure. Fixed. 
     3116<p>Updated xmlschema.dtd, by "Alec Smecher" asmecher#smecher.bc.ca 
     3117<p>Hardened SelectLimit, typecasting nrows and offset to integer. 
     3118<p>Fixed misc bugs in AutoExecute() and GetInsertSQL(). 
     3119<p>Added $conn->database as the property holding the database name. The older $conn->databaseName is retained for backward 
     3120compat. 
     3121<p>Changed _adodb_backtrace() compat check to use function_exists(). 
     3122<p>Bug in postgresql MetaIndexes fixed. Thx Kevin Jamieson.  
     3123<p>Improved OffsetDate for MySQL, reducing rounding error. 
     3124<p>Metacolumns added to sqlite. Thx Mark Newnham. 
     3125<p>PHP 4.4 compat fixes for GetAssoc(). 
     3126<p>Added postgresql bind support for php 5.1. Thx Cristiano da Cunha Duarte 
     3127<p>OffsetDate() fixes for postgresql, typecasting strings to date or timestamp. 
     3128<p>DBTimeStamp formats for mssql, odbc_mssql and postgresql made to conform with other db's. 
     3129<p>Changed PDO constants from PDO_ to PDO:: to support latest spec. 
     3130<p><a name="4.65"></a><b>4.65 22 July  2005</b> 
     3131<p>Reverted 'X' in mssql datadict to 'TEXT' to be compat with mssql driver. However now you can  
     3132set $datadict->typeX = 'varchar(4000)' or 'TEXT' or 'CLOB' for mssql and oci8 drivers.  
     3133<p>Added charset support when using DSN for Oracle. 
     3134<p>_adodb_getmenu did not use fieldcount() to get number of fields. Fixed. 
     3135<p>MetaForeignKeys() for mysql/mysqli contributed by Juan Carlos Gonzalez. 
     3136<p>MetaDatabases() now correctly returns an array for mysqli driver. Thx Cristian MARIN. 
     3137<p>CompleteTrans(false) did not return false. Fixed. Thx to JMF. 
     3138<p>AutoExecute() did not work with Oracle. Fixed. Thx José Moreira. 
     3139<p>MetaType() added to connection object. 
     3140<p>More PHP 4.4 reference return fixes. Thx Ryan C Bonham and others. 
     3141 
     3142<p><a name="4.64"></a><b>4.64 20 June 2005</b> 
     3143<p>In datadict, if the default field value is set to '', then it is not applied when the field is created. Fixed by Eugenio. 
     3144<p>MetaPrimaryKeys for postgres did not work because of true/false change in 4.63. Fixed. 
     3145<p>Tested ocifetchstatement in oci8. Rejected at the end. 
     3146<p>Added port to dsn handling. Supported in postgres, mysql, mysqli,ldap. 
     3147<p>Added  'w' and 'l' to mysqli SQLDate(). 
     3148<p>Fixed error handling in ldap _connect() to be more consistent. Also added ErrorMsg() handling to ldap. 
     3149<p>Added support for union in _adodb_getcount, adodb-lib.inc.php for postgres and oci8. 
     3150<p>rs2html() did not work with null dates properly. 
     3151<p>PHP 4.4 reference return fixes. 
     3152 
     3153<p><a name="4.63"></a><b>4.63  18 May 2005</b> 
     3154<p>Added $nrows<0 check to mysqli's SelectLimit(). 
     3155<p>Added OptimizeTable() and OptimizeTables() in adodb-perf.inc.php. By Markus Staab. 
     3156<p>PostgreSQL inconsistencies fixed. true and false set to TRUE and FALSE, and boolean type in datadict-postgres.inc.php set 
     3157to 'L' => 'BOOLEAN'. Thx Kevin Jamieson. 
     3158<p>New adodb_session_create_table() function in adodb-session.inc.php. By Markus Staab. 
     3159<p>Added null check to UserTimeStamp(). 
     3160<p>Fixed typo in mysqlt driver in adorecordset. Thx to Andy Staudacher. 
     3161<p>GenID() had a bug in the raiseErrorFn handling. Fixed. Thx Marcos Pont. 
     3162<p>Datadict name quoting now handles ( ) in index fields correctly - they aren't part of the index field. 
     3163<p>Performance monitoring: (1) oci8 Ixora checks moved down; (2) expensive sql changed so that only those sql with  
     3164count(*)>1 are shown; (3) changed sql1 field to a length+crc32 checksum - this breaks backward compat. 
     3165<p>We remap firebird15 to firebird in data dictionary. 
     3166 
     3167<p><a name="4.62"></a><b>4.62  2 Apr 2005</b> 
     3168<p>Added 'w' (dow as 0-6 or 1-7) and 'l' (dow as string) for SQLDate for oci8, postgres and mysql. 
     3169<p>Rolled back MetaType() changes for mysqli done in prev version. 
     3170<p>Datadict change by chris, cblin#tennaxia.com data mappings from: 
     3171<pre> 
     3172oci8:  X->varchar(4000) XL->CLOB 
     3173mssql: X->XL->TEXT 
     3174mysql: X->XL->LONGTEXT 
     3175fbird: X->XL->varchar(4000) 
     3176</pre> 
     3177<p>to: 
     3178<pre> 
     3179oci8:  X->varchar(4000) XL->CLOB 
     3180mssql: X->VARCHAR(4000) XL->TEXT 
     3181mysql: X->TEXT          XL->LONGTEXT 
     3182fbird: X->VARCHAR(4000) XL->VARCHAR(32000) 
     3183</pre> 
     3184<p>Added $connection->disableBlobs to postgresql to improve performance when no bytea is used (2-5% improvement). 
     3185<p>Removed all HTTP_* vars. 
     3186<p>Added $rs->tableName to be set before calling AutoExecute(). 
     3187<p>Alex Rootoff rootoff#pisem.net contributed ukrainian language file. 
     3188<p>Added new mysql_option() support using $conn->optionFlags array. 
     3189<p>Added support for ldap_set_option() using the $LDAP_CONNECT_OPTIONS global variable. Contributed by Josh Eldridge. 
     3190<p>Added LDAP_* constant definitions to ldap. 
     3191<p>Added support for boolean bind variables. We use $conn->false and $conn->true to hold values to set false/true to. 
     3192<p>We now do not close the session connection in adodb-session.inc.php as other objects could be using this connection. 
     3193<p>We now strip off \0 at end of Ixora SQL strings in $perf->tohtml() for oci8. 
     3194<p><a name="4.61"></a><b>4.61 23 Feb 2005</b> 
     3195<p>MySQLi added support for mysqli_connect_errno() and mysqli_connect_error(). 
     3196<p>Massive improvements to alpha PDO driver. 
     3197<p>Quote string bind parameters logged by performance monitor for easy type checking. Thx Jason Judge. 
     3198<p>Added support for $role when connecting with Interbase/firebird. 
     3199<p>Added support for enum recognition in MetaColumns() mysql and mysqli. Thx Amedeo Petrella. 
     3200<p>The sybase_ase driver contributed by Interakt Online. Thx Cristian Marin cristic#interaktonline.com. 
     3201<p>Removed not_null, has_default, and default_value from ADOFieldObject. 
     3202<p>Sessions code, fixed quoting of keys when handling LOBs in session write() function. 
     3203<p>Sessions code, added adodb_session_regenerate_id(), to reduce risk of session hijacking by changing session cookie dynamically. Thx Joe Li. 
     3204<p>Perf monitor, polling for CPU did not work for PHP 4.3.10 and 5.0.0-5.0.3 due to PHP bugs, so we special case these versions. 
     3205<p>Postgresql, UpdateBlob() added code to handle type==CLOB. 
     3206<p><a name="4.60"></a><b>4.60 24 Jan 2005</b> 
     3207<p>Implemented PEAR DB's autoExecute(). Simplified design because I don't like using constants when 
     3208strings work fine. 
     3209<p>_rs2serialize will now update $rs->sql and $rs->oldProvider. 
     3210<p>Added autoExecute(). 
     3211<p>Added support for postgres8 driver. Currently just remapped to postgres7 driver. 
     3212<p>Changed oci8 _query(), so that OCIBindByName() sets the length to -1 if element size is > 4000. This provides better support 
     3213for LONGs. 
     3214<p>Added SetDateLocale() support for netherlands (Nl). 
     3215<p>Spelling error in pivot code ($iff should be $iif). 
     3216</p><p>mysql insert_id() did not work with mysql 3.x. Fixed. 
     3217</p><p>"\r\n" not converted to spaces correctly in exporting data. Fixed. 
     3218</p><p>_nconnect() in mysqli did not return value correctly. Fixed. 
     3219</p><p>Arne Eckmann contributed danish language file. 
     3220</p><p>Added clone() support to FetchObject() for PHP5.<br> 
    32383221</p> 
    3239 <p><b>ErrorMsg</b>: Stores the error message in the private variable _errorMsg.  
     3222<p>Removed SQL_CUR_USE_ODBC from odbc_mssql.<br> 
    32403223</p> 
    3241 <p><b>ADOConnection Fields to Set</b></p> 
    3242 <p>_<b>bindInputArray</b>: Set to true if binding of parameters for SQL inserts  
    3243   and updates is allowed using ?, eg. as with ODBC.</p> 
    3244 <p><b>fmtDate</b></p> 
    3245 <p><b>fmtTimeStamp</b></p> 
    3246 <p><b>true</b></p> 
    3247 <p><b>false</b></p> 
    3248 <p><b>concat_operator</b></p> 
    3249 <p><b>replaceQuote</b></p> 
    3250 <p><b>hasLimit</b> support SELECT * FROM TABLE LIMIT 10 of MySQL.</p> 
    3251 <p><b>hasTop</b> support Microsoft style SELECT TOP 10 * FROM TABLE.</p> 
    3252 <p><b>ADORecordSet Functions to Override</b></p> 
    3253 <p>You will need to define a constructor for your ADORecordSet derived class that  
    3254   calls the parent class constructor.</p> 
    3255 <p><b>FetchField: </b> as documented above in ADORecordSet</p> 
    3256 <p>_<b>initrs</b>: low level initialization of the recordset: setup the _<b>numOfRows</b>  
    3257   and _<b>numOfFields</b> fields -- called by the constructor.</p> 
    3258 <p>_<b>seek</b>: seek to a particular row. Do not load the data into the fields  
    3259   array. This is done by _fetch. Returns true or false. Note that some implementations  
    3260   such as Interbase do not support seek. Set canSeek to false.</p> 
    3261 <p>_<b>fetch</b>: fetch a row using the database extension function and then move  
    3262   to the next row. Sets the <b>fields</b> array. If the parameter $ignore_fields  
    3263   is true then there is no need to populate the <b>fields</b> array, just move  
    3264   to the next row. then Returns true or false.</p> 
    3265 <p>_<b>close</b>: close the recordset</p> 
    3266 <p><b>Fields</b>: If the array row returned by the PHP extension is not an associative  
    3267   one, you will have to override this. See adodb-odbc.inc.php for an example.  
    3268   For databases such as MySQL and MSSQL where an associative array is returned,  
    3269   there is no need to override this function.</p> 
    3270 <p><b>ADOConnection Fields to Set</b></p> 
    3271 <p>canSeek: Set to true if the _seek function works.</p> 
    3272 <h2>ToDo:</h2> 
    3273 <p>See the <a href=http://php.weblogs.com/adodb-todo-roadmap>RoadMap</a> article.</p> 
    3274 <p>Also see the ADOdb <a href=http://php.weblogs.com/adodb_csv>proxy</a> article  
    3275   for bridging Windows and Unix databases using http remote procedure calls. For  
    3276   your education, visit <a href=http://palslib.com/>palslib.com</a> for database info,  
    3277   and read this article on <a href=http://phplens.com/lens/php-book/optimizing-debugging-php.php>Optimizing  
    3278   PHP</a>. </p> 
    3279 </font> 
    3280 <h2>Change Log<a name="Changes"></a><a name="changes"></a><a name="changelog"></a></h2> 
    3281 <p><a name=4.51></a><b>4.51  29 July  2004</b> 
    3282 <p>Added adodb-xmlschema 1.0.2. Thx dan and richard. 
    3283 <p>Added new adorecordset_ext_* classes. If ADOdb extension installed for mysql, mysqlt and oci8  
     3224<p><a name="4.55"></a><b>4.55 5 Jan 2005</b> 
     3225</p><p>Found bug in Execute() with bind params for db's that do not support binding natively. 
     3226</p><p>DropSequence() now correctly uses default parameter. 
     3227</p><p>Now Execute() ignores locale for floats, so 1.23 is NEVER converted to 1,23. 
     3228</p><p>SetFetchMode() not properly saved in adodb-perf, suspicious sql and expensive sql. Fixed. 
     3229</p><p>Added INET to postgresql metatypes. Thx motzel. 
     3230</p><p>Allow oracle hints to work when counting with _adodb_getcount in adodb-lib.inc.php. Thx Chris Wrye. 
     3231</p><p>Changed mysql insert_id() to use SELECT LAST_INSERT_ID(). 
     3232</p><p>If alter col in datadict does not modify col type/size of actual 
     3233col, then it is removed from alter col code. By Mark Newham. Not 
     3234perfect as MetaType() !== ActualType(). 
     3235</p><p>Added handling of view fields in metacolumns() for postgresql. Thx Renato De Giovanni. 
     3236</p><p>Added to informix MetaPrimaryKeys and MetaColumns fixes for null bit. Thx to Cecilio Albero. 
     3237</p><p>Removed obsolete connection_timeout() from perf code. 
     3238</p><p>Added support for arrayClass in adodb-csv.inc.php. 
     3239</p><p>RSFilter now accepts methods of the form $array($obj, 'methodname'). Thx to blake#near-time.com. 
     3240</p><p>Changed CacheFlush to $cmd = 'rm -rf '.$ADODB_CACHE_DIR.'/[0-9a-f][0-9a-f]/';  
     3241</p><p>For better cursor concurrency, added code to free ref cursors in 
     3242oci8 when $rs-&gt;Close() is called. Note that CLose() is called 
     3243internally by the Get* functions too. 
     3244</p><p>Added IIF support for access when pivoting.  Thx Volodia Krupach. 
     3245</p><p>Added mssql datadict support for timestamp. Thx Alexios. 
     3246</p><p>Informix pager fix. By Mario Ramirez. 
     3247</p><p>ADODB_TABLE_REGEX now includes ':'. By Mario Ramirez. 
     3248</p><p>Mark Newnham contributed MetaIndexes for oci8 and db2. 
     3249</p><p><a name="4.54"></a><b>4.54 5 Nov 2004</b> 
     3250</p><p> 
     3251Now you can set $db-&gt;charSet = ?? before doing a Connect() in oci8. 
     3252</p><p> 
     3253Added adodbFetchMode to sqlite. 
     3254</p><p> 
     3255Perf code, added a string typecast to substr in adodb_log_sql(). 
     3256</p><p> 
     3257Postgres: Changed BlobDecode() to use po_loread, added new $maxblobsize parameter, and now it returns the blob instead 
     3258of sending it to stdout - make sure to mention that as a compat warning. 
     3259Also added $db-&gt;IsOID($oid) function; uses a heuristic, not guaranteed to work 100%. 
     3260</p><p> 
     3261Contributed arabic language file by "El-Shamaa, Khaled" k.el-shamaa#cgiar.org 
     3262</p><p> 
     3263PHP5 exceptions did not handle @ protocol properly. Fixed. 
     3264</p><p> 
     3265Added ifnull handling for postgresql (using coalesce). 
     3266</p><p> 
     3267Added  metatables() support for Postgresql 8.0 (no longer uses pg_% dictionary tables). 
     3268</p><p> 
     3269Improved Sybase ErrorMsg() function. By Gaetano Giunta. 
     3270</p><p> 
     3271Improved oci8 SelectLimit() to use Prepare(). By Cristiano Duarte. 
     3272</p><p> 
     3273Type-cast $row parameter in ifx_fetch_row() to int. Thx stefan bodgan. 
     3274</p><p>Ralf becker contributed improvements in postgresql, sapdb, mysql data dictionary handling:<br> 
     3275- MySql and Postgres MetaType was reporting every int column which was  
     3276part of a primary key and unique as serial<br> 
     3277- Postgres was not reporting the scale of decimal types<br> 
     3278- MaxDB was padding the defaults of none-string types with spaces<br> 
     3279- MySql now correctly converts enum columns to varchar 
     3280</p><p> 
     3281Ralf also changed Postgresql datadict:<br> 
     3282- you cant add NOT NULL columns in postgres in one go, they need to be  
     3283added as NULL and then altered to NOT NULL<br> 
     3284- AlterColumnSQL could not change a varchar column with numbers into an  
     3285integer column, postgres need an explicit conversation<br> 
     3286- a re-created sequence was not set to the correct value, if the name  
     3287was the old name (no implicit sequence), now always the new name of the  
     3288implicit sequence is used<br> 
     3289</p><p>Sergio Strampelli added extra $intoken check to Lens_ParseArgs() in datadict code. 
     3290</p><p><a name="4.53"></a><b>4.53 28 Sept 2004</b> 
     3291</p><p>FetchMode cached in recordset is sometimes mapped to native db fetchMode. Normally this does not matter, 
     3292but when using cached recordsets, we need to switch back to using adodb fetchmode.  So we cache this 
     3293in $rs-&gt;adodbFetchMode if it differs from the db's fetchMode. 
     3294</p><p>For informix we now set canSeek = false driver because stefan bodgan tells me that seeking doesn't work.  
     3295</p><p>SetDateLocale() never worked till now ;-) Thx david#tomato.it 
     3296</p><p>Set $_bindInputArray = true in sapdb driver. Required for clob support. 
     3297</p><p>Fixed some PEAR::DB emulation issues with isError() and isWarning. Thx to Gert-Rainer Bitterlich. 
     3298</p><p>Empty() used in getupdatesql without strlen() check. Fixed.</p> 
     3299<p>Added unsigned detection to mysql and mysqli drivers. Thx to dan cech. 
     3300</p><p>Added hungarian language file. Thx to Hal&aacute;szv&aacute;ri G&aacute;bor. 
     3301</p><p>Improved fieldname-type formatting of datadict SQL generated (adding $widespacing parameter to _GenField). 
     3302</p><p>Datadict oci8 DROP CONSTRAINTS misspelt. Fixed. Thx Mark Newnham. 
     3303</p><p>Changed odbtp to dynamically change databaseType based on connection, eg. from 'odbtp' to 'odbtp_mssql' when connecting 
     3304to mssql database. 
     3305</p><p>In datadict, MySQL I4 was wrongly mapped to MEDIUMINT, which is actually I3. Fixed. 
     3306</p><p>Fixed mysqli MetaType() recognition. Mysqli returns numeric types unlike mysql extension. Thx Francesco Riosa. 
     3307</p><p>VFP odbc driver curmode set wrongly, causing problems with memo fields. Fixed. 
     3308</p><p>Odbc driver did not recognize odbc version 2 driver date types properly. Fixed. Thx Bostjan. 
     3309</p><p>ChangeTableSQL() fixes to datadict-db2.inc.php by Mark Newnham. 
     3310</p><p>Perf monitoring with odbc improved. Now we try in perf code to manually set the sysTimeStamp using date() if sysTimeStamp 
     3311is empty. 
     3312</p><p>All ADO errors are thrown as exceptions in PHP5.  
     3313So we added exception handling to ado in PHP5 by creating new adodb-ado5.inc.php driver. 
     3314</p><p>Added IsConnected(). Returns true if connection object connected. By Luca.Gioppo. 
     3315</p><p>"Ralf Becker" 
     3316RalfBecker#digitalROCK.de contributed new sapdb data-dictionary driver 
     3317and a large patch that implements field and table renaming for oracle, 
     3318mssql, postgresql, mysql and sapdb. See the new RenameTableSQL() and 
     3319RenameColumnSQL() functions. 
     3320</p><p>We now check ExecuteCursor to see if PrepareSP was initially called. 
     3321</p><p>Changed oci8 datadict to use MODIFY for $dd-&gt;alterCol. Thx Mark Newnham. 
     3322</p><p><a name="4.52"></a><b>4.52  10 Aug 2004</b> 
     3323</p><p>Bug found in Replace() when performance logging enabled, introduced in ADOdb 4.50. Fixed. 
     3324</p><p>Replace() checks update stmt. If update stmt fails, we now return immediately. Thx to alex. 
     3325</p><p>Added support for $ADODB_FORCE_TYPE in GetUpdateSQL/GetInsertSQL. Thx to niko. 
     3326</p><p>Added ADODB_ASSOC_CASE support to postgres/postgres7 driver. 
     3327</p><p>Support for DECLARE stmt in oci8. Thx Lochbrunner. 
     3328</p><p><a name="4.51"></a><b>4.51  29 July  2004</b> 
     3329</p><p>Added adodb-xmlschema 1.0.2. Thx dan and richard. 
     3330</p><p>Added new adorecordset_ext_* classes. If ADOdb extension installed for mysql, mysqlt and oci8  
    32843331(but not oci8po),  we use the superfast ADOdb extension code for movenext. 
    3285 <p>Added schema support to mssql and odbc_mssql MetaPrimaryKeys(). 
    3286 <p>Patched MSSQL driver to support PHP NULL and Boolean values  
     3332</p><p>Added schema support to mssql and odbc_mssql MetaPrimaryKeys(). 
     3333</p><p>Patched MSSQL driver to support PHP NULL and Boolean values  
    32873334while binding the input array parameters in the _query() function. By Stephen Farmer. 
    3288 <p>Added support for clob's for mssql,  UpdateBlob(). Thx to gfran#directa.com.br 
    3289 <p>Added normalize support for postgresql (true=lowercase table name, or false=case-sensitive table names)  
     3335</p><p>Added support for clob's for mssql,  UpdateBlob(). Thx to gfran#directa.com.br 
     3336</p><p>Added normalize support for postgresql (true=lowercase table name, or false=case-sensitive table names)  
    32903337to MetaColumns($table, $normalize=true). 
    3291 <p>PHP5 variant dates in ADO not working. Fixed in adodb-ado.inc.php. 
    3292 <p>Constant ADODB_FORCE_NULLS was not working properly for many releases (for GetUpdateSQL). Fixed.  
    3293 Also GetUpdateSQL strips off ORDER BY now - thx Elieser Leão. 
    3294 <p>Perf Monitor for oci8 now dynamically highlights optimizer_* params if too high/low. 
    3295 <p>Added dsn support to NewADOConnection/ADONewConnection. 
    3296 <p>Fixed out of page bounds bug in _adodb_pageexecute_all_rows() Thx to "Sergio Strampelli" sergio#rir.it 
    3297 <p>Speedup of movenext for mysql and oci8 drivers. 
    3298 <p>Moved debugging code _adodb_debug_execute() to adodb-lib.inc.php. 
    3299 <p>Fixed postgresql bytea detection bug. See http://phplens.com/lens/lensforum/msgs.php?id=9849. 
    3300 <p>Fixed ibase datetimestamp typo in PHP5. Thx stefan. 
    3301 <p>Removed whitespace at end of odbtp drivers. 
    3302 <p>Added db2 metaprimarykeys fix. 
    3303 <p>Optimizations to MoveNext() for mysql and oci8. Misc speedups to Get* functions. 
    3304 <p><a name=4.50></a><b>4.50  6 July  2004</b> 
    3305 <p>Bumped it to 4.50 to avoid confusion with PHP 4.3.x series. 
    3306 <p>Added db2 metatables and metacolumns extensions. 
    3307 <p>Added alpha PDO driver. Very buggy, only works with odbc. 
    3308 <p>Tested mysqli. Set poorAffectedRows = true. Cleaned up movenext() and _fetch(). 
    3309 <p>PageExecute does not work properly with php5 (return val not a variable). Reported Dmytro Sychevsky sych#php.com.ua.  Fixed. 
    3310 <p>MetaTables() for mysql, $showschema parameter was not backward compatible with older versions of adodb. Fixed. 
    3311 <p>Changed mysql GetOne() to work with mysql 3.23 when using with non-select stmts (e.g. SHOW TABLES). 
    3312 <p>Changed TRIG_ prefix to a variable in datadict-oci8.inc.php. Thx to Luca.Gioppo#csi.it. 
    3313 <p>New to adodb-time code. We allow you to define your own daylights savings function,  
     3338</p><p>PHP5 variant dates in ADO not working. Fixed in adodb-ado.inc.php. 
     3339</p><p>Constant ADODB_FORCE_NULLS was not working properly for many releases (for GetUpdateSQL). Fixed.  
     3340Also GetUpdateSQL strips off ORDER BY now - thx Elieser Le&atilde;o. 
     3341</p><p>Perf Monitor for oci8 now dynamically highlights optimizer_* params if too high/low. 
     3342</p><p>Added dsn support to NewADOConnection/ADONewConnection. 
     3343</p><p>Fixed out of page bounds bug in _adodb_pageexecute_all_rows() Thx to "Sergio Strampelli" sergio#rir.it 
     3344</p><p>Speedup of movenext for mysql and oci8 drivers. 
     3345</p><p>Moved debugging code _adodb_debug_execute() to adodb-lib.inc.php. 
     3346</p><p>Fixed postgresql bytea detection bug. See http://phplens.com/lens/lensforum/msgs.php?id=9849. 
     3347</p><p>Fixed ibase datetimestamp typo in PHP5. Thx stefan. 
     3348</p><p>Removed whitespace at end of odbtp drivers. 
     3349</p><p>Added db2 metaprimarykeys fix. 
     3350</p><p>Optimizations to MoveNext() for mysql and oci8. Misc speedups to Get* functions. 
     3351</p><p><a name="4.50"></a><b>4.50  6 July  2004</b> 
     3352</p><p>Bumped it to 4.50 to avoid confusion with PHP 4.3.x series. 
     3353</p><p>Added db2 metatables and metacolumns extensions. 
     3354</p><p>Added alpha PDO driver. Very buggy, only works with odbc. 
     3355</p><p>Tested mysqli. Set poorAffectedRows = true. Cleaned up movenext() and _fetch(). 
     3356</p><p>PageExecute does not work properly with php5 (return val not a variable). Reported Dmytro Sychevsky sych#php.com.ua.  Fixed. 
     3357</p><p>MetaTables() for mysql, $showschema parameter was not backward compatible with older versions of adodb. Fixed. 
     3358</p><p>Changed mysql GetOne() to work with mysql 3.23 when using with non-select stmts (e.g. SHOW TABLES). 
     3359</p><p>Changed TRIG_ prefix to a variable in datadict-oci8.inc.php. Thx to Luca.Gioppo#csi.it. 
     3360</p><p>New to adodb-time code. We allow you to define your own daylights savings function,  
    33143361adodb_daylight_sv for pre-1970 dates. If the function is defined  
    33153362(somewhere in an include), then you can correct  
    33163363for daylights savings. See http://phplens.com/phpeverywhere/node/view/16#daylightsavings 
    33173364for more info. 
    3318 <p>New sqlitepo driver. This is because assoc mode does not work like other drivers in sqlite. 
     3365</p><p>New sqlitepo driver. This is because assoc mode does not work like other drivers in sqlite. 
    33193366   Namely, when selecting (joining) multiple tables, in assoc mode the table 
    33203367          names are included in the assoc keys in the "sqlite" driver. 
     
    33223369          When this results in a conflict,  the first field get preference. 
    33233370        Contributed by Herman Kuiper  herman#ozuzo.net   
    3324 <p>Added $forcenull parameter to GetInsertSQL/GetUpdateSQL. Idea by Marco Aurelio Silva. 
    3325 <p>More XHTML changes for GetMenu. By Jeremy Evans. 
    3326 <p>Fixes some ibase date issues. Thx to stefan bogdan. 
    3327 <p>Improvements to mysqli driver to support $ADODB_COUNTRECS. 
    3328 <p>Fixed adodb-csvlib.inc.php problem when reading stream from socket. We need to poll stream continiously. 
    3329 <p><a name=4.23></a><b>4.23  16 June   2004</b> 
    3330 <p> 
     3371</p><p>Added $forcenull parameter to GetInsertSQL/GetUpdateSQL. Idea by Marco Aurelio Silva. 
     3372</p><p>More XHTML changes for GetMenu. By Jeremy Evans. 
     3373</p><p>Fixes some ibase date issues. Thx to stefan bogdan. 
     3374</p><p>Improvements to mysqli driver to support $ADODB_COUNTRECS. 
     3375</p><p>Fixed adodb-csvlib.inc.php problem when reading stream from socket. We need to poll stream continiously. 
     3376</p><p><a name="4.23"></a><b>4.23  16 June   2004</b> 
     3377</p><p> 
    33313378New interbase/firebird fixes thx to Lester Caine. 
    33323379Driver fixes a problem with getting field names in the result array, and  
    33333380corrects a couple of data conversions. Also we default to dialect3 for firebird. 
    33343381Also ibase sysDate property was wrong. Changed to cast as timestamp. 
    3335 <p> 
     3382</p><p> 
    33363383The datadict driver is set up to give quoted tables and fields as this  
    33373384was the only way round reserved words being used as field names in  
     
    33403387table names. The conversion of TikiWiki to ADOdb helped in that, but  
    33413388until the database is completely tidied up in TikiPro ... 
    3342 <p>Modified _gencachename() to include fetchmode in name hash. 
     3389</p><p>Modified _gencachename() to include fetchmode in name hash. 
    33433390This means you should clear your cache directory after installing this release as the  
    33443391cache name algorithm has changed. 
    3345 <p>Now Cache* functions work in safe mode, because we do not create sub-directories in the $ADODB_CACHE_DIR in safe mode. In non-safe mode we still create sub-directories. Done by modifying _gencachename(). 
    3346 <p>Added $gmt parameter (true/false) to UserDate and UserTimeStamp in connection class, to force conversion of input (in local time) to be converted to UTC/GMT. 
    3347 <p>Mssql datadict did not support INT types properly (no size param allowed).  
     3392</p><p>Now Cache* functions work in safe 
     3393mode, because we do not create sub-directories in the $ADODB_CACHE_DIR 
     3394in safe mode. In non-safe mode we still create sub-directories. Done by 
     3395modifying _gencachename(). 
     3396</p><p>Added $gmt parameter (true/false) 
     3397to UserDate and UserTimeStamp in connection class, to force conversion 
     3398of input (in local time) to be converted to UTC/GMT. 
     3399</p><p>Mssql datadict did not support INT types properly (no size param allowed).  
    33483400Added _GetSize() to datadict-mssql.inc.php. 
    3349 <p>For borland_ibase, BeginTrans(), changed:<br> 
    3350 <pre>   $this->_transactionID = $this->_connectionID;</pre> 
     3401</p><p>For borland_ibase, BeginTrans(), changed:<br> 
     3402</p><pre>   $this-&gt;_transactionID = $this-&gt;_connectionID;</pre> 
    33513403to<br> 
    3352 <pre>   $this->_transactionID = ibase_trans($this->ibasetrans, $this->_connectionID);</pre> 
     3404<pre>   $this-&gt;_transactionID = ibase_trans($this-&gt;ibasetrans, $this-&gt;_connectionID);</pre> 
    33533405                 
    33543406<p>Fixed typo in mysqi_field_seek(). Thx to Sh4dow (sh4dow#php.pl). 
    3355 <p>LogSQL did not work with Firebird/Interbase. Fixed. 
    3356 <p>Postgres: made errorno() handling more consistent. Thx to Michael Jahn, Michael.Jahn#mailbox.tu-dresden.de. 
    3357 <p>Added informix patch to better support metatables, metacolumns by "Cecilio Albero" c-albero#eos-i.com 
    3358 <p>Cyril Malevanov contributed patch to oci8 to support passing of LOB parameters: 
    3359 <pre> 
    3360         $text = 'test test test'; 
    3361         $sql = "declare rs clob; begin :rs := lobinout(:sa0); end;"; 
    3362         $stmt = $conn -> PrepareSP($sql); 
    3363         $conn -> InParameter($stmt,$text,'sa0', -1, OCI_B_CLOB); 
    3364         $rs = ''; 
    3365         $conn -> OutParameter($stmt,$rs,'rs', -1, OCI_B_CLOB); 
    3366         $conn -> Execute($stmt); 
    3367         echo "return = ".$rs."&lt;br>"; 
    3368 </pre> 
     3407</p><p>LogSQL did not work with Firebird/Interbase. Fixed. 
     3408</p><p>Postgres: made errorno() handling more consistent. Thx to Michael Jahn, Michael.Jahn#mailbox.tu-dresden.de. 
     3409</p><p>Added informix patch to better support metatables, metacolumns by "Cecilio Albero" c-albero#eos-i.com 
     3410</p><p>Cyril Malevanov contributed patch to oci8 to support passing of LOB parameters: 
     3411</p><pre>       $text = 'test test test';<br>   $sql = "declare rs clob; begin :rs := lobinout(:sa0); end;";<br>        $stmt = $conn -&gt; PrepareSP($sql);<br>        $conn -&gt; InParameter($stmt,$text,'sa0', -1, OCI_B_CLOB);<br> $rs = '';<br>   $conn -&gt; OutParameter($stmt,$rs,'rs', -1, OCI_B_CLOB);<br>   $conn -&gt; Execute($stmt);<br> echo "return = ".$rs."&lt;br&gt;";<br></pre> 
    33693412As he says, the LOBs limitations are: 
    3370 <pre> 
    3371  - use OCINewDescriptor before binding 
    3372  - if Param is IN, uses save() before each execute. This is done automatically for you. 
    3373  - if Param is OUT, uses load() after each execute. This is done automatically for you. 
    3374  - when we bind $var as LOB, we create new descriptor and return it as a 
    3375    Bind Result, so if we want to use OUT parameters, we have to store 
    3376    somewhere &$var to load() data from LOB to it. 
    3377  - IN OUT params are not working now (should not be a big problem to fix it) 
    3378  - now mass binding not working too (I've wrote about it before) 
    3379 </pre> 
     3413<pre> - use OCINewDescriptor before binding<br> - if Param is IN, uses save() before each execute. This is done automatically for you.<br> - if Param is OUT, uses load() after each execute. This is done automatically for you.<br> - when we bind $var as LOB, we create new descriptor and return it as a<br>   Bind Result, so if we want to use OUT parameters, we have to store<br>   somewhere &amp;$var to load() data from LOB to it.<br> - IN OUT params are not working now (should not be a big problem to fix it)<br> - now mass binding not working too (I've wrote about it before)<br></pre> 
    33803414<p>Simplified Connect() and PConnect() error handling. 
    3381 <p>When extension not loaded, Connect() and PConnect() will return null. On connect error, the fns will return false. 
    3382 <p>CacheGetArray() added to code. 
    3383 <p>Added Init() to adorecordset_empty(). 
    3384 <p>Changed postgres64 driver, MetaColumns() to not strip off quotes in default value if :: detected (type-casting of default). 
    3385 <p>Added test: if (!defined('ADODB_DIR')) die(). Useful to prevent hackers from detecting file paths. 
    3386 <p>Changed metaTablesSQL to ignore Postgres 7.4 information schemas (sql_*). 
    3387 <p>New polish language file by  Grzegorz Pacan 
    3388 <p>Added support for UNION in _adodb_getcount(). 
    3389 <p>Added security check for ADODB_DIR to limit path disclosure issues. Requested by postnuke team. 
    3390 <p>Added better error message support to oracle driver. Thx to Gaetano Giunta. 
    3391 <p>Added showSchema support to mysql. 
    3392 <p>Bind in oci8 did not handle $name=false properly. Fixed. 
    3393 <p>If extension not loaded, Connect(), PConnect(), NConnect() will return null. 
    3394 <p><b>4.22  15 Apr   2004</b> 
    3395 <p>Moved docs to own adodb/docs folder. 
    3396 <p>Fixed session bug when quoting compressed/encrypted data in Replace(). 
    3397 <p>Netezza Driver and LDAP drivers contributed by Josh Eldridge. 
    3398 <p>GetMenu now uses rtrim() on values instead of trim(). 
    3399 <p>Changed MetaColumnNames to return an associative array, keys being the field names in uppercase. 
    3400 <p>Suggested fix to adodb-ado.inc.php affected_rows to support PHP5 variants. Thx to Alexios Fakos. 
    3401 <p>Contributed bulgarian language file by Valentin Sheiretsky valio#valio.eu.org. 
    3402 <p>Contributed romanian language file by stefan bogdan. 
    3403 <p>GetInsertSQL now checks for table name (string) in $rs, and will create a recordset for that 
     3415</p><p>When extension not loaded, Connect() and PConnect() will return null. On connect error, the fns will return false. 
     3416</p><p>CacheGetArray() added to code. 
     3417</p><p>Added Init() to adorecordset_empty(). 
     3418</p><p>Changed postgres64 driver, MetaColumns() to not strip off quotes in default value if :: detected (type-casting of default). 
     3419</p><p>Added test: if (!defined('ADODB_DIR')) die(). Useful to prevent hackers from detecting file paths. 
     3420</p><p>Changed metaTablesSQL to ignore Postgres 7.4 information schemas (sql_*). 
     3421</p><p>New polish language file by  Grzegorz Pacan 
     3422</p><p>Added support for UNION in _adodb_getcount(). 
     3423</p><p>Added security check for ADODB_DIR to limit path disclosure issues. Requested by postnuke team. 
     3424</p><p>Added better error message support to oracle driver. Thx to Gaetano Giunta. 
     3425</p><p>Added showSchema support to mysql. 
     3426</p><p>Bind in oci8 did not handle $name=false properly. Fixed. 
     3427</p><p>If extension not loaded, Connect(), PConnect(), NConnect() will return null. 
     3428</p><p><b>4.22  15 Apr   2004</b> 
     3429</p><p>Moved docs to own adodb/docs folder. 
     3430</p><p>Fixed session bug when quoting compressed/encrypted data in Replace(). 
     3431</p><p>Netezza Driver and LDAP drivers contributed by Josh Eldridge. 
     3432</p><p>GetMenu now uses rtrim() on values instead of trim(). 
     3433</p><p>Changed MetaColumnNames to return an associative array, keys being the field names in uppercase. 
     3434</p><p>Suggested fix to adodb-ado.inc.php affected_rows to support PHP5 variants. Thx to Alexios Fakos. 
     3435</p><p>Contributed bulgarian language file by Valentin Sheiretsky valio#valio.eu.org. 
     3436</p><p>Contributed romanian language file by stefan bogdan. 
     3437</p><p>GetInsertSQL now checks for table name (string) in $rs, and will create a recordset for that 
    34043438table automatically. Contributed by Walt Boring. Also added OCI_B_BLOB in bind on Walt's request - hope 
    34053439it doesn't break anything :-) 
    3406 <p>Some minor postgres speedups in _initrs(). 
    3407 <p> ChangeTableSQL checks now if MetaColumns returns empty. Thx Jason Judge. 
    3408 <p>Added ADOConnection::Time(), returns current database time in unix timestamp format, or false. 
    3409 <p><b>4.21 20 Mar 2004</b> 
    3410 <p>We no longer in SelectLimit for VFP driver add SELECT TOP X unless an ORDER BY exists. 
    3411 <p>Pim Koeman contributed dutch language file adodb-nl.inc.php. 
    3412 <p>Rick Hickerson added CLOB support to db2 datadict. 
    3413 <p>Added odbtp driver. Thx to "stefan bogdan" sbogdan#rsb.ro. 
    3414 <p>Changed PrepareSP() 2nd parameter, $cursor, to default to true (formerly false). Fixes oci8 backward 
     3440</p><p>Some minor postgres speedups in _initrs(). 
     3441</p><p> ChangeTableSQL checks now if MetaColumns returns empty. Thx Jason Judge. 
     3442</p><p>Added ADOConnection::Time(), returns current database time in unix timestamp format, or false. 
     3443</p><p><b>4.21 20 Mar 2004</b> 
     3444</p><p>We no longer in SelectLimit for VFP driver add SELECT TOP X unless an ORDER BY exists. 
     3445</p><p>Pim Koeman contributed dutch language file adodb-nl.inc.php. 
     3446</p><p>Rick Hickerson added CLOB support to db2 datadict. 
     3447</p><p>Added odbtp driver. Thx to "stefan bogdan" sbogdan#rsb.ro. 
     3448</p><p>Changed PrepareSP() 2nd parameter, $cursor, to default to true (formerly false). Fixes oci8 backward 
    34153449compat problems with OUT params. 
    3416 <p>Fixed month calculation error in adodb-time.inc.php. 2102-June-01 appeared as 2102-May-32. 
    3417 <p>Updated PHP5 RC1 iterator support. API changed, hasMore() renamed to valid(). 
    3418 <p>Changed internal format of serialized cache recordsets. As we store a version number, this should be 
     3450</p><p>Fixed month calculation error in adodb-time.inc.php. 2102-June-01 appeared as 2102-May-32. 
     3451</p><p>Updated PHP5 RC1 iterator support. API changed, hasMore() renamed to valid(). 
     3452</p><p>Changed internal format of serialized cache recordsets. As we store a version number, this should be 
    34193453backward compatible. 
    3420 <p>Error handling when driver file not found was flawed in ADOLoadCode(). Fixed. 
    3421 <p><b>4.20 27 Feb 2004</b> 
    3422 <p>Updated to AXMLS 1.01. 
    3423 <p>MetaForeignKeys for postgres7 modified by Edward Jaramilla, works on pg 7.4. 
    3424 <p>Now numbers accepts function calls or sequences for GetInsertSQL/GetUpdateSQL numeric fields. 
    3425 <p>Changed quotes of 'delete from $perf_table' to "". Thx Kehui (webmaster#kehui.net) 
    3426 <p>Added ServerInfo() for ifx, and putenv trim fix. Thx Fernando Ortiz. 
    3427 <p>Added addq(), which is analogous to addslashes(). 
    3428 <p>Tested with php5b4. Fix some php5 compat problems with exceptions and sybase. 
    3429 <P>Carl-Christian Salvesen added patch to mssql _query to support binds greater than 4000 chars. 
    3430 <p>Mike suggested patch to PHP5 exception handler. $errno must be numeric. 
    3431 <p>Added double quotes (") to ADODB_TABLE_REGEX. 
    3432 <p>For oci8, Prepare(...,$cursor), $cursor's meaning was accidentally inverted in 4.11. This causes problems with ExecuteCursor() too, which calls Prepare() internally. Thx to William Lovaton. 
    3433 <p>Now dateHasTime property in connection object renamed to datetime for consistency. This could break bc. 
    3434 <p>Csongor Halmai reports that db2 SelectLimit with input array is not working. Fixed.. 
    3435 <p><b>4.11 27 Jan 2004</b> 
    3436 <p>Csongor Halmai reports db2 binding not working. Reverted back to emulated binding. 
    3437 <p>Dan Cech modifies datadict code. Adds support for DropIndex. Minor cleanups. 
    3438 <p>Table misspelt in perf-oci8.inc.php. Changed v$conn_cache_advice to v$db_cache_advice. Reported by Steve W. 
    3439 <p>UserTimeStamp and DBTimeStamp did not handle YYYYMMDDHHMMSS format properly. Reported by Mike Muir. Fixed. 
    3440 <p>Changed oci8 Prepare(). Does not auto-allocate OCINewCursor automatically, unless 2nd param is set to true. 
     3454</p><p>Error handling when driver file not found was flawed in ADOLoadCode(). Fixed. 
     3455</p><p><b>4.20 27 Feb 2004</b> 
     3456</p><p>Updated to AXMLS 1.01. 
     3457</p><p>MetaForeignKeys for postgres7 modified by Edward Jaramilla, works on pg 7.4. 
     3458</p><p>Now numbers accepts function calls or sequences for GetInsertSQL/GetUpdateSQL numeric fields. 
     3459</p><p>Changed quotes of 'delete from $perf_table' to "". Thx Kehui (webmaster#kehui.net) 
     3460</p><p>Added ServerInfo() for ifx, and putenv trim fix. Thx Fernando Ortiz. 
     3461</p><p>Added addq(), which is analogous to addslashes(). 
     3462</p><p>Tested with php5b4. Fix some php5 compat problems with exceptions and sybase. 
     3463</p><p>Carl-Christian Salvesen added patch to mssql _query to support binds greater than 4000 chars. 
     3464</p><p>Mike suggested patch to PHP5 exception handler. $errno must be numeric. 
     3465</p><p>Added double quotes (") to ADODB_TABLE_REGEX. 
     3466</p><p>For oci8, Prepare(...,$cursor), 
     3467$cursor's meaning was accidentally inverted in 4.11. This causes 
     3468problems with ExecuteCursor() too, which calls Prepare() internally. 
     3469Thx to William Lovaton. 
     3470</p><p>Now dateHasTime property in connection object renamed to datetime for consistency. This could break bc. 
     3471</p><p>Csongor Halmai reports that db2 SelectLimit with input array is not working. Fixed.. 
     3472</p><p><b>4.11 27 Jan 2004</b> 
     3473</p><p>Csongor Halmai reports db2 binding not working. Reverted back to emulated binding. 
     3474</p><p>Dan Cech modifies datadict code. Adds support for DropIndex. Minor cleanups. 
     3475</p><p>Table misspelt in perf-oci8.inc.php. Changed v$conn_cache_advice to v$db_cache_advice. Reported by Steve W. 
     3476</p><p>UserTimeStamp and DBTimeStamp did not handle YYYYMMDDHHMMSS format properly. Reported by Mike Muir. Fixed. 
     3477</p><p>Changed oci8 Prepare(). Does not auto-allocate OCINewCursor automatically, unless 2nd param is set to true. 
    34413478This will break backward compat, if Prepare/Execute is used instead of ExecuteCursor. Reported by Chris Jones. 
    3442 <p>Added InParameter() and OutParameter(). Wrapper functions to Parameter(), but nicer because they 
     3479</p><p>Added InParameter() and OutParameter(). Wrapper functions to Parameter(), but nicer because they 
    34433480are self-documenting. 
    3444 <p>Added 'R' handling in ActualType() to datadict-mysql.inc.php 
    3445 <p>Added ADOConnection::SerializableRS($rs). Returns a recordset that can be serialized in a session. 
    3446 <p>Added "Run SQL" to performance UI(). 
    3447 <p>Misc spelling corrections in adodb-mysqli.inc.php, adodb-oci8.inc.php and datadict-oci8.inc.php, from Heinz Hombergs. 
    3448 <p>MetaIndexes() for ibase contributed by Heinz Hombergs. 
    3449 <p><b>4.10 12 Jan 2004</b> 
    3450 <p>Dan Cech contributed extensive changes to data dictionary to support name quoting (with `), and drop table/index. 
    3451 <p>Informix added cursorType property. Default remains IFX_SCROLL, but you can change to 0 (non-scrollable cursor) for performance. 
    3452 <p>Added ADODB_View_PrimaryKeys() for returning view primary keys to MetaPrimaryKeys(). 
    3453 <p>Simplified chinese file, adodb-cn.inc.php from cysoft. 
    3454 <p>Added check for ctype_alnum in adodb-datadict.inc.php. Thx to Jason Judge. 
    3455 <p>Added connection parameter to ibase Prepare(). Fix by Daniel Hassan. 
    3456 <p>Added nameQuote for quoting identifiers and names to connection obj. Requested by Jason Judge. Also the 
     3481</p><p>Added 'R' handling in ActualType() to datadict-mysql.inc.php 
     3482</p><p>Added ADOConnection::SerializableRS($rs). Returns a recordset that can be serialized in a session. 
     3483</p><p>Added "Run SQL" to performance UI(). 
     3484</p><p>Misc spelling corrections in adodb-mysqli.inc.php, adodb-oci8.inc.php and datadict-oci8.inc.php, from Heinz Hombergs. 
     3485</p><p>MetaIndexes() for ibase contributed by Heinz Hombergs. 
     3486</p><p><b>4.10 12 Jan 2004</b> 
     3487</p><p>Dan Cech contributed extensive changes to data dictionary to support name quoting (with `), and drop table/index. 
     3488</p><p>Informix added cursorType property. Default remains IFX_SCROLL, but you can change to 0 (non-scrollable cursor) for performance. 
     3489</p><p>Added ADODB_View_PrimaryKeys() for returning view primary keys to MetaPrimaryKeys(). 
     3490</p><p>Simplified chinese file, adodb-cn.inc.php from cysoft. 
     3491</p><p>Added check for ctype_alnum in adodb-datadict.inc.php. Thx to Jason Judge. 
     3492</p><p>Added connection parameter to ibase Prepare(). Fix by Daniel Hassan. 
     3493</p><p>Added nameQuote for quoting identifiers and names to connection obj. Requested by Jason Judge. Also the 
    34573494data dictionary parser now detects `field name` and generates column names with spaces correctly. 
    3458 <p>BOOL type not recognised correctly as L. Fixed. 
    3459 <p>Fixed paths in ADODB_DIR for session files, and back-ported it to 4.05 (15 Dec 2003) 
    3460 <p>Added Schema to postgresql MetaTables. Thx to col#gear.hu 
    3461 <p>Empty postgresql recordsets that had blob fields did not set EOF properly. Fixed. 
    3462 <p>CacheSelectLimit internal parameters to SelectLimit were wrong. Thx to Nio. 
    3463 <p>Modified adodb_pr() and adodb_backtrace() to support command-line usage (eg. no html). 
    3464 <p>Fixed some fr and it lang errors. Thx to Gaetano G. 
    3465 <p>Added contrib directory, with adodb rs to xmlrpc convertor by Gaetano G. 
    3466 <p>Fixed array recordset bugs when _skiprow1 is true. Thx to Gaetano G. 
    3467 <p>Fixed pivot table code when count is false. 
    3468 <p> 
    3469  
    3470 <p><b>4.05 13 Dec 2003 </b> 
    3471 <p>Added MetaIndexes - thx to Dan Cech. 
    3472 <p>Rewritten session code by Ross Smith. Moved code to adodb/session directory. 
    3473 <p>Added function exists check on connecting to most drivers, so we don't crash with the unknown function error. 
    3474 <p>Smart Transactions failed with GenID() when it no seq table has been created because the sql 
     3495</p><p>BOOL type not recognised correctly as L. Fixed. 
     3496</p><p>Fixed paths in ADODB_DIR for session files, and back-ported it to 4.05 (15 Dec 2003) 
     3497</p><p>Added Schema to postgresql MetaTables. Thx to col#gear.hu 
     3498</p><p>Empty postgresql recordsets that had blob fields did not set EOF properly. Fixed. 
     3499</p><p>CacheSelectLimit internal parameters to SelectLimit were wrong. Thx to Nio. 
     3500</p><p>Modified adodb_pr() and adodb_backtrace() to support command-line usage (eg. no html). 
     3501</p><p>Fixed some fr and it lang errors. Thx to Gaetano G. 
     3502</p><p>Added contrib directory, with adodb rs to xmlrpc convertor by Gaetano G. 
     3503</p><p>Fixed array recordset bugs when _skiprow1 is true. Thx to Gaetano G. 
     3504</p><p>Fixed pivot table code when count is false. 
     3505</p><p> 
     3506 
     3507</p><p><b>4.05 13 Dec 2003 </b> 
     3508</p><p>Added MetaIndexes to data-dict code - thx to Dan Cech. 
     3509</p><p>Rewritten session code by Ross Smith. Moved code to adodb/session directory. 
     3510</p><p>Added function exists check on connecting to most drivers, so we don't crash with the unknown function error. 
     3511</p><p>Smart Transactions failed with GenID() when it no seq table has been created because the sql 
    34753512        statement fails. Fix by Mark Newnham. 
    3476 <p>Added $db->length, which holds name of function that returns strlen. 
    3477 <p>Fixed error handling for bad driver in ADONewConnection - passed too few params to error-handler. 
    3478 <p>Datadict did not handle types like 16.0 properly in _GetSize. Fixed. 
    3479 <p>Oci8 driver SelectLimit() bug &= instead of =& used. Thx to Swen Thümmler. 
    3480 <p>Jesse Mullan suggested not flushing outp when output buffering enabled. Due to Apache 2.0 bug. Added. 
    3481 <p>MetaTables/MetaColumns return ref bug with PHP5 fixed in adodb-datadict.inc.php. 
    3482 <p>New mysqli driver contributed by Arjen de Rijke. Based on adodb 3.40 driver. 
     3513</p><p>Added $db-&gt;length, which holds name of function that returns strlen. 
     3514</p><p>Fixed error handling for bad driver in ADONewConnection - passed too few params to error-handler. 
     3515</p><p>Datadict did not handle types like 16.0 properly in _GetSize. Fixed. 
     3516</p><p>Oci8 driver SelectLimit() bug &amp;= instead of =&amp; used. Thx to Swen Th&uuml;mmler. 
     3517</p><p>Jesse Mullan suggested not flushing outp when output buffering enabled. Due to Apache 2.0 bug. Added. 
     3518</p><p>MetaTables/MetaColumns return ref bug with PHP5 fixed in adodb-datadict.inc.php. 
     3519</p><p>New mysqli driver contributed by Arjen de Rijke. Based on adodb 3.40 driver. 
    34833520Then jlim added BeginTrans, CommitTrans, RollbackTrans, IfNull, SQLDate. Also fixed return ref bug. 
    3484 <p>$ADODB_FLUSH added, if true then force flush in debugging outp. Default is false.  In earlier 
     3521</p><p>$ADODB_FLUSH added, if true then force flush in debugging outp. Default is false.  In earlier 
    34853522versions, outp defaulted to flush, which is not compat with apache 2.0. 
    3486 <p>Mysql driver's GenID() function did not work when when sql logging is on. Fixed. 
    3487 <p>$ADODB_SESSION_TBL not declared as global var. Not available if adodb-session.inc.php included in function. Fixed. 
    3488 <p>The input array not passed to Execute() in _adodb_getcount(). Fixed. 
    3489 <p><b>4.04 13 Nov 2003 </b> 
    3490 <p>Switched back to foreach - faster than list-each. 
    3491 <p>Fixed bug in ado driver - wiping out $this->fields with date fields. 
    3492 <p>Performance Monitor, View SQL, Explain Plan did not work if strlen($SQL)>max($_GET length). Fixed. 
    3493 <p>Performance monitor, oci8 driver added memory sort ratio. 
    3494 <p>Added random property, returns SQL to generate a floating point number between 0 and 1; 
    3495 <p><b>4.03 6 Nov 2003 </b> 
    3496 <p>The path to adodb-php4.inc.php and adodb-iterators.inc.php was not setup properly. 
    3497 <p>Patched SQLDate in interbase to support hours/mins/secs. Thx to ari kuorikoski. 
    3498 <p>Force autorollback for pgsql persistent connections -  
     3523</p><p>Mysql driver's GenID() function did not work when when sql logging is on. Fixed. 
     3524</p><p>$ADODB_SESSION_TBL not declared as global var. Not available if adodb-session.inc.php included in function. Fixed. 
     3525</p><p>The input array not passed to Execute() in _adodb_getcount(). Fixed. 
     3526</p><p><b>4.04 13 Nov 2003 </b> 
     3527</p><p>Switched back to foreach - faster than list-each. 
     3528</p><p>Fixed bug in ado driver - wiping out $this-&gt;fields with date fields. 
     3529</p><p>Performance Monitor, View SQL, Explain Plan did not work if strlen($SQL)&gt;max($_GET length). Fixed. 
     3530</p><p>Performance monitor, oci8 driver added memory sort ratio. 
     3531</p><p>Added random property, returns SQL to generate a floating point number between 0 and 1; 
     3532</p><p><b>4.03 6 Nov 2003 </b> 
     3533</p><p>The path to adodb-php4.inc.php and adodb-iterators.inc.php was not setup properly. 
     3534</p><p>Patched SQLDate in interbase to support hours/mins/secs. Thx to ari kuorikoski. 
     3535</p><p>Force autorollback for pgsql persistent connections -  
    34993536apparently pgsql did not autorollback properly before 4.3.4. See http://bugs.php.net/bug.php?id=25404 
    3500 <p><b>4.02 5 Nov 2003 </b> 
    3501 <p>Some errors in adodb_error_pg() fixed. Thx to Styve. 
    3502 <p>Spurious Insert_ID() error was generated by LogSQL(). Fixed. 
    3503 <p>Insert_ID was interfering with Affected_Rows() and Replace()  when LogSQL() enabled. Fixed. 
    3504 <p>More foreach loops optimized with list/each. 
    3505 <p>Null dates not handled properly in ADO driver (it becomes 31 Dec 1969!). 
    3506 <p>Heinz Hombergs contributed patches for mysql MetaColumns - adding scale, made 
     3537</p><p><b>4.02 5 Nov 2003 </b> 
     3538</p><p>Some errors in adodb_error_pg() fixed. Thx to Styve. 
     3539</p><p>Spurious Insert_ID() error was generated by LogSQL(). Fixed. 
     3540</p><p>Insert_ID was interfering with Affected_Rows() and Replace()  when LogSQL() enabled. Fixed. 
     3541</p><p>More foreach loops optimized with list/each. 
     3542</p><p>Null dates not handled properly in ADO driver (it becomes 31 Dec 1969!). 
     3543</p><p>Heinz Hombergs contributed patches for mysql MetaColumns - adding scale, made 
    35073544interbase MetaColumns work with firebird/interbase, and added lang/adodb-de.inc.php. 
    3508 <p>Added INFORMIXSERVER environment variable. 
    3509 <p>Added $ADODB_ANSI_PADDING_OFF for interbase/firebird. 
    3510 <p>PHP 5 beta 2 compat check. Foreach (Iterator) support. Exceptions support. 
    3511 <p><b>4.01 23 Oct 2003 </b> 
    3512 <p>Fixed bug in rs2html(), tohtml.inc.php, that generated blank table cells. 
    3513 <p>Fixed insert_id() incorrectly generated when logsql() enabled. 
    3514 <p>Modified PostgreSQL _fixblobs to use list/each instead of foreach. 
    3515 <p>Informix ErrorNo() implemented correctly. 
    3516 <p>Modified several places to use list/each, including GetRowAssoc(). 
    3517 <p>Added UserTimeStamp() to connection class. 
    3518 <p>Added $ADODB_ANSI_PADDING_OFF for oci8po. 
    3519 <p><b>4.00 20 Oct 2003 </b> 
    3520 <p>Upgraded adodb-xmlschema to 1 Oct 2003 snapshot. 
    3521 <p>Fix to rs2html warning message. Thx to Filo. 
    3522 <p>Fix for odbc_mssql/mssql SQLDate(), hours was wrong. 
    3523 <p>Added MetaColumns and MetaPrimaryKeys for sybase. Thx to Chris Phillipson. 
    3524 <p>Added autoquoting to datadict for MySQL and PostgreSQL. Suggestion by Karsten Dambekalns   
    3525 <p><b>3.94 11 Oct 2003 </b> 
    3526 <p>Create trigger in datadict-oci8.inc.php did not work, because all cr/lf's must be removed.  
    3527 <p>ErrorMsg()/ErrorNo() did not work for many databases when logging enabled. Fixed. 
    3528 <p>Removed global variable $ADODB_LOGSQL as it does not work properly with multiple connections. 
    3529 <p>Added SQLDate support for sybase. Thx to Chris Phillipson 
    3530 <p>Postgresql checking of pgsql resultset resource was incorrect. Fix by Bharat Mediratta bharat#menalto.com. 
     3545</p><p>Added INFORMIXSERVER environment variable. 
     3546</p><p>Added $ADODB_ANSI_PADDING_OFF for interbase/firebird. 
     3547</p><p>PHP 5 beta 2 compat check. Foreach (Iterator) support. Exceptions support. 
     3548</p><p><b>4.01 23 Oct 2003 </b> 
     3549</p><p>Fixed bug in rs2html(), tohtml.inc.php, that generated blank table cells. 
     3550</p><p>Fixed insert_id() incorrectly generated when logsql() enabled. 
     3551</p><p>Modified PostgreSQL _fixblobs to use list/each instead of foreach. 
     3552</p><p>Informix ErrorNo() implemented correctly. 
     3553</p><p>Modified several places to use list/each, including GetRowAssoc(). 
     3554</p><p>Added UserTimeStamp() to connection class. 
     3555</p><p>Added $ADODB_ANSI_PADDING_OFF for oci8po. 
     3556</p><p><b>4.00 20 Oct 2003 </b> 
     3557</p><p>Upgraded adodb-xmlschema to 1 Oct 2003 snapshot. 
     3558</p><p>Fix to rs2html warning message. Thx to Filo. 
     3559</p><p>Fix for odbc_mssql/mssql SQLDate(), hours was wrong. 
     3560</p><p>Added MetaColumns and MetaPrimaryKeys for sybase. Thx to Chris Phillipson. 
     3561</p><p>Added autoquoting to datadict for MySQL and PostgreSQL. Suggestion by Karsten Dambekalns   
     3562</p><p><b>3.94 11 Oct 2003 </b> 
     3563</p><p>Create trigger in datadict-oci8.inc.php did not work, because all cr/lf's must be removed.  
     3564</p><p>ErrorMsg()/ErrorNo() did not work for many databases when logging enabled. Fixed. 
     3565</p><p>Removed global variable $ADODB_LOGSQL as it does not work properly with multiple connections. 
     3566</p><p>Added SQLDate support for sybase. Thx to Chris Phillipson 
     3567</p><p>Postgresql checking of pgsql resultset resource was incorrect. Fix by Bharat Mediratta bharat#menalto.com. 
    35313568Same patch applied to  _insertid and _affectedrows for adodb-postgres64.inc.php. 
    3532 <p>Added support for NConnect for postgresql. 
    3533 <p>Added Sybase data dict support. Thx to Chris Phillipson   
    3534 <p>Extensive improvements in $perf->UI(), eg. Explain now opens in new window, we show scripts 
     3569</p><p>Added support for NConnect for postgresql. 
     3570</p><p>Added Sybase data dict support. Thx to Chris Phillipson   
     3571</p><p>Extensive improvements in $perf-&gt;UI(), eg. Explain now opens in new window, we show scripts 
    35353572which call sql, etc. 
    3536 <p>Perf Monitor UI works with magic quotes enabled. 
    3537 <p>rsPrefix was declared twice. Removed. 
    3538 <p>Oci8 stored procedure support, eg. "begin func(); end;" was incorrect in _query. Fixed. 
    3539 <p>Tiraboschi Massimiliano contributed italian language file. 
    3540 <p>Fernando Ortiz, fortiz#lacorona.com.mx, contributed informix performance monitor. 
    3541 <p>Added _varchar (varchar arrays) support for postgresql. Reported by PREVOT Stéphane. 
    3542 <p><b>3.92 22 Sept 2003</b>  
    3543 <p>Added GetAssoc and CacheGetAssoc to connection object. 
    3544 <p>Removed TextMax and CharMax functions from adodb.inc.php.  
    3545 <p>HasFailedTrans() returned false when trans failed. Fixed.  
    3546 <p>Moved perf driver classes into adodb/perf/*.php.  
    3547 <p>Misc improvements to performance monitoring, including UI().  
    3548 <p>RETVAL in mssql Parameter(), we do not append @ now.  
    3549 <p>Added Param($name) to connection class, returns '?' or ":$name", for defining  
    3550   bind parameters portably.  
    3551 <p>LogSQL traps affected_rows() and saves its value properly now. Also fixed oci8  
    3552   _stmt and _affectedrows() bugs.  
    3553 <p>Session code timestamp check for oci8 works now. Formerly default NLS_DATE_FORMAT  
    3554   stripped off time portion. Thx to Tony Blair (tonanbarbarian#hotmail.com). Also  
    3555   added new $conn->datetime field to oci8, controls whether MetaType() returns  
    3556   'D' ($this->datetime==false) or 'T' ($this->datetime == true) for DATE type.  
    3557 <p>Fixed bugs in adodb-cryptsession.inc.php and adodb-session-clob.inc.php.  
    3558 <p>Fixed misc bugs in adodb_key_exists, GetInsertSQL() and GetUpdateSQL().  
    3559 <p>Tuned include_once handling to reduce file-system checking overhead.  
    3560 <p><b>3.91 9 Sept 2003</b>  
    3561 <p>Only released to InterAkt  
    3562 <p>Added LogSQL() for sql logging and $ADODB_NEWCONNECTION to override factory  
    3563   for driver instantiation.  
    3564 <p>Added IfNull($field,$ifNull) function, thx to johnwilk#juno.com  
    3565 <p>Added portable substr support.  
    3566 <p>Now rs2html() has new parameter, $echo. Set to false to return $html instead  
    3567   of echoing it.  
    3568 <p><b>3.90 5 Sept 2003</b>  
    3569 <p>First beta of performance monitoring released.  
    3570 <p>MySQL supports MetaTable() masking.  
    3571 <p>Fixed key_exists() bug in adodb-lib.inc.php  
    3572 <p>Added sp_executesql Prepare() support to mssql.  
    3573 <p>Added bind support to db2.  
    3574 <p>Added swedish language file - Christian Tiberg" christian#commsoft.nu  
    3575 <p>Bug in drop index for mssql data dict fixed. Thx to Gert-Rainer Bitterlich.  
    3576 <p>Left join setting for oci8 was wrong. Thx to johnwilk#juno.com  
    3577 <p><b>3.80 27 Aug 2003</b>  
    3578 <p>Patch for PHP 4.3.3 cached recordset csv2rs() fread loop incompatibility.  
    3579 <p>Added matching mask for MetaTables. Only for oci8, mssql and postgres currently.  
    3580 <p>Rewrite of "oracle" driver connection code, merging with "oci8", by Gaetano.  
    3581 <p>Added better debugging for Smart Transactions.  
    3582 <p>Postgres DBTimeStamp() was wrongly using TO_DATE. Changed to TO_TIMESTAMP.  
    3583 <p>ADODB_FETCH_CASE check pushed to ADONewConnection to allow people to define  
    3584   it after including adodb.inc.php.  
    3585 <p>Added portugese (brazilian) to languages. Thx to "Levi Fukumori".  
    3586 <p>Removed arg3 parameter from Execute/SelectLimit/Cache* functions.  
    3587 <p>Execute() now accepts 2-d array as $inputarray. Also changed docs of fnExecute()  
    3588   to note change in sql query counting with 2-d arrays.  
    3589 <p>Added MONEY to MetaType in PostgreSQL.  
    3590 <p>Added more debugging output to CacheFlush().  
    3591 <p><b>3.72 9 Aug 2003</b>  
    3592 <p>Added qmagic($str), which is a qstr($str) that auto-checks for magic quotes  
    3593   and does the right thing...  
    3594 <p>Fixed CacheFlush() bug - Thx to martin#gmx.de  
    3595 <p>Walt Boring contributed MetaForeignKeys for postgres7.  
    3596 <p>_fetch() called _BlobDecode() wrongly in interbase. Fixed.  
    3597 <p>adodb_time bug fixed with dates after 2038 fixed by Jason Pell. http://phplens.com/lens/lensforum/msgs.php?id=6980  
    3598 <p><b>3.71 4 Aug 2003</b>  
    3599 <p>The oci8 driver, MetaPrimaryKeys() did not check the owner correctly when $owner  
    3600   == false.  
    3601 <p>Russian language file contributed by "Cyrill Malevanov" cyrill#malevanov.spb.ru.  
    3602 <p>Spanish language file contributed by "Horacio Degiorgi" horaciod#codigophp.com.  
    3603 <p>Error handling in oci8 bugfix - if there was an error in Execute(), then when  
    3604   calling ErrorNo() and/or ErrorMsg(), the 1st call would return the error, but  
    3605   the 2nd call would return no error.  
    3606 <p>Error handling in odbc bugfix. ODBC would always return the last error, even  
    3607   if it happened 5 queries ago. Now we reset the errormsg to '' and errorno to  
    3608   0 everytime before CacheExecute() and Execute().  
    3609 <p><b>3.70 29 July 2003</b>  
    3610 <p>Added new SQLite driver. Tested on PHP 4.3 and PHP 5.  
    3611 <p>Added limited "sapdb" driver support - mainly date support.  
    3612 <p>The oci8 driver did not identify NUMBER with no defined precision correctly.  
    3613 <p>Added ADODB_FORCE_NULLS, if set, then PHP nulls are converted to SQL nulls  
    3614   in GetInsertSQL/GetUpdateSQL.  
    3615 <p>DBDate() and DBTimeStamp() format for postgresql had problems. Fixed.  
    3616 <p>Added tableoptions to ChangeTableSQL(). Thx to Mike Benoit.  
    3617 <p>Added charset support to postgresql. Thx to Julian Tarkhanov.  
    3618 <p>Changed OS check for MS-Windows to prevent confusion with darWIN (MacOS)  
    3619 <p>Timestamp format for db2 was wrong. Changed to yyyy-mm-dd-hh.mm.ss.nnnnnn.  
    3620 <p>adodb-cryptsession.php includes wrong. Fixed.  
    3621 <p>Added MetaForeignKeys(). Supported by mssql, odbc_mssql and oci8.  
    3622 <p>Fixed some oci8 MetaColumns/MetaPrimaryKeys bugs. Thx to Walt Boring.  
    3623 <p>adodb_getcount() did not init qryRecs to 0. Missing "WHERE" clause checking  
    3624   in GetUpdateSQL fixed. Thx to Sebastiaan van Stijn.  
    3625 <p>Added support for only 'VIEWS' and "TABLES" in MetaTables. From Walt Boring.  
    3626 <p>Upgraded to adodb-xmlschema.inc.php 0.0.2.  
    3627 <p>NConnect for mysql now returns value. Thx to Dennis Verspuij.  
    3628 <p>ADODB_FETCH_BOTH support added to interbase/firebird.  
    3629 <p>Czech language file contributed by Kamil Jakubovic jake#host.sk.  
    3630 <p>PostgreSQL BlobDecode did not use _connectionID properly. Thx to Juraj Chlebec.  
    3631 <p>Added some new initialization stuff for Informix. Thx to "Andrea Pinnisi" pinnisi#sysnet.it  
    3632 <p>ADODB_ASSOC_CASE constant wrong in sybase _fetch(). Fixed.  
    3633 <p><b>3.60 16 June 2003</b>  
    3634 <p>We now SET CONCAT_NULL_YIELDS_NULL OFF for odbc_mssql driver to be compat with  
    3635   mssql driver.  
    3636 <p>The property $emptyDate missing from connection class. Also changed 1903 to  
    3637   constant (TIMESTAMP_FIRST_YEAR=100). Thx to Sebastiaan van Stijn.  
    3638 <p>ADOdb speedup optimization - we now return all arrays by reference.  
    3639 <p>Now DBDate() and DBTimeStamp() now accepts the string 'null' as a parameter.  
    3640   Suggested by vincent.  
    3641 <p>Added GetArray() to connection class.  
    3642 <p>Added not_null check in informix metacolumns().  
    3643 <p>Connection parameters for postgresql did not work correctly when port was defined.  
    3644 <p>DB2 is now a tested driver, making adodb 100% compatible. Extensive changes  
    3645   to odbc driver for DB2, including implementing serverinfo() and SQLDate(), switching  
    3646   to SQL_CUR_USE_ODBC as the cursor mode, and lastAffectedRows and SelectLimit()  
    3647   fixes.  
    3648 <p>The odbc driver's FetchField() field names did not obey ADODB_ASSOC_CASE. Fixed.  
    3649 <p>Some bugs in adodb_backtrace() fixed.  
    3650 <p>Added "INT IDENTITY" type to adorecordset::MetaType() to support odbc_mssql  
    3651   properly.  
    3652 <p>MetaColumns() for oci8, mssql, odbc revised to support scale. Also minor revisions  
    3653   to odbc MetaColumns() for vfp and db2 compat.  
    3654 <p>Added unsigned support to mysql datadict class. Thx to iamsure.  
    3655 <p>Infinite loop in mssql MoveNext() fixed when ADODB_FETCH_ASSOC used. Thx to  
    3656   Josh R, Night_Wulfe#hotmail.com.  
    3657 <p>ChangeTableSQL contributed by Florian Buzin.  
    3658 <p>The odbc_mssql driver now sets CONCAT_NULL_YIELDS_NULL OFF for compat with  
    3659   mssql driver.  
    3660 <hr> 
     3573</p><p>Perf Monitor UI works with magic quotes enabled. 
     3574</p><p>rsPrefix was declared twice. Removed. 
     3575</p><p>Oci8 stored procedure support, eg. "begin func(); end;" was incorrect in _query. Fixed. 
     3576</p><p>Tiraboschi Massimiliano contributed italian language file. 
     3577</p><p>Fernando Ortiz, fortiz#lacorona.com.mx, contributed informix performance monitor. 
     3578</p><p>Added _varchar (varchar arrays) support for postgresql. Reported by PREVOT St&eacute;phane.<hr /> 
    36613579<p><strong>0.10 Sept 9 2000</strong> First release  
    3662 <h3><strong>Old changelog history moved to <a href=old-changelog.htm>old-changelog.htm</a>.  
     3580</p><h3><strong>Old change log history moved to <a href="old-changelog.htm">old-changelog.htm</a>.  
    36633581  </strong></h3> 
    36643582<p>&nbsp;</p> 
    3665 <p> </font>  
    3666 </body> 
    3667 </html> 
     3583<p>   
     3584</p></body></html> 
  • trunk/phpgwapi/inc/adodb/docs/docs-datadict.htm

    r2 r34  
    22<html> 
    33<head> 
    4   <title>ADODB Data Dictionary Manual</title> 
     4  <title>ADOdb Data Dictionary Manual</title> 
    55  <meta http-equiv="Content-Type" 
    66 content="text/html; charset=iso-8859-1"> 
     
    2121<body style="background-color: rgb(255, 255, 255);"> 
    2222<h2>ADOdb Data Dictionary Library for PHP</h2> 
    23 <p>V4.50 6 July 2004 (c) 2000-2004 John Lim (<a 
     23<p>V4.94 23 Jan 2007 (c) 2000-2007 John Lim (<a 
    2424 href="mailto:jlim#natsoft.com.my">jlim#natsoft.com.my</a>).<br> 
    2525AXMLS (c) 2004 ars Cognita, Inc</p> 
     
    2727LGPL. This means you can use it in compiled proprietary and commercial 
    2828products.</font></p> 
    29 <table border="1"> 
    30   <tbody> 
    31     <tr> 
    32       <td><font color="red">Kindly note that the ADOdb home page has 
    33 moved to <a href="http://adodb.sourceforge.net/">http://adodb.sourceforge.net/</a> 
    34 because of the persistent unreliability of http://php.weblogs.com. <b>Please 
    35 change your links</b>!</font></td> 
    36     </tr> 
    37   </tbody> 
    38 </table> 
     29 
    3930<p>Useful ADOdb links: <a href="http://adodb.sourceforge.net/#download">Download</a> 
    4031&nbsp; <a href="http://adodb.sourceforge.net/#docs">Other Docs</a> 
     
    5344</p> 
    5445<h3>Example Usage</h3> 
    55 <pre>  include_once('adodb.inc.php');<br>  <font color="#006600"># First create a normal connection</font><br>  $db-&gt;NewADOConnection('mysql');<br>  $db-&gt;Connect(...);<br><br>  <font 
     46<pre>  include_once('adodb.inc.php');<br>  <font color="#006600"># First create a normal connection</font><br>  $db = NewADOConnection('mysql');<br>  $db-&gt;Connect(...);<br><br>  <font 
    5647 color="#006600"># Then create a data dictionary object, using this connection</font><br>  $dict = <strong>NewDataDictionary</strong>($db);<br><br>  <font 
    5748 color="#006600"># We have a portable declarative data dictionary format in ADOdb, similar to SQL.<br>  # Field types use 1 character codes, and fields are separated by commas.<br>  # The following example creates three fields: "col1", "col2" and "col3":</font><br>  $flds = " <br>  <font 
    5849 color="#663300"><strong> col1 C(32) NOTNULL DEFAULT 'abc',<br>   col2 I  DEFAULT 0,<br>   col3 N(12.2)</strong></font><br>  ";<br><br>  <font 
    5950 color="#006600"># We demonstrate creating tables and indexes</font><br>  $sqlarray = $dict-&gt;<strong>CreateTableSQL</strong>($tabname, $flds, $taboptarray);<br>  $dict-&gt;<strong>ExecuteSQLArray</strong>($sqlarray);<br><br>  $idxflds = 'co11, col2';<br>  $sqlarray = $dict-&gt;<strong>CreateIndexSQL</strong>($idxname, $tabname, $idxflds);<br>  $dict-&gt;<strong>ExecuteSQLArray</strong>($sqlarray);<br></pre> 
    60 <h3>Functions</h3> 
     51<h3>More Complex Table Sample</h3> 
     52<p> 
     53The following string will create a table with a primary key event_id and multiple indexes, including one compound index idx_ev1. The ability to define indexes using the INDEX keyword was added in ADOdb 4.94 by Gaetano Giunta. 
     54<pre> 
     55$flds = " 
     56  event_id I(11) NOTNULL AUTOINCREMENT PRIMARY, 
     57  event_type I(4) NOTNULL  <b>INDEX idx_evt</b>, 
     58  event_start_date T DEFAULT NULL <b>INDEX id_esd</b>, 
     59  event_end_date T DEFAULT '0000-00-00 00:00:00' <b>INDEX id_eted</b>, 
     60  event_parent I(11) UNSIGNED NOTNULL DEFAULT 0 <b>INDEX id_evp</b>, 
     61  event_owner I(11) DEFAULT 0 <b>INDEX idx_ev1</b>, 
     62  event_project I(11) DEFAULT 0 <b>INDEX idx_ev1</b>, 
     63  event_times_recuring I(11) UNSIGNED NOTNULL DEFAULT 0, 
     64  event_icon C(20) DEFAULT 'obj/event', 
     65  event_description X 
     66"; 
     67$sqlarray = $db-><b>CreateTableSQL</b>($tablename, $flds); 
     68$dict-><b>ExecuteSQLArray</b>($sqlarray); 
     69</pre> 
     70<h3>Class Factory</h3> 
     71<h4>NewDataDictionary($connection, $drivername=false)</h4> 
     72<p>Creates a new data dictionary object. You pass a database connection object in $connection. The $connection does not have to be actually connected to the database. Some database connection objects are generic (eg. odbtp and odbc). Since 4.53, you can tell ADOdb  the actual database with $drivername. E.g.</p> 
     73<pre> 
     74$db =& NewADOConnection('odbtp'); 
     75$datadict = NewDataDictionary($db, 'mssql'); # force mssql 
     76</pre> 
     77<h3>Class Functions</h3> 
    6178<h4>function CreateDatabase($dbname, $optionsarray=false)</h4> 
    6279<p>Create a database with the name $dbname;</p> 
     
    7794database.</p> 
    7895<p>Legal portable type codes include:</p> 
    79 <pre>  C:  varchar<br>  X:  Largest varchar size <br>  XL: For Oracle, returns CLOB, otherwise same as 'X' above<br><br>  C2: Multibyte varchar<br>  X2: Multibyte varchar (largest size)<br><br>  B:  BLOB (binary large object)<br><br>  D:  Date (some databases do not support this, and we return a datetime type)<br>  T:  Datetime or Timestamp<br>  L:  Integer field suitable for storing booleans (0 or 1)<br>  I:  Integer (mapped to I4)<br>  I1: 1-byte integer<br>  I2: 2-byte integer<br>  I4: 4-byte integer<br>  I8: 8-byte integer<br>  F:  Floating point number<br>  N:  Numeric or decimal number<br></pre> 
     96<pre>  C:  Varchar, capped to 255 characters.<br>  X:  Larger varchar, capped to 4000 characters (to be compatible with Oracle). <br>  XL: For Oracle, returns CLOB, otherwise the largest varchar size.<br><br>  C2: Multibyte varchar<br>  X2: Multibyte varchar (largest size)<br><br>  B:  BLOB (binary large object)<br><br>  D:  Date (some databases do not support this, and we return a datetime type)<br>  T:  Datetime or Timestamp<br>  L:  Integer field suitable for storing booleans (0 or 1)<br>  I:  Integer (mapped to I4)<br>  I1: 1-byte integer<br>  I2: 2-byte integer<br>  I4: 4-byte integer<br>  I8: 8-byte integer<br>  F:  Floating point number<br>  N:  Numeric or decimal number<br></pre> 
    8097<p>The $colsize field represents the size of the field. If a decimal 
    8198number is used, then it is assumed that the number following the dot is 
     
    105122  <li><b>CONSTRAINTS</b><br> 
    106123Define this as the key, with the constraint as the value. See the 
    107 postgresql example below. Additional constraints defined for the whole 
     124postgresql <a href="#foreignkey">example</a> below. Additional constraints defined for the whole 
    108125table. You will probably need to prefix this with a comma. </li> 
    109126</ul> 
     
    114131the table first.</p> 
    115132<pre>  $taboptarray = array('mysql' =&gt; 'TYPE=ISAM', 'oci8' =&gt; 'tablespace users', 'REPLACE');</pre> 
    116 <p>You can also define foreignkey constraints. The following is syntax 
     133<p><a name=foreignkey></a>You can also define foreign key constraints. The following is syntax 
    117134for postgresql: 
    118135</p> 
     
    128145detect the existence of the table. Idea and code contributed by Florian 
    129146Buzin.</p> 
     147<h4>function RenameTableSQL($tabname,$newname)</h4> 
     148<p>Rename a table.  Returns the an array of strings, which is the SQL required to rename a table. Since ADOdb 4.53. Contributed by Ralf Becker.</p> 
     149<h4> function RenameColumnSQL($tabname,$oldcolumn,$newcolumn,$flds='')</h4> 
     150<p>Rename a table field. Returns the an array of strings, which is the SQL required to rename a column. The optional $flds is a complete column-defintion-string like for AddColumnSQL, only used by mysql at the moment. Since ADOdb 4.53. Contributed by Ralf Becker.</p> 
    130151<h4>function CreateIndexSQL($idxname, $tabname, $flds, 
    131152$idxoptarray=false)</h4> 
     
    167188<p>Executes an array of SQL strings returned by CreateTableSQL or 
    168189CreateIndexSQL.</p> 
    169 <hr> 
     190<hr /> 
    170191<a name="xmlschema"></a> 
    171192<h2>ADOdb XML Schema (AXMLS)</h2> 
     
    240261it to your database. Here's a simple PHP script that shows how to load 
    241262the schema.</p> 
    242 <pre class="listing"><pre>&lt;?PHP<br>/* You must tell the script where to find the ADOdb and<br> * the AXMLS libraries.<br> */<br>require( "path_to_adodb/adodb.inc.php");<br>require( "path_to_adodb/adodb-xmlschema.inc.php" );<br><br>/* Configuration information. Define the schema filename,<br> * RDBMS platform (see the ADODB documentation for valid<br> * platform names), and database connection information here.<br> */<br>$schemaFile = 'example.xml';<br>$platform = 'mysql';<br>$dbHost = 'localhost';<br>$dbName = 'database';<br>$dbUser = 'username';<br>$dbPassword = 'password';<br><br>/* Start by creating a normal ADODB connection.<br> */<br>$db = ADONewConnection( $platform );<br>$db-&gt;Connect( $dbHost, $dbUser, $dbPassword, $dbName );<br><br>/* Use the database connection to create a new adoSchema object.<br> */<br>$schema = new adoSchema( $db );<br><br>/* Call ParseSchema() to build SQL from the XML schema file.<br> * Then call ExecuteSchema() to apply the resulting SQL to <br> * the database.<br> */<br>$sql = $schema-&gt;ParseSchema( $schemaFile );<br>$result = $schema-&gt;ExecuteSchema();<br>?&gt;<br></pre></pre> 
     263<pre class="listing"><pre>&lt;?PHP<br>/* You must tell the script where to find the ADOdb and<br> * the AXMLS libraries.<br> */ 
     264require( "path_to_adodb/adodb.inc.php"); 
     265require( "path_to_adodb/adodb-xmlschema.inc.php" ); # or adodb-xmlschema03.inc.php 
     266 
     267/* Configuration information. Define the schema filename,<br> * RDBMS platform (see the ADODB documentation for valid<br> * platform names), and database connection information here.<br> */<br>$schemaFile = 'example.xml';<br>$platform = 'mysql';<br>$dbHost = 'localhost';<br>$dbName = 'database';<br>$dbUser = 'username';<br>$dbPassword = 'password';<br><br>/* Start by creating a normal ADODB connection.<br> */<br>$db = ADONewConnection( $platform );<br>$db-&gt;Connect( $dbHost, $dbUser, $dbPassword, $dbName );<br><br>/* Use the database connection to create a new adoSchema object.<br> */<br>$schema = new adoSchema( $db );<br><br>/* Call ParseSchema() to build SQL from the XML schema file.<br> * Then call ExecuteSchema() to apply the resulting SQL to <br> * the database.<br> */<br>$sql = $schema-&gt;ParseSchema( $schemaFile );<br>$result = $schema-&gt;ExecuteSchema();<br>?&gt;<br></pre></pre> 
    243268<p>Let's look at each part of the example in turn. After you manually 
    244269create the database, there are three steps required to load (or 
     
    250275schema. You must pass an ADOdb database connection object in order to 
    251276create the adoSchema object.</p> 
    252 <pre class="listing"><pre>$schema = new adoSchema( $db );<br></pre></pre> 
     277<pre class="listing">$schema = new adoSchema( $db );<br></pre> 
    253278<p>Third, call ParseSchema() to parse the schema and then 
    254279ExecuteSchema() to apply it to the database. You must pass 
    255280ParseSchema() the path and filename of your schema file.</p> 
    256 <pre class="listing"><pre><br>$schema-&gt;ParseSchema( $schemaFile ); <br>$schema-&gt;ExecuteSchema(); <br></pre></pre> 
     281<pre class="listing">$schema-&gt;ParseSchema( $schemaFile ); <br>$schema-&gt;ExecuteSchema();</pre> 
    257282<p>Execute the above code and then log into your database. If you've 
    258283done all this right, you should see your tables, indexes, and SQL.</p> 
     
    262287including methods and schema elements that are not described in this 
    263288tutorial.</p> 
     289<h3>XML Schema Version 3</h3> 
     290<p>In March 2006, we added adodb-xmlschema03.inc.php to the release, which supports version 3 of XML Schema.  
     291The adodb-xmlschema.inc.php remains the same as previous releases, and supports version 2 of XML Schema.  
     292Version 3 provides some enhancements: 
     293 
     294<ul> 
     295     <li> Support for updating table data during an upgrade. 
     296     <li> Support for platform-specific table options and platform negation. 
     297     <li> Support for unsigned fields. 
     298     <li> Fixed opt and constraint support 
     299     <li> Many other fixes such as OPT tag, which allows you to set optional platform settings: 
     300</ul> 
     301 
     302<p>Example usage: 
     303<pre>&lt;?xml version="1.0"?> 
     304<b>&lt;schema version="0.3"></b> 
     305 &lt;table name="ats_kb"> 
     306  &lt;descr>ATS KnowledgeBase&lt;/descr> 
     307  &lt;opt platform="mysql">TYPE=INNODB&lt;/opt> 
     308  &lt;field name="recid" type="I"/> 
     309  &lt;field name="organization_code" type="I4"/>  
     310  &lt;field name="sub_code" type="C" size="20"/> 
     311  etc... 
     312</pre> 
     313<p>To use it, change your code to include adodb-xmlschema03.inc.php. 
     314 
    264315<h3>Upgrading</h3> 
     316<p> 
    265317If your schema version is older, than XSLT is used to transform the 
    266318schema to the newest version. This means that if you are using an older 
     
    269321installed, make sure you modify your XML schema to conform to the 
    270322latest version. 
    271 <hr> 
     323<hr /> 
    272324<address>If you have any questions or comments, please email them to 
    273325Richard at richtl#arscognita.com. 
  • trunk/phpgwapi/inc/adodb/docs/docs-perf.htm

    r2 r34  
    1919<body> 
    2020<h3>The ADOdb Performance Monitoring Library</h3> 
    21 <p>V4.50 6 July 2004 (c) 2000-2004 John Lim (jlim#natsoft.com.my)</p> 
     21<p>V4.94 23 Jan 2007 (c) 2000-2007 John Lim (jlim#natsoft.com.my)</p> 
    2222<p><font size="1">This software is dual licensed using BSD-Style and 
    2323LGPL. This means you can use it in compiled proprietary and commercial 
    2424products.</font></p> 
    25 <table border="1"> 
    26   <tbody> 
    27     <tr> 
    28       <td><font color="red">Kindly note that the ADOdb home page has 
    29 moved to <a href="http://adodb.sourceforge.net/">http://adodb.sourceforge.net/</a> 
    30 because of the persistent unreliability of http://php.weblogs.com. <b>Please 
    31 change your links</b>!</font></td> 
    32     </tr> 
    33   </tbody> 
    34 </table> 
    3525<p>Useful ADOdb links: <a href="http://adodb.sourceforge.net/#download">Download</a> 
    3626&nbsp; <a href="http://adodb.sourceforge.net/#docs">Other Docs</a> 
  • trunk/phpgwapi/inc/adodb/docs/docs-session.htm

    r2 r34  
    2020</head> 
    2121<body style="background-color: rgb(255, 255, 255);"> 
    22 <h3>ADODB Session Management Manual</h3> 
     22<h1>ADODB Session 2 Management Manual</h1> 
    2323<p> 
    24 V4.50 6 July 2004 (c) 2000-2004 John Lim (jlim#natsoft.com.my) 
     24V4.94 23 Jan 2007 (c) 2000-2007 John Lim (jlim#natsoft.com.my) 
    2525</p> 
    2626<p> <font size="1">This software is dual licensed using BSD-Style and 
    2727LGPL. This means you can use it in compiled proprietary and commercial 
    2828products. </font> 
    29 <table border="1"> 
    30   <tbody> 
    31     <tr> 
    32       <td><font color="red">Kindly note that the ADOdb home page has 
    33 moved to <a href="http://adodb.sourceforge.net/">http://adodb.sourceforge.net/</a> 
    34 because of the persistent unreliability of http://php.weblogs.com. <b>Please 
    35 change your links</b>!</font></td> 
    36     </tr> 
    37     <tr> 
    38     </tr> 
    39   </tbody> 
    40 </table> 
    41 </p> 
    4229<p>Useful ADOdb links: <a href="http://adodb.sourceforge.net/#download">Download</a> 
    4330&nbsp; <a href="http://adodb.sourceforge.net/#docs">Other Docs</a> 
    4431</p> 
    45 <h3>Introduction</h3> 
    46 <p> We store state information specific to a user or web client in 
    47 session variables. These session variables persist throughout a 
     32<h2>Introduction</h2> 
     33<p> This document discusses the newer session handler adodb-session2.php. If 
     34  you have used the older adodb-session.php, then be forewarned that you will 
     35  need to alter your session table format. Otherwise everything is <a href="#compat">backward 
     36  compatible</a>. 
     37  Here are the <a href="docs-session.old.htm">older 
     38    docs</a> for 
     39  adodb-session.php.</p> 
     40<h2>Why Session Variables in a Database? </h2> 
     41<p>We store state information specific to a user or web 
     42    client in session variables. These session variables persist throughout a 
    4843session, as the user moves from page to page. </p> 
    4944<p>To use session variables, call session_start() at the beginning of 
     
    6257  <li>Require notification when a session expires</li> 
    6358</ul> 
    64 <p>Then the ADOdb session handler provides you with the above 
     59<p>The ADOdb session handler provides you with the above 
    6560additional capabilities by storing the session information as records 
    6661in a database table that can be shared across multiple servers. </p> 
    67 <p><b>Important Upgrade Notice:</b> Since ADOdb 4.05, the session files 
    68 have been moved to its own folder, adodb/session. This is a rewrite 
    69 of the session code by Ross Smith. The old session code is in 
    70 adodb/session/old. </p> 
    71 <h4>ADOdb Session Handler Features</h4> 
     62<p>These records will be garbage collected based on the php.ini [session] timeout settings.  
     63You can register a notification function to notify you when the record has expired and  
     64is about to be freed by the garbage collector.</p> 
     65<p>An alternative to using a database backed session handler is to use <a href="http://www.danga.com/memcached/">memcached</a>. 
     66  This is a distributed memory based caching system suitable for storing session 
     67  information. 
     68  </p> 
     69<h2> The Improved Session Handler</h2> 
     70<p>In ADOdb 4.91, we added a new session handler, in adodb-session2.php. 
     71It features the following improvements: 
     72<ul> 
     73<li>Fully supports server farms using a new database table format. The 
     74  previous version used the web server time for timestamps, which can cause problems 
     75  on a system with multiple web servers with possibly inconsistent 
     76  times. The new version uses the database server time instead for all timestamps. 
     77<li>The older database table format is obsolete. The database table must be modified 
     78  to support storage of the database server time mentioned above. Also the field 
     79  named DATA has been changed to SESSDATA. In some databases, DATA is a reserved 
     80  word. 
     81<li>The functions dataFieldName() and syncSeconds() is obsolete. 
     82</ul> 
     83 
     84<p>Usage is  
     85 
     86<pre> 
     87include_once("adodb/session/adodb-session2.php"); 
     88ADOdb_Session::config($driver, $host, $user, $password, $database,$options=false); 
     89session_start(); 
     90 
     91<font 
     92 color="#004040">#<br># Test session vars, the following should increment on refresh<br>#<br>$_SESSION['AVAR'] += 1;<br>print "&lt;p&gt;\$_SESSION['AVAR']={$_SESSION['AVAR']}&lt;/p&gt;";</font> 
     93</pre> 
     94 
     95<p>When the session is created in session_start( ), the global variable $<b>ADODB_SESS_CONN</b> holds 
     96the connection object. 
     97<p>The default name of the table is sessions2. If you want to override it: 
     98   
     99<pre> 
     100include_once("adodb/session/adodb-session2.php"); 
     101$options['table'] = 'mytablename'; 
     102ADOdb_Session::config($driver, $host, $user, $password, $database,$options); 
     103session_start(); 
     104</pre> 
     105 
     106 
     107<h3>ADOdb Session Handler Features</h3> 
    72108<ul> 
    73109  <li>Ability to define a notification function that is called when a 
     
    78114to the session data if there is a data change. </li> 
    79115  <li>Support for large amounts of session data with CLOBs (see 
    80 adodb-session-clob.php). Useful 
     116adodb-session-clob2.php). Useful 
    81117for Oracle. </li> 
    82118  <li>Support for encrypted session data, see 
    83 adodb-cryptsession.inc.php. Enabling encryption is simply a matter of 
    84 including adodb-cryptsession.inc.php instead of adodb-session.inc.php. </li> 
     119adodb-cryptsession2.php. Enabling encryption is simply a matter of 
     120including adodb-cryptsession2.php instead of adodb-session2.php. </li> 
    85121</ul> 
    86 <h3>Setup</h3> 
     122<h3>Session Handler Files </h3> 
    87123<p>There are 3 session management files that you can use: 
    88124</p> 
    89 <pre>adodb-session.php        : The default<br>adodb-session-clob.php   : Use this if you are storing DATA in clobs<br>adodb-cryptsession.php   : Use this if you want to store encrypted session data in the database<br><br> 
    90 </pre> 
    91 <p><strong>Examples</strong> 
    92 <p><pre> 
    93  <font 
    94  color="#004040">    include('adodb/adodb.inc.php');<br>    <br><b>    $ADODB_SESSION_DRIVER='mysql';<br>    $ADODB_SESSION_CONNECT='localhost';<br>    $ADODB_SESSION_USER ='scott';<br>    $ADODB_SESSION_PWD ='tiger';<br>    $ADODB_SESSION_DB ='sessiondb';</b><br>    <br>    <b>include('adodb/session/adodb-session.php');</b><br>    session_start();<br>    <br>    #<br>    # Test session vars, the following should increment on refresh<br>    #<br>    $_SESSION['AVAR'] += 1;<br>    print "&lt;p&gt;\$_SESSION['AVAR']={$_SESSION['AVAR']}&lt;/p&gt;";<br></font></pre> 
    95  <p>To force non-persistent connections, call adodb_session_open first before session_start():<p> 
     125<pre>adodb-session2.php        : The default<br>adodb-cryptsession2.php   : Use this if you want to store encrypted session data in the database<br>adodb-session-clob2.php   : Use this if you are storing DATA in clobs and you are NOT using oci8 driver</pre> 
     126<h2><strong>Usage Examples</strong></h2> 
     127<p>To force non-persistent connections, call <font color="#004040"><b>Persist</b></font>() first before session_start(): 
     128 
     129  
     130<pre> 
     131 <font color="#004040"> 
     132include_once("adodb/session/adodb-session2.php"); 
     133$driver = 'mysql'; $host = 'localhost'; $user = 'auser'; $pwd = 'secret'; $database = 'sessiondb'; 
     134ADOdb_Session::config($driver, $host, $user, $password, $database,$options=false);<b><br>ADOdb_session::Persist($connectMode=false);</b> 
     135session_start();<br> </font> 
     136</pre> 
     137<p> The parameter to the Persist( ) method sets the connection mode. You can 
     138  pass the following:</p> 
     139<table width="50%" border="1"> 
     140  <tr> 
     141    <td><b>$connectMode</b></td> 
     142    <td><b>Connection Method</b></td> 
     143  </tr> 
     144  <tr> 
     145    <td>true</td> 
     146    <td><p>PConnect( )</p></td> 
     147  </tr> 
     148  <tr> 
     149    <td>false</td> 
     150    <td>Connect( )</td> 
     151  </tr> 
     152  <tr> 
     153    <td>'N'</td> 
     154    <td>NConnect( )</td> 
     155  </tr> 
     156  <tr> 
     157    <td>'P'</td> 
     158    <td>PConnect( )</td> 
     159  </tr> 
     160  <tr> 
     161    <td>'C'</td> 
     162    <td>Connect( )</td> 
     163  </tr> 
     164</table> 
     165<p>To use a encrypted sessions, simply replace the file adodb-session2.php:</p> 
     166 <pre> <font 
     167 color="#004040"><b><br>include('adodb/session/adodb-cryptsession2.php');</b><br>$driver = 'mysql'; $host = 'localhost'; $user = 'auser'; $pwd = 'secret'; $database = 'sessiondb'; 
     168ADOdb_Session::config($driver, $host, $user, $password, $database,$options=false);<b><br>adodb_sess_open(false,false,$connectMode=false);</b> 
     169session_start();<br></font></pre> 
     170 <p>And the same technique for adodb-session-clob2.php:</p> 
     171 <pre>  <font 
     172 color="#004040"><br><b>include('adodb/session/adodb-session2-clob2.php');</b><br>$driver = 'oci8'; $host = 'localhost'; $user = 'auser'; $pwd = 'secret'; $database = 'sessiondb'; 
     173ADOdb_Session::config($driver, $host, $user, $password, $database,$options=false);<b><br>adodb_sess_open(false,false,$connectMode=false);</b> 
     174session_start();</font></pre> 
     175 <h2>Installation</h2> 
     176<p>1. Create this table in your database. Here is the MySQL version: 
     177<pre> <a 
     178 name="sessiontab"></a> <font color="#004040"> 
     179CREATE TABLE sessions2( 
     180          sesskey VARCHAR( 64 ) NOT NULL DEFAULT '', 
     181          expiry DATETIME NOT NULL , 
     182          expireref VARCHAR( 250 ) DEFAULT '', 
     183          created DATETIME NOT NULL , 
     184          modified DATETIME NOT NULL , 
     185          sessdata LONGTEXT DEFAULT '', 
     186          PRIMARY KEY ( sesskey ) , 
     187          INDEX sess2_expiry( expiry ), 
     188          INDEX sess2_expireref( expireref ) 
     189)</font></pre> 
     190 
     191 <p> For PostgreSQL, use: 
     192 <pre>CREATE TABLE sessions2( 
     193 sesskey VARCHAR( 64 ) NOT NULL DEFAULT '', 
     194 expiry TIMESTAMP NOT NULL , 
     195 expireref VARCHAR( 250 ) DEFAULT '', 
     196 created TIMESTAMP NOT NULL , 
     197 modified TIMESTAMP NOT NULL , 
     198 sessdata TEXT DEFAULT '', 
     199 PRIMARY KEY ( sesskey ) 
     200 ); 
     201</pre> 
     202 <pre>create INDEX sess2_expiry on sessions2( expiry ); 
     203create INDEX sess2_expireref on sessions2 ( expireref );</pre> 
     204 <p>Here is the Oracle definition, which uses a CLOB for the SESSDATA field: 
    96205 <pre> 
    97  <font color="#004040"><br>    include('adodb/adodb.inc.php');<br>    <br><b>    $ADODB_SESSION_DRIVER='mysql';<br>    $ADODB_SESSION_CONNECT='localhost';<br>    $ADODB_SESSION_USER ='scott';<br>    $ADODB_SESSION_PWD ='tiger';<br>    $ADODB_SESSION_DB ='sessiondb';</b><br>    <br>    <b>include('adodb/session/adodb-session.php');<br>    adodb_sess_open(false,false,false);</b><br>    session_start();<br> </font> 
    98  </pre> 
    99 <p> To use a encrypted sessions, simply replace the file:</p> 
    100  <pre> <font 
    101  color="#004040"><br>    include('adodb/adodb.inc.php');<br>    <br><b>    $ADODB_SESSION_DRIVER='mysql';<br>    $ADODB_SESSION_CONNECT='localhost';<br>    $ADODB_SESSION_USER ='scott';<br>    $ADODB_SESSION_PWD ='tiger';<br>    $ADODB_SESSION_DB ='sessiondb';<br>    <br>    include('adodb/session/adodb-cryptsession.php');</b><br>    session_start();</font><br> 
    102  </pre> 
    103  <p>And the same technique for adodb-session-clob.php:</p> 
    104  <pre>  <font 
    105  color="#004040"><br>    include('adodb/adodb.inc.php');<br>    <br><b>    $ADODB_SESSION_DRIVER='mysql';<br>    $ADODB_SESSION_CONNECT='localhost';<br>    $ADODB_SESSION_USER ='scott';<br>    $ADODB_SESSION_PWD ='tiger';<br>    $ADODB_SESSION_DB ='sessiondb';<br>    <br>    include('adodb/session/adodb-session-clob.php');</b><br>    session_start();</font> 
    106  </pre> 
    107  <h4>Installation</h4> 
    108 <p>1. Create this table in your database (syntax might vary depending on your db): 
    109 <p><pre> <a 
    110  name="sessiontab"></a> <font color="#004040"><br>  create table sessions (<br>       SESSKEY char(32) not null,<br>       EXPIRY int(11) unsigned not null,<br>       EXPIREREF varchar(64),<br>       DATA text not null,<br>      primary key (sesskey)<br>  );</font><br>  
    111  </pre> 
    112  <p> For the adodb-session-clob.php version, create this: 
    113   <pre> 
    114     <font 
    115  color="#004040"><br>    create table sessions (<br>       SESSKEY char(32) not null,<br>       EXPIRY int(11) unsigned not null,<br>       EXPIREREF varchar(64),<br>       DATA CLOB,<br>      primary key (sesskey)<br>  );</font> 
    116  </pre> 
    117  <p>2. Then define the following parameters. You can either modify this file, or define them before this file is included: 
    118  <pre>      <font 
    119  color="#004040"><br>    $ADODB_SESSION_DRIVER='database driver, eg. mysql or ibase';<br>    $ADODB_SESSION_CONNECT='server to connect to';<br>    $ADODB_SESSION_USER ='user';<br>    $ADODB_SESSION_PWD ='password';<br>    $ADODB_SESSION_DB ='database';<br>    $ADODB_SESSION_TBL = 'sessions'; # setting this is optional<br>     </font> 
    120  </pre><p> 
    121      When the session is created, $<b>ADODB_SESS_CONN</b> holds the connection object.<br>    <br>  3. Recommended is PHP 4.0.6 or later. There are documented session bugs <br>  in earlier versions of PHP. 
    122 <h3>Notifications</h3> 
    123 <p>If you want to receive notification when a session expires, then tag 
    124 the session record with a <a href="#sessiontab">EXPIREREF</a> tag (see 
    125 the definition of the sessions table above). Before any session record 
    126 is deleted, ADOdb will call a notification function, passing in the 
    127 EXPIREREF. 
    128 </p> 
    129 <p>When a session is first created, we check a global variable 
    130 $ADODB_SESSION_EXPIRE_NOTIFY. This is an array with 2 elements, the 
     206  <font 
     207 color="#004040">CREATE TABLE SESSIONS2<br>(<br>   SESSKEY    VARCHAR2(48 BYTE)                  NOT NULL,<br>   EXPIRY     DATE                               NOT NULL,<br>   EXPIREREF  VARCHAR2(200 BYTE),<br>   CREATED    DATE                               NOT NULL,<br>   MODIFIED   DATE                               NOT NULL,<br>   SESSDATA   CLOB,<br>  PRIMARY KEY(SESSKEY)<br>); 
     208<br>CREATE INDEX SESS2_EXPIRY ON SESSIONS2(EXPIRY); 
     209CREATE INDEX SESS2_EXPIREREF ON SESSIONS2(EXPIREREF);</font></pre> 
     210<p> We need to use a CLOB here because for text greater than 4000 bytes long, 
     211  Oracle requires you to use the CLOB data type. If you are using the oci8 driver, 
     212  ADOdb will automatically enable CLOB handling. So you can use either adodb-session2.php 
     213  or adodb-session-clob2.php - in this case it doesn't matter. <br>     
     214<h2>Notifications</h2> 
     215<p>You can receive notification when your session is cleaned up by the session garbage collector or 
     216when you call session_destroy(). 
     217<p>PHP's session extension will automatically run a special garbage collection function based on 
     218your php.ini session.cookie_lifetime and session.gc_probability settings. This will in turn call 
     219adodb's garbage collection function, which can be setup to do notification. 
     220<p> 
     221<pre> 
     222        PHP Session --> ADOdb Session  --> Find all recs  --> Send          --> Delete queued 
     223        GC Function     GC Function        to be deleted      notification      records 
     224        executed at     called by                             for all recs 
     225        random time     Session Extension                     queued for deletion 
     226</pre> 
     227<p>When a session is created, we need to store a value in the session record (in the EXPIREREF field), typically  
     228the userid of the session. Later when the session has expired,  just before the record is deleted, 
     229we reload the EXPIREREF field and call the notification function with the value of EXPIREREF, which  
     230is the userid of the person being logged off. 
     231<p>ADOdb uses a global variable $ADODB_SESSION_EXPIRE_NOTIFY that you must predefine before session 
     232start to store the notification configuration.  
     233$ADODB_SESSION_EXPIRE_NOTIFY is an array with 2 elements, the 
    131234first being the name of the session variable you would like to store in 
    132235the EXPIREREF field, and the 2nd is the notification function's name. </p> 
    133 <p> Suppose we want to be notified when a user's session has expired, 
    134 based on the userid. The user id in the global session variable 
    135 $USERID. The function name is 'NotifyFn'. So we define: </p> 
    136 <pre> <font color="#004040"><br>        $ADODB_SESSION_EXPIRE_NOTIFY = array('USERID','NotifyFn');<br>    </font></pre> 
    137 And when the NotifyFn is called (when the session expires), we pass the 
    138 $USERID as the first parameter, eg. NotifyFn($userid, $sesskey). The 
     236<p>For example, suppose we want to be notified when a user's session has expired, 
     237based on the userid. When the user logs in, we store the id in the global session variable 
     238$USERID. The function name is 'NotifyFn'.  
     239<p> 
     240So we define (before session_start() is called): </p> 
     241<pre> <font color="#004040"> 
     242        $ADODB_SESSION_EXPIRE_NOTIFY = array('USERID','NotifyFn'); 
     243</font></pre> 
     244And when the NotifyFn is called (when the session expires), the 
     245$USERID is passed in as the first parameter, eg. NotifyFn($userid, $sesskey). The 
    139246session key (which is the primary key of the record in the sessions 
    140247table) is the 2nd parameter. 
    141248<p> Here is an example of a Notification function that deletes some 
    142249records in the database and temporary files: </p> 
    143 <pre><font color="#004040"><br>        function NotifyFn($expireref, $sesskey)<br>        {<br>        global $ADODB_SESS_CONN; # the session connection object<br><br>          $user = $ADODB_SESS_CONN-&gt;qstr($expireref);<br>          $ADODB_SESS_CONN-&gt;Execute("delete from shopping_cart where user=$user");<br>          system("rm /work/tmpfiles/$expireref/*");<br>        }</font><br>    </pre> 
     250<pre><font color="#004040"> 
     251        function NotifyFn($expireref, $sesskey) 
     252        { 
     253                global $ADODB_SESS_CONN; # the session connection object 
     254                $user = $ADODB_SESS_CONN-&gt;qstr($expireref); 
     255                 
     256                $ADODB_SESS_CONN-&gt;Execute("delete from shopping_cart where user=$user");           
     257                system("rm /work/tmpfiles/$expireref/*"); 
     258        }</font>   
     259                          </pre> 
    144260<p> NOTE 1: If you have register_globals disabled in php.ini, then you 
    145261will have to manually set the EXPIREREF. E.g. </p> 
    146262<pre> <font color="#004040"> 
    147     $GLOBALS['USERID'] =&amp; $_SESSION['USERID']; 
    148     $ADODB_SESSION_EXPIRE_NOTIFY = array('USERID','NotifyFn');</font> 
     263$GLOBALS['USERID'] = GetUserID(); 
     264$ADODB_SESSION_EXPIRE_NOTIFY = array('USERID','NotifyFn');</font> 
    149265</pre> 
    150266<p> NOTE 2: If you want to change the EXPIREREF after the session 
     
    152268to force a database record update. 
    153269</p> 
    154 <h4>Neat Notification Tricks</h4> 
     270<h3>Neat Notification Tricks</h3> 
    155271<p><i>ExpireRef</i> normally holds the user id of the current session. 
    156272</p> 
     
    166282can be logged in twice. Useful for security reasons. 
    167283</p> 
    168 <h3>Compression/Encryption Schemes</h3> 
     284<h2>Compression/Encryption Schemes</h2> 
    169285Since ADOdb 4.05, thanks to Ross Smith, multiple encryption and 
    170286compression schemes are supported. Currently, supported are: 
     
    172288<pre>  MD5Crypt (crypt.inc.php)<br>  MCrypt<br>  Secure (Horde's emulation of MCrypt, if MCrypt module is not available.)<br>  GZip<br>  BZip2<br></pre> 
    173289<p>These are stackable. E.g. 
    174 <p><pre>ADODB_Session::filter(new ADODB_Compress_Bzip2());<br>ADODB_Session::filter(new ADODB_Encrypt_MD5());<br></pre> 
     290<pre>ADODB_Session::filter(new ADODB_Compress_Bzip2());<br>ADODB_Session::filter(new ADODB_Encrypt_MD5());<br></pre> 
    175291will compress and then encrypt the record in the database. 
    176 <p>Also see the <a href="docs-adodb.htm">core ADOdb documentation</a>. 
    177 </p> 
     292<h2>Session Cookie Regeneration: adodb_session_regenerate_id()</h2> 
     293<p>Dynamically change the current session id with a newly generated one and update 
     294  database. Currently only works with cookies. Useful to improve security by 
     295  reducing the risk of session-hijacking. See this article on <a href=http://shiflett.org/articles/security-corner-feb2004>Session 
     296  Fixation</a> for more info  
     297on the theory behind this feature. Usage:<pre> 
     298        include('path/to/adodb/session/adodb-session2.php'); 
     299         
     300        session_start(); 
     301        # Approximately every 10 page loads, reset cookie for safety. 
     302        # This is extremely simplistic example, better  
     303        # to regenerate only when the user logs in or changes 
     304        # user privilege levels. 
     305        if ((rand()%10) == 0) adodb_session_regenerate_id();  
     306</pre> 
     307<p>This function calls session_regenerate_id() internally or simulates it if the function does not exist. 
     308<h2>Vacuum/Optimize Database</h2> 
     309<p>During session garbage collection, if postgresql is detected, 
     310  ADOdb can be set to run VACUUM. If mysql is detected, then optimize database 
     311  could be called.You can turn this on or off using:</p> 
     312<pre>$turnOn = true; # or false 
     313ADODB_Session::optimize($turnOn); 
     314</pre> 
     315<p>The default  is optimization is disabled.</p> 
     316<h2><a name=compat></a>Backwards Compatability </h2> 
     317<p>The older method of connecting to ADOdb using global variables is still supported:</p> 
     318<pre> $ADODB_SESSION_DRIVER='mysql'; 
     319 $ADODB_SESSION_CONNECT='localhost'; 
     320 $ADODB_SESSION_USER ='root'; 
     321 $ADODB_SESSION_PWD ='abc'; 
     322 $ADODB_SESSION_DB ='phplens'; 
     323  
     324 include('path/to/adodb/session/adodb-<strong>session2</strong>.php'); </pre> 
     325<p>In the above example, the only things you need to change in your code to upgrade 
     326  is </p> 
     327<ul> 
     328  <li>your session table format to the new one.</li> 
     329  <li>the include file from adodb-session.php to adodb-session2.php. </li> 
     330</ul> 
     331<h2>More Info</h2> 
     332<p>Also see the <a href="docs-adodb.htm">core ADOdb documentation</a>. And if 
     333  you are interested in the obsolete adodb-session.php, see <a href="docs-session.old.htm">old 
     334    session documentation</a>. </p> 
    178335</body> 
    179336</html> 
  • trunk/phpgwapi/inc/adodb/docs/old-changelog.htm

    r2 r34  
     1<html><title>Old Changelog: ADOdb</title><body> 
    12<h3>Old Changelog</h3> 
     3 
     4</p><p><b>3.92 22 Sept 2003</b>  
     5</p><p>Added GetAssoc and CacheGetAssoc to connection object. 
     6</p><p>Removed TextMax and CharMax functions from adodb.inc.php.  
     7</p><p>HasFailedTrans() returned false when trans failed. Fixed.  
     8</p><p>Moved perf driver classes into adodb/perf/*.php.  
     9</p><p>Misc improvements to performance monitoring, including UI().  
     10</p><p>RETVAL in mssql Parameter(), we do not append @ now.  
     11</p><p>Added Param($name) to connection class, returns '?' or ":$name", for defining  
     12  bind parameters portably.  
     13</p><p>LogSQL traps affected_rows() and saves its value properly now. Also fixed oci8  
     14  _stmt and _affectedrows() bugs.  
     15</p><p>Session code timestamp check for oci8 works now. Formerly default NLS_DATE_FORMAT  
     16  stripped off time portion. Thx to Tony Blair (tonanbarbarian#hotmail.com). Also  
     17  added new $conn-&gt;datetime field to oci8, controls whether MetaType() returns  
     18  'D' ($this-&gt;datetime==false) or 'T' ($this-&gt;datetime == true) for DATE type.  
     19</p><p>Fixed bugs in adodb-cryptsession.inc.php and adodb-session-clob.inc.php.  
     20</p><p>Fixed misc bugs in adodb_key_exists, GetInsertSQL() and GetUpdateSQL().  
     21</p><p>Tuned include_once handling to reduce file-system checking overhead.  
     22</p><p><b>3.91 9 Sept 2003</b>  
     23</p><p>Only released to InterAkt  
     24</p><p>Added LogSQL() for sql logging and $ADODB_NEWCONNECTION to override factory  
     25  for driver instantiation.  
     26</p><p>Added IfNull($field,$ifNull) function, thx to johnwilk#juno.com  
     27</p><p>Added portable substr support.  
     28</p><p>Now rs2html() has new parameter, $echo. Set to false to return $html instead  
     29  of echoing it.  
     30</p><p><b>3.90 5 Sept 2003</b>  
     31</p><p>First beta of performance monitoring released.  
     32</p><p>MySQL supports MetaTable() masking.  
     33</p><p>Fixed key_exists() bug in adodb-lib.inc.php  
     34</p><p>Added sp_executesql Prepare() support to mssql.  
     35</p><p>Added bind support to db2.  
     36</p><p>Added swedish language file - Christian Tiberg" christian#commsoft.nu  
     37</p><p>Bug in drop index for mssql data dict fixed. Thx to Gert-Rainer Bitterlich.  
     38</p><p>Left join setting for oci8 was wrong. Thx to johnwilk#juno.com  
     39</p><p><b>3.80 27 Aug 2003</b>  
     40</p><p>Patch for PHP 4.3.3 cached recordset csv2rs() fread loop incompatibility.  
     41</p><p>Added matching mask for MetaTables. Only for oci8, mssql and postgres currently.  
     42</p><p>Rewrite of "oracle" driver connection code, merging with "oci8", by Gaetano.  
     43</p><p>Added better debugging for Smart Transactions.  
     44</p><p>Postgres DBTimeStamp() was wrongly using TO_DATE. Changed to TO_TIMESTAMP.  
     45</p><p>ADODB_FETCH_CASE check pushed to ADONewConnection to allow people to define  
     46  it after including adodb.inc.php.  
     47</p><p>Added portugese (brazilian) to languages. Thx to "Levi Fukumori".  
     48</p><p>Removed arg3 parameter from Execute/SelectLimit/Cache* functions.  
     49</p><p>Execute() now accepts 2-d array as $inputarray. Also changed docs of fnExecute()  
     50  to note change in sql query counting with 2-d arrays.  
     51</p><p>Added MONEY to MetaType in PostgreSQL.  
     52</p><p>Added more debugging output to CacheFlush().  
     53</p><p><b>3.72 9 Aug 2003</b>  
     54</p><p>Added qmagic($str), which is a qstr($str) that auto-checks for magic quotes  
     55  and does the right thing...  
     56</p><p>Fixed CacheFlush() bug - Thx to martin#gmx.de  
     57</p><p>Walt Boring contributed MetaForeignKeys for postgres7.  
     58</p><p>_fetch() called _BlobDecode() wrongly in interbase. Fixed.  
     59</p><p>adodb_time bug fixed with dates after 2038 fixed by Jason Pell. http://phplens.com/lens/lensforum/msgs.php?id=6980  
     60</p><p><b>3.71 4 Aug 2003</b>  
     61</p><p>The oci8 driver, MetaPrimaryKeys() did not check the owner correctly when $owner  
     62  == false.  
     63</p><p>Russian language file contributed by "Cyrill Malevanov" cyrill#malevanov.spb.ru.  
     64</p><p>Spanish language file contributed by "Horacio Degiorgi" horaciod#codigophp.com.  
     65</p><p>Error handling in oci8 bugfix - if there was an error in Execute(), then when  
     66  calling ErrorNo() and/or ErrorMsg(), the 1st call would return the error, but  
     67  the 2nd call would return no error.  
     68</p><p>Error handling in odbc bugfix. ODBC would always return the last error, even  
     69  if it happened 5 queries ago. Now we reset the errormsg to '' and errorno to  
     70  0 everytime before CacheExecute() and Execute().  
     71</p><p><b>3.70 29 July 2003</b>  
     72</p><p>Added new SQLite driver. Tested on PHP 4.3 and PHP 5.  
     73</p><p>Added limited "sapdb" driver support - mainly date support.  
     74</p><p>The oci8 driver did not identify NUMBER with no defined precision correctly.  
     75</p><p>Added ADODB_FORCE_NULLS, if set, then PHP nulls are converted to SQL nulls  
     76  in GetInsertSQL/GetUpdateSQL.  
     77</p><p>DBDate() and DBTimeStamp() format for postgresql had problems. Fixed.  
     78</p><p>Added tableoptions to ChangeTableSQL(). Thx to Mike Benoit.  
     79</p><p>Added charset support to postgresql. Thx to Julian Tarkhanov.  
     80</p><p>Changed OS check for MS-Windows to prevent confusion with darWIN (MacOS)  
     81</p><p>Timestamp format for db2 was wrong. Changed to yyyy-mm-dd-hh.mm.ss.nnnnnn.  
     82</p><p>adodb-cryptsession.php includes wrong. Fixed.  
     83</p><p>Added MetaForeignKeys(). Supported by mssql, odbc_mssql and oci8.  
     84</p><p>Fixed some oci8 MetaColumns/MetaPrimaryKeys bugs. Thx to Walt Boring.  
     85</p><p>adodb_getcount() did not init qryRecs to 0. Missing "WHERE" clause checking  
     86  in GetUpdateSQL fixed. Thx to Sebastiaan van Stijn.  
     87</p><p>Added support for only 'VIEWS' and "TABLES" in MetaTables. From Walt Boring.  
     88</p><p>Upgraded to adodb-xmlschema.inc.php 0.0.2.  
     89</p><p>NConnect for mysql now returns value. Thx to Dennis Verspuij.  
     90</p><p>ADODB_FETCH_BOTH support added to interbase/firebird.  
     91</p><p>Czech language file contributed by Kamil Jakubovic jake#host.sk.  
     92</p><p>PostgreSQL BlobDecode did not use _connectionID properly. Thx to Juraj Chlebec.  
     93</p><p>Added some new initialization stuff for Informix. Thx to "Andrea Pinnisi" pinnisi#sysnet.it  
     94</p><p>ADODB_ASSOC_CASE constant wrong in sybase _fetch(). Fixed.  
     95</p><p><b>3.60 16 June 2003</b>  
     96</p><p>We now SET CONCAT_NULL_YIELDS_NULL OFF for odbc_mssql driver to be compat with  
     97  mssql driver.  
     98</p><p>The property $emptyDate missing from connection class. Also changed 1903 to  
     99  constant (TIMESTAMP_FIRST_YEAR=100). Thx to Sebastiaan van Stijn.  
     100</p><p>ADOdb speedup optimization - we now return all arrays by reference.  
     101</p><p>Now DBDate() and DBTimeStamp() now accepts the string 'null' as a parameter.  
     102  Suggested by vincent.  
     103</p><p>Added GetArray() to connection class.  
     104</p><p>Added not_null check in informix metacolumns().  
     105</p><p>Connection parameters for postgresql did not work correctly when port was defined.  
     106</p><p>DB2 is now a tested driver, making adodb 100% compatible. Extensive changes  
     107  to odbc driver for DB2, including implementing serverinfo() and SQLDate(), switching  
     108  to SQL_CUR_USE_ODBC as the cursor mode, and lastAffectedRows and SelectLimit()  
     109  fixes.  
     110</p><p>The odbc driver's FetchField() field names did not obey ADODB_ASSOC_CASE. Fixed.  
     111</p><p>Some bugs in adodb_backtrace() fixed.  
     112</p><p>Added "INT IDENTITY" type to adorecordset::MetaType() to support odbc_mssql  
     113  properly.  
     114</p><p>MetaColumns() for oci8, mssql, odbc revised to support scale. Also minor revisions  
     115  to odbc MetaColumns() for vfp and db2 compat.  
     116</p><p>Added unsigned support to mysql datadict class. Thx to iamsure.  
     117</p><p>Infinite loop in mssql MoveNext() fixed when ADODB_FETCH_ASSOC used. Thx to  
     118  Josh R, Night_Wulfe#hotmail.com.  
     119</p><p>ChangeTableSQL contributed by Florian Buzin.  
     120</p><p>The odbc_mssql driver now sets CONCAT_NULL_YIELDS_NULL OFF for compat with  
     121  mssql driver.  
     122</p> 
     123 
    2124<p><b>3.50 19 May 2003</b></p> 
    3125<p>Fixed mssql compat with FreeTDS. FreeTDS does not implement mssql_fetch_assoc().  
     
    698820<p><b>0.10 Sept 9 2000</b></p> 
    699821<p>First release</p> 
    700 <p> 
     822</body></html> 
  • trunk/phpgwapi/inc/adodb/docs/readme.htm

    r2 r34  
    1313<h3>ADOdb Library for PHP</h3> 
    1414<p>ADOdb is a suite of database libraries that allow you to connect to multiple  
    15         databases in a portable manner. Download from <a href=http://php.weblogs.com/adodb>http://php.weblogs.com/adodb</a>. 
     15        databases in a portable manner. Download from <a href=http://adodb.sourceforge.net/>http://adodb.sourceforge.net/</a>. 
    1616<ul><li>The ADOdb documentation has moved to <a href=docs-adodb.htm>docs-adodb.htm</a>  
    1717        This allows you to query, update and insert records using a portable API. 
     
    4141</pre> 
    4242<h3>How are people using ADOdb</h3> 
    43 Here are some examples of how people are using ADOdb (for a much longer list,  
    44 visit <a href="http://php.weblogs.com/adodb-cool-applications">http://php.weblogs.com/adodb-cool-applications</a>):  
     43Here are some examples of how people are using ADOdb:  
    4544<ul> 
    4645        <li> <strong>PhpLens</strong> is a commercial data grid component that allows  
  • trunk/phpgwapi/inc/adodb/docs/tips_portable_sql.htm

    r2 r34  
    99<table width=100% border=0><tr><td><h2>Tips on Writing Portable SQL &nbsp;</h2></td><td> 
    1010 <div align=right><img src="cute_icons_for_site/adodb.gif"></div></td></tr></table> 
     11  <p>Updated 6 Oct 2006. Added OffsetDate example. 
    1112  <p>Updated 18 Sep 2003. Added Portable Native SQL section. 
    1213<p> 
     
    270271<p>We also provide functions to convert database dates to Unix timestamps:</p> 
    271272<pre>$unixts = $recordset-&gt;UnixDate('#2002-02-30#'); <font color="green"># MS Access date =&gt; unix timestamp</font></pre> 
     273<p>For date calculations, we have OffsetDate which allows you to calculate dates such as <i>yesterday</i> and <i>next week</i> in a RDBMS independant fashion. For example, if we want to set a field to 6 hour from now, use: 
     274<pre> 
     275$sql = 'update table set dtimefld='.$db-&gt;OffsetDate($db-&gtsysTimeStamp, 6/24).' where ...'; 
     276</pre> 
    272277<p>The maximum length of a char/varchar field is also database specific. You can  
    273278  only assume that field lengths of up to 250 characters are supported. This is  
Note: See TracChangeset for help on using the changeset viewer.