예제 #1
0
 /**
  * Creates a criteria object from a method name and a value as
  * a criterion.
  *
  * @param string $methodName
  * @param mixed  $criterion
  * @return stdClass
  * @throws PIECE_ORM_ERROR_UNEXPECTED_VALUE
  */
 function &_createCriteria($methodName, $criterion)
 {
     if (preg_match('/By(.+)$/', $methodName, $matches)) {
         $criteria =& new stdClass();
         $criteria->{Piece_ORM_Inflector::lowercaseFirstLetter($matches[1])} = $criterion;
         return $criteria;
     } else {
         Piece_ORM_Error::push(PIECE_ORM_ERROR_UNEXPECTED_VALUE, "An unexpected value detected. {$methodName}() can only receive object or null. Or the method name does not contain the appropriate field name.");
         $return = null;
         return $return;
     }
 }
예제 #2
0
 /**
  * Creates a Piece_ORM_Config object from a configuration file or
  * a cache.
  *
  * @param string $configDirectory
  * @param string $cacheDirectory
  * @return Piece_ORM_Config
  * @static
  */
 function &factory($configDirectory = null, $cacheDirectory = null)
 {
     if (is_null($configDirectory)) {
         $config =& new Piece_ORM_Config();
         return $config;
     }
     if (!file_exists($configDirectory)) {
         Piece_ORM_Error::push(PIECE_ORM_ERROR_NOT_FOUND, "The configuration directory [ {$configDirectory} ] not found.");
         $return = null;
         return $return;
     }
     $configFile = "{$configDirectory}/piece-orm-config.yaml";
     if (!file_exists($configFile)) {
         Piece_ORM_Error::push(PIECE_ORM_ERROR_NOT_FOUND, "The configuration file [ {$configFile} ] not found.");
         $return = null;
         return $return;
     }
     if (!is_readable($configFile)) {
         Piece_ORM_Error::push(PIECE_ORM_ERROR_NOT_READABLE, "The configuration file [ {$configFile} ] is not readable.");
         $return = null;
         return $return;
     }
     if (is_null($cacheDirectory)) {
         return Piece_ORM_Config_Factory::_createConfigurationFromFile($configFile);
     }
     if (!file_exists($cacheDirectory)) {
         trigger_error("The cache directory [ {$cacheDirectory} ] is not found.", E_USER_WARNING);
         return Piece_ORM_Config_Factory::_createConfigurationFromFile($configFile);
     }
     if (!is_readable($cacheDirectory) || !is_writable($cacheDirectory)) {
         trigger_error("The cache directory [ {$cacheDirectory} ] is not readable or writable.", E_USER_WARNING);
         return Piece_ORM_Config_Factory::_createConfigurationFromFile($configFile);
     }
     return Piece_ORM_Config_Factory::_getConfiguration($configFile, $cacheDirectory);
 }
예제 #3
0
 /**
  * Removes associated objects from a table.
  *
  * @param array $relationship
  * @throws PIECE_ORM_ERROR_INVALID_CONFIGURATION
  */
 function delete($relationship)
 {
     Piece_ORM_Error::push(PIECE_ORM_ERROR_INVALID_CONFIGURATION, "This operation does not supported for the relationship type [ {$relationship['type']} ]. Please check your configuration.");
 }
예제 #4
0
 /**
  * Executes a query.
  *
  * @param string                $query
  * @param MDB2_Statement_Common $sth
  * @return MDB2_Result_Common|integer
  * @throws PIECE_ORM_ERROR_CANNOT_INVOKE
  * @throws PIECE_ORM_ERROR_UNEXPECTED_VALUE
  * @throws PIECE_ORM_ERROR_CONSTRAINT
  */
 function &execute($query, $sth)
 {
     $dbh =& $this->_mapper->getConnection();
     PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
     if (!$this->_isManip) {
         $result =& $dbh->query($query);
     } else {
         if (is_null($sth)) {
             $result = $dbh->exec($query);
         } else {
             if (!is_subclass_of($sth, 'MDB2_Statement_Common')) {
                 PEAR::staticPopErrorHandling();
                 Piece_ORM_Error::push(PIECE_ORM_ERROR_UNEXPECTED_VALUE, 'An unexpected value detected. executeQuery() with a prepared statement can only receive a MDB2_Statement_Common object.');
                 $return = null;
                 return $return;
             }
             $result = $sth->execute();
         }
     }
     PEAR::staticPopErrorHandling();
     $this->_mapper->setLastQuery($dbh->last_query);
     if (MDB2::isError($result)) {
         if ($result->getCode() == MDB2_ERROR_CONSTRAINT) {
             $code = PIECE_ORM_ERROR_CONSTRAINT;
         } else {
             $code = PIECE_ORM_ERROR_CANNOT_INVOKE;
         }
         Piece_ORM_Error::pushPEARError($result, $code, "Failed to invoke MDB2_Driver_{$dbh->phptype}::query() for any reasons.");
         $return = null;
         return $return;
     }
     return $result;
 }
