Esempio n. 1
0
 public function _connect()
 {
     // avoid those annoying PEAR::DB strict standards warnings it causes
     $old = error_reporting();
     error_reporting(error_reporting() & ~E_STRICT);
     $res = parent::_connect();
     // reset
     error_reporting($old);
     return $res;
 }
Esempio n. 2
0
 /**
  * joinAdd - adds another dataobject to this, building a joined query.
  *
  * example (requires links.ini to be set up correctly)
  * // get all the images for product 24
  * $i = new DataObject_Image();
  * $pi = new DataObjects_Product_image();
  * $pi->product_id = 24; // set the product id to 24
  * $i->joinAdd($pi); // add the product_image connectoin
  * $i->find();
  * while ($i->fetch()) {
  *     // do stuff
  * }
  * // an example with 2 joins
  * // get all the images linked with products or productgroups
  * $i = new DataObject_Image();
  * $pi = new DataObject_Product_image();
  * $pgi = new DataObject_Productgroup_image();
  * $i->joinAdd($pi);
  * $i->joinAdd($pgi);
  * $i->find();
  * while ($i->fetch()) {
  *     // do stuff
  * }
  *
  *
  * @param    optional $obj       object |array    the joining object (no value resets the join)
  *                                          If you use an array here it should be in the format:
  *                                          array('local_column','remotetable:remote_column');
  *                                          if remotetable does not have a definition, you should
  *                                          use @ to hide the include error message..
  *                                      
  *
  * @param    optional $joinType  string | array
  *                                          'LEFT'|'INNER'|'RIGHT'|'' Inner is default, '' indicates 
  *                                          just select ... from a,b,c with no join and 
  *                                          links are added as where items.
  *                                          
  *                                          If second Argument is array, it is assumed to be an associative
  *                                          array with arguments matching below = eg.
  *                                          'joinType' => 'INNER',
  *                                          'joinAs' => '...'
  *                                          'joinCol' => ....
  *                                          'useWhereAsOn' => false,
  *
  * @param    optional $joinAs    string     if you want to select the table as anther name
  *                                          useful when you want to select multiple columsn
  *                                          from a secondary table.
  * @param    optional $joinCol   string     The column on This objects table to match (needed
  *                                          if this table links to the child object in 
  *                                          multiple places eg.
  *                                          user->friend (is a link to another user)
  *                                          user->mother (is a link to another user..)
  *
  *           optional 'useWhereAsOn' bool   default false;
  *                                          convert the where argments from the object being added
  *                                          into ON arguments.
  * 
  * 
  * @return   none
  * @access   public
  * @author   Stijn de Reede      <*****@*****.**>
  */
 function joinAdd($obj = false, $joinType = 'INNER', $joinAs = false, $joinCol = false)
 {
     global $_DB_DATAOBJECT;
     if ($obj === false) {
         $this->_join = '';
         return;
     }
     //echo '<PRE>'; print_r(func_get_args());
     $useWhereAsOn = false;
     // support for 2nd argument as an array of options
     if (is_array($joinType)) {
         // new options can now go in here... (dont forget to document them)
         $useWhereAsOn = !empty($joinType['useWhereAsOn']);
         $joinCol = isset($joinType['joinCol']) ? $joinType['joinCol'] : $joinCol;
         $joinAs = isset($joinType['joinAs']) ? $joinType['joinAs'] : $joinAs;
         $joinType = isset($joinType['joinType']) ? $joinType['joinType'] : 'INNER';
     }
     // support for array as first argument
     // this assumes that you dont have a links.ini for the specified table.
     // and it doesnt exist as am extended dataobject!! - experimental.
     $ofield = false;
     // object field
     $tfield = false;
     // this field
     $toTable = false;
     if (is_array($obj)) {
         $tfield = $obj[0];
         list($toTable, $ofield) = explode(':', $obj[1]);
         $obj = DB_DataObject::factory($toTable);
         if (!$obj || is_a($obj, 'PEAR_Error')) {
             $obj = new DB_DataObject();
             $obj->__table = $toTable;
         }
         $obj->_connect();
         // set the table items to nothing.. - eg. do not try and match
         // things in the child table...???
         $items = array();
     }
     if (!is_object($obj) || !is_a($obj, 'DB_DataObject')) {
         return $this->raiseError("joinAdd: called without an object", DB_DATAOBJECT_ERROR_NODATA, PEAR_ERROR_DIE);
     }
     /*  make sure $this->_database is set.  */
     $this->_connect();
     $DB =& $_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5];
     /// CHANGED 26 JUN 2009 - we prefer links from our local table over the remote one.
     /* otherwise see if there are any links from this table to the obj. */
     //print_r($this->links());
     if ($ofield === false && ($links = $this->links())) {
         foreach ($links as $k => $v) {
             /* link contains {this column} = {linked table}:{linked column} */
             $ar = explode(':', $v);
             // Feature Request #4266 - Allow joins with multiple keys
             if (strpos($k, ',') !== false) {
                 $k = explode(',', $k);
             }
             if (strpos($ar[1], ',') !== false) {
                 $ar[1] = explode(',', $ar[1]);
             }
             if ($ar[0] == $obj->__table) {
                 if ($joinCol !== false) {
                     if ($k == $joinCol) {
                         $tfield = $k;
                         $ofield = $ar[1];
                         break;
                     } else {
                         continue;
                     }
                 } else {
                     $tfield = $k;
                     $ofield = $ar[1];
                     break;
                 }
             }
         }
     }
     /* look up the links for obj table */
     //print_r($obj->links());
     if (!$ofield && ($olinks = $obj->links())) {
         foreach ($olinks as $k => $v) {
             /* link contains {this column} = {linked table}:{linked column} */
             $ar = explode(':', $v);
             // Feature Request #4266 - Allow joins with multiple keys
             $links_key_array = strpos($k, ',');
             if ($links_key_array !== false) {
                 $k = explode(',', $k);
             }
             $ar_array = strpos($ar[1], ',');
             if ($ar_array !== false) {
                 $ar[1] = explode(',', $ar[1]);
             }
             if ($ar[0] == $this->__table) {
                 // you have explictly specified the column
                 // and the col is listed here..
                 // not sure if 1:1 table could cause probs here..
                 if ($joinCol !== false) {
                     $this->raiseError("joinAdd: You cannot target a join column in the " . "'link from' table ({$obj->__table}). " . "Either remove the fourth argument to joinAdd() " . "({$joinCol}), or alter your links.ini file.", DB_DATAOBJECT_ERROR_NODATA);
                     return false;
                 }
                 $ofield = $k;
                 $tfield = $ar[1];
                 break;
             }
         }
     }
     // finally if these two table have column names that match do a join by default on them
     if ($ofield === false && $joinCol) {
         $ofield = $joinCol;
         $tfield = $joinCol;
     }
     /* did I find a conneciton between them? */
     if ($ofield === false) {
         $this->raiseError("joinAdd: {$obj->__table} has no link with {$this->__table}", DB_DATAOBJECT_ERROR_NODATA);
         return false;
     }
     $joinType = strtoupper($joinType);
     // we default to joining as the same name (this is remvoed later..)
     if ($joinAs === false) {
         $joinAs = $obj->__table;
     }
     $quoteIdentifiers = !empty($_DB_DATAOBJECT['CONFIG']['quote_identifiers']);
     $options = $_DB_DATAOBJECT['CONFIG'];
     // not sure  how portable adding database prefixes is..
     $objTable = $quoteIdentifiers ? $DB->quoteIdentifier($obj->__table) : $obj->__table;
     $dbPrefix = '';
     if (strlen($obj->_database) && in_array($DB->dsn['phptype'], array('mysql', 'mysqli'))) {
         $dbPrefix = ($quoteIdentifiers ? $DB->quoteIdentifier($obj->_database) : $obj->_database) . '.';
     }
     // if they are the same, then dont add a prefix...
     if ($obj->_database == $this->_database) {
         $dbPrefix = '';
     }
     // as far as we know only mysql supports database prefixes..
     // prefixing the database name is now the default behaviour,
     // as it enables joining mutiple columns from multiple databases...
     // prefix database (quoted if neccessary..)
     $objTable = $dbPrefix . $objTable;
     $cond = '';
     // if obj only a dataobject - eg. no extended class has been defined..
     // it obvioulsy cant work out what child elements might exist...
     // until we get on the fly querying of tables..
     // note: we have already checked that it is_a(db_dataobject earlier)
     if (strtolower(get_class($obj)) != 'db_dataobject') {
         // now add where conditions for anything that is set in the object
         $items = $obj->table();
         // will return an array if no items..
         // only fail if we where expecting it to work (eg. not joined on a array)
         if (!$items) {
             $this->raiseError("joinAdd: No table definition for {$obj->__table}", DB_DATAOBJECT_ERROR_INVALIDCONFIG);
             return false;
         }
         $ignore_null = !isset($options['disable_null_strings']) || !is_string($options['disable_null_strings']) || strtolower($options['disable_null_strings']) !== 'full';
         foreach ($items as $k => $v) {
             if (!isset($obj->{$k}) && $ignore_null) {
                 continue;
             }
             $kSql = $quoteIdentifiers ? $DB->quoteIdentifier($k) : $k;
             if (DB_DataObject::_is_null($obj, $k)) {
                 $obj->whereAdd("{$joinAs}.{$kSql} IS NULL");
                 continue;
             }
             if ($v & DB_DATAOBJECT_STR) {
                 $obj->whereAdd("{$joinAs}.{$kSql} = " . $this->_quote((string) ($v & DB_DATAOBJECT_BOOL ? $obj->{$k} === 'f' ? 0 : (int) (bool) $obj->{$k} : $obj->{$k})));
                 continue;
             }
             if (is_numeric($obj->{$k})) {
                 $obj->whereAdd("{$joinAs}.{$kSql} = {$obj->{$k}}");
                 continue;
             }
             if (is_a($obj->{$k}, 'DB_DataObject_Cast')) {
                 $value = $obj->{$k}->toString($v, $DB);
                 if (PEAR::isError($value)) {
                     $this->raiseError($value->getMessage(), DB_DATAOBJECT_ERROR_INVALIDARG);
                     return false;
                 }
                 $obj->whereAdd("{$joinAs}.{$kSql} = {$value}");
                 continue;
             }
             /* this is probably an error condition! */
             $obj->whereAdd("{$joinAs}.{$kSql} = 0");
         }
         if ($this->_query === false) {
             $this->raiseError("joinAdd can not be run from a object that has had a query run on it,\n                    clone the object or create a new one and use setFrom()", DB_DATAOBJECT_ERROR_INVALIDARGS);
             return false;
         }
     }
     // and finally merge the whereAdd from the child..
     if ($obj->_query['condition']) {
         $cond = preg_replace('/^\\sWHERE/i', '', $obj->_query['condition']);
         if (!$useWhereAsOn) {
             $this->whereAdd($cond);
         }
     }
     // nested (join of joined objects..)
     $appendJoin = '';
     if ($obj->_join) {
         // postgres allows nested queries, with ()'s
         // not sure what the results are with other databases..
         // may be unpredictable..
         if (in_array($DB->dsn["phptype"], array('pgsql'))) {
             $objTable = "({$objTable} {$obj->_join})";
         } else {
             $appendJoin = $obj->_join;
         }
     }
     // fix for #2216
     // add the joinee object's conditions to the ON clause instead of the WHERE clause
     if ($useWhereAsOn && strlen($cond)) {
         $appendJoin = ' AND ' . $cond . ' ' . $appendJoin;
     }
     $table = $this->__table;
     if ($quoteIdentifiers) {
         $joinAs = $DB->quoteIdentifier($joinAs);
         $table = $DB->quoteIdentifier($table);
         $ofield = is_array($ofield) ? array_map(array($DB, 'quoteIdentifier'), $ofield) : $DB->quoteIdentifier($ofield);
         $tfield = is_array($tfield) ? array_map(array($DB, 'quoteIdentifier'), $tfield) : $DB->quoteIdentifier($tfield);
     }
     // add database prefix if they are different databases
     $fullJoinAs = '';
     $addJoinAs = ($quoteIdentifiers ? $DB->quoteIdentifier($obj->__table) : $obj->__table) != $joinAs;
     if ($addJoinAs) {
         // join table a AS b - is only supported by a few databases and is probably not needed
         // , however since it makes the whole Statement alot clearer we are leaving it in
         // for those databases.
         $fullJoinAs = in_array($DB->dsn["phptype"], array('mysql', 'mysqli', 'pgsql')) ? "AS {$joinAs}" : $joinAs;
     } else {
         // if
         $joinAs = $dbPrefix . $joinAs;
     }
     switch ($joinType) {
         case 'INNER':
         case 'LEFT':
         case 'RIGHT':
             // others??? .. cross, left outer, right outer, natural..?
             // Feature Request #4266 - Allow joins with multiple keys
             $jadd = "\n {$joinType} JOIN {$objTable} {$fullJoinAs}";
             //$this->_join .= "\n {$joinType} JOIN {$objTable} {$fullJoinAs}";
             if (is_array($ofield)) {
                 $key_count = count($ofield);
                 for ($i = 0; $i < $key_count; $i++) {
                     if ($i == 0) {
                         $jadd .= " ON ({$joinAs}.{$ofield[$i]}={$table}.{$tfield[$i]}) ";
                     } else {
                         $jadd .= " AND {$joinAs}.{$ofield[$i]}={$table}.{$tfield[$i]} ";
                     }
                 }
                 $jadd .= ' ' . $appendJoin . ' ';
             } else {
                 $jadd .= " ON ({$joinAs}.{$ofield}={$table}.{$tfield}) {$appendJoin} ";
             }
             // jadd avaliable for debugging join build.
             //echo $jadd ."\n";
             $this->_join .= $jadd;
             break;
         case '':
             // this is just a standard multitable select..
             $this->_join .= "\n , {$objTable} {$fullJoinAs} {$appendJoin}";
             $this->whereAdd("{$joinAs}.{$ofield}={$table}.{$tfield}");
     }
     return true;
 }
