• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • Examples
  • File List

E:/E/GEAMP/www/openbiz/openbiz/others/Zend/Db/Table/Abstract.php

00001 <?php
00026 require_once 'Zend/Db/Adapter/Abstract.php';
00027 
00031 require_once 'Zend/Db/Select.php';
00032 
00036 require_once 'Zend/Db.php';
00037 
00047 abstract class Zend_Db_Table_Abstract
00048 {
00049 
00050     const ADAPTER          = 'db';
00051     const DEFINITION        = 'definition';
00052     const DEFINITION_CONFIG_NAME = 'definitionConfigName';
00053     const SCHEMA           = 'schema';
00054     const NAME             = 'name';
00055     const PRIMARY          = 'primary';
00056     const COLS             = 'cols';
00057     const METADATA         = 'metadata';
00058     const METADATA_CACHE   = 'metadataCache';
00059     const METADATA_CACHE_IN_CLASS = 'metadataCacheInClass';
00060     const ROW_CLASS        = 'rowClass';
00061     const ROWSET_CLASS     = 'rowsetClass';
00062     const REFERENCE_MAP    = 'referenceMap';
00063     const DEPENDENT_TABLES = 'dependentTables';
00064     const SEQUENCE         = 'sequence';
00065 
00066     const COLUMNS          = 'columns';
00067     const REF_TABLE_CLASS  = 'refTableClass';
00068     const REF_COLUMNS      = 'refColumns';
00069     const ON_DELETE        = 'onDelete';
00070     const ON_UPDATE        = 'onUpdate';
00071 
00072     const CASCADE          = 'cascade';
00073     const RESTRICT         = 'restrict';
00074     const SET_NULL         = 'setNull';
00075 
00076     const DEFAULT_NONE     = 'defaultNone';
00077     const DEFAULT_CLASS    = 'defaultClass';
00078     const DEFAULT_DB       = 'defaultDb';
00079 
00080     const SELECT_WITH_FROM_PART    = true;
00081     const SELECT_WITHOUT_FROM_PART = false;
00082 
00088     protected static $_defaultDb;
00089 
00095     protected $_definition = null;
00096 
00102     protected $_definitionConfigName = null;
00103 
00109     protected static $_defaultMetadataCache = null;
00110 
00116     protected $_db;
00117 
00123     protected $_schema = null;
00124 
00130     protected $_name = null;
00131 
00137     protected $_cols;
00138 
00147     protected $_primary = null;
00148 
00159     protected $_identity = 1;
00160 
00167     protected $_sequence = true;
00168 
00174     protected $_metadata = array();
00175 
00181     protected $_metadataCache = null;
00182 
00187     protected $_metadataCacheInClass = true;
00188 
00194     protected $_rowClass = 'Zend_Db_Table_Row';
00195 
00201     protected $_rowsetClass = 'Zend_Db_Table_Rowset';
00202 
00221     protected $_referenceMap = array();
00222 
00231     protected $_dependentTables = array();
00232 
00233 
00234     protected $_defaultSource = self::DEFAULT_NONE;
00235     protected $_defaultValues = array();
00236 
00255     public function __construct($config = array())
00256     {
00260         if (!is_array($config)) {
00261             $config = array(self::ADAPTER => $config);
00262         }
00263 
00264         if ($config) {
00265             $this->setOptions($config);
00266         }
00267 
00268         $this->_setup();
00269         $this->init();
00270     }
00271 
00278     public function setOptions(Array $options)
00279     {
00280         foreach ($options as $key => $value) {
00281             switch ($key) {
00282                 case self::ADAPTER:
00283                     $this->_setAdapter($value);
00284                     break;
00285                 case self::DEFINITION:
00286                     $this->setDefinition($value);
00287                     break;
00288                 case self::DEFINITION_CONFIG_NAME:
00289                     $this->setDefinitionConfigName($value);
00290                     break;
00291                 case self::SCHEMA:
00292                     $this->_schema = (string) $value;
00293                     break;
00294                 case self::NAME:
00295                     $this->_name = (string) $value;
00296                     break;
00297                 case self::PRIMARY:
00298                     $this->_primary = (array) $value;
00299                     break;
00300                 case self::ROW_CLASS:
00301                     $this->setRowClass($value);
00302                     break;
00303                 case self::ROWSET_CLASS:
00304                     $this->setRowsetClass($value);
00305                     break;
00306                 case self::REFERENCE_MAP:
00307                     $this->setReferences($value);
00308                     break;
00309                 case self::DEPENDENT_TABLES:
00310                     $this->setDependentTables($value);
00311                     break;
00312                 case self::METADATA_CACHE:
00313                     $this->_setMetadataCache($value);
00314                     break;
00315                 case self::METADATA_CACHE_IN_CLASS:
00316                     $this->setMetadataCacheInClass($value);
00317                     break;
00318                 case self::SEQUENCE:
00319                     $this->_setSequence($value);
00320                     break;
00321                 default:
00322                     // ignore unrecognized configuration directive
00323                     break;
00324             }
00325         }
00326 
00327         return $this;
00328     }
00329 
00336     public function setDefinition(Zend_Db_Table_Definition $definition)
00337     {
00338         $this->_definition = $definition;
00339         return $this;
00340     }
00341 
00347     public function getDefinition()
00348     {
00349         return $this->_definition;
00350     }
00351 
00358     public function setDefinitionConfigName($definitionConfigName)
00359     {
00360         $this->_definitionConfigName = $definitionConfigName;
00361         return $this;
00362     }
00363 
00369     public function getDefinitionConfigName()
00370     {
00371         return $this->_definitionConfigName;
00372     }
00373 
00378     public function setRowClass($classname)
00379     {
00380         $this->_rowClass = (string) $classname;
00381 
00382         return $this;
00383     }
00384 
00388     public function getRowClass()
00389     {
00390         return $this->_rowClass;
00391     }
00392 
00397     public function setRowsetClass($classname)
00398     {
00399         $this->_rowsetClass = (string) $classname;
00400 
00401         return $this;
00402     }
00403 
00407     public function getRowsetClass()
00408     {
00409         return $this->_rowsetClass;
00410     }
00411 
00423     public function addReference($ruleKey, $columns, $refTableClass, $refColumns,
00424                                  $onDelete = null, $onUpdate = null)
00425     {
00426         $reference = array(self::COLUMNS         => (array) $columns,
00427                            self::REF_TABLE_CLASS => $refTableClass,
00428                            self::REF_COLUMNS     => (array) $refColumns);
00429 
00430         if (!empty($onDelete)) {
00431             $reference[self::ON_DELETE] = $onDelete;
00432         }
00433 
00434         if (!empty($onUpdate)) {
00435             $reference[self::ON_UPDATE] = $onUpdate;
00436         }
00437 
00438         $this->_referenceMap[$ruleKey] = $reference;
00439 
00440         return $this;
00441     }
00442 
00447     public function setReferences(array $referenceMap)
00448     {
00449         $this->_referenceMap = $referenceMap;
00450 
00451         return $this;
00452     }
00453 
00460     public function getReference($tableClassname, $ruleKey = null)
00461     {
00462         $thisClass = get_class($this);
00463         if ($thisClass === 'Zend_Db_Table') {
00464             $thisClass = $this->_definitionConfigName;
00465         }
00466         $refMap = $this->_getReferenceMapNormalized();
00467         if ($ruleKey !== null) {
00468             if (!isset($refMap[$ruleKey])) {
00469                 require_once "Zend/Db/Table/Exception.php";
00470                 throw new Zend_Db_Table_Exception("No reference rule \"$ruleKey\" from table $thisClass to table $tableClassname");
00471             }
00472             if ($refMap[$ruleKey][self::REF_TABLE_CLASS] != $tableClassname) {
00473                 require_once "Zend/Db/Table/Exception.php";
00474                 throw new Zend_Db_Table_Exception("Reference rule \"$ruleKey\" does not reference table $tableClassname");
00475             }
00476             return $refMap[$ruleKey];
00477         }
00478         foreach ($refMap as $reference) {
00479             if ($reference[self::REF_TABLE_CLASS] == $tableClassname) {
00480                 return $reference;
00481             }
00482         }
00483         require_once "Zend/Db/Table/Exception.php";
00484         throw new Zend_Db_Table_Exception("No reference from table $thisClass to table $tableClassname");
00485     }
00486 
00491     public function setDependentTables(array $dependentTables)
00492     {
00493         $this->_dependentTables = $dependentTables;
00494 
00495         return $this;
00496     }
00497 
00501     public function getDependentTables()
00502     {
00503         return $this->_dependentTables;
00504     }
00505 
00512     public function setDefaultSource($defaultSource = self::DEFAULT_NONE)
00513     {
00514         if (!in_array($defaultSource, array(self::DEFAULT_CLASS, self::DEFAULT_DB, self::DEFAULT_NONE))) {
00515             $defaultSource = self::DEFAULT_NONE;
00516         }
00517 
00518         $this->_defaultSource = $defaultSource;
00519         return $this;
00520     }
00521 
00527     public function getDefaultSource()
00528     {
00529         return $this->_defaultSource;
00530     }
00531 
00538     public function setDefaultValues(Array $defaultValues)
00539     {
00540         foreach ($defaultValues as $defaultName => $defaultValue) {
00541             if (array_key_exists($defaultName, $this->_metadata)) {
00542                 $this->_defaultValues[$defaultName] = $defaultValue;
00543             }
00544         }
00545         return $this;
00546     }
00547 
00548     public function getDefaultValues()
00549     {
00550         return $this->_defaultValues;
00551     }
00552 
00553 
00560     public static function setDefaultAdapter($db = null)
00561     {
00562         self::$_defaultDb = self::_setupAdapter($db);
00563     }
00564 
00570     public static function getDefaultAdapter()
00571     {
00572         return self::$_defaultDb;
00573     }
00574 
00579     protected function _setAdapter($db)
00580     {
00581         $this->_db = self::_setupAdapter($db);
00582         return $this;
00583     }
00584 
00590     public function getAdapter()
00591     {
00592         return $this->_db;
00593     }
00594 
00600     protected static function _setupAdapter($db)
00601     {
00602         if ($db === null) {
00603             return null;
00604         }
00605         if (is_string($db)) {
00606             require_once 'Zend/Registry.php';
00607             $db = Zend_Registry::get($db);
00608         }
00609         if (!$db instanceof Zend_Db_Adapter_Abstract) {
00610             require_once 'Zend/Db/Table/Exception.php';
00611             throw new Zend_Db_Table_Exception('Argument must be of type Zend_Db_Adapter_Abstract, or a Registry key where a Zend_Db_Adapter_Abstract object is stored');
00612         }
00613         return $db;
00614     }
00615 
00624     public static function setDefaultMetadataCache($metadataCache = null)
00625     {
00626         self::$_defaultMetadataCache = self::_setupMetadataCache($metadataCache);
00627     }
00628 
00634     public static function getDefaultMetadataCache()
00635     {
00636         return self::$_defaultMetadataCache;
00637     }
00638 
00650     protected function _setMetadataCache($metadataCache)
00651     {
00652         $this->_metadataCache = self::_setupMetadataCache($metadataCache);
00653         return $this;
00654     }
00655 
00661     public function getMetadataCache()
00662     {
00663         return $this->_metadataCache;
00664     }
00665 
00673     public function setMetadataCacheInClass($flag)
00674     {
00675         $this->_metadataCacheInClass = (bool) $flag;
00676         return $this;
00677     }
00678 
00685     public function metadataCacheInClass()
00686     {
00687         return $this->_metadataCacheInClass;
00688     }
00689 
00695     protected static function _setupMetadataCache($metadataCache)
00696     {
00697         if ($metadataCache === null) {
00698             return null;
00699         }
00700         if (is_string($metadataCache)) {
00701             require_once 'Zend/Registry.php';
00702             $metadataCache = Zend_Registry::get($metadataCache);
00703         }
00704         if (!$metadataCache instanceof Zend_Cache_Core) {
00705             require_once 'Zend/Db/Table/Exception.php';
00706             throw new Zend_Db_Table_Exception('Argument must be of type Zend_Cache_Core, or a Registry key where a Zend_Cache_Core object is stored');
00707         }
00708         return $metadataCache;
00709     }
00710 
00723     protected function _setSequence($sequence)
00724     {
00725         $this->_sequence = $sequence;
00726 
00727         return $this;
00728     }
00729 
00737     protected function _setup()
00738     {
00739         $this->_setupDatabaseAdapter();
00740         $this->_setupTableName();
00741     }
00742 
00748     protected function _setupDatabaseAdapter()
00749     {
00750         if (! $this->_db) {
00751             $this->_db = self::getDefaultAdapter();
00752             if (!$this->_db instanceof Zend_Db_Adapter_Abstract) {
00753                 require_once 'Zend/Db/Table/Exception.php';
00754                 throw new Zend_Db_Table_Exception('No adapter found for ' . get_class($this));
00755             }
00756         }
00757     }
00758 
00770     protected function _setupTableName()
00771     {
00772         if (! $this->_name) {
00773             $this->_name = get_class($this);
00774         } else if (strpos($this->_name, '.')) {
00775             list($this->_schema, $this->_name) = explode('.', $this->_name);
00776         }
00777     }
00778 
00788     protected function _setupMetadata()
00789     {
00790         if ($this->metadataCacheInClass() && (count($this->_metadata) > 0)) {
00791             return true;
00792         }
00793 
00794         // Assume that metadata will be loaded from cache
00795         $isMetadataFromCache = true;
00796 
00797         // If $this has no metadata cache but the class has a default metadata cache
00798         if (null === $this->_metadataCache && null !== self::$_defaultMetadataCache) {
00799             // Make $this use the default metadata cache of the class
00800             $this->_setMetadataCache(self::$_defaultMetadataCache);
00801         }
00802 
00803         // If $this has a metadata cache
00804         if (null !== $this->_metadataCache) {
00805             // Define the cache identifier where the metadata are saved
00806 
00807             //get db configuration
00808             $dbConfig = $this->_db->getConfig();
00809 
00810             // Define the cache identifier where the metadata are saved
00811             $cacheId = md5( // port:host/dbname:schema.table (based on availabilty)
00812                 (isset($dbConfig['options']['port']) ? ':'.$dbConfig['options']['port'] : null)
00813                 . (isset($dbConfig['options']['host']) ? ':'.$dbConfig['options']['host'] : null)
00814                 . '/'.$dbConfig['dbname'].':'.$this->_schema.'.'.$this->_name
00815                 );
00816         }
00817 
00818         // If $this has no metadata cache or metadata cache misses
00819         if (null === $this->_metadataCache || !($metadata = $this->_metadataCache->load($cacheId))) {
00820             // Metadata are not loaded from cache
00821             $isMetadataFromCache = false;
00822             // Fetch metadata from the adapter's describeTable() method
00823             $metadata = $this->_db->describeTable($this->_name, $this->_schema);
00824             // If $this has a metadata cache, then cache the metadata
00825             if (null !== $this->_metadataCache && !$this->_metadataCache->save($metadata, $cacheId)) {
00829                 require_once 'Zend/Db/Table/Exception.php';
00830                 throw new Zend_Db_Table_Exception('Failed saving metadata to metadataCache');
00831             }
00832         }
00833 
00834         // Assign the metadata to $this
00835         $this->_metadata = $metadata;
00836 
00837         // Return whether the metadata were loaded from cache
00838         return $isMetadataFromCache;
00839     }
00840 
00846     protected function _getCols()
00847     {
00848         if (null === $this->_cols) {
00849             $this->_setupMetadata();
00850             $this->_cols = array_keys($this->_metadata);
00851         }
00852         return $this->_cols;
00853     }
00854 
00863     protected function _setupPrimaryKey()
00864     {
00865         if (!$this->_primary) {
00866             $this->_setupMetadata();
00867             $this->_primary = array();
00868             foreach ($this->_metadata as $col) {
00869                 if ($col['PRIMARY']) {
00870                     $this->_primary[ $col['PRIMARY_POSITION'] ] = $col['COLUMN_NAME'];
00871                     if ($col['IDENTITY']) {
00872                         $this->_identity = $col['PRIMARY_POSITION'];
00873                     }
00874                 }
00875             }
00876             // if no primary key was specified and none was found in the metadata
00877             // then throw an exception.
00878             if (empty($this->_primary)) {
00879                 require_once 'Zend/Db/Table/Exception.php';
00880                 throw new Zend_Db_Table_Exception('A table must have a primary key, but none was found');
00881             }
00882         } else if (!is_array($this->_primary)) {
00883             $this->_primary = array(1 => $this->_primary);
00884         } else if (isset($this->_primary[0])) {
00885             array_unshift($this->_primary, null);
00886             unset($this->_primary[0]);
00887         }
00888 
00889         $cols = $this->_getCols();
00890         if (! array_intersect((array) $this->_primary, $cols) == (array) $this->_primary) {
00891             require_once 'Zend/Db/Table/Exception.php';
00892             throw new Zend_Db_Table_Exception("Primary key column(s) ("
00893                 . implode(',', (array) $this->_primary)
00894                 . ") are not columns in this table ("
00895                 . implode(',', $cols)
00896                 . ")");
00897         }
00898 
00899         $primary    = (array) $this->_primary;
00900         $pkIdentity = $primary[(int) $this->_identity];
00901 
00906         if ($this->_sequence === true && $this->_db instanceof Zend_Db_Adapter_Pdo_Pgsql) {
00907             $this->_sequence = $this->_db->quoteIdentifier("{$this->_name}_{$pkIdentity}_seq");
00908             if ($this->_schema) {
00909                 $this->_sequence = $this->_db->quoteIdentifier($this->_schema) . '.' . $this->_sequence;
00910             }
00911         }
00912     }
00913 
00919     protected function _getReferenceMapNormalized()
00920     {
00921         $referenceMapNormalized = array();
00922 
00923         foreach ($this->_referenceMap as $rule => $map) {
00924 
00925             $referenceMapNormalized[$rule] = array();
00926 
00927             foreach ($map as $key => $value) {
00928                 switch ($key) {
00929 
00930                     // normalize COLUMNS and REF_COLUMNS to arrays
00931                     case self::COLUMNS:
00932                     case self::REF_COLUMNS:
00933                         if (!is_array($value)) {
00934                             $referenceMapNormalized[$rule][$key] = array($value);
00935                         } else {
00936                             $referenceMapNormalized[$rule][$key] = $value;
00937                         }
00938                         break;
00939 
00940                     // other values are copied as-is
00941                     default:
00942                         $referenceMapNormalized[$rule][$key] = $value;
00943                         break;
00944                 }
00945             }
00946         }
00947 
00948         return $referenceMapNormalized;
00949     }
00950 
00958     public function init()
00959     {
00960     }
00961 
00971     public function info($key = null)
00972     {
00973         $this->_setupPrimaryKey();
00974 
00975         $info = array(
00976             self::SCHEMA           => $this->_schema,
00977             self::NAME             => $this->_name,
00978             self::COLS             => $this->_getCols(),
00979             self::PRIMARY          => (array) $this->_primary,
00980             self::METADATA         => $this->_metadata,
00981             self::ROW_CLASS        => $this->getRowClass(),
00982             self::ROWSET_CLASS     => $this->getRowsetClass(),
00983             self::REFERENCE_MAP    => $this->_referenceMap,
00984             self::DEPENDENT_TABLES => $this->_dependentTables,
00985             self::SEQUENCE         => $this->_sequence
00986         );
00987 
00988         if ($key === null) {
00989             return $info;
00990         }
00991 
00992         if (!array_key_exists($key, $info)) {
00993             require_once 'Zend/Db/Table/Exception.php';
00994             throw new Zend_Db_Table_Exception('There is no table information for the key "' . $key . '"');
00995         }
00996 
00997         return $info[$key];
00998     }
00999 
01006     public function select($withFromPart = self::SELECT_WITHOUT_FROM_PART)
01007     {
01008         require_once 'Zend/Db/Table/Select.php';
01009         $select = new Zend_Db_Table_Select($this);
01010         if ($withFromPart == self::SELECT_WITH_FROM_PART) {
01011             $select->from($this->info(self::NAME), Zend_Db_Table_Select::SQL_WILDCARD, $this->info(self::SCHEMA));
01012         }
01013         return $select;
01014     }
01015 
01022     public function insert(array $data)
01023     {
01024         $this->_setupPrimaryKey();
01025 
01031         $primary = (array) $this->_primary;
01032         $pkIdentity = $primary[(int)$this->_identity];
01033 
01040         if (is_string($this->_sequence) && !isset($data[$pkIdentity])) {
01041             $data[$pkIdentity] = $this->_db->nextSequenceId($this->_sequence);
01042         }
01043 
01048         if (array_key_exists($pkIdentity, $data) && $data[$pkIdentity] === null) {
01049             unset($data[$pkIdentity]);
01050         }
01051 
01055         $tableSpec = ($this->_schema ? $this->_schema . '.' : '') . $this->_name;
01056         $this->_db->insert($tableSpec, $data);
01057 
01063         if ($this->_sequence === true && !isset($data[$pkIdentity])) {
01064             $data[$pkIdentity] = $this->_db->lastInsertId();
01065         }
01066 
01071         $pkData = array_intersect_key($data, array_flip($primary));
01072         if (count($primary) == 1) {
01073             reset($pkData);
01074             return current($pkData);
01075         }
01076 
01077         return $pkData;
01078     }
01079 
01087     public function isIdentity($column)
01088     {
01089         $this->_setupPrimaryKey();
01090 
01091         if (!isset($this->_metadata[$column])) {
01095             require_once 'Zend/Db/Table/Exception.php';
01096 
01097             throw new Zend_Db_Table_Exception('Column "' . $column . '" not found in table.');
01098         }
01099 
01100         return (bool) $this->_metadata[$column]['IDENTITY'];
01101     }
01102 
01110     public function update(array $data, $where)
01111     {
01112         $tableSpec = ($this->_schema ? $this->_schema . '.' : '') . $this->_name;
01113         return $this->_db->update($tableSpec, $data, $where);
01114     }
01115 
01124     public function _cascadeUpdate($parentTableClassname, array $oldPrimaryKey, array $newPrimaryKey)
01125     {
01126         $this->_setupMetadata();
01127         $rowsAffected = 0;
01128         foreach ($this->_getReferenceMapNormalized() as $map) {
01129             if ($map[self::REF_TABLE_CLASS] == $parentTableClassname && isset($map[self::ON_UPDATE])) {
01130                 switch ($map[self::ON_UPDATE]) {
01131                     case self::CASCADE:
01132                         $newRefs = array();
01133                         $where = array();
01134                         for ($i = 0; $i < count($map[self::COLUMNS]); ++$i) {
01135                             $col = $this->_db->foldCase($map[self::COLUMNS][$i]);
01136                             $refCol = $this->_db->foldCase($map[self::REF_COLUMNS][$i]);
01137                             if (array_key_exists($refCol, $newPrimaryKey)) {
01138                                 $newRefs[$col] = $newPrimaryKey[$refCol];
01139                             }
01140                             $type = $this->_metadata[$col]['DATA_TYPE'];
01141                             $where[] = $this->_db->quoteInto(
01142                                 $this->_db->quoteIdentifier($col, true) . ' = ?',
01143                                 $oldPrimaryKey[$refCol], $type);
01144                         }
01145                         $rowsAffected += $this->update($newRefs, $where);
01146                         break;
01147                     default:
01148                         // no action
01149                         break;
01150                 }
01151             }
01152         }
01153         return $rowsAffected;
01154     }
01155 
01162     public function delete($where)
01163     {
01164         $tableSpec = ($this->_schema ? $this->_schema . '.' : '') . $this->_name;
01165         return $this->_db->delete($tableSpec, $where);
01166     }
01167 
01175     public function _cascadeDelete($parentTableClassname, array $primaryKey)
01176     {
01177         $this->_setupMetadata();
01178         $rowsAffected = 0;
01179         foreach ($this->_getReferenceMapNormalized() as $map) {
01180             if ($map[self::REF_TABLE_CLASS] == $parentTableClassname && isset($map[self::ON_DELETE])) {
01181                 switch ($map[self::ON_DELETE]) {
01182                     case self::CASCADE:
01183                         $where = array();
01184                         for ($i = 0; $i < count($map[self::COLUMNS]); ++$i) {
01185                             $col = $this->_db->foldCase($map[self::COLUMNS][$i]);
01186                             $refCol = $this->_db->foldCase($map[self::REF_COLUMNS][$i]);
01187                             $type = $this->_metadata[$col]['DATA_TYPE'];
01188                             $where[] = $this->_db->quoteInto(
01189                                 $this->_db->quoteIdentifier($col, true) . ' = ?',
01190                                 $primaryKey[$refCol], $type);
01191                         }
01192                         $rowsAffected += $this->delete($where);
01193                         break;
01194                     default:
01195                         // no action
01196                         break;
01197                 }
01198             }
01199         }
01200         return $rowsAffected;
01201     }
01202 
01221     public function find()
01222     {
01223         $this->_setupPrimaryKey();
01224         $args = func_get_args();
01225         $keyNames = array_values((array) $this->_primary);
01226 
01227         if (count($args) < count($keyNames)) {
01228             require_once 'Zend/Db/Table/Exception.php';
01229             throw new Zend_Db_Table_Exception("Too few columns for the primary key");
01230         }
01231 
01232         if (count($args) > count($keyNames)) {
01233             require_once 'Zend/Db/Table/Exception.php';
01234             throw new Zend_Db_Table_Exception("Too many columns for the primary key");
01235         }
01236 
01237         $whereList = array();
01238         $numberTerms = 0;
01239         foreach ($args as $keyPosition => $keyValues) {
01240             $keyValuesCount = count($keyValues);
01241             // Coerce the values to an array.
01242             // Don't simply typecast to array, because the values
01243             // might be Zend_Db_Expr objects.
01244             if (!is_array($keyValues)) {
01245                 $keyValues = array($keyValues);
01246             }
01247             if ($numberTerms == 0) {
01248                 $numberTerms = $keyValuesCount;
01249             } else if ($keyValuesCount != $numberTerms) {
01250                 require_once 'Zend/Db/Table/Exception.php';
01251                 throw new Zend_Db_Table_Exception("Missing value(s) for the primary key");
01252             }
01253             $keyValues = array_values($keyValues);
01254             for ($i = 0; $i < $keyValuesCount; ++$i) {
01255                 if (!isset($whereList[$i])) {
01256                     $whereList[$i] = array();
01257                 }
01258                 $whereList[$i][$keyPosition] = $keyValues[$i];
01259             }
01260         }
01261 
01262         $whereClause = null;
01263         if (count($whereList)) {
01264             $whereOrTerms = array();
01265             $tableName = $this->_db->quoteTableAs($this->_name, null, true);
01266             foreach ($whereList as $keyValueSets) {
01267                 $whereAndTerms = array();
01268                 foreach ($keyValueSets as $keyPosition => $keyValue) {
01269                     $type = $this->_metadata[$keyNames[$keyPosition]]['DATA_TYPE'];
01270                     $columnName = $this->_db->quoteIdentifier($keyNames[$keyPosition], true);
01271                     $whereAndTerms[] = $this->_db->quoteInto(
01272                         $tableName . '.' . $columnName . ' = ?',
01273                         $keyValue, $type);
01274                 }
01275                 $whereOrTerms[] = '(' . implode(' AND ', $whereAndTerms) . ')';
01276             }
01277             $whereClause = '(' . implode(' OR ', $whereOrTerms) . ')';
01278         }
01279 
01280         // issue ZF-5775 (empty where clause should return empty rowset)
01281         if ($whereClause == null) {
01282             $rowsetClass = $this->getRowsetClass();
01283             if (!class_exists($rowsetClass)) {
01284                 require_once 'Zend/Loader.php';
01285                 Zend_Loader::loadClass($rowsetClass);
01286             }
01287             return new $rowsetClass(array('table' => $this, 'rowClass' => $this->getRowClass(), 'stored' => true));
01288         }
01289 
01290         return $this->fetchAll($whereClause);
01291     }
01292 
01304     public function fetchAll($where = null, $order = null, $count = null, $offset = null)
01305     {
01306         if (!($where instanceof Zend_Db_Table_Select)) {
01307             $select = $this->select();
01308 
01309             if ($where !== null) {
01310                 $this->_where($select, $where);
01311             }
01312 
01313             if ($order !== null) {
01314                 $this->_order($select, $order);
01315             }
01316 
01317             if ($count !== null || $offset !== null) {
01318                 $select->limit($count, $offset);
01319             }
01320 
01321         } else {
01322             $select = $where;
01323         }
01324 
01325         $rows = $this->_fetch($select);
01326 
01327         $data  = array(
01328             'table'    => $this,
01329             'data'     => $rows,
01330             'readOnly' => $select->isReadOnly(),
01331             'rowClass' => $this->getRowClass(),
01332             'stored'   => true
01333         );
01334 
01335         $rowsetClass = $this->getRowsetClass();
01336         if (!class_exists($rowsetClass)) {
01337             require_once 'Zend/Loader.php';
01338             Zend_Loader::loadClass($rowsetClass);
01339         }
01340         return new $rowsetClass($data);
01341     }
01342 
01352     public function fetchRow($where = null, $order = null)
01353     {
01354         if (!($where instanceof Zend_Db_Table_Select)) {
01355             $select = $this->select();
01356 
01357             if ($where !== null) {
01358                 $this->_where($select, $where);
01359             }
01360 
01361             if ($order !== null) {
01362                 $this->_order($select, $order);
01363             }
01364 
01365             $select->limit(1);
01366 
01367         } else {
01368             $select = $where->limit(1);
01369         }
01370 
01371         $rows = $this->_fetch($select);
01372 
01373         if (count($rows) == 0) {
01374             return null;
01375         }
01376 
01377         $data = array(
01378             'table'   => $this,
01379             'data'     => $rows[0],
01380             'readOnly' => $select->isReadOnly(),
01381             'stored'  => true
01382         );
01383 
01384         $rowClass = $this->getRowClass();
01385         if (!class_exists($rowClass)) {
01386             require_once 'Zend/Loader.php';
01387             Zend_Loader::loadClass($rowClass);
01388         }
01389         return new $rowClass($data);
01390     }
01391 
01398     public function fetchNew()
01399     {
01400         return $this->createRow();
01401     }
01402 
01410     public function createRow(array $data = array(), $defaultSource = null)
01411     {
01412         $cols     = $this->_getCols();
01413         $defaults = array_combine($cols, array_fill(0, count($cols), null));
01414 
01415         // nothing provided at call-time, take the class value
01416         if ($defaultSource == null) {
01417             $defaultSource = $this->_defaultSource;
01418         }
01419 
01420         if (!in_array($defaultSource, array(self::DEFAULT_CLASS, self::DEFAULT_DB, self::DEFAULT_NONE))) {
01421             $defaultSource = self::DEFAULT_NONE;
01422         }
01423 
01424         if ($defaultSource == self::DEFAULT_DB) {
01425             foreach ($this->_metadata as $metadataName => $metadata) {
01426                 if (($metadata['DEFAULT'] != null) &&
01427                     ($metadata['NULLABLE'] !== true || ($metadata['NULLABLE'] === true && isset($this->_defaultValues[$metadataName]) && $this->_defaultValues[$metadataName] === true)) &&
01428                     (!(isset($this->_defaultValues[$metadataName]) && $this->_defaultValues[$metadataName] === false))) {
01429                     $defaults[$metadataName] = $metadata['DEFAULT'];
01430                 }
01431             }
01432         } elseif ($defaultSource == self::DEFAULT_CLASS && $this->_defaultValues) {
01433             foreach ($this->_defaultValues as $defaultName => $defaultValue) {
01434                 if (array_key_exists($defaultName, $defaults)) {
01435                     $defaults[$defaultName] = $defaultValue;
01436                 }
01437             }
01438         }
01439 
01440         $config = array(
01441             'table'    => $this,
01442             'data'     => $defaults,
01443             'readOnly' => false,
01444             'stored'   => false
01445         );
01446 
01447         $rowClass = $this->getRowClass();
01448         if (!class_exists($rowClass)) {
01449             require_once 'Zend/Loader.php';
01450             Zend_Loader::loadClass($rowClass);
01451         }
01452         $row = new $rowClass($config);
01453         $row->setFromArray($data);
01454         return $row;
01455     }
01456 
01463     protected function _where(Zend_Db_Table_Select $select, $where)
01464     {
01465         $where = (array) $where;
01466 
01467         foreach ($where as $key => $val) {
01468             // is $key an int?
01469             if (is_int($key)) {
01470                 // $val is the full condition
01471                 $select->where($val);
01472             } else {
01473                 // $key is the condition with placeholder,
01474                 // and $val is quoted into the condition
01475                 $select->where($key, $val);
01476             }
01477         }
01478 
01479         return $select;
01480     }
01481 
01488     protected function _order(Zend_Db_Table_Select $select, $order)
01489     {
01490         if (!is_array($order)) {
01491             $order = array($order);
01492         }
01493 
01494         foreach ($order as $val) {
01495             $select->order($val);
01496         }
01497 
01498         return $select;
01499     }
01500 
01507     protected function _fetch(Zend_Db_Table_Select $select)
01508     {
01509         $stmt = $this->_db->query($select);
01510         $data = $stmt->fetchAll(Zend_Db::FETCH_ASSOC);
01511         return $data;
01512     }
01513 
01514 }

Generated on Thu Apr 19 2012 17:01:17 for openbiz by  doxygen 1.7.2