예제 #5
0
 /**
  * Normalizes a relationship definition.
  *
  * @return array
  * @throws PIECE_ORM_ERROR_INVALID_CONFIGURATION
  * @throws PIECE_ORM_ERROR_NOT_FOUND
  */
 function normalize()
 {
     if (!array_key_exists('table', $this->_relationship)) {
         Piece_ORM_Error::push(PIECE_ORM_ERROR_INVALID_CONFIGURATION, 'The element [ table ] is required to generate a relationship property declaration.');
         return;
     }
     if (!array_key_exists('mappedAs', $this->_relationship)) {
         Piece_ORM_Error::push(PIECE_ORM_ERROR_INVALID_CONFIGURATION, 'The element [ mappedAs ] is required to generate a relationship property declaration.');
         return;
     }
     $this->_relationshipMetadata =& Piece_ORM_Metadata_Factory::factory($this->_relationship['table']);
     if (Piece_ORM_Error::hasErrors()) {
         return;
     }
     if ($this->_checkHavingSinglePrimaryKey()) {
         if (!$this->_relationshipMetadata->getPrimaryKey()) {
             Piece_ORM_Error::push(PIECE_ORM_ERROR_NOT_FOUND, 'A single primary key field is required in the table [ ' . $this->_relationshipMetadata->getTableName(true) . ' ].');
             return;
         }
     }
     if (!array_key_exists('column', $this->_relationship)) {
         if (!$this->_normalizeColumn()) {
             Piece_ORM_Error::push(PIECE_ORM_ERROR_INVALID_CONFIGURATION, 'A single primary key field is required, if the element [ column ] in the element [ relationship ] omit.');
             return;
         }
     }
     if (!$this->_relationshipMetadata->hasField($this->_relationship['column'])) {
         Piece_ORM_Error::push(PIECE_ORM_ERROR_INVALID_CONFIGURATION, "The field [ {$this->_relationship['column']} ] not found in the table [ " . $this->_relationshipMetadata->getTableName(true) . ' ].');
         return;
     }
     if (!array_key_exists('referencedColumn', $this->_relationship)) {
         if (!$this->_normalizeReferencedColumn()) {
             Piece_ORM_Error::push(PIECE_ORM_ERROR_INVALID_CONFIGURATION, 'A single primary key field is required, if the element [ referencedColumn ] in the element [ relationship ] omit.');
             return;
         }
     }
     if ($this->_referencedColumnRequired && !$this->_metadata->hasField($this->_relationship['referencedColumn'])) {
         Piece_ORM_Error::push(PIECE_ORM_ERROR_INVALID_CONFIGURATION, "The field [ {$this->_relationship['referencedColumn']} ] not found in the table [ " . $this->_metadata->getTableName(true) . ' ].');
         return;
     }
     if (!array_key_exists('orderBy', $this->_relationship)) {
         $this->_relationship['orderBy'] = null;
     }
     $this->_normalizeOrderBy();
     $this->_normalizeThrough();
     if (Piece_ORM_Error::hasErrors()) {
         return;
     }
     return $this->_relationship;
 }
예제 #6
0
 /**
  * Adds a PEAR error to the stack for the package.
  *
  * @param PEAR_Error $error
  * @param integer    $code
  * @param string     $message
  * @param string     $level
  * @param array      $params
  * @param array      $backtrace
  */
 function pushPEARError($error, $code, $message = false, $level = 'exception', $params = array(), $backtrace = false)
 {
     $time = explode(' ', microtime());
     $time = $time[1] + $time[0];
     if (!$backtrace) {
         $backtrace = debug_backtrace();
     }
     Piece_ORM_Error::push($code, $message, 'exception', $params, array('code' => $error->getCode(), 'message' => $error->getMessage(), 'params' => array('userinfo' => $error->getUserInfo(), 'debuginfo' => $error->getDebugInfo()), 'package' => 'PEAR', 'level' => 'exception', 'time' => $time), $backtrace);
 }