Esempio n. 3
0
 /**
  * joinAdd - adds another dataobject to this, building a joined query.
  *
  * example (requires links.ini to be set up correctly)
  * // get all the images for product 24
  * $i = new DataObject_Image();
  * $pi = new DataObjects_Product_image();
  * $pi->product_id = 24; // set the product id to 24
  * $i->joinAdd($pi); // add the product_image connectoin
  * $i->find();
  * while ($i->fetch()) {
  *     // do stuff
  * }
  * // an example with 2 joins
  * // get all the images linked with products or productgroups
  * $i = new DataObject_Image();
  * $pi = new DataObject_Product_image();
  * $pgi = new DataObject_Productgroup_image();
  * $i->joinAdd($pi);
  * $i->joinAdd($pgi);
  * $i->find();
  * while ($i->fetch()) {
  *     // do stuff
  * }
  *
  *
  * @param    optional $obj       object |array    the joining object (no value resets the join)
  *                                          If you use an array here it should be in the format:
  *                                          array('local_column','remotetable:remote_column');
  *                                          if remotetable does not have a definition, you should
  *                                          use @ to hide the include error message..
  *                                      
  *
  * @param    optional $joinType  string     'LEFT'|'INNER'|'RIGHT'|'' Inner is default, '' indicates 
  *                                          just select ... from a,b,c with no join and 
  *                                          links are added as where items.
  *
  * @param    optional $joinAs    string     if you want to select the table as anther name
  *                                          useful when you want to select multiple columsn
  *                                          from a secondary table.
  * @param    optional $joinCol   string     The column on This objects table to match (needed
  *                                          if this table links to the child object in 
  *                                          multiple places eg.
  *                                          user->friend (is a link to another user)
  *                                          user->mother (is a link to another user..)
  *
  * @return   none
  * @access   public
  * @author   Stijn de Reede      <*****@*****.**>
  */
 function joinAdd($obj = false, $joinType = 'INNER', $joinAs = false, $joinCol = false)
 {
     global $_DB_DATAOBJECT;
     if ($obj === false) {
         $this->_join = '';
         return;
     }
     // support for array as first argument
     // this assumes that you dont have a links.ini for the specified table.
     // and it doesnt exist as am extended dataobject!! - experimental.
     $ofield = false;
     // object field
     $tfield = false;
     // this field
     $toTable = false;
     if (is_array($obj)) {
         $tfield = $obj[0];
         list($toTable, $ofield) = explode(':', $obj[1]);
         $obj = DB_DataObject::factory($toTable);
         if (!$obj || is_a($obj, 'PEAR_Error')) {
             $obj = new DB_DataObject();
             $obj->__table = $toTable;
         }
         $obj->_connect();
         // set the table items to nothing.. - eg. do not try and match
         // things in the child table...???
         $items = array();
     }
     if (!is_object($obj)) {
         $this->raiseError("joinAdd: called without an object", DB_DATAOBJECT_ERROR_NODATA, PEAR_ERROR_DIE);
     }
     /*  make sure $this->_database is set.  */
     $this->_connect();
     $DB =& $_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5];
     /* look up the links for obj table */
     //print_r($obj->links());
     if (!$ofield && ($olinks = $obj->links())) {
         foreach ($olinks as $k => $v) {
             /* link contains {this column} = {linked table}:{linked column} */
             $ar = explode(':', $v);
             if ($ar[0] == $this->__table) {
                 // you have explictly specified the column
                 // and the col is listed here..
                 // not sure if 1:1 table could cause probs here..
                 if ($joinCol !== false) {
                     $this->raiseError("joinAdd: You cannot target a join column in the " . "'link from' table ({$obj->__table}). " . "Either remove the fourth argument to joinAdd() " . "({$joinCol}), or alter your links.ini file.", DB_DATAOBJECT_ERROR_NODATA);
                     return false;
                 }
                 $ofield = $k;
                 $tfield = $ar[1];
                 break;
             }
         }
     }
     /* otherwise see if there are any links from this table to the obj. */
     //print_r($this->links());
     if ($ofield === false && ($links = $this->links())) {
         foreach ($links as $k => $v) {
             /* link contains {this column} = {linked table}:{linked column} */
             $ar = explode(':', $v);
             if ($ar[0] == $obj->__table) {
                 if ($joinCol !== false) {
                     if ($k == $joinCol) {
                         $tfield = $k;
                         $ofield = $ar[1];
                         break;
                     } else {
                         continue;
                     }
                 } else {
                     $tfield = $k;
                     $ofield = $ar[1];
                     break;
                 }
             }
         }
     }
     /* did I find a conneciton between them? */
     if ($ofield === false) {
         $this->raiseError("joinAdd: {$obj->__table} has no link with {$this->__table}", DB_DATAOBJECT_ERROR_NODATA);
         return false;
     }
     $joinType = strtoupper($joinType);
     // we default to joining as the same name (this is remvoed later..)
     if ($joinAs === false) {
         $joinAs = $obj->__table;
     }
     $quoteIdentifiers = !empty($_DB_DATAOBJECT['CONFIG']['quote_identifiers']);
     // not sure  how portable adding database prefixes is..
     $objTable = $quoteIdentifiers ? $DB->quoteIdentifier($obj->__table) : $obj->__table;
     // as far as we know only mysql supports database prefixes..
     if (in_array($DB->dsn['phptype'], array('mysql', 'mysqli')) && $obj->_database != $this->_database && strlen($obj->_database)) {
         // prefix database (quoted if neccessary..)
         $objTable = ($quoteIdentifiers ? $DB->quoteIdentifier($obj->_database) : $obj->_database) . '.' . $objTable;
     }
     // nested (join of joined objects..)
     $appendJoin = '';
     if ($obj->_join) {
         // postgres allows nested queries, with ()'s
         // not sure what the results are with other databases..
         // may be unpredictable..
         if (in_array($DB->dsn["phptype"], array('pgsql'))) {
             $objTable = "({$objTable} {$obj->_join})";
         } else {
             $appendJoin = $obj->_join;
         }
     }
     $table = $this->__table;
     if ($quoteIdentifiers) {
         $joinAs = $DB->quoteIdentifier($joinAs);
         $table = $DB->quoteIdentifier($table);
         $ofield = $DB->quoteIdentifier($ofield);
         $tfield = $DB->quoteIdentifier($tfield);
     }
     // add database prefix if they are different databases
     $fullJoinAs = '';
     $addJoinAs = ($quoteIdentifiers ? $DB->quoteIdentifier($obj->__table) : $obj->__table) != $joinAs;
     if ($addJoinAs) {
         $fullJoinAs = "AS {$joinAs}";
     } else {
         // if
         if (in_array($DB->dsn['phptype'], array('mysql', 'mysqli')) && $obj->_database != $this->_database && strlen($this->_database)) {
             $joinAs = ($quoteIdentifiers ? $DB->quoteIdentifier($obj->_database) : $obj->_database) . '.' . $joinAs;
         }
     }
     switch ($joinType) {
         case 'INNER':
         case 'LEFT':
         case 'RIGHT':
             // others??? .. cross, left outer, right outer, natural..?
             $this->_join .= "\n {$joinType} JOIN {$objTable}  {$fullJoinAs}" . " ON {$joinAs}.{$ofield}={$table}.{$tfield} {$appendJoin} ";
             break;
         case '':
             // this is just a standard multitable select..
             $this->_join .= "\n , {$objTable} {$fullJoinAs} {$appendJoin}";
             $this->whereAdd("{$joinAs}.{$ofield}={$table}.{$tfield}");
     }
     // if obj only a dataobject - eg. no extended class has been defined..
     // it obvioulsy cant work out what child elements might exist...
     // untill we get on the fly querying of tables..
     if (strtolower(get_class($obj)) == 'db_dataobject') {
         return true;
     }
     /* now add where conditions for anything that is set in the object */
     $items = $obj->table();
     // will return an array if no items..
     // only fail if we where expecting it to work (eg. not joined on a array)
     if (!$items) {
         $this->raiseError("joinAdd: No table definition for {$obj->__table}", DB_DATAOBJECT_ERROR_INVALIDCONFIG);
         return false;
     }
     foreach ($items as $k => $v) {
         if (!isset($obj->{$k})) {
             continue;
         }
         $kSql = $quoteIdentifiers ? $DB->quoteIdentifier($k) : $k;
         if ($v & DB_DATAOBJECT_STR) {
             $this->whereAdd("{$joinAs}.{$kSql} = " . $this->_quote((string) ($v & DB_DATAOBJECT_BOOL ? $obj->{$k} == 'f' ? 0 : (int) (bool) $obj->{$k} : $obj->{$k})));
             continue;
         }
         if (is_numeric($obj->{$k})) {
             $this->whereAdd("{$joinAs}.{$kSql} = {$obj->{$k}}");
             continue;
         }
         /* this is probably an error condition! */
         $this->whereAdd("{$joinAs}.{$kSql} = 0");
     }
     if (!isset($this->_query)) {
         $this->raiseError("joinAdd can not be run from a object that has had a query run on it,\n                clone the object or create a new one and use setFrom()", DB_DATAOBJECT_ERROR_INVALIDARGS);
         return false;
     }
     // and finally merge the whereAdd from the child..
     if (!$obj->_query['condition']) {
         return true;
     }
     $cond = preg_replace('/^\\sWHERE/i', '', $obj->_query['condition']);
     $this->whereAdd("({$cond})");
     return true;
 }
 /**
  * Added storing reference to DataBase connection
  *
  * @todo Add sharing connections in connection Pool
  * @see DB_DataObject::_connect()
  *
  * @return PEAR_Error | true
  */
 function _connect()
 {
     if ($this->_database_dsn_md5 && !empty($GLOBALS['_DB_DATAOBJECT']['CONNECTIONS'][$this->_database_dsn_md5]) && $this->_database) {
         return true;
     }
     if (empty($_DB_DATAOBJECT['CONFIG'])) {
         $this->_loadConfig();
     }
     $dbh =& OA_DB::singleton();
     if (PEAR::isError($dbh)) {
         return $dbh;
     }
     $this->_database_dsn_md5 = md5(OA_DB::getDsn());
     $GLOBALS['_DB_DATAOBJECT']['CONNECTIONS'][$this->_database_dsn_md5] =& $dbh;
     $GLOBALS['_DB_DATAOBJECT']['CONFIG']['quote_identifiers'] = $dbh->options['quote_identifier'];
     $this->_database = $dbh->getDatabase();
     // store the reference in ADMIN_DB_LINK - backward compatibility
     $GLOBALS['_MAX']['ADMIN_DB_LINK'] =& $dbh->connection;
     return parent::_connect();
 }
