Documentation TYPO3 par Ameos

adodb-active-record.inc.php

00001 <?php
00002 /*
00003 
00004 @version V4.80 8 Mar 2006  (c) 2000-2006 John Lim (jlim#natsoft.com.my). All rights reserved.
00005   Latest version is available at http://adodb.sourceforge.net
00006  
00007   Released under both BSD license and Lesser GPL library license. 
00008   Whenever there is any discrepancy between the two licenses, 
00009   the BSD license will take precedence.
00010   
00011   Active Record implementation. Superset of Zend Framework's.
00012   
00013   Version 0.02
00014 */
00015 
00016 global $_ADODB_ACTIVE_DBS;
00017 
00018 // array of ADODB_Active_DB's, indexed by ADODB_Active_Record->_dbat
00019 $_ADODB_ACTIVE_DBS = array();
00020 
00021 
00022 class ADODB_Active_DB {
00023         var $db; // ADOConnection
00024         var $tables; // assoc array of ADODB_Active_Table objects, indexed by tablename
00025 }
00026 
00027 class ADODB_Active_Table {
00028         var $name; // table name
00029         var $flds; // assoc array of adofieldobjs, indexed by fieldname
00030         var $keys; // assoc array of primary keys, indexed by fieldname
00031 }
00032 
00033 // returns index into $_ADODB_ACTIVE_DBS
00034 function ADODB_SetDatabaseAdapter(&$db)
00035 {
00036         global $_ADODB_ACTIVE_DBS;
00037         
00038                 foreach($_ADODB_ACTIVE_DBS as $k => $d) {
00039                         if ($d->db == $db) return $k;
00040                 }
00041                 
00042                 $obj = new ADODB_Active_DB();
00043                 $obj->db =& $db;
00044                 $obj->tables = array();
00045                 
00046                 $_ADODB_ACTIVE_DBS[] = $obj;
00047                 
00048                 return sizeof($_ADODB_ACTIVE_DBS)-1;
00049 }
00050 
00051 class ADODB_Active_Record {
00052         var $_dbat; // associative index pointing to ADODB_Active_DB eg. $ADODB_Active_DBS[_dbat]
00053         var $_table; // tablename
00054         var $_tableat; // associative index pointing to ADODB_Active_Table, eg $ADODB_Active_DBS[_dbat]->tables[$this->_tableat]
00055         var $_where; // where clause set in Load()
00056         var $_saved = false; // indicates whether data is already inserted.
00057         var $_lasterr = false; // last error message
00058         
00059         // should be static
00060         function SetDatabaseAdapter(&$db) 
00061         {
00062                 return ADODB_SetDatabaseAdapter($db);
00063         }
00064         
00065         // php4 constructor
00066         function ADODB_Active_Record($table = false, $pkeyarr=false, $db=false)
00067         {
00068                 ADODB_Active_Record::__construct($table,$pkeyarr,$db);
00069         }
00070         
00071         // php5 constructor
00072         function __construct($table = false, $pkeyarr=false, $db=false)
00073         {
00074         global $ADODB_ASSOC_CASE,$_ADODB_ACTIVE_DBS;
00075         
00076                 if ($db == false && is_object($pkeyarr)) {
00077                         $db = $pkeyarr;
00078                         $pkeyarr = false;
00079                 }
00080                 
00081                 if (!$table) $table = $this->_pluralize(get_class($this));
00082                 
00083                 if ($db) {
00084                         $this->_dbat = ADODB_Active_Record::SetDatabaseAdapter($db);
00085                 } else
00086                         $this->_dbat = sizeof($_ADODB_ACTIVE_DBS)-1;
00087                 
00088                 
00089                 if ($this->_dbat < 0) $this->Error("No database connection set; use ADOdb_Active_Record::SetDatabaseAdapter(\$db)",'ADODB_Active_Record::__constructor');
00090                 
00091                 $this->_table = $table;
00092                 $this->_tableat = $table; # reserved for setting the assoc value to a non-table name, eg. the sql string in future
00093                 $this->UpdateActiveTable($pkeyarr);
00094         }
00095         
00096         function _pluralize($table)
00097         {
00098                 $ut = strtoupper($table);
00099                 $len = strlen($table);
00100                 $lastc = $ut[$len-1];
00101                 $lastc2 = substr($ut,$len-2);
00102                 switch ($lastc) {
00103                 case 'S':
00104                         return $table.'es';     
00105                 case 'Y':
00106                         return substr($table,0,$len-1).'ies';
00107                 case 'X':       
00108                         return $table.'es';
00109                 case 'H': 
00110                         if ($lastc2 == 'CH' || $lastc2 == 'SH')
00111                                 return $table.'es';
00112                 default:
00113                         return $table.'s';
00114                 }
00115         }
00116         
00118         
00119         // update metadata
00120         function UpdateActiveTable($pkeys=false,$forceUpdate=false)
00121         {
00122         global $ADODB_ASSOC_CASE,$_ADODB_ACTIVE_DBS;
00123         
00124                 $activedb =& $_ADODB_ACTIVE_DBS[$this->_dbat];
00125 
00126                 $table = $this->_table;
00127                 $tables = $activedb->tables;
00128                 $tableat = $this->_tableat;
00129                 if (!$forceUpdate && !empty($tables[$tableat])) {
00130                         $tobj =& $tables[$tableat];
00131                         foreach($tobj->flds as $name => $fld) 
00132                                 $this->$name = null;
00133                         return;
00134                 }
00135                 
00136                 $activetab = new ADODB_Active_Table();
00137                 $activetab->name = $table;
00138                 
00139                 $db =& $activedb->db;
00140                 
00141                 $cols = $db->MetaColumns($table);
00142                 if (!$cols) {
00143                         $this->Error("Invalid table name: $table",'UpdateActiveTable'); 
00144                         return false;
00145                 }
00146                 $fld = reset($cols);
00147                 if (!$pkeys) {
00148                         if (isset($fld->primary_key)) {
00149                                 $pkeys = array();
00150                                 foreach($cols as $name => $fld) {
00151                                         if (!empty($fld->primary_key)) $pkeys[] = $name;
00152                                 }
00153                         } else  
00154                                 $pkeys = $this->GetPrimaryKeys($db, $table);
00155                 }
00156                 if (empty($pkeys)) {
00157                         $this->Error("No primary key found for table $table",'UpdateActiveTable');
00158                         return false;
00159                 }
00160                 
00161                 $attr = array();
00162                 $keys = array();
00163                 
00164                 switch($ADODB_ASSOC_CASE) {
00165                 case 0:
00166                         foreach($cols as $name => $fldobj) {
00167                                 $name = strtolower($name);
00168                                 $this->$name = null;
00169                                 $attr[$name] = $fldobj;
00170                         }
00171                         foreach($pkeys as $k => $name) {
00172                                 $keys[strtolower($name)] = strtolower($name);
00173                         }
00174                         break;
00175                         
00176                 case 1: 
00177                         foreach($cols as $name => $fldobj) {
00178                                 $name = strtoupper($name);
00179                                 $this->$name = null;
00180                                 $attr[$name] = $fldobj;
00181                         }
00182                         
00183                         foreach($pkeys as $k => $name) {
00184                                 $keys[strtoupper($name)] = strtoupper($name);
00185                         }
00186                         break;
00187                 default:
00188                         foreach($cols as $name => $fldobj) {
00189                                 $name = ($name);
00190                                 $this->$name = null;
00191                                 $attr[$name] = $fldobj;
00192                         }
00193                         foreach($pkeys as $k => $name) {
00194                                 $keys[$name] = ($name);
00195                         }
00196                         break;
00197                 }
00198                 
00199                 $activetab->keys = $keys;
00200                 $activetab->flds = $attr;
00201                 $activedb->tables[$table] = $activetab;
00202         }
00203         
00204         function GetPrimaryKeys(&$db, $table)
00205         {
00206                 return $db->MetaPrimaryKeys($table);
00207         }
00208         
00209         // error handler for both PHP4+5. 
00210         function Error($err,$fn)
00211         {
00212         global $_ADODB_ACTIVE_DBS;
00213         
00214                 $fn = get_class($this).'::'.$fn;
00215                 $this->_lasterr = $fn.': '.$err;
00216                 
00217                 if ($this->_dbat < 0) $db = false;
00218                 else {
00219                         $activedb = $_ADODB_ACTIVE_DBS[$this->_dbat];
00220                         $db =& $activedb->db;
00221                 }
00222                 
00223                 if (function_exists('adodb_throw')) {   
00224                         if (!$db) adodb_throw('ADOdb_Active_Record', $fn, -1, $err, 0, 0, false);
00225                         else adodb_throw($db->databaseType, $fn, -1, $err, 0, 0, $db);
00226                 } else
00227                         if (!$db || $db->debug) ADOConnection::outp($this->_lasterr);
00228                 
00229         }
00230         
00231         // return last error message
00232         function ErrorMsg()
00233         {
00234                 if (!function_exists('adodb_throw')) {
00235                         if ($this->_dbat < 0) $db = false;
00236                         else $db = $this->DB();
00237                 
00238                         // last error could be database error too
00239                         if ($db && $db->ErrorMsg()) return $db->ErrorMsg();
00240                 }
00241                 return $this->_lasterr;
00242         }
00243         
00244         // retrieve ADOConnection from _ADODB_Active_DBs
00245         function &DB()
00246         {
00247         global $_ADODB_ACTIVE_DBS;
00248         
00249                 if ($this->_dbat < 0) {
00250                         $false = false;
00251                         $this->Error("No database connection set: use ADOdb_Active_Record::SetDatabaseAdaptor(\$db)", "DB");
00252                         return $false;
00253                 }
00254                 $activedb = $_ADODB_ACTIVE_DBS[$this->_dbat];
00255                 $db =& $activedb->db;
00256                 return $db;
00257         }
00258         
00259         // retrieve ADODB_Active_Table
00260         function &TableInfo()
00261         {
00262         global $_ADODB_ACTIVE_DBS;
00263         
00264                 $activedb = $_ADODB_ACTIVE_DBS[$this->_dbat];
00265                 $table =& $activedb->tables[$this->_tableat];
00266                 return $table;
00267         }
00268         
00269         // set a numeric array (using natural table field ordering) as object properties
00270         function Set(&$row)
00271         {
00272                 $db =& $this->DB();
00273                 
00274                 if (!$row) {
00275                         $this->_saved = false;          
00276                         return false;
00277                 }
00278                 
00279                 $this->_saved = true;
00280                 
00281                 $table =& $this->TableInfo();
00282                 if (sizeof($table->flds) != sizeof($row)) {
00283                         $this->Error("Table structure of $this->_table has changed","Load");
00284                         return false;
00285                 }
00286                 
00287                 $cnt = 0;
00288                 foreach($table->flds as $name=>$fld) {
00289                         $this->$name = $row[$cnt];
00290                         $cnt += 1;
00291                 }
00292                 #$this->_original =& $row;
00293                 return true;
00294         }
00295         
00296         // get last inserted id for INSERT
00297         function LastInsertID(&$db,$fieldname)
00298         {
00299                 if ($db->hasInsertID)
00300                         $val = $db->Insert_ID($this->_table,$fieldname);
00301                 else
00302                         $val = false;
00303                         
00304                 if (is_null($val) || $val === false) {
00305                         // this might not work reliably in multi-user environment
00306                         return $db->GetOne("select max(".$fieldname.") from ".$this->_table);
00307                 }
00308                 return $val;
00309         }
00310         
00311         // quote data in where clause
00312         function doquote(&$db, $val,$t)
00313         {
00314                 switch($t) {
00315                 case 'D':
00316                 case 'T':
00317                         if (empty($val)) return 'null';
00318                         
00319                 case 'C':
00320                 case 'X':
00321                         if (is_null($val)) return 'null';
00322                         
00323                         if (strncmp($val,"'",1) != 0 && substr($val,strlen($val)-1,1) != "'") { 
00324                                 return $db->qstr($val);
00325                                 break;
00326                         }
00327                 default:
00328                         return $val;
00329                         break;
00330                 }
00331         }
00332         
00333         // generate where clause for an UPDATE/SELECT
00334         function GenWhere(&$db, &$table)
00335         {
00336                 $keys = $table->keys;
00337                 $parr = array();
00338                 
00339                 foreach($keys as $k) {
00340                         $f = $table->flds[$k];
00341                         if ($f) {
00342                                 $parr[] = $k.' = '.$this->doquote($db,$this->$k,$db->MetaType($f->type));
00343                         }
00344                 }
00345                 return implode(' and ', $parr);
00346         }
00347         
00348         
00349         //------------------------------------------------------------ Public functions below
00350         
00351         function Load($where,$bindarr=false)
00352         {
00353                 $db =& $this->DB(); if (!$db) return false;
00354                 $this->_where = $where;
00355                 
00356                 $save = $db->SetFetchMode(ADODB_FETCH_NUM);
00357                 $row = $db->GetRow("select * from ".$this->_table.' WHERE '.$where,$bindarr);
00358                 $db->SetFetchMode($save);
00359                 
00360                 return $this->Set($row);
00361         }
00362         
00363         // false on error
00364         function Save()
00365         {
00366                 if ($this->_saved) $ok = $this->Update();
00367                 else $ok = $this->Insert();
00368                 
00369                 return $ok;
00370         }
00371         
00372         // false on error
00373         function Insert()
00374         {
00375                 $db =& $this->DB(); if (!$db) return false;
00376                 $cnt = 0;
00377                 $table =& $this->TableInfo();
00378 
00379                 foreach($table->flds as $name=>$fld) {
00380                         $val = $this->$name;
00381                         /*
00382                         if (is_null($val)) {
00383                                 if (isset($fld->not_null) && $fld->not_null) {
00384                                         if (isset($fld->default_value) && strlen($fld->default_value)) continue;
00385                                         else $this->Error("Cannot insert null into $name","Insert");
00386                                 }
00387                         }*/
00388                         
00389                         $valarr[] = $val;
00390                         $names[] = $name;
00391                         $valstr[] = $db->Param($cnt);
00392                         $cnt += 1;
00393                 }
00394                 
00395                 $sql = 'INSERT INTO '.$this->_table."(".implode(',',$names).') VALUES ('.implode(',',$valstr).')';
00396                 $ok = $db->Execute($sql,$valarr);
00397                 
00398                 if ($ok) {
00399                         $this->_saved = true;
00400                         $autoinc = false;
00401                         foreach($table->keys as $k) {
00402                                 if (is_null($this->$k)) {
00403                                         $autoinc = true;
00404                                         break;
00405                                 }
00406                         }
00407                         if ($autoinc && sizeof($table->keys) == 1) {
00408                                 $k = reset($table->keys);
00409                                 $this->$k = $this->LastInsertID($db,$k);
00410                         }
00411                 }
00412                 
00413                 #$this->_original =& $valarr;
00414                 return !empty($ok);
00415         }
00416         
00417         function Delete()
00418         {
00419                 $db =& $this->DB(); if (!$db) return false;
00420                 $table =& $this->TableInfo();
00421                 
00422                 $where = $this->GenWhere($db,$table);
00423                 $sql = 'DELETE FROM '.$this->_table.' WHERE '.$where;
00424                 $db->Execute($sql);
00425         }
00426         
00427         
00428         // returns 0 on error, 1 on update, 2 on insert
00429         function Replace()
00430         {
00431         global $ADODB_ASSOC_CASE;
00432                 
00433                 $db =& $this->DB(); if (!$db) return false;
00434                 $table =& $this->TableInfo();
00435                 
00436                 $pkey = $table->keys;
00437                 
00438                 foreach($table->flds as $name=>$fld) {
00439                         $val = $this->$name;
00440                         /*
00441                         if (is_null($val)) {
00442                                 if (isset($fld->not_null) && $fld->not_null) {
00443                                         if (isset($fld->default_value) && strlen($fld->default_value)) continue;
00444                                         else {
00445                                                 $this->Error("Cannot update null into $name","Replace");
00446                                                 return false;
00447                                         }
00448                                 }
00449                         }*/
00450                         $t = $db->MetaType($fld->type);
00451                         $arr[$name] = $this->doquote($db,$val,$t);
00452                         $valarr[] = $val;
00453                 }
00454                 
00455                 if (!is_array($pkey)) $pkey = array($pkey);
00456                 
00457                 
00458                 if ($ADODB_ASSOC_CASE == 0) 
00459                         foreach($pkey as $k => $v)
00460                                 $pkey[$k] = strtolower($v);
00461                 elseif ($ADODB_ASSOC_CASE == 0) 
00462                         foreach($pkey as $k => $v)
00463                                 $pkey[$k] = strtoupper($v);
00464                                 
00465                 $ok = $db->Replace($this->_table,$arr,$pkey);
00466                 if ($ok) {
00467                         $this->_saved = true; // 1= update 2=insert
00468                         if ($ok == 2) {
00469                                 $autoinc = false;
00470                                 foreach($table->keys as $k) {
00471                                         if (is_null($this->$k)) {
00472                                                 $autoinc = true;
00473                                                 break;
00474                                         }
00475                                 }
00476                                 if ($autoinc && sizeof($table->keys) == 1) {
00477                                         $k = reset($table->keys);
00478                                         $this->$k = $this->LastInsertID($db,$k);
00479                                 }
00480                         }
00481                         
00482                         #$this->_original =& $valarr;
00483                 } 
00484                 return $ok;
00485         }
00486 
00487         // returns false on error
00488         function Update()
00489         {
00490                 $db =& $this->DB(); if (!$db) return false;
00491                 $table =& $this->TableInfo();
00492                 
00493                 $where = $this->GenWhere($db, $table);
00494                 
00495                 if (!$where) {
00496                         $this->error("Where missing for table $table", "Update");
00497                         return false;
00498                 }
00499                 $cnt = 0;
00500                 foreach($table->flds as $name=>$fld) {
00501                         if (isset($table->keys[$name])) continue;
00502                         
00503                         $val = $this->$name;
00504                         
00505                         if (is_null($val)) {
00506                                 if (isset($fld->not_null) && $fld->not_null) {
00507                                         if (isset($fld->default_value) && strlen($fld->default_value)) continue;
00508                                         else {
00509                                                 $this->Error("Cannot set field $name to NULL","Update");
00510                                                 return false;
00511                                         }
00512                                 }
00513                         }
00514                         $valarr[] = $val;
00515                         $pairs[] = $name.'='.$db->Param($cnt);
00516                         $cnt += 1;
00517                 }
00518                 
00519                 #$this->_original =& $valarr;
00520                 
00521                 $sql = 'UPDATE '.$this->_table." SET ".implode(",",$pairs)." WHERE ".$where;
00522                 $ok = $db->Execute($sql,$valarr);
00523                 
00524                 return !empty($ok);
00525         }
00526         
00527         function GetAttributeNames()
00528         {
00529                 $table =& $this->TableInfo();
00530                 if (!$table) return false;
00531                 return array_keys($table->flds);
00532         }
00533         
00534 };
00535 
00536 ?>


Généré par TYPO3 Ameos avec  doxygen 1.4.6