예제 #7
0
 /**
  * Loads a mapper class based on the given information.
  *
  * @param string $mapperID
  * @param string $mapperName
  * @throws PIECE_ORM_ERROR_INVALID_OPERATION
  * @throws PIECE_ORM_ERROR_NOT_FOUND
  * @throws PIECE_ORM_ERROR_NOT_READABLE
  */
 function _load($mapperID, $mapperName)
 {
     if (Piece_ORM_Mapper_Factory::_loaded($mapperID)) {
         return;
     }
     if (is_null($GLOBALS['PIECE_ORM_Mapper_ConfigDirectory'])) {
         Piece_ORM_Error::push(PIECE_ORM_ERROR_INVALID_OPERATION, 'The configuration directory must be specified.');
         return;
     }
     if (!file_exists($GLOBALS['PIECE_ORM_Mapper_ConfigDirectory'])) {
         Piece_ORM_Error::push(PIECE_ORM_ERROR_NOT_FOUND, "The configuration directory [ {$GLOBALS['PIECE_ORM_Mapper_ConfigDirectory']} ] not found.");
         return;
     }
     if (is_null($GLOBALS['PIECE_ORM_Mapper_CacheDirectory'])) {
         Piece_ORM_Error::push(PIECE_ORM_ERROR_INVALID_OPERATION, 'The cache directory must be specified.');
         return;
     }
     if (!file_exists($GLOBALS['PIECE_ORM_Mapper_CacheDirectory'])) {
         Piece_ORM_Error::push(PIECE_ORM_ERROR_NOT_FOUND, "The cache directory [ {$GLOBALS['PIECE_ORM_Mapper_CacheDirectory']} ] not found.");
         return;
     }
     if (!is_readable($GLOBALS['PIECE_ORM_Mapper_CacheDirectory']) || !is_writable($GLOBALS['PIECE_ORM_Mapper_CacheDirectory'])) {
         Piece_ORM_Error::push(PIECE_ORM_ERROR_NOT_READABLE, "The cache directory [ {$GLOBALS['PIECE_ORM_Mapper_CacheDirectory']} ] is not readable or writable.");
         return;
     }
     $configFile = "{$GLOBALS['PIECE_ORM_Mapper_ConfigDirectory']}/{$mapperName}.yaml";
     if (!file_exists($configFile)) {
         Piece_ORM_Error::push(PIECE_ORM_ERROR_NOT_FOUND, "The configuration file [ {$configFile} ] not found.");
         return;
     }
     if (!is_readable($configFile)) {
         Piece_ORM_Error::push(PIECE_ORM_ERROR_NOT_READABLE, "The configuration file [ {$configFile} ] is not readable.");
         return;
     }
     $mapperSource = Piece_ORM_Mapper_Factory::_getMapperSource($mapperID, $mapperName, $configFile);
     if (Piece_ORM_Error::hasErrors()) {
         return;
     }
     eval($mapperSource);
     if (!Piece_ORM_Mapper_Factory::_loaded($mapperID)) {
         Piece_ORM_Error::push(PIECE_ORM_ERROR_NOT_FOUND, "The mapper [ {$mapperName} ] not found.");
     }
 }