Esempio n. 5
0
 /**
  * classic factory method for loading a table class
  * usage: $do = DB_DataObject::factory('person')
  * WARNING - this may emit a include error if the file does not exist..
  * use @ to silence it (if you are sure it is acceptable)
  * eg. $do = @DB_DataObject::factory('person')
  *
  * table name will eventually be databasename/table
  * - and allow modular dataobjects to be written..
  * (this also helps proxy creation)
  *
  *
  * @param  string  $table  tablename (use blank to create a new instance of the same class.)
  * @access private
  * @return DataObject|PEAR_Error 
  */
 function factory($table = '')
 {
     global $_DB_DATAOBJECT;
     if (empty($_DB_DATAOBJECT['CONFIG'])) {
         DB_DataObject::_loadConfig();
     }
     if ($table === '') {
         if (is_a($this, 'DB_DataObject') && strlen($this->__table)) {
             $table = $this->__table;
         } else {
             return DB_DataObject::raiseError("factory did not recieve a table name", DB_DATAOBJECT_ERROR_INVALIDARGS);
         }
     }
     $p = isset($_DB_DATAOBJECT['CONFIG']['class_prefix']) ? $_DB_DATAOBJECT['CONFIG']['class_prefix'] : '';
     $class = $p . preg_replace('/[^A-Z0-9]/i', '_', ucfirst($table));
     $class = class_exists($class) ? $class : DB_DataObject::_autoloadClass($class);
     // proxy = full|light
     if (!$class && isset($_DB_DATAOBJECT['CONFIG']['proxy'])) {
         $proxyMethod = 'getProxy' . $_DB_DATAOBJECT['CONFIG']['proxy'];
         require_once 'DB/DataObject/Generator.php';
         $d = new DB_DataObject();
         $d->__table = $table;
         $d->_connect();
         $x = new DB_DataObject_Generator();
         return $x->{$proxyMethod}($d->_database, $table);
     }
     if (!$class) {
         return DB_DataObject::raiseError("factory could not find class {$class} from {$table}", DB_DATAOBJECT_ERROR_INVALIDCONFIG);
     }
     return new $class();
 }