logo       

mantisbt/core/adodb/docs docs-active-record.htm,NONE,1.1 tute.htm,1.3,1.4 t: msg#00049

Subject: mantisbt/core/adodb/docs docs-active-record.htm,NONE,1.1 tute.htm,1.3,1.4 tips_portable_sql.htm,1.3,1.4 readme.htm,1.3,1.4 old-changelog.htm,1.3,1.4 docs-session.htm,1.3,1.4 docs-perf.htm,1.2,1.3 docs-oracle.htm,1.3,1.4 docs-datadict.htm,1.3,1.4 docs-adodb.htm,1.3,1.4
Update of /cvsroot/mantisbt/mantisbt/core/adodb/docs
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20789

Modified Files:
        tute.htm tips_portable_sql.htm readme.htm old-changelog.htm 
        docs-session.htm docs-perf.htm docs-oracle.htm 
        docs-datadict.htm docs-adodb.htm 
Added Files:
        docs-active-record.htm 
Log Message:
Sync: V4.80 8 Mar 2006 of adodb

Index: docs-oracle.htm
===================================================================
RCS file: /cvsroot/mantisbt/mantisbt/core/adodb/docs/docs-oracle.htm,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- docs-oracle.htm     12 Feb 2005 20:01:24 -0000      1.3
+++ docs-oracle.htm     22 Apr 2006 11:09:48 -0000      1.4
@@ -25,7 +25,7 @@
 <table width=100%><tr><td>
 <h2>Using ADOdb with PHP and Oracle: an advanced tutorial</h2>
 </td><td><div align="right"><img src=cute_icons_for_site/adodb.gif width="88" 
height="31"></div></tr></table>
-<p><font size="1">(c)2004 John Lim. All rights reserved.</font></p>
+<p><font size="1">(c)2004-2005 John Lim. All rights reserved.</font></p>
 <h3>1. Introduction</h3>
 <p>Oracle is the most popular commercial database used with PHP. There are 
many ways of accessing Oracle databases in PHP. These include:</p>
 <ul>
@@ -48,21 +48,21 @@
 </table>
 <p>Here is an example of using the oci8 extension to query the <i>emp</i> 
table of the <i>scott</i> schema with bind parameters:
 <pre>
-$conn = OCILogon("scott","tiger", $tnsName);
+$conn = OCILogon("scott","tiger", $tnsName); 
 
-$stmt = OCIParse($conn,"select * from emp where empno > :emp order by empno");
+$stmt = OCIParse($conn,"select * from emp where empno > :emp order by empno"); 
 $emp = 7900;
 OCIBindByName($stmt, ':emp', $emp);
 $ok = OCIExecute($stmt);
 while (OCIFetchInto($stmt,$arr)) {
        print_r($arr);
-       echo "&lt;hr>";
-}
+       echo "&lt;hr>"; 
+} 
 </pre>
 <p>This generates the following output:
 <div class=greybg>
-Array ( [0] => 7902 [1] => FORD [2] => ANALYST [3] => 7566 [4] => 03/DEC/81 
[5] => 3000 [7] => 20 )
-<hr>
+Array ( [0] => 7902 [1] => FORD [2] => ANALYST [3] => 7566 [4] => 03/DEC/81 
[5] => 3000 [7] => 20 ) 
+<hr />
   Array ( [0] => 7934 [1] => MILLER [2] => CLERK [3] => 7782 [4] => 23/JAN/82 
[5] => 1300 [7] => 10 )
 </div>
 <p>We also have  many higher level PHP libraries that allow you to simplify 
the above code. The most popular are <a href="http://pear.php.net/";>PEAR DB</a> 
and <a href="http://adodb.sourceforge.net/";>ADOdb</a>.  Here are some of the 
differences between these libraries:</p>
@@ -135,7 +135,7 @@
   <tr valign="top">
     <td>High Speed Extension available</td>
     <td>No</td>
-    <td>Yes. You can install the ADOdb extension, which implements the most 
frequently used parts of ADOdb as fast C code.</td>
+    <td>Yes. You can install the optional ADOdb extension, which reimplements 
the most frequently used parts of ADOdb as fast C code. Note that the source 
code version of ADOdb runs just fine without this extension, and only makes use 
of the extension if detected.</td>
   </tr>
 </table>
 <p> PEAR DB is good enough for simple web apps. But if you need more power, 
you can see ADOdb offers more sophisticated functionality. The rest of this 
article will concentrate on using ADOdb with Oracle. You can find out more 
about <a href="#connecting">connecting to Oracle</a> later in this guide.</p>
@@ -146,7 +146,7 @@
 $db = NewADOConnection("oci8");
 $db->Connect($tnsName, "scott", "tiger");
 