예제 #8
0
 /**
  * Normalizes "through" definition.
  *
  * @throws PIECE_ORM_ERROR_INVALID_CONFIGURATION
  */
 function _normalizeThrough()
 {
     if (!array_key_exists('through', $this->_relationship)) {
         $this->_relationship['through'] = array();
     }
     if (!array_key_exists('table', $this->_relationship['through'])) {
         $throughTableName1 = $this->_metadata->getTableName(true) . "_{$this->_relationship['table']}";
         $throughTableName2 = "{$this->_relationship['table']}_" . $this->_metadata->getTableName(true);
         foreach (array($throughTableName1, $throughTableName2) as $throughTableName) {
             Piece_ORM_Error::disableCallback();
             $throughMetadata =& Piece_ORM_Metadata_Factory::factory($throughTableName);
             Piece_ORM_Error::enableCallback();
             if (Piece_ORM_Error::hasErrors()) {
                 $error = Piece_ORM_Error::pop();
                 if ($error['code'] != PIECE_ORM_ERROR_NOT_FOUND) {
                     Piece_ORM_Error::push($error['code'], $error['message'], 'exception', array(), $error);
                     return;
                 }
                 continue;
             }
             $this->_relationship['through']['table'] = $throughTableName;
             break;
         }
         if (!$throughMetadata) {
             Piece_ORM_Error::push(PIECE_ORM_ERROR_INVALID_CONFIGURATION, "One of [ {$throughTableName1} ] or [ {$throughTableName2} ] must exists in the database, if the element [ table ] in the element [ through ] omit.");
             return;
         }
     }
     $throughMetadata =& Piece_ORM_Metadata_Factory::factory($this->_relationship['through']['table']);
     if (Piece_ORM_Error::hasErrors()) {
         return;
     }
     if (!array_key_exists('column', $this->_relationship['through'])) {
         if ($primaryKey = $this->_metadata->getPrimaryKey()) {
             $this->_relationship['through']['column'] = $this->_metadata->getTableName(true) . "_{$primaryKey}";
         } else {
             Piece_ORM_Error::push(PIECE_ORM_ERROR_INVALID_CONFIGURATION, 'A single primary key field is required, if the element [ column ] in the element [ through ] omit.');
             return;
         }
     }
     if (!$throughMetadata->hasField($this->_relationship['through']['column'])) {
         Piece_ORM_Error::push(PIECE_ORM_ERROR_INVALID_CONFIGURATION, "The field [ {$this->_relationship['through']['column']} ] not found in the table [ " . $throughMetadata->getTableName(true) . ' ].');
         return;
     }
     if (!array_key_exists('referencedColumn', $this->_relationship['through'])) {
         if ($primaryKey = $this->_metadata->getPrimaryKey()) {
             $this->_relationship['through']['referencedColumn'] = $primaryKey;
         } else {
             Piece_ORM_Error::push(PIECE_ORM_ERROR_INVALID_CONFIGURATION, 'A single primary key field is required, if the element [ referencedColumn ] in the element [ through ] omit.');
             return;
         }
     }
     if (!$this->_metadata->hasField($this->_relationship['through']['referencedColumn'])) {
         Piece_ORM_Error::push(PIECE_ORM_ERROR_INVALID_CONFIGURATION, "The field [ {$this->_relationship['through']['referencedColumn']} ] not found in the table [ " . $this->_metadata->getTableName(true) . ' ].');
         return;
     }
     if (!array_key_exists('inverseColumn', $this->_relationship['through'])) {
         if ($primaryKey = $this->_relationshipMetadata->getPrimaryKey()) {
             $this->_relationship['through']['inverseColumn'] = $this->_relationshipMetadata->getTableName(true) . "_{$primaryKey}";
         } else {
             Piece_ORM_Error::push(PIECE_ORM_ERROR_INVALID_CONFIGURATION, 'A single primary key field is required, if the element [ column ] in the element [ through ] omit.');
             return;
         }
     }
     if (!$throughMetadata->hasField($this->_relationship['through']['inverseColumn'])) {
         Piece_ORM_Error::push(PIECE_ORM_ERROR_INVALID_CONFIGURATION, "The field [ {$this->_relationship['through']['inverseColumn']} ] not found in the table [ " . $throughMetadata->getTableName(true) . ' ].');
         return;
     }
 }
예제 #9
0
 /**
  * Adds a findOneXXX method and its query to the mapper source.
  *
  * @param string $methodName
  * @param string $query
  * @param string $orderBy
  * @throws PIECE_ORM_ERROR_INVALID_CONFIGURATION
  */
 function _addFindOne($methodName, $query, $orderBy)
 {
     if (!$query) {
         Piece_ORM_Error::push(PIECE_ORM_ERROR_INVALID_CONFIGURATION, 'The element [ query ] or its value is required to generate a findOne method declaration.');
         return;
     }
     $propertyName = strtolower($methodName);
     $this->_propertyDefinitions['query'][$propertyName] = $this->_generateQueryPropertyDeclaration($propertyName, $query);
     $this->_propertyDefinitions['orderBy'][$propertyName] = $this->_generateOrderByPropertyDeclaration($propertyName, $orderBy);
     $this->_methodDefinitions[strtolower($methodName)] = "\n    function {$methodName}(\$criteria = null)\n    {\n        return \$this->_findOne('{$methodName}', \$criteria);\n    }";
 }
예제 #10
0
 /**
  * Removes an object from a table.
  *
  * @param string $methodName
  * @return integer
  * @throws PIECE_ORM_ERROR_UNEXPECTED_VALUE
  */
 function delete($methodName)
 {
     if (!is_object($this->_subject)) {
         Piece_ORM_Error::push(PIECE_ORM_ERROR_UNEXPECTED_VALUE, "An unexpected value detected. {$methodName}() cannot receive non-object.");
         return;
     }
     if ($this->_metadata->hasPrimaryKey() && !$this->_validatePrimaryValues()) {
         Piece_ORM_Error::push(PIECE_ORM_ERROR_UNEXPECTED_VALUE, "An unexpected value detected. Correct values are required for the primary keys to invoke {$methodName}().");
         return;
     }
     foreach ($this->_relationships as $relationship) {
         $this->_associatedObjectPersisters[$relationship['type']]->delete($relationship);
         if (Piece_ORM_Error::hasErrors()) {
             return;
         }
     }
     return $this->_mapper->executeQueryWithCriteria($methodName, $this->_subject, true);
 }
예제 #11
0
 /**
  * Loads the LOB data of this field.
  *
  * @return string
  * @throws PIECE_ORM_ERROR_CANNOT_INVOKE
  * @throws PIECE_ORM_ERROR_UNEXPECTED_VALUE
  */
 function load()
 {
     PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
     $datatype =& $this->_dbh->loadModule('Datatype');
     PEAR::staticPopErrorHandling();
     if (MDB2::isError($datatype)) {
         Piece_ORM_Error::pushPEARError($datatype, PIECE_ORM_ERROR_CANNOT_INVOKE, 'Failed to invoke $dbh->loadModule() for any reasons.');
         return;
     }
     PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
     $lob = $datatype->convertResult($this->_value, $this->_metadata->getDatatype($this->_fieldName));
     PEAR::staticPopErrorHandling();
     if (MDB2::isError($lob)) {
         Piece_ORM_Error::pushPEARError($lob, PIECE_ORM_ERROR_CANNOT_INVOKE, 'Failed to invoke $datatype->convertResult() for any reasons.');
         return;
     }
     if (!is_resource($lob)) {
         Piece_ORM_Error::push(PIECE_ORM_ERROR_UNEXPECTED_VALUE, 'An unexpected value detected. $datatype->convertResult() should return a resource.');
         return;
     }
     $data = '';
     while (!feof($lob)) {
         $data .= fread($lob, 8192);
     }
     $datatype->destroyLOB($lob);
     return $data;
 }
예제 #12
0
 /**
  * Sets a database as the current database.
  *
  * @param string $database
  * @throws PIECE_ORM_ERROR_NOT_FOUND
  */
 function setDatabase($database)
 {
     if (!$this->_config->checkDatabase($database)) {
         Piece_ORM_Error::push(PIECE_ORM_ERROR_NOT_FOUND, "The given database [ {$database} ] not found in the current configuration.");
         return;
     }
     $this->_database = $database;
     $directorySuffix = $this->_config->getDirectorySuffix($this->_database);
     if (is_null($directorySuffix) || !strlen($directorySuffix)) {
         Piece_ORM_Mapper_Factory::setConfigDirectory($this->_mapperConfigDirectory);
     } else {
         Piece_ORM_Mapper_Factory::setConfigDirectory("{$this->_mapperConfigDirectory}/{$directorySuffix}");
     }
 }
예제 #13
0
 /**
  * Creates an object from the metadata.
  *
  * @param string $mapperName
  * @return stdClass
  * @throws PIECE_ORM_ERROR_INVALID_OPERATION
  */
 function &createObject($mapperName)
 {
     if (!$GLOBALS['PIECE_ORM_Configured']) {
         Piece_ORM_Error::push(PIECE_ORM_ERROR_INVALID_OPERATION, __FUNCTION__ . ' method must be called after calling configure().');
         $return = null;
         return $return;
     }
     $mapper =& Piece_ORM_Mapper_Factory::factory($mapperName);
     if (Piece_ORM_Error::hasErrors()) {
         $return = null;
         return $return;
     }
     return $mapper->createObject();
 }