-$rs = $db->Execute("select * from emp where empno>:emp order by empno",
+$rs = $db->Execute("select * from emp where empno>:emp order by empno", 
                     array('emp' => 7900));
 while ($arr = $rs->FetchRow()) {
     print_r($arr);
@@ -162,21 +162,18 @@
   </tr>
   <tr valign="top" bgcolor="#CCCCCC">
     <td><pre><font size="1">$stmt = <b>OCIParse</b>($conn,
-       "select * from emp where empno > :emp");
+       "select * from emp where empno > :emp"); 
 $emp = 7900;
 <b>OCIBindByName</b>($stmt, ':emp', $emp);
 $ok = <b>OCIExecute</b>($stmt);
 
 while (<b>OCIFetchInto</b>($stmt,$arr)) {
        print_r($arr);
-       echo "&lt;hr>";
+       echo "&lt;hr>"; 
 } </font></pre></td>
-    <td><pre><font size="1">$recordset = $db-><b>Execute</b>("select * from 
emp where empno>:emp",
+    <td><pre><font size="1">$recordset = $db-><b>Execute</b>("select * from 
emp where empno>:emp", 
                            array('emp' => 7900));
 
-
-
-
 while ($arr = $recordset-><b>FetchRow</b>()) {
        print_r($arr);
        echo "&lt;hr>";
@@ -213,7 +210,7 @@
 </pre>
 <p>The $limitrows parameter is optional.
 <h4>Array Fetch Mode</h4>
-<p>When data is being returned in an array, you can choose the type of array 
the data is returned in.
+<p>When data is being returned in an array, you can choose the type of array 
the data is returned in. 
 <ol>
   <li> Numeric indexes - use <font size="2" face="Courier New, Courier, 
mono">$connection-&gt;SetFetchMode(ADODB_FETCH_NUM).</font></li>
   <li>Associative indexes - the keys of the array are the names of the fields 
(in upper-case). Use <font size="2" face="Courier New, Courier, 
mono">$connection-&gt;SetFetchMode(ADODB_FETCH_ASSOC)</font><font face="Courier 
New, Courier, mono">.</font></li>
@@ -251,7 +248,7 @@
 <p>ADOdb will transparently handle LOBs  in <i>select</i> statements. The LOBs 
are automatically converted to PHP variables without any special coding.</p>
 <p>For updating records with LOBs, the functions UpdateBlob( ) and UpdateClob( 
) are provided. Here's a BLOB example. The parameters should be 
self-explanatory:
 <pre>
-$ok = $db->Execute("insert into aTable (id, name, ablob)
+$ok = $db->Execute("insert into aTable (id, name, ablob) 
                                 values (aSequence.nextVal, 'Name', null)");
 if (!$ok) return LogError($db-&gt;ErrorMsg());
 <font color="#006600"># params: $tableName, $blobFieldName, $blobValue, 
$whereClause</font>
@@ -259,7 +256,7 @@
 </pre>
 <p>and the analogous CLOB example:
 <pre>
-$ok = $db->Execute("insert into aTable (id, name, aclob)
+$ok = $db->Execute("insert into aTable (id, name, aclob) 
                                 values (aSequence.nextVal, 'Name', null)");
 if (!$ok) return LogError($db-&gt;ErrorMsg());
 $db->UpdateClob('aTable', 'aclob', $clobValue, 'id=aSequence.currVal');
@@ -279,7 +276,7 @@
                $db->StartTrans();
                $ok = $db->Execute($stmt);
                $db->CompleteTrans();
-</pre>
+</pre> 
 <p>
 <h3>5. REF CURSORs</h3>
 <p>Oracle recordsets can be passed around as variables called REF Cursors. For 
example, in PL/SQL, we could define a function <i>open_tab</i> that returns a 
REF CURSOR in the first parameter:</p>
@@ -330,7 +327,7 @@
 while ($arr = $rs->FetchRow()) print_r($arr);
 </pre>
 <h4>Bind Parameters and LOBs</h4>
-<p>You can also operate on LOBs. In this example, we have IN and OUT 
parameters using CLOBs.
+<p>You can also operate on LOBs. In this example, we have IN and OUT 
parameters using CLOBs. 
 <pre>
        $text = 'test test test';
        $sql = "declare rs clob; begin :rs := lobinout(:sa0); end;";
@@ -375,38 +372,38 @@
 <p>If you are not concerned about date portability and do not use ADOdb's 
portability layer, you can use your preferred date format instead.
 <p>
 <h3>8. Database Portability Layer</h3>
-<p>ADOdb provides the following functions for portably generating SQL functions
+<p>ADOdb provides the following functions for portably generating SQL 
functions 
   as strings to be merged into your SQL statements:</p>
 <table width="75%" border="1" align=center>
-  <tr>
+  <tr> 
     <td width=30%><b>Function</b></td>
     <td><b>Description</b></td>
   </tr>
-  <tr>
+  <tr> 
     <td>DBDate($date)</td>
-    <td>Pass in a UNIX timestamp or ISO date and it will convert it to a date
+    <td>Pass in a UNIX timestamp or ISO date and it will convert it to a date 
       string formatted for INSERT/UPDATE</td>
   </tr>
-  <tr>
+  <tr> 
     <td>DBTimeStamp($date)</td>
-    <td>Pass in a UNIX timestamp or ISO date and it will convert it to a 
timestamp
+    <td>Pass in a UNIX timestamp or ISO date and it will convert it to a 
timestamp 
       string formatted for INSERT/UPDATE</td>
   </tr>
-  <tr>
+  <tr> 
     <td>SQLDate($date, $fmt)</td>
-    <td>Portably generate a date formatted using $fmt mask, for use in SELECT
+    <td>Portably generate a date formatted using $fmt mask, for use in SELECT 
       statements.</td>
   </tr>
-  <tr>
+  <tr> 
     <td>OffsetDate($date, $ndays)</td>
     <td>Portably generate a $date offset by $ndays.</td>
   </tr>
-  <tr>
+  <tr> 
     <td>Concat($s1, $s2, ...)</td>
-    <td>Portably concatenate strings. Alternatively, for mssql use mssqlpo 
driver,
+    <td>Portably concatenate strings. Alternatively, for mssql use mssqlpo 
driver, 
       which allows || operator.</td>
   </tr>
-  <tr>
+  <tr> 
     <td>IfNull($fld, $replaceNull)</td>
     <td>Returns a string that is the equivalent of MySQL IFNULL or Oracle 
NVL.</td>
   </tr>
@@ -475,7 +472,9 @@
 <p>or</p>
 <pre>  $conn-&gt;PConnect('myTNS', 'scott', 'tiger');</pre>
 <p>c. Host Address and SID</p>
-<pre>  $conn-&gt;Connect('192.168.0.1', 'scott', 'tiger', 'SID');</pre>
+<pre>
+       $conn->connectSID = true;       
+       $conn-&gt;Connect('192.168.0.1', 'scott', 'tiger', 'SID');</pre>
 <p>d. Host Address and Service Name</p>
 <pre>  $conn-&gt;Connect('192.168.0.1', 'scott', 'tiger', 'servicename');</pre>
 <p>e. Oracle connection string:
@@ -487,10 +486,10 @@
 <pre>
        $dsn = 'oci8://user:pwd@tnsname/?persist';  # persist is optional
        $conn = ADONewConnection($dsn);  # no need for Connect/PConnect
-
+       
        $dsn = 'oci8://user:pwd@host/sid';
        $conn = ADONewConnection($dsn);
-
+       
        $dsn = 'oci8://user:pwd@/';   # oracle on local machine
        $conn = ADONewConnection($dsn);</pre>
 <p>With ADOdb data source names,
@@ -505,7 +504,7 @@
 }
 if (!$db-&gt;Connect($tns, $usr, $pwd)) InvokeErrorHandler();
 
-$rs = $db->Execute("select * from emp where empno>:emp order by empno",
+$rs = $db->Execute("select * from emp where empno>:emp order by empno", 
                     array('emp' => 7900));
 if (!$rs) return InvokeErrorHandler();
 while ($arr = $rs->FetchRow()) {
@@ -516,6 +515,14 @@
 <p>You can retrieve the  error message and error number of the last SQL 
statement executed from ErrorMsg( ) and ErrorNo( ). You can also <a 
href=http://phplens.com/adodb/using.custom.error.handlers.and.pear_error.html>define
 a custom error handler function</a>.
 ADOdb also supports throwing exceptions in PHP5.
 <p>&nbsp;</p>
+<h3>Handling Large Recordsets (added 27 May 2005)</h3>
+The oci8 driver does not support counting the number of records returned in a 
SELECT statement, so the function RecordCount() 
+is emulated when the global variable $ADODB_COUNTRECS is set to true, which is 
the default. 
+We emulate this by buffering all the records. This can take up large amounts 
of memory for big recordsets.
+ Set $ADODB_COUNTRECS to false for the best performance. 
+ <p>
+This variable is checked every time a query is executed, so you can 
selectively choose which recordsets to count.
+<p>&nbsp;</p>
 <h3>11. Other ADOdb Features</h3>
 <p><a href="http://phplens.com/lens/adodb/docs-datadict.htm";>Schema 
generation</a>. This allows you to define a schema using XML and import it into 
different RDBMS systems portably.</p>
 <p><a href="http://phplens.com/lens/adodb/docs-perf.htm";>Performance 
monitoring and tracing</a>. Highlights of performance monitoring include 
identification of poor and suspicious SQL, with explain plan support, and 
identifying which web pages the SQL ran on.</p>
@@ -526,6 +533,7 @@
 <h3>13. Resources</h3>
 <ul>
   <li>Oracle's <a 
href="http://www.oracle.com/technology/pub/articles/php_experts/index.html";>Hitchhiker
 Guide to PHP</a></li>
+  <li>OTN article on <a 
href=http://www.oracle.com/technology/pub/articles/deployphp/lim_deployphp.html>Optimizing
 PHP and Oracle</a> by this author.
   <li>Oracle has an excellent <a 
href="http://www.oracle.com/technology/tech/opensource/php/php_troubleshooting_faq.html";>FAQ
 on PHP</a></li>
   <li>PHP <a href="http://php.net/oci8";>oci8</a> manual pages</li>
   <li><a href=http://phplens.com/lens/lensforum/topics.php?id=4>ADOdb 
forums</a>.

Index: docs-perf.htm
===================================================================
RCS file: /cvsroot/mantisbt/mantisbt/core/adodb/docs/docs-perf.htm,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- docs-perf.htm       27 Jan 2005 14:43:42 -0000      1.2
+++ docs-perf.htm       22 Apr 2006 11:09:48 -0000      1.3
@@ -18,20 +18,10 @@
 </head>
 <body>
 <h3>The ADOdb Performance Monitoring Library</h3>
-<p>V4.60 24 Jan 2005 (c) 2000-2005 John Lim (jlim#natsoft.com.my)</p>
+<p>V4.80 8 Mar 2006 (c) 2000-2006 John Lim (jlim#natsoft.com.my)</p>
 <p><font size="1">This software is dual licensed using BSD-Style and
 LGPL. This means you can use it in compiled proprietary and commercial
 products.</font></p>
-<table border="1">
-  <tbody>
-    <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 unreliability of http://php.weblogs.com. <b>Please
-change your links</b>!</font></td>
-    </tr>
-  </tbody>
-</table>
 <p>Useful ADOdb links: <a 
href="http://adodb.sourceforge.net/#download";>Download</a>
 &nbsp; <a href="http://adodb.sourceforge.net/#docs";>Other Docs</a>
 </p>

Index: tute.htm
===================================================================
RCS file: /cvsroot/mantisbt/mantisbt/core/adodb/docs/tute.htm,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- tute.htm    12 Feb 2005 20:01:24 -0000      1.3
+++ tute.htm    22 Apr 2006 11:09:48 -0000      1.4
@@ -1,290 +1,290 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-
-<html>
-<head>
-       <title>Tutorial: Moving from MySQL to ADODB</title>
-</head>
-
-<body bgcolor=white>
-<h1>Tutorial: Moving from MySQL to ADODB</h1>
-
-<pre>          You say eether and I say eyether,
-               You say neether and I say nyther;
-               Eether, eyether, neether, nyther -
-               Let's call the whole thing off !
-<br>
-               You like potato and I like po-tah-to,
-               You like tomato and I like to-mah-to;
-               Potato, po-tah-to, tomato, to-mah-to -
-               Let's call the whole thing off !
-</pre>
-<p>I love this song, especially the version with Louis Armstrong and Ella 
singing
-  duet. It is all about how hard it is for two people in love to be compatible
-  with each other. It's about compromise and finding a common ground, and 
that's
-  what this article is all about.
-<p>PHP is all about creating dynamic web-sites with the least fuss and the most
-  fun. To create these websites we need to use databases to retrieve login 
information,
-  to splash dynamic news onto the web page and store forum postings. So let's
-  say we were using the popular MySQL database for this. Your company has done
-  such a fantastic job that the Web site is more popular than your wildest 
dreams.
-  You find that MySQL cannot scale to handle the workload; time to switch 
databases.
-<p> Unfortunately in PHP every database is accessed slightly differently. To 
connect
-  to MySQL, you would use <i>mysql_connect()</i>; when you decide to upgrade to
-  Oracle or Microsoft SQL Server, you would use <i>ocilogon() </i>or 
<i>mssql_connect()</i>
-  respectively. What is worse is that the parameters you use for the different
-  connect functions are different also.. One database says po-tato, the other
-  database says pota-to. Oh-oh.
-<h3>Let's NOT call the whole thing off</h3>
-<p>A database wrapper library such as ADODB comes in handy when you need to 
ensure portability. It provides
-  you with a common API to communicate with any supported database so you 
don't have to call things off. <p>
-
-<p>ADODB stands for Active Data Objects DataBase (sorry computer guys are 
sometimes
-  not very original). ADODB currently supports MySQL, PostgreSQL, Oracle, 
Interbase,
-  Microsoft SQL Server, Access, FoxPro, Sybase, ODBC and ADO. You can download
-  ADODB from <a href=http://php.weblogs.com/adodb></a><a 
href="http://php.weblogs.com/adodb";>http://php.weblogs.com/adodb</a>.
-<h3>MySQL Example</h3>
-<p>The most common database used with PHP is MySQL, so I guess you should be 
familiar
-  with the following code. It connects to a MySQL server at <i>localhost</i>,
-  database <i>mydb</i>, and executes an SQL select statement. The results are
-  printed, one line per row.
-<pre><font color="#666600">$db = <b>mysql_connect</b>(&quot;localhost&quot;, 
&quot;root&quot;, &quot;password&quot;);
-<b>mysql_select_db</b>(&quot;mydb&quot;,$db);</font>
-<font color="#660000">$result = <b>mysql_query</b>(&quot;SELECT * FROM 
employees&quot;,$db)</font><code><font color="#663300">;
-if ($result === false) die(&quot;failed&quot;);</font></code>
-<font color="#006666"><b>while</b> ($fields =<b> mysql_fetch_row</b>($result)) 
&#123;
- <b>for</b> ($i=0, $max=sizeof($fields); $i &lt; $max; $i++) &#123;
-               <b>print</b> $fields[$i].' ';
- &#125;
- <b>print</b> &quot;&lt;br&gt;\n&quot;;
-&#125;</font>
-</pre>
-<p>The above code has been color-coded by section. The first section is the 
connection
-  phase. The second is the execution of the SQL, and the last section is 
displaying
-  the fields. The <i>while</i> loop scans the rows of the result, while the 
<i>for</i>
-  loop scans the fields in one row.</p>
-<p>Here is the equivalent code in ADODB</p>
-<pre><b><font color="#666600"> 
include(&quot;adodb.inc.php&quot;);</font></b><font color="#666600">
- $db = <b>NewADOConnection</b>('mysql');
- $db-&gt;<b>Connect</b>(&quot;localhost&quot;, &quot;root&quot;, 
&quot;password&quot;, &quot;mydb&quot;);</font>
- <font color="#663300">$result = $db-&gt;<b>Execute</b>(&quot;SELECT * FROM 
employees&quot;);
- </font><font color="#663300"></font><code><font color="#663300">if ($result 
=== false) die(&quot;failed&quot;)</font></code><code><font 
color="#663300">;</font></code>
- <font color="#006666"><b>while</b> (!$result-&gt;EOF) &#123;
-       <b>for</b> ($i=0, $max=$result-&gt;<b>FieldCount</b>(); $i &lt; $max; 
$i++)
-                  <b>print</b> $result-&gt;fields[$i].' ';
-       $result-&gt;<b>MoveNext</b>();
-       <b>print</b> &quot;&lt;br&gt;\n&quot;;
- &#125;</font> </pre>
-<p></p>
-<p>Now porting to Oracle is as simple as changing the second line to 
<code>NewADOConnection('oracle')</code>.
-  Let's walk through the code...</p>
-<h3>Connecting to the Database</h3>
-<p></p>
-<pre><b><font 
color="#666600">include(&quot;adodb.inc.php&quot;);</font></b><font 
color="#666600">
-$db = <b>NewADOConnection</b>('mysql');
-$db-&gt;<b>Connect</b>(&quot;localhost&quot;, &quot;root&quot;, 
&quot;password&quot;, &quot;mydb&quot;);</font></pre>
-<p>The connection code is a bit more sophisticated than MySQL's because our 
needs
-  are more sophisticated. In ADODB, we use an object-oriented approach to 
managing
-  the complexity of handling multiple databases. We have different classes to
-  handle different databases. If you aren't familiar with object-oriented 
programing,
-  don't worry -- the complexity is all hidden away in the<code> 
NewADOConnection()</code>
-  function.</p>
-<p>To conserve memory, we only load the PHP code specific to the database you
-  are connecting to. We do this by calling 
<code>NewADOConnection(databasedriver)</code>.
-  Legal database drivers include <i>mysql, mssql, oracle, oci8, postgres, 
sybase,
-  vfp, access, ibase </i>and many others.</p>
-<p>Then we create a new instance of the connection class by calling 
<code>NewADOConnection()</code>.
-  Finally we connect to the database using <code>$db-&gt;Connect(). </code></p>
-<h3>Executing the SQL</h3>
-<p><code><font color="#663300">$result = $db-&gt;<b>Execute</b>(&quot;SELECT *
-  FROM employees&quot;);<br>
-  if ($result === false) die(&quot;failed&quot;)</font></code><code><font 
color="#663300">;</font></code>
-  <br>
-</p>
-<p>Sending the SQL statement to the server is straight forward. Execute() will
-  return a recordset object on successful execution. You should check $result
-  as we do above.
-<p>An issue that confuses beginners is the fact that we have two types of 
objects
-  in ADODB, the connection object and the recordset object. When do we use 
each?
-<p>The connection object ($db) is responsible for connecting to the database,
-  formatting your SQL and querying the database server. The recordset object 
($result)
-  is responsible for retrieving the results and formatting the reply as text or
-  as an array.
-<p>The only thing I need to add is that ADODB provides several helper functions
-  for making INSERT and UPDATE statements easier, which we will cover in the 
Advanced
-  section.
-<h3>Retrieving the Data<br>
-</h3>
-<pre><font color="#006666"><b>while</b> (!$result-&gt;EOF) &#123;
-   <b>for</b> ($i=0, $max=$result-&gt;<b>FieldCount</b>(); $i &lt; $max; $i++)
-          <b>print</b> $result-&gt;fields[$i].' ';
-   $result-&gt;<b>MoveNext</b>();
-   <b>print</b> &quot;&lt;br&gt;\n&quot;;
-&#125;</font></pre>
-<p>The paradigm for getting the data is that it's like reading a file. For 
every
-  line, we check first whether we have reached the end-of-file (EOF). While not
-  end-of-file, loop through each field in the row. Then move to the next line
-  (MoveNext) and repeat.
-<p>The <code>$result-&gt;fields[]</code> array is generated by the PHP database
-  extension. Some database extensions do not index the array by field name.
-  To force indexing by name - that is associative arrays -
-  use the $ADODB_FETCH_MODE global variable.
-<pre>
-       $<b>ADODB_FETCH_MODE</b> = ADODB_FETCH_NUM;
-       $rs1 = $db->Execute('select * from table');
-       $<b>ADODB_FETCH_MODE</b> = ADODB_FETCH_ASSOC;
-       $rs2 = $db->Execute('select * from table');
-       print_r($rs1->fields); // shows <i>array([0]=>'v0',[1] =>'v1')</i>
-       print_r($rs2->fields); // shows <i>array(['col1']=>'v0',['col2'] 
=>'v1')</i>
-</pre>
-<p>
-As you can see in the above example, both recordsets store and use different 
fetch modes
-based on the $ADODB_FETCH_MODE setting when the recordset was created by 
Execute().</p>
-<h2>ADOConnection<a name="ADOConnection"></a></h2>
-<p>Object that performs the connection to the database, executes SQL statements
-  and has a set of utility functions for standardising the format of SQL 
statements
-  for issues such as concatenation and date formats.</p>
-
-<h3>Other Useful Functions</h3>
-<p><code>$recordset-&gt;Move($pos)</code> scrolls to that particular row. 
ADODB supports forward
-  scrolling for all databases. Some databases will not support backwards 
scrolling.
-  This is normally not a problem as you can always cache records to simulate 
backwards
-  scrolling.
-<p><code>$recordset-&gt;RecordCount()</code> returns the number of records 
accessed by the
-  SQL statement. Some databases will return -1 because it is not supported.
-<p><code>$recordset-&gt;GetArray()</code> returns the result as an array.
-<p><code>rs2html($recordset)</code> is a function that is generates a HTML 
table based on the
-  $recordset passed to it. An example with the relevant lines in bold:
-<pre>   include('adodb.inc.php');
-   <b>include('tohtml.inc.php');</b> /* includes the rs2html function */
-   $conn = &amp;ADONewConnection('mysql');
-   $conn-&gt;PConnect('localhost','userid','password','database');
-   $rs = $conn-&gt;Execute('select * from table');
-  <b> rs2html($rs)</b>; /* recordset to html table */ </pre>
-<p>There are many other helper functions that are listed in the documentation 
available at <a href="http://php.weblogs.com/adodb_manual";></a><a 
href="http://php.weblogs.com/adodb_manual";>http://php.weblogs.com/adodb_manual</a>.
-<h2>Advanced Material</h2>
-<h3>Inserts and Updates </h3>
-<p>Let's say you want to insert the following data into a database.
-<p><b>ID</b> = 3<br>
-  <b>TheDate</b>=mktime(0,0,0,8,31,2001) /* 31st August 2001 */<br>
-  <b>Note</b>= sugar why don't we call it off
-<p>When you move to another database, your insert might no longer work.</p>
-<p>The first problem is that each database has a different default date format.
-  MySQL expects YYYY-MM-DD format, while other databases have different 
defaults.
-  ADODB has a function called DBDate() that addresses this issue by converting
-  converting the date to the correct format.</p>
-<p>The next problem is that the <b>don't</b> in the Note needs to be quoted. In
-  MySQL, we use <b>don\'t</b> but in some other databases (Sybase, Access, 
Microsoft
-  SQL Server) we use <b>don''t. </b>The qstr() function addresses this 
issue.</p>
-<p>So how do we use the functions? Like this:</p>
-<pre>$sql = &quot;INSERT INTO table (id, thedate,note) values (&quot;
-   . $<b>ID</b> . ','
-   . $db-&gt;DBDate($<b>TheDate</b>) .','
-   . $db-&gt;qstr($<b>Note</b>).&quot;)&quot;;
-$db-&gt;Execute($sql);</pre>
-<p>ADODB also supports <code>$connection-&gt;Affected_Rows()</code> (returns 
the
-  number of rows affected by last update or delete) and 
<code>$recordset-&gt;Insert_ID()</code>
-  (returns last autoincrement number generated by an insert statement). Be 
forewarned
-  that not all databases support the two functions.<br>
-</p>
-<h3>MetaTypes</h3>
-<p>You can find out more information about each of the fields (I use the words
-  fields and columns interchangebly) you are selecting by calling the recordset
-  method <code>FetchField($fieldoffset)</code>. This will return an object with
-  3 properties: name, type and max_length.
-<pre>For example:</pre>
-<pre>$recordset = $conn-&gt;Execute(&quot;select adate from 
table&quot;);<br>$f0 = $recordset-&gt;FetchField(0);
-</pre>
-<p>Then <code>$f0-&gt;name</code> will hold <i>'adata'</i>, 
<code>$f0-&gt;type</code>
-  will be set to '<i>date'</i>. If the max_length is unknown, it will be set to
-  -1.
-<p>One problem with handling different databases is that each database often 
calls
-  the same type by a different name. For example a <i>timestamp</i> type is 
called
-  <i>datetime</i> in one database and <i>time</i> in another. So ADODB has a 
special
-  <code>MetaType($type, $max_length)</code> function that standardises the 
types
-  to the following:
-<p>C: character and varchar types<br>
-  X: text or long character (eg. more than 255 bytes wide).<br>
-  B: blob or binary image<br>
-  D: date<br>
-  T: timestamp<br>
-  L: logical (boolean)<br>
-  I: integer<br>
-  N: numeric (float, double, money)
-<p>In the above date example,
-<p><code>$recordset = $conn-&gt;Execute(&quot;select adate from 
table&quot;);<br>
-  $f0 = $recordset-&gt;FetchField(0);<br>
-  $type = $recordset-&gt;MetaType($f0-&gt;type, $f0-&gt;max_length);<br>
-  print $type; /* should print 'D'</code> */
-<p>
-<p><b>Select Limit and Top Support</b>
-<p>ADODB has a function called $connection->SelectLimit($sql,$nrows,$offset) 
that allows
-you to retrieve a subset of the recordset. This will take advantage of native
-SELECT TOP on Microsoft products and SELECT ... LIMIT with PostgreSQL and 
MySQL, and
-emulated if the database does not support it.
-<p><b>Caching Support</b>
-<p>ADODB allows you to cache recordsets in your file system, and only requery 
the database
-server after a certain timeout period with 
$connection->CacheExecute($secs2cache,$sql) and
-$connection->CacheSelectLimit($secs2cache,$sql,$nrows,$offset).
-<p><b>PHP4 Session Handler Support</b>
-<p>ADODB also supports PHP4 session handlers. You can store your session 
variables
-  in a database for true scalability using ADODB. For further information, 
visit
-  <a href="http://php.weblogs.com/adodb-sessions";></a><a 
href="http://php.weblogs.com/adodb-sessions";>http://php.weblogs.com/adodb-sessions</a>
-<h3>Commercial Use Encouraged</h3>
-<p>If you plan to write commercial PHP applications that you want to resell, 
you should consider ADODB. It has been released using the lesser GPL, which 
means you can legally include it in commercial applications, while keeping your 
code proprietary. Commercial use of ADODB is strongly encouraged! We are using 
it internally for this reason.<p>
-
-<h2>Conclusion</h2>
-<p>As a thank you for finishing this article, here are the complete lyrics for
-  <i>let's call the whole thing off</i>.<br>
-  <br>
-<pre>
-   Refrain
-<br>
-               You say eether and I say eyether,
-               You say neether and I say nyther;
-               Eether, eyether, neether, nyther -
-               Let's call the whole thing off !
-<br>
-               You like potato and I like po-tah-to,
-               You like tomato and I like to-mah-to;
-               Potato, po-tah-to, tomato, to-mah-to -
-               Let's call the whole thing off !
-<br>
-But oh, if we call the whole thing off, then we must part.
-And oh, if we ever part, then that might break my heart.
-<br>
-               So, if you like pajamas and I like pa-jah-mas,
-               I'll wear pajamas and give up pa-jah-mas.
-               For we know we
-               Need each other, so we
-               Better call the calling off off.
-               Let's call the whole thing off !
-<br>
-   Second Refrain
-<br>
-               You say laughter and I say lawfter,
-               You say after and I say awfter;
-               Laughter, lawfter, after, awfter -
-               Let's call the whole thing off !
-<br>
-               You like vanilla and I like vanella,
-               You, sa's'parilla and I sa's'parella;
-               Vanilla, vanella, choc'late, strawb'ry -
-               Let's call the whole thing off !
-<br>
-But oh, if we call the whole thing off, then we must part.
-And oh, if we ever part, then that might break my heart.
-<br>
-               So, if you go for oysters and I go for ersters,
-               I'll order oysters and cancel the ersters.
-               For we know we
-               Need each other, so we
-               Better call the calling off off.
-               Let's call the whole thing off !
-  </pre>
-<p><font size=2>Song and lyrics by George and Ira Gershwin, introduced by Fred 
Astaire and Ginger Rogers
-in the film "Shall We Dance?"  </font><p>
-<p>
-(c)2001-2002 John Lim.
-
-</body>
-</html>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+
+<html>
+<head>
+       <title>Tutorial: Moving from MySQL to ADODB</title>
+</head>
+
+<body bgcolor=white>
+<h1>Tutorial: Moving from MySQL to ADODB</h1>
+
+<pre>          You say eether and I say eyether, 
+               You say neether and I say nyther; 
+               Eether, eyether, neether, nyther - 
+               Let's call the whole thing off ! 
+<br>
+               You like potato and I like po-tah-to, 
+               You like tomato and I like to-mah-to; 
+               Potato, po-tah-to, tomato, to-mah-to - 
+               Let's call the whole thing off ! 
+</pre>
+<p>I love this song, especially the version with Louis Armstrong and Ella 
singing 
+  duet. It is all about how hard it is for two people in love to be compatible 
+  with each other. It's about compromise and finding a common ground, and 
that's 
+  what this article is all about. 
+<p>PHP is all about creating dynamic web-sites with the least fuss and the 
most 
+  fun. To create these websites we need to use databases to retrieve login 
information, 
+  to splash dynamic news onto the web page and store forum postings. So let's 
+  say we were using the popular MySQL database for this. Your company has done 
+  such a fantastic job that the Web site is more popular than your wildest 
dreams. 
+  You find that MySQL cannot scale to handle the workload; time to switch 
databases. 
+<p> Unfortunately in PHP every database is accessed slightly differently. To 
connect 
+  to MySQL, you would use <i>mysql_connect()</i>; when you decide to upgrade 
to 
+  Oracle or Microsoft SQL Server, you would use <i>ocilogon() </i>or 
<i>mssql_connect()</i> 
+  respectively. What is worse is that the parameters you use for the different 
+  connect functions are different also.. One database says po-tato, the other 
+  database says pota-to. Oh-oh. 
+<h3>Let's NOT call the whole thing off</h3>
+<p>A database wrapper library such as ADODB comes in handy when you need to 
ensure portability. It provides 
+  you with a common API to communicate with any supported database so you 
don't have to call things off. <p>
+
+<p>ADODB stands for Active Data Objects DataBase (sorry computer guys are 
sometimes 
+  not very original). ADODB currently supports MySQL, PostgreSQL, Oracle, 
Interbase, 
+  Microsoft SQL Server, Access, FoxPro, Sybase, ODBC and ADO. You can download 
+  ADODB from <a href=http://php.weblogs.com/adodb></a><a 
href="http://php.weblogs.com/adodb";>http://php.weblogs.com/adodb</a>.
+<h3>MySQL Example</h3>
+<p>The most common database used with PHP is MySQL, so I guess you should be 
familiar 
+  with the following code. It connects to a MySQL server at <i>localhost</i>, 
+  database <i>mydb</i>, and executes an SQL select statement. The results are 
+  printed, one line per row. 
+<pre><font color="#666600">$db = <b>mysql_connect</b>(&quot;localhost&quot;, 
&quot;root&quot;, &quot;password&quot;);
+<b>mysql_select_db</b>(&quot;mydb&quot;,$db);</font>
+<font color="#660000">$result = <b>mysql_query</b>(&quot;SELECT * FROM 
employees&quot;,$db)</font><code><font color="#663300">;
+if ($result === false) die(&quot;failed&quot;);</font></code> 
+<font color="#006666"><b>while</b> ($fields =<b> mysql_fetch_row</b>($result)) 
&#123;
+ <b>for</b> ($i=0, $max=sizeof($fields); $i &lt; $max; $i++) &#123;
+               <b>print</b> $fields[$i].' ';
+ &#125;
+ <b>print</b> &quot;&lt;br&gt;\n&quot;;
+&#125;</font> 
+</pre>
+<p>The above code has been color-coded by section. The first section is the 
connection 
+  phase. The second is the execution of the SQL, and the last section is 
displaying 
+  the fields. The <i>while</i> loop scans the rows of the result, while the 
<i>for</i> 
+  loop scans the fields in one row.</p>
+<p>Here is the equivalent code in ADODB</p>
+<pre><b><font color="#666600"> 
include(&quot;adodb.inc.php&quot;);</font></b><font color="#666600">
+ $db = <b>NewADOConnection</b>('mysql');
+ $db-&gt;<b>Connect</b>(&quot;localhost&quot;, &quot;root&quot;, 
&quot;password&quot;, &quot;mydb&quot;);</font>
+ <font color="#663300">$result = $db-&gt;<b>Execute</b>(&quot;SELECT * FROM 
employees&quot;);
+ </font><font color="#663300"></font><code><font color="#663300">if ($result 
=== false) die(&quot;failed&quot;)</font></code><code><font 
color="#663300">;</font></code>  
+ <font color="#006666"><b>while</b> (!$result-&gt;EOF) &#123;
+       <b>for</b> ($i=0, $max=$result-&gt;<b>FieldCount</b>(); $i &lt; $max; 
$i++)
+                  <b>print</b> $result-&gt;fields[$i].' ';
+       $result-&gt;<b>MoveNext</b>();
+       <b>print</b> &quot;&lt;br&gt;\n&quot;;
+ &#125;</font> </pre>
+<p></p>
+<p>Now porting to Oracle is as simple as changing the second line to 
<code>NewADOConnection('oracle')</code>. 
+  Let's walk through the code...</p>
+<h3>Connecting to the Database</h3>
+<p></p>
+<pre><b><font 
color="#666600">include(&quot;adodb.inc.php&quot;);</font></b><font 
color="#666600">
+$db = <b>NewADOConnection</b>('mysql');
+$db-&gt;<b>Connect</b>(&quot;localhost&quot;, &quot;root&quot;, 
&quot;password&quot;, &quot;mydb&quot;);</font></pre>
+<p>The connection code is a bit more sophisticated than MySQL's because our 
needs 
+  are more sophisticated. In ADODB, we use an object-oriented approach to 
managing 
+  the complexity of handling multiple databases. We have different classes to 
+  handle different databases. If you aren't familiar with object-oriented 
programing, 
+  don't worry -- the complexity is all hidden away in the<code> 
NewADOConnection()</code> 
+  function.</p>
+<p>To conserve memory, we only load the PHP code specific to the database you 
+  are connecting to. We do this by calling 
<code>NewADOConnection(databasedriver)</code>. 
+  Legal database drivers include <i>mysql, mssql, oracle, oci8, postgres, 
sybase, 
+  vfp, access, ibase </i>and many others.</p>
+<p>Then we create a new instance of the connection class by calling 
<code>NewADOConnection()</code>. 
+  Finally we connect to the database using <code>$db-&gt;Connect(). </code></p>
+<h3>Executing the SQL</h3>
+<p><code><font color="#663300">$result = $db-&gt;<b>Execute</b>(&quot;SELECT * 
+  FROM employees&quot;);<br>
+  if ($result === false) die(&quot;failed&quot;)</font></code><code><font 
color="#663300">;</font></code> 
+  <br>
+</p>
+<p>Sending the SQL statement to the server is straight forward. Execute() will 
+  return a recordset object on successful execution. You should check $result 
+  as we do above.
+<p>An issue that confuses beginners is the fact that we have two types of 
objects 
+  in ADODB, the connection object and the recordset object. When do we use 
each?
+<p>The connection object ($db) is responsible for connecting to the database, 
+  formatting your SQL and querying the database server. The recordset object 
($result) 
+  is responsible for retrieving the results and formatting the reply as text 
or 
+  as an array.
+<p>The only thing I need to add is that ADODB provides several helper 
functions 
+  for making INSERT and UPDATE statements easier, which we will cover in the 
Advanced 
+  section. 
+<h3>Retrieving the Data<br>
+</h3>
+<pre><font color="#006666"><b>while</b> (!$result-&gt;EOF) &#123;
+   <b>for</b> ($i=0, $max=$result-&gt;<b>FieldCount</b>(); $i &lt; $max; $i++)
+          <b>print</b> $result-&gt;fields[$i].' ';
+   $result-&gt;<b>MoveNext</b>();
+   <b>print</b> &quot;&lt;br&gt;\n&quot;;
+&#125;</font></pre>
+<p>The paradigm for getting the data is that it's like reading a file. For 
every 
+  line, we check first whether we have reached the end-of-file (EOF). While 
not 
+  end-of-file, loop through each field in the row. Then move to the next line 
+  (MoveNext) and repeat. 
+<p>The <code>$result-&gt;fields[]</code> array is generated by the PHP 
database 
+  extension. Some database extensions do not index the array by field name. 
+  To force indexing by name - that is associative arrays - 
+  use the $ADODB_FETCH_MODE global variable. 
+<pre>
+       $<b>ADODB_FETCH_MODE</b> = ADODB_FETCH_NUM;
+       $rs1 = $db->Execute('select * from table');
+       $<b>ADODB_FETCH_MODE</b> = ADODB_FETCH_ASSOC;
+       $rs2 = $db->Execute('select * from table');
+       print_r($rs1->fields); // shows <i>array([0]=>'v0',[1] =>'v1')</i>
+       print_r($rs2->fields); // shows <i>array(['col1']=>'v0',['col2'] 
=>'v1')</i>
+</pre>
+<p>
+As you can see in the above example, both recordsets store and use different 
fetch modes
+based on the $ADODB_FETCH_MODE setting when the recordset was created by 
Execute().</p>
+<h2>ADOConnection<a name="ADOConnection"></a></h2>
+<p>Object that performs the connection to the database, executes SQL 
statements 
+  and has a set of utility functions for standardising the format of SQL 
statements 
+  for issues such as concatenation and date formats.</p>
+  
+<h3>Other Useful Functions</h3>
+<p><code>$recordset-&gt;Move($pos)</code> scrolls to that particular row. 
ADODB supports forward 
+  scrolling for all databases. Some databases will not support backwards 
scrolling. 
+  This is normally not a problem as you can always cache records to simulate 
backwards 
+  scrolling. 
+<p><code>$recordset-&gt;RecordCount()</code> returns the number of records 
accessed by the 
+  SQL statement. Some databases will return -1 because it is not supported. 
+<p><code>$recordset-&gt;GetArray()</code> returns the result as an array. 
+<p><code>rs2html($recordset)</code> is a function that is generates a HTML 
table based on the 
+  $recordset passed to it. An example with the relevant lines in bold:
+<pre>   include('adodb.inc.php'); 
+   <b>include('tohtml.inc.php');</b> /* includes the rs2html function */
+   $conn = &amp;ADONewConnection('mysql'); 
+   $conn-&gt;PConnect('localhost','userid','password','database');
+   $rs = $conn-&gt;Execute('select * from table');
+  <b> rs2html($rs)</b>; /* recordset to html table */ </pre>
+<p>There are many other helper functions that are listed in the documentation 
available at <a href="http://php.weblogs.com/adodb_manual";></a><a 
href="http://php.weblogs.com/adodb_manual";>http://php.weblogs.com/adodb_manual</a>.
 
+<h2>Advanced Material</h2>
+<h3>Inserts and Updates </h3>
+<p>Let's say you want to insert the following data into a database. 
+<p><b>ID</b> = 3<br>
+  <b>TheDate</b>=mktime(0,0,0,8,31,2001) /* 31st August 2001 */<br>
+  <b>Note</b>= sugar why don't we call it off 
+<p>When you move to another database, your insert might no longer work.</p>
+<p>The first problem is that each database has a different default date 
format. 
+  MySQL expects YYYY-MM-DD format, while other databases have different 
defaults. 
+  ADODB has a function called DBDate() that addresses this issue by converting 
+  converting the date to the correct format.</p>
+<p>The next problem is that the <b>don't</b> in the Note needs to be quoted. 
In 
+  MySQL, we use <b>don\'t</b> but in some other databases (Sybase, Access, 
Microsoft 
+  SQL Server) we use <b>don''t. </b>The qstr() function addresses this 
issue.</p>
+<p>So how do we use the functions? Like this:</p>
+<pre>$sql = &quot;INSERT INTO table (id, thedate,note) values (&quot; 
+   . $<b>ID</b> . ','
+   . $db-&gt;DBDate($<b>TheDate</b>) .','
+   . $db-&gt;qstr($<b>Note</b>).&quot;)&quot;;
+$db-&gt;Execute($sql);</pre>
+<p>ADODB also supports <code>$connection-&gt;Affected_Rows()</code> (returns 
the 
+  number of rows affected by last update or delete) and 
<code>$recordset-&gt;Insert_ID()</code> 
+  (returns last autoincrement number generated by an insert statement). Be 
forewarned 
+  that not all databases support the two functions.<br>
+</p>
+<h3>MetaTypes</h3>
+<p>You can find out more information about each of the fields (I use the words 
+  fields and columns interchangebly) you are selecting by calling the 
recordset 
+  method <code>FetchField($fieldoffset)</code>. This will return an object 
with 
+  3 properties: name, type and max_length. 
+<pre>For example:</pre>
+<pre>$recordset = $conn-&gt;Execute(&quot;select adate from 
table&quot;);<br>$f0 = $recordset-&gt;FetchField(0);
+</pre>
+<p>Then <code>$f0-&gt;name</code> will hold <i>'adata'</i>, 
<code>$f0-&gt;type</code> 
+  will be set to '<i>date'</i>. If the max_length is unknown, it will be set 
to 
+  -1. 
+<p>One problem with handling different databases is that each database often 
calls 
+  the same type by a different name. For example a <i>timestamp</i> type is 
called 
+  <i>datetime</i> in one database and <i>time</i> in another. So ADODB has a 
special 
+  <code>MetaType($type, $max_length)</code> function that standardises the 
types 
+  to the following: 
+<p>C: character and varchar types<br>
+  X: text or long character (eg. more than 255 bytes wide).<br>
+  B: blob or binary image<br>
+  D: date<br>
+  T: timestamp<br>
+  L: logical (boolean)<br>
+  I: integer<br>
+  N: numeric (float, double, money) 
+<p>In the above date example, 
+<p><code>$recordset = $conn-&gt;Execute(&quot;select adate from 
table&quot;);<br>
+  $f0 = $recordset-&gt;FetchField(0);<br>
+  $type = $recordset-&gt;MetaType($f0-&gt;type, $f0-&gt;max_length);<br>
+  print $type; /* should print 'D'</code> */
+<p> 
+<p><b>Select Limit and Top Support</b> 
+<p>ADODB has a function called $connection->SelectLimit($sql,$nrows,$offset) 
that allows
+you to retrieve a subset of the recordset. This will take advantage of native
+SELECT TOP on Microsoft products and SELECT ... LIMIT with PostgreSQL and 
MySQL, and
+emulated if the database does not support it.
+<p><b>Caching Support</b> 
+<p>ADODB allows you to cache recordsets in your file system, and only requery 
the database
+server after a certain timeout period with 
$connection->CacheExecute($secs2cache,$sql) and 
+$connection->CacheSelectLimit($secs2cache,$sql,$nrows,$offset).
+<p><b>PHP4 Session Handler Support</b> 
+<p>ADODB also supports PHP4 session handlers. You can store your session 
variables 
+  in a database for true scalability using ADODB. For further information, 
visit 
+  <a href="http://php.weblogs.com/adodb-sessions";></a><a 
href="http://php.weblogs.com/adodb-sessions";>http://php.weblogs.com/adodb-sessions</a>
+<h3>Commercial Use Encouraged</h3>
+<p>If you plan to write commercial PHP applications that you want to resell, 
you should consider ADODB. It has been released using the lesser GPL, which 
means you can legally include it in commercial applications, while keeping your 
code proprietary. Commercial use of ADODB is strongly encouraged! We are using 
it internally for this reason.<p>
+
+<h2>Conclusion</h2>
+<p>As a thank you for finishing this article, here are the complete lyrics for 
+  <i>let's call the whole thing off</i>.<br>
+  <br>
+<pre>
+   Refrain 
+<br>
+               You say eether and I say eyether, 
+               You say neether and I say nyther; 
+               Eether, eyether, neether, nyther - 
+               Let's call the whole thing off ! 
+<br>
+               You like potato and I like po-tah-to, 
+               You like tomato and I like to-mah-to; 
+               Potato, po-tah-to, tomato, to-mah-to - 
+               Let's call the whole thing off ! 
+<br>
+But oh, if we call the whole thing off, then we must part. 
+And oh, if we ever part, then that might break my heart. 
+<br>
+               So, if you like pajamas and I like pa-jah-mas, 
+               I'll wear pajamas and give up pa-jah-mas. 
+               For we know we 
+               Need each other, so we 
+               Better call the calling off off. 
+               Let's call the whole thing off ! 
+<br>
+   Second Refrain 
+<br>
+               You say laughter and I say lawfter, 
+               You say after and I say awfter; 
+               Laughter, lawfter, after, awfter - 
+               Let's call the whole thing off ! 
+<br>
+               You like vanilla and I like vanella, 
+               You, sa's'parilla and I sa's'parella; 
+               Vanilla, vanella, choc'late, strawb'ry - 
+               Let's call the whole thing off ! 
+<br>
+But oh, if we call the whole thing off, then we must part. 
+And oh, if we ever part, then that might break my heart. 
+<br>
+               So, if you go for oysters and I go for ersters, 
+               I'll order oysters and cancel the ersters. 
+               For we know we 
+               Need each other, so we 
+               Better call the calling off off. 
+               Let's call the whole thing off ! 
+  </pre>
+<p><font size=2>Song and lyrics by George and Ira Gershwin, introduced by Fred 
Astaire and Ginger Rogers
+in the film "Shall We Dance?"  </font><p>
+<p>
+(c)2001-2002 John Lim.
+
+</body>
+</html>

Index: docs-adodb.htm
===================================================================
RCS file: /cvsroot/mantisbt/mantisbt/core/adodb/docs/docs-adodb.htm,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- docs-adodb.htm      12 Feb 2005 20:01:23 -0000      1.3
+++ docs-adodb.htm      22 Apr 2006 11:09:48 -0000      1.4
@@ -3,7 +3,7 @@
 
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 
-
+       
 <style>
 pre {
   background-color: #eee;
@@ -12,13 +12,13 @@
   border: 1px solid #ddd;
 }
[...3692 lines suppressed...]
-  to odbc MetaColumns() for vfp and db2 compat.
-</p><p>Added unsigned support to mysql datadict class. Thx to iamsure.
-</p><p>Infinite loop in mssql MoveNext() fixed when ADODB_FETCH_ASSOC used. 
Thx to
-  Josh R, Night_Wulfe#hotmail.com.
-</p><p>ChangeTableSQL contributed by Florian Buzin.
-</p><p>The odbc_mssql driver now sets CONCAT_NULL_YIELDS_NULL OFF for compat 
with
-  mssql driver.
-</p><hr>
-<p><strong>0.10 Sept 9 2000</strong> First release
-</p><h3><strong>Old change log history moved to <a 
href="old-changelog.htm">old-changelog.htm</a>.
+</p><p>Added _varchar (varchar arrays) support for postgresql. Reported by 
PREVOT St&eacute;phane.<hr />
+<p><strong>0.10 Sept 9 2000</strong> First release 
+</p><h3><strong>Old change log history moved to <a 
href="old-changelog.htm">old-changelog.htm</a>. 
   </strong></h3>
 <p>&nbsp;</p>
-<p>
-</p></body></html>
+<p>  
+</p></body></html>
\ No newline at end of file

Index: old-changelog.htm
===================================================================
RCS file: /cvsroot/mantisbt/mantisbt/core/adodb/docs/old-changelog.htm,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- old-changelog.htm   12 Feb 2005 20:01:24 -0000      1.3
+++ old-changelog.htm   22 Apr 2006 11:09:48 -0000      1.4
@@ -1,700 +1,822 @@
-<h3>Old Changelog</h3>
-<p><b>3.50 19 May 2003</b></p>
-<p>Fixed mssql compat with FreeTDS. FreeTDS does not implement 
mssql_fetch_assoc().
-<p>Merged back connection and recordset code into adodb.inc.php.
-<p>ADOdb sessions using oracle clobs contributed by achim.gosse#ddd.de. See 
adodb-session-clob.php.
-<p>Added /s modifier to preg_match everywhere, which ensures that regex does 
not
-  stop at /n. Thx Pao-Hsi Huang.
-<p>Fixed error in metacolumns() for mssql.
-<p>Added time format support for SQLDate.
-<p>Image => B added to metatype.
-<p>MetaType now checks empty($this->blobSize) instead of empty($this).
[...1492 lines suppressed...]
+<p>Added BeginTrans, CommitTrans and RollbackTrans functions.</p>
+<p>Added Affected_Rows() and Insert_ID(), _affectedrows() and _insertID(), 
ListTables(), 
+ ListDatabases(), ListColumns().</p>
+<p>Need to add New_ID() and hasInsertID and hasAffectedRows, autoCommit </p>
+<p><b>0.20 Sept 12</b></p>
+<p>Added support for Microsoft's ADO.</p>
+<p>Added new field to ADORecordSet -- canSeek</p>
+<p>Added new parameter to _fetch($ignore_fields = false). Setting to true will 
+ not update fields array for faster performance.</p>
+<p>Added new field to ADORecordSet/ADOConnection -- dataProvider to indicate 
whether 
+ a class is derived from odbc or ado.</p>
+<p>Changed class ODBCFieldObject to ADOFieldObject -- not documented 
currently.</p>
+<p>Added benchmark.php and testdatabases.inc.php to the test suite.</p>
+<p>Added to ADORecordSet FastForward( ) for future high speed scrolling. Not 
documented.</p>
+<p>Realised that ADO's Move( ) uses relative positioning. ADOdb uses absolute. 
+</p>
+<p><b>0.10 Sept 9 2000</b></p>
+<p>First release</p>
+</body></html>
\ No newline at end of file

Index: docs-datadict.htm
===================================================================
RCS file: /cvsroot/mantisbt/mantisbt/core/adodb/docs/docs-datadict.htm,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- docs-datadict.htm   12 Feb 2005 20:01:24 -0000      1.3
+++ docs-datadict.htm   22 Apr 2006 11:09:48 -0000      1.4
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 <html>
 <head>
-  <title>ADODB Data Dictionary Manual</title>
+  <title>ADOdb Data Dictionary Manual</title>
   <meta http-equiv="Content-Type"
  content="text/html; charset=iso-8859-1">
   <style type="text/css">
@@ -11,7 +11,7 @@
       }
       pre {
         font-size: 9pt;
-         background-color: #EEEEEE; padding: .5em; margin: 0px;
+         background-color: #EEEEEE; padding: .5em; margin: 0px; 
       }
       .toplink {
         font-size: 8pt;
@@ -20,22 +20,13 @@
 </head>
 <body style="background-color: rgb(255, 255, 255);">
 <h2>ADOdb Data Dictionary Library for PHP</h2>
-<p>V4.60 24 Jan 2005 (c) 2000-2005 John Lim (<a
+<p>V4.80 8 Mar 2006 (c) 2000-2006 John Lim (<a
  href="mailto:jlim#natsoft.com.my";>jlim#natsoft.com.my</a>).<br>
 AXMLS (c) 2004 ars Cognita, Inc</p>
 <p><font size="1">This software is dual licensed using BSD-Style and
 LGPL. This means you can use it in compiled proprietary and commercial
 products.</font></p>
-<table border="1">
-  <tbody>
-    <tr>
-      <td height="38"><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 unreliability of http://php.weblogs.com. <b>Please
-change your links</b>!</font></td>
-    </tr>
-  </tbody>
-</table>
+
 <p>Useful ADOdb links: <a 
href="http://adodb.sourceforge.net/#download";>Download</a>
 &nbsp; <a href="http://adodb.sourceforge.net/#docs";>Other Docs</a>
 </p>
@@ -52,7 +43,7 @@
 generic ODBC.
 </p>
 <h3>Example Usage</h3>
-<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
+<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
  color="#006600"># Then create a data dictionary object, using this 
connection</font><br>  $dict = <strong>NewDataDictionary</strong>($db);<br><br> 
 <font
  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
  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
@@ -83,7 +74,7 @@
 field type can be a portable type codes or the actual type for that
 database.</p>
 <p>Legal portable type codes include:</p>
-<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>
+<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>
 <p>The $colsize field represents the size of the field. If a decimal
 number is used, then it is assumed that the number following the dot is
 the precision, so 6.2 means a number of size 6 digits and 2 decimal
@@ -177,7 +168,7 @@
 <pre>  RETURNS:      0 if failed, 1 if executed all but with errors, 2 if 
executed successfully<br>  $sqlarray:    an array of strings with sql code (no 
semicolon at the end of string)<br>  $contOnError: if true, then continue 
executing even if error occurs<br></pre>
 <p>Executes an array of SQL strings returned by CreateTableSQL or
 CreateIndexSQL.</p>
-<hr>
+<hr />
 <a name="xmlschema"></a>
 <h2>ADOdb XML Schema (AXMLS)</h2>
 <p>This is a class contributed by Richard Tango-Lowy and Dan Cech that
@@ -250,7 +241,11 @@
 <p>Now that we've defined an XML schema, you need to know how to apply
 it to your database. Here's a simple PHP script that shows how to load
 the schema.</p>
-<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 buil
 d 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>
+<pre class="listing"><pre>&lt;?PHP<br>/* You must tell the script where to 
find the ADOdb and<br> * the AXMLS libraries.<br> */
+require( "path_to_adodb/adodb.inc.php");
+require( "path_to_adodb/adodb-xmlschema.inc.php" ); # or 
adodb-xmlschema03.inc.php
+
+/* 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>
 <p>Let's look at each part of the example in turn. After you manually
 create the database, there are three steps required to load (or
 upgrade) your schema.</p>
@@ -260,11 +255,11 @@
 <p>Second, create the adoSchema object that load and manipulate your
 schema. You must pass an ADOdb database connection object in order to
 create the adoSchema object.</p>
-<pre class="listing"><pre>$schema = new adoSchema( $db );<br></pre></pre>
+<pre class="listing">$schema = new adoSchema( $db );<br></pre>
 <p>Third, call ParseSchema() to parse the schema and then
 ExecuteSchema() to apply it to the database. You must pass
 ParseSchema() the path and filename of your schema file.</p>
-<pre class="listing"><pre><br>$schema-&gt;ParseSchema( $schemaFile ); 
<br>$schema-&gt;ExecuteSchema(); <br></pre></pre>
+<pre class="listing">$schema-&gt;ParseSchema( $schemaFile ); 
<br>$schema-&gt;ExecuteSchema();</pre>
 <p>Execute the above code and then log into your database. If you've
 done all this right, you should see your tables, indexes, and SQL.</p>
 <p>You can find the source files for this tutorial in the examples
@@ -272,14 +267,41 @@
 documentation for a more detailed description of the adoSchema methods,
 including methods and schema elements that are not described in this
 tutorial.</p>
+<h3>XML Schema Version 3</h3>
+<p>In March 2006, we added adodb-xmlschema03.inc.php to the release, which 
supports version 3 of XML Schema. 
+The adodb-xmlschema.inc.php remains the same as previous releases, and 
supports version 2 of XML Schema. 
+Version 3 provides some enhancements:
+
+<ul>
+     <li> Support for updating table data during an upgrade.
+     <li> Support for platform-specific table options and platform negation.
+     <li> Support for unsigned fields.
+     <li> Fixed opt and constraint support
+     <li> Many other fixes such as OPT tag, which allows you to set optional 
platform settings:
+</ul>
+
+<p>Example usage:
+<pre>&lt;?xml version="1.0"?>
+<b>&lt;schema version="0.3"></b>
+ &lt;table name="ats_kb">
+  &lt;descr>ATS KnowledgeBase&lt;/descr>
+  &lt;opt platform="mysql">TYPE=INNODB&lt;/opt>
+  &lt;field name="recid" type="I"/>
+  &lt;field name="organization_code" type="I4"/> 
+  &lt;field name="sub_code" type="C" size="20"/>
+  etc...
+</pre>
+<p>To use it, change your code to include adodb-xmlschema03.inc.php.
+
 <h3>Upgrading</h3>
+<p>
 If your schema version is older, than XSLT is used to transform the
 schema to the newest version. This means that if you are using an older
 XML schema format, you need to have the XSLT extension installed.
 If you do not want to require your users to have the XSLT extension
 installed, make sure you modify your XML schema to conform to the
 latest version.
-<hr>
+<hr />
 <address>If you have any questions or comments, please email them to
 Richard at richtl#arscognita.com.
 </address>

Index: docs-session.htm
===================================================================
RCS file: /cvsroot/mantisbt/mantisbt/core/adodb/docs/docs-session.htm,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- docs-session.htm    12 Feb 2005 20:01:24 -0000      1.3
+++ docs-session.htm    22 Apr 2006 11:09:48 -0000      1.4
@@ -21,24 +21,11 @@
 <body style="background-color: rgb(255, 255, 255);">
 <h3>ADODB Session Management Manual</h3>
 <p>
-V4.60 24 Jan 2005 (c) 2000-2005 John Lim (jlim#natsoft.com.my)
+V4.80 8 Mar 2006 (c) 2000-2006 John Lim (jlim#natsoft.com.my)
 </p>
 <p> <font size="1">This software is dual licensed using BSD-Style and
 LGPL. This means you can use it in compiled proprietary and commercial
 products. </font>
-<table border="1">
-  <tbody>
-    <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 unreliability of http://php.weblogs.com. <b>Please
-change your links</b>!</font></td>
-    </tr>
-    <tr>
-    </tr>
-  </tbody>
-</table>
-<p></p>
 <p>Useful ADOdb links: <a 
href="http://adodb.sourceforge.net/#download";>Download</a>
 &nbsp; <a href="http://adodb.sourceforge.net/#docs";>Other Docs</a>
 </p>
@@ -61,9 +48,12 @@
   <li>Need to do special processing of each session</li>
   <li>Require notification when a session expires</li>
 </ul>
-<p>Then the ADOdb session handler provides you with the above
+<p>The ADOdb session handler provides you with the above
 additional capabilities by storing the session information as records
 in a database table that can be shared across multiple servers. </p>
+<p>These records will be garbage collected based on the php.ini [session] 
timeout settings. 
+You can register a notification function to notify you when the record has 
expired and 
+is about to be freed by the garbage collector.</p>
 <p><b>Important Upgrade Notice:</b> Since ADOdb 4.05, the session files
 have been moved to its own folder, adodb/session. This is a rewrite
 of the session code by Ross Smith. The old session code is in
@@ -92,7 +82,7 @@
 <p><pre>
  <font
  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>
-
+ 
 <p>To force non-persistent connections, call adodb_session_open() first before 
session_start():
 <p>
  <pre>
@@ -136,8 +126,22 @@
  <h4>Installation</h4>
 <p>1. Create this table in your database (syntax might vary depending on your 
db):
 <p><pre> <a
- 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>
+ 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> 
  </pre>
+ <p>You may want to rename the 'data' field to 'session_data' as
+       'data' appears to be a reserved word for one or more of the following:
+       <ul>
+       <li>    ANSI SQL
+       <li>    IBM DB2
+       <li>    MS SQL Server
+       <li>    Postgres
+       <li>    SAP
+               </ul>
+<p>
+       If you do, then execute:
+<pre>
+               ADODB_Session::dataFieldName('session_data');
+</pre>
  <p> For the adodb-session-clob.php version, create this:
 <p>  <pre>
     <font
@@ -149,22 +153,35 @@
  </pre><p>
      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 in earlier versions of PHP.
 <h3>Notifications</h3>
-<p>If you want to receive notification when a session expires, then tag
-the session record with a <a href="#sessiontab">EXPIREREF</a> tag (see
-the definition of the sessions table above). Before any session record
-is deleted, ADOdb will call a notification function, passing in the
-EXPIREREF.
-</p>
-<p>When a session is first created, we check a global variable
-$ADODB_SESSION_EXPIRE_NOTIFY. This is an array with 2 elements, the
+<p>You can receive notification when your session is cleaned up by the session 
garbage collector or
+when you call session_destroy().
+<p>PHP's session extension will automatically run a special garbage collection 
function based on
+your php.ini session.cookie_lifetime and session.gc_probability settings. This 
will in turn call
+adodb's garbage collection function, which can be setup to do notification.
+<p>
+<pre>
+       PHP Session --> ADOdb Session  --> Find all recs  --> Send          --> 
Delete queued
+       GC Function     GC Function        to be deleted      notification      
records
+       executed at     called by                             for all recs
+       random time     Session Extension                     queued for 
deletion
+</pre>
+<p>When a session is created, we need to store a value in the session record 
(in the EXPIREREF field), typically 
+the userid of the session. Later when the session has expired,  just before 
the record is deleted,
+we reload the EXPIREREF field and call the notification function with the 
value of EXPIREREF, which 
+is the userid of the person being logged off.
+<p>ADOdb use a global variable $ADODB_SESSION_EXPIRE_NOTIFY that you must 
predefine before session
+start to store the notification configuratioin. 
+$ADODB_SESSION_EXPIRE_NOTIFY is an array with 2 elements, the
 first being the name of the session variable you would like to store in
 the EXPIREREF field, and the 2nd is the notification function's name. </p>
-<p> Suppose we want to be notified when a user's session has expired,
-based on the userid. The user id in the global session variable
-$USERID. The function name is 'NotifyFn'. So we define: </p>
+<p>For example, suppose we want to be notified when a user's session has 
expired,
+based on the userid. When the user logs in, we store the id in the global 
session variable
+$USERID. The function name is 'NotifyFn'. 
+<p>
+So we define (before session_start() is called): </p>
 <pre> <font color="#004040"><br>        $ADODB_SESSION_EXPIRE_NOTIFY = 
array('USERID','NotifyFn');<br>    </font></pre>
-And when the NotifyFn is called (when the session expires), we pass the
-$USERID as the first parameter, eg. NotifyFn($userid, $sesskey). The
+And when the NotifyFn is called (when the session expires), the
+$USERID is passed in as the first parameter, eg. NotifyFn($userid, $sesskey). 
The
 session key (which is the primary key of the record in the sessions
 table) is the 2nd parameter.
 <p> Here is an example of a Notification function that deletes some
@@ -173,7 +190,7 @@
 <p> NOTE 1: If you have register_globals disabled in php.ini, then you
 will have to manually set the EXPIREREF. E.g. </p>
 <pre> <font color="#004040">
-    $GLOBALS['USERID'] =&amp; $_SESSION['USERID'];
+    $GLOBALS['USERID'] = GetUserID();
     $ADODB_SESSION_EXPIRE_NOTIFY = array('USERID','NotifyFn');</font>
 </pre>
 <p> NOTE 2: If you want to change the EXPIREREF after the session
@@ -202,6 +219,28 @@
 <p>These are stackable. E.g.
 <p><pre>ADODB_Session::filter(new 
ADODB_Compress_Bzip2());<br>ADODB_Session::filter(new 
ADODB_Encrypt_MD5());<br></pre>
 will compress and then encrypt the record in the database.
+<h3>adodb_session_regenerate_id()</h3>
+<p>Dynamically change the current session id with a newly generated one and 
update database. Currently only
+works with cookies. Useful to improve security by reducing the risk of 
session-hijacking.
+See this article on <a 
href=http://shiflett.org/articles/security-corner-feb2004>Session Fixation</a> 
for more info 
+on the theory behind this feature. Usage:
+<pre>
+       $ADODB_SESSION_DRIVER='mysql';
+       $ADODB_SESSION_CONNECT='localhost';
+       $ADODB_SESSION_USER ='root';
+       $ADODB_SESSION_PWD ='abc';
+       $ADODB_SESSION_DB ='phplens';
+       
+       include('path/to/adodb/session/adodb-session.php');
+       
+       session_start();
+       # Every 10 page loads, reset cookie for safety.
+       # This is extremely simplistic example, better 
+       # to regenerate only when the user logs in or changes
+       # user privilege levels.
+       if ((rand()%10) == 0) adodb_session_regenerate_id(); </pre>
+<p>This function calls session_regenerate_id() internally or simulates it if 
the function does not exist.
+<h2>More Info</h2>
 <p>Also see the <a href="docs-adodb.htm">core ADOdb documentation</a>.
 </p>
 </body>

--- NEW FILE: docs-active-record.htm ---
<html>
<style>
pre {
  background-color: #eee;
  padding: 0.75em 1.5em;
  font-size: 12px;
  border: 1px solid #ddd;
}

li,p {
font-family: Arial, Helvetica, sans-serif ;
}
</style>
<title>ADOdb Active Record</title>
<body>
<h1>ADOdb Active Record</h1>
<p> (c) 2000-2006 John Lim (jlim#natsoft.com)</p>
<p><font size="1">This software is dual licensed using BSD-Style and LGPL. This 
  means you can use it in compiled proprietary and commercial 
products.</font></p>
<p><hr>
<ol>

<h3><li>Introduction</h3>
<p>
ADOdb_Active_Record is an Object Relation Mapping (ORM) implementation using 
PHP. In an ORM system, the tables and rows of the database are abstracted into 
native PHP objects. This allows the programmer to focus more on manipulating 
the data and less on writing SQL queries.
<p>
This implementation differs from Zend Framework's implementation in the 
following ways:
<ul>
<li>Works with PHP4 and PHP5 and provides equivalent functionality in both 
versions of PHP.<p>
<li>ADOdb_Active_Record works when you are connected to multiple databases. 
Zend's only works when connected to a default database.<p>
<li>Support for $ADODB_ASSOC_CASE. The field names are upper-cased, lower-cased 
or left in natural case depending on this setting.<p>
<li>No field name conversion to camel-caps style, unlike Zend's implementation 
which will convert field names such as 'first_name' to 'firstName'.<p>
<li>New ADOConnection::GetActiveRecords() and 
ADOConnection::GetActiveRecordsClass() functions in adodb.inc.php.<p>
<li>Caching of table metadata so it is only queried once per table, no matter 
how many Active Records are created.<p>
<li>The additional functionality is described <a href=#additional>below</a>. 
</ul>
<P>
ADOdb_Active_Record is designed upon the principles of the "ActiveRecord" 
design pattern, which was first described by Martin Fowler. The ActiveRecord 
pattern has been implemented in many forms across the spectrum of programming 
languages. ADOdb_Active_Record attempts to represent the database as closely to 
native PHP objects as possible.
<p>
ADOdb_Active_Record maps a database table to a PHP class, and each instance of 
that class represents a table row. Relations between tables can also be 
defined, allowing the ADOdb_Active_Record objects to be nested.
<p>

<h3><li>Setting the Database Connection</h3>
<p>
The first step to using  ADOdb_Active_Record is to set the default connection 
that an ADOdb_Active_Record objects will use to connect to a database. 

<pre>
require_once('adodb/adodb-active-record.php');

$db = new ADOConnection('mysql://root:pwd@localhost/dbname');
ADOdb_Active_Record::SetDatabaseAdapter($db);
</pre>        

<h3><li>Table Rows as Objects</h3>
<p>
First, let's create a temporary table in our MySQL database that we can use for 
demonstrative purposes throughout the rest of this tutorial. We can do this by 
sending a CREATE query:

<pre>
$db->Execute("CREATE TEMPORARY TABLE `persons` (
                `id` int(10) unsigned NOT NULL auto_increment,
                `name_first` varchar(100) NOT NULL default '',
                `name_last` varchar(100) NOT NULL default '',
                `favorite_color` varchar(100) NOT NULL default '',
                PRIMARY KEY  (`id`)
            ) ENGINE=MyISAM;
           ");
 </pre>   
<p>
ADOdb_Active_Record's are object representations of table rows. Each table in 
the database is represented by a class in PHP. To begin working with a table as 
a ADOdb_Active_Record, a class that extends ADOdb_Active_Records needs to be 
created for it.

<pre>
class Person extends ADOdb_Active_Record{}
$person = new Person();
</pre>   

<p>
In the above example, a new ADOdb_Active_Record object $person was created to 
access the "persons" table. Zend_Db_DataObject takes the name of the class, 
pluralizes it (according to American English rules), and assumes that this is 
the name of the table in the database.
<p>
This kind of behavior is typical of ADOdb_Active_Record. It will assume as much 
as possible by convention rather than explicit configuration. In situations 
where it isn't possible to use the conventions that ADOdb_Active_Record 
expects, options can be overridden as we'll see later.

<h3><li>Table Columns as Object Properties</h3>
<p>
When the $person object was instantiated, ADOdb_Active_Record read the table 
metadata from the database itself, and then exposed the table's columns 
(fields) as object properties.
<p>
Our "persons" table has three fields: "name_first", "name_last", and 
"favorite_color". Each of these fields is now a property of the $person object. 
To see all these properties, use the ADOdb_Active_Record::getAttributeNames() 
method:
<pre>
var_dump($person->getAttributeNames());

/**
 * Outputs the following:
 * array(4) {
 *    [0]=>
 *    string(2) "id"
 *    [1]=>
 *    string(9) "name_first"
 *    [2]=>
 *    string(8) "name_last"
 *    [3]=>
 *    string(13) "favorite_color"
 *  }
 */
    </pre>   
<p>
One big difference between ADOdb and Zend's implementation is we do not 
automatically convert to camelCaps style.
<p>
<h3><li>Inserting and Updating a Record</h3><p>

An ADOdb_Active_Record object is a representation of a single table row. 
However, when our $person object is instantiated, it does not reference any 
particular row. It is a blank record that does not yet exist in the database. 
An ADOdb_Active_Record object is considered blank when its primary key is NULL. 
The primary key in our persons table is "id".
<p>
To insert a new record into the database, change the object's properties and 
then call the ADOdb_Active_Record::save() method:
<pre>
$person = new Person();
$person->nameFirst = 'Andi';
$person->nameLast  = 'Gutmans';
$person->save();
 </pre>   
<p>
Oh, no! The above code snippet does not insert a new record into the database. 
Instead, outputs an error:
<pre>
1048: Column 'name_first' cannot be null
 </pre>   
<p>
This error occurred because MySQL rejected the INSERT query that was generated 
by ADOdb_Active_Record. If exceptions are enabled in ADOdb and you are using 
PHP5, an error will be thrown. In the definition of our table, we specified all 
of the fields as NOT NULL; i.e., they must contain a value.
<p>
ADOdb_Active_Records are bound by the same contraints as the database tables 
they represent. If the field in the database cannot be NULL, the corresponding 
property in the ADOdb_Active_Record also cannot be NULL. In the example above, 
we failed to set the property $person->favoriteColor, which caused the INSERT 
to be rejected by MySQL.
<p>
To insert a new ADOdb_Active_Record in the database, populate all of 
ADOdb_Active_Record's properties so that they satisfy the constraints of the 
database table, and then call the save() method:
<pre>
/**
 * Calling the save() method will successfully INSERT
 * this $person into the database table.
 */
$person = new Person();
$person->name_first     = 'Andi';
$person->name_last      = 'Gutmans';
$person->favorite_color = 'blue';
$person->save();
</pre>
<p>
Once this $person has been INSERTed into the database by calling save(), the 
primary key can now be read as a property. Since this is the first row inserted 
into our temporary table, its "id" will be 1:
<pre>
var_dump($person->id);

/**
 * Outputs the following:
 * string(1)
 */
 </pre>       
<p>
<Prev in Thread] Current Thread [Next in Thread>
Google Custom Search

Recently Viewed:
audio.irate.dev...    yellowdog.gener...    ietf.ips/2002-0...    xfree86.fonts/2...    busybox/2003-07...    emacs.jdee/2004...    linux.mandrake....    hardware.microc...    user-groups.lin...    science.analysi...    version-control...    db.filemaker.de...    cluster.openmos...    mail.eyebrowse....    text.xml.xerces...    kde.devel.kwrit...    finance.moneyda...    gcc.regression/...    network.routing...    os.freebsd.deve...    recreation.radi...    qnx.openqnx.dev...    python.xml/2002...   
Home | blog view | USPTO Patent Archive | advertise | OSDir is an inevitable website. super tiny logo

Free Magazines

Cisco News
Receive a free quarterly e-newsletter with exclusive articles on how Cisco IT uses its own products and solutions to enable the business.
subscribe

Systems Management News, the newspaper for IT systems administration and data center managers! Each issue of Systems Management News is chock-full of news and analysis to help you understand what's happening in your field.
subscribe

The Enterprise Newsweekly eWeek is the essential technology information source for builders of e-business.
subscribe

Oracle Magazine Oracle Magazine contains technology strategy articles, sample code, tips, Oracle and partner news, how to articles for developers and DBAs, and more. Oracle (NASDAQ: ORCL) is the world's largest enterprise software company.
subscribe

Total Telecom Total Telecom is "The Economist of the communications industry".
subscribe