Index: /fORM.php
===================================================================
--- /fORM.php (revision 591)
+++ /fORM.php (revision 603)
@@ -10,5 +10,6 @@
* @link http://flourishlib.com/fORM
*
- * @version 1.0.0b8
+ * @version 1.0.0b9
+ * @changes 1.0.0b9 Added caching for performance and changed some method APIs to only allow class names instead of instances [wb, 2009-06-15]
* @changes 1.0.0b8 Updated documentation to reflect removal of `$associate` parameter for callbacks passed to ::registerRecordSetMethod() [wb, 2009-06-02]
* @changes 1.0.0b7 Added ::enableSchemaCaching() to replace fORMSchema::enableSmartCaching() [wb, 2009-05-04]
@@ -60,4 +61,15 @@
/**
+ * Cache for repetitive computation
+ *
+ * @var array
+ */
+ static private $cache = array(
+ 'parseMethod' => array(),
+ 'getActiveRecordMethod' => array(),
+ 'objectify' => array()
+ );
+
+ /**
* Custom mappings for class <-> table
*
@@ -159,5 +171,5 @@
static public function callHookCallbacks($object, $hook, &$values, &$old_values, &$related_records, &$cache, &$parameter=NULL)
{
- $class = self::getClass($object);
+ $class = get_class($object);
if (empty(self::$hook_callbacks[$class][$hook]) && empty(self::$hook_callbacks['*'][$hook])) {
@@ -205,5 +217,5 @@
static public function callReflectCallbacks($object, &$signatures, $include_doc_comments)
{
- $class = self::getClass($object);
+ $class = get_class($object);
if (!isset(self::$reflect_callbacks[$class]) && !isset(self::$reflect_callbacks['*'])) {
@@ -242,5 +254,5 @@
* @internal
*
- * @param mixed $class The name of the class, or an instance of it
+ * @param string $class The name of the class
* @param string $hook The hook to check
* @param array $callback The specific callback to check for
@@ -249,6 +261,4 @@
static public function checkHookCallback($class, $hook, $callback=NULL)
{
- $class = self::getClass($class);
-
if (empty(self::$hook_callbacks[$class][$hook]) && empty(self::$hook_callbacks['*'][$hook])) {
return FALSE;
@@ -360,5 +370,5 @@
* @internal
*
- * @param mixed $class The name of the class, or an instance of it
+ * @param string $class The name of the class
* @param string $method The method to get the callback for
* @return string|null The callback for the method or `NULL` if none exists - see method description for details
@@ -366,22 +376,28 @@
static public function getActiveRecordMethod($class, $method)
{
- $class = self::getClass($class);
+ // This caches method lookups, providing a significant performance
+ // boost to pages with lots of method calls that get passed to
+ // fActiveRecord::__call()
+ if (isset(self::$cache['getActiveRecordMethod'][$class . '::' . $method])) {
+ return (!$method = self::$cache['getActiveRecordMethod'][$class . '::' . $method]) ? NULL : $method;
+ }
+
+ $callback = NULL;
if (isset(self::$active_record_method_callbacks[$class][$method])) {
- return self::$active_record_method_callbacks[$class][$method];
- }
-
- if (isset(self::$active_record_method_callbacks['*'][$method])) {
- return self::$active_record_method_callbacks['*'][$method];
- }
-
- if (preg_match('#[A-Z0-9]#', $method)) {
+ $callback = self::$active_record_method_callbacks[$class][$method];
+
+ } elseif (isset(self::$active_record_method_callbacks['*'][$method])) {
+ $callback = self::$active_record_method_callbacks['*'][$method];
+
+ } elseif (preg_match('#[A-Z0-9]#', $method)) {
list($action, $subject) = self::parseMethod($method);
if (isset(self::$active_record_method_callbacks[$class][$action . '*'])) {
- return self::$active_record_method_callbacks[$class][$action . '*'];
+ $callback = self::$active_record_method_callbacks[$class][$action . '*'];
}
}
- return NULL;
+ self::$cache['getActiveRecordMethod'][$class . '::' . $method] = ($callback === NULL) ? FALSE : $callback;
+ return $callback;
}
@@ -410,5 +426,5 @@
* @internal
*
- * @param mixed $class The class name or instance of the class the column is part of
+ * @param string $class The class name the column is part of
* @param string $column The database column
* @return string The column name for the column specified
@@ -416,6 +432,4 @@
static public function getColumnName($class, $column)
{
- $class = self::getClass($class);
-
if (!isset(self::$column_names[$class])) {
self::$column_names[$class] = array();
@@ -438,11 +452,9 @@
* @internal
*
- * @param mixed $class The class name or instance of the class to get the record name of
+ * @param string $class The class name to get the record name of
* @return string The record name for the class specified
*/
static public function getRecordName($class)
{
- $class = self::getClass($class);
-
if (!isset(self::$record_names[$class])) {
self::$record_names[$class] = fGrammar::humanize($class);
@@ -496,5 +508,9 @@
static public function objectify($class, $column, $value)
{
- $class = self::getClass($class);
+ // This short-circuits computation for already checked columns, providing
+ // a nice little performance boost to pages with lots of records
+ if (isset(self::$cache['objectify'][$class . '::' . $column])) {
+ return $value;
+ }
if (!empty(self::$objectify_callbacks[$class][$column])) {
@@ -520,4 +536,7 @@
// Validation exception results in the raw value being saved
}
+
+ } else {
+ self::$cache['objectify'][$class . '::' . $column] = TRUE;
}
@@ -576,4 +595,8 @@
static public function parseMethod($method)
{
+ if (isset(self::$cache['parseMethod'][$method])) {
+ return self::$cache['parseMethod'][$method];
+ }
+
if (!preg_match('#^([a-z]+)(.*)$#D', $method, $matches)) {
throw new fProgrammerException(
@@ -582,5 +605,6 @@
);
}
- return array($matches[1], fGrammar::underscorize($matches[2]));
+ self::$cache['parseMethod'][$method] = array($matches[1], fGrammar::underscorize($matches[2]));
+ return self::$cache['parseMethod'][$method];
}
@@ -617,4 +641,6 @@
self::$active_record_method_callbacks[$class][$method] = $callback;
+
+ self::$cache['getActiveRecordMethod'] = array();
}
@@ -733,4 +759,6 @@
self::$objectify_callbacks[$class][$column] = $callback;
+
+ self::$cache['objectify'] = array();
}
@@ -849,5 +877,5 @@
* @internal
*
- * @param mixed $class The class name or instance of the class the column is part of
+ * @param string $class The class the column is part of
* @param string $column The database column
* @param mixed $value The value to copy/clone
@@ -856,6 +884,4 @@
static public function replicate($class, $column, $value)
{
- $class = self::getClass($class);
-
if (!empty(self::$replicate_callbacks[$class][$column])) {
return call_user_func(self::$replicate_callbacks[$class][$column], $class, $column, $value);
@@ -879,6 +905,11 @@
static public function reset()
{
+ self::$active_record_method_callbacks = array();
+ self::$cache = array(
+ 'parseMethod' => array(),
+ 'getActiveRecordMethod' => array(),
+ 'objectify' => array()
+ );
self::$class_table_map = array();
- self::$active_record_method_callbacks = array();
self::$column_names = array();
self::$hook_callbacks = array();
@@ -928,6 +959,4 @@
static public function tablize($class)
{
- $class = self::getClass($class);
-
if (!isset(self::$class_table_map[$class])) {
self::$class_table_map[$class] = fGrammar::underscorize(fGrammar::pluralize($class));
Index: /fORMFile.php
===================================================================
--- /fORMFile.php (revision 600)
+++ /fORMFile.php (revision 603)
@@ -10,5 +10,6 @@
* @link http://flourishlib.com/fORMFile
*
- * @version 1.0.0b12
+ * @version 1.0.0b13
+ * @changes 1.0.0b13 Updated code for new fORM API [wb, 2009-06-15]
* @changes 1.0.0b12 Changed replacement values in preg_replace() calls to be properly escaped [wb, 2009-06-11]
* @changes 1.0.0b11 Updated code to use new fValidationException::formatField() method [wb, 2009-06-04]
@@ -744,5 +745,5 @@
list ($action, $column) = fORM::parseMethod($method_name);
- $class = fORM::getClass($object);
+ $class = get_class($object);
self::processImage($class, $column, $values[$column]);
Index: /fDatabase.php
===================================================================
--- /fDatabase.php (revision 600)
+++ /fDatabase.php (revision 603)
@@ -47,5 +47,6 @@
* @link http://flourishlib.com/fDatabase
*
- * @version 1.0.0b11
+ * @version 1.0.0b12
+ * @changes 1.0.0b12 Updates to ::unescape() to improve performance [wb, 2009-06-15]
* @changes 1.0.0b11 Changed replacement values in preg_replace() calls to be properly escaped [wb, 2009-06-11]
* @changes 1.0.0b10 Changed date/time/timestamp escaping from `strtotime()` to fDate/fTime/fTimestamp for better localization support [wb, 2009-06-01]
@@ -2280,24 +2281,7 @@
switch ($data_type) {
- case 'blob':
- case '%l':
- $callback = $this->unescapeBlob;
- break;
- case 'boolean':
- case '%b':
- $callback = $this->unescapeBoolean;
- break;
- case 'date':
- case '%d':
- $callback = $this->unescapeDate;
- break;
- case 'float':
- case '%f':
- $callback = $this->unescapeFloat;
- break;
- case 'integer':
- case '%i':
- $callback = $this->unescapeInteger;
- break;
+ // Testing showed that strings tend to be most common,
+ // and moving this to the top of the switch statement
+ // improved performance on read-heavy pages
case 'string':
case 'varchar':
@@ -2305,13 +2289,37 @@
case 'text':
case '%s':
- $callback = $this->unescapeString;
+ return $value;
+
+ case 'boolean':
+ case '%b':
+ $callback = $this->unescapeBoolean;
break;
+
+ case 'date':
+ case '%d':
+ $callback = $this->unescapeDate;
+ break;
+
+ case 'float':
+ case '%f':
+ return $value;
+
+ case 'integer':
+ case '%i':
+ return $value;
+
case 'time':
case '%t':
$callback = $this->unescapeTime;
break;
+
case 'timestamp':
case '%p':
$callback = $this->unescapeTimestamp;
+ break;
+
+ case 'blob':
+ case '%l':
+ $callback = $this->unescapeBlob;
break;
}
@@ -2382,40 +2390,4 @@
}
return date('Y-m-d', strtotime($value));
- }
-
-
- /**
- * Unescapes a float coming out of the database (included for completeness)
- *
- * @param string $value The value to unescape
- * @return float The float
- */
- private function unescapeFloat($value)
- {
- return $value;
- }
-
-
- /**
- * Unescapes an integer coming out of the database (included for completeness)
- *
- * @param string $value The value to unescape
- * @return integer The integer
- */
- private function unescapeInteger($value)
- {
- return $value;
- }
-
-
- /**
- * Unescapes a string coming out of the database (included for completeness)
- *
- * @param string $value The value to unescape
- * @return string The string
- */
- private function unescapeString($value)
- {
- return $value;
}
Index: /fActiveRecord.php
===================================================================
--- /fActiveRecord.php (revision 600)
+++ /fActiveRecord.php (revision 603)
@@ -16,5 +16,6 @@
* @link http://flourishlib.com/fActiveRecord
*
- * @version 1.0.0b20
+ * @version 1.0.0b21
+ * @changes 1.0.0b21 Performance tweaks and updates for fORM and fORMRelated API changes [wb, 2009-06-15]
* @changes 1.0.0b20 Changed replacement values in preg_replace() calls to be properly escaped [wb, 2009-06-11]
* @changes 1.0.0b19 Added `list{RelatedRecords}()` methods, updated code for new fORMRelated API [wb, 2009-06-02]
@@ -265,5 +266,7 @@
public function __call($method_name, $parameters)
{
- if ($callback = fORM::getActiveRecordMethod($this, $method_name)) {
+ $class = get_class($this);
+
+ if ($callback = fORM::getActiveRecordMethod($class, $method_name)) {
return call_user_func_array(
$callback,
@@ -326,7 +329,7 @@
if (isset($parameters[1])) {
- return fORMRelated::associateRecords($this, $this->related_records, $subject, $parameters[0], $parameters[1]);
- }
- return fORMRelated::associateRecords($this, $this->related_records, $subject, $parameters[0]);
+ return fORMRelated::associateRecords($class, $this->related_records, $subject, $parameters[0], $parameters[1]);
+ }
+ return fORMRelated::associateRecords($class, $this->related_records, $subject, $parameters[0]);
case 'build':
@@ -335,7 +338,7 @@
if (isset($parameters[0])) {
- return fORMRelated::buildRecords($this, $this->values, $this->related_records, $subject, $parameters[0]);
- }
- return fORMRelated::buildRecords($this, $this->values, $this->related_records, $subject);
+ return fORMRelated::buildRecords($class, $this->values, $this->related_records, $subject, $parameters[0]);
+ }
+ return fORMRelated::buildRecords($class, $this->values, $this->related_records, $subject);
case 'count':
@@ -344,7 +347,7 @@
if (isset($parameters[0])) {
- return fORMRelated::countRecords($this, $this->values, $this->related_records, $subject, $parameters[0]);
- }
- return fORMRelated::countRecords($this, $this->values, $this->related_records, $subject);
+ return fORMRelated::countRecords($class, $this->values, $this->related_records, $subject, $parameters[0]);
+ }
+ return fORMRelated::countRecords($class, $this->values, $this->related_records, $subject);
case 'create':
@@ -352,7 +355,7 @@
if (isset($parameters[0])) {
- return fORMRelated::createRecord($this, $this->values, $subject, $parameters[0]);
- }
- return fORMRelated::createRecord($this, $this->values, $subject);
+ return fORMRelated::createRecord($class, $this->values, $subject, $parameters[0]);
+ }
+ return fORMRelated::createRecord($class, $this->values, $subject);
case 'inject':
@@ -361,7 +364,7 @@
if (isset($parameters[1])) {
- return fORMRelated::setRecordSet($this, $this->related_records, $subject, $parameters[0], $parameters[1]);
- }
- return fORMRelated::setRecordSet($this, $this->related_records, $subject, $parameters[0]);
+ return fORMRelated::setRecordSet($class, $this->related_records, $subject, $parameters[0], $parameters[1]);
+ }
+ return fORMRelated::setRecordSet($class, $this->related_records, $subject, $parameters[0]);
case 'link':
@@ -370,7 +373,7 @@
if (isset($parameters[0])) {
- return fORMRelated::linkRecords($this, $this->related_records, $subject, $parameters[0]);
- }
- return fORMRelated::linkRecords($this, $this->related_records, $subject);
+ return fORMRelated::linkRecords($class, $this->related_records, $subject, $parameters[0]);
+ }
+ return fORMRelated::linkRecords($class, $this->related_records, $subject);
case 'list':
@@ -379,7 +382,7 @@
if (isset($parameters[0])) {
- return fORMRelated::getPrimaryKeys($this, $this->values, $this->related_records, $subject, $parameters[0]);
- }
- return fORMRelated::getPrimaryKeys($this, $this->values, $this->related_records, $subject);
+ return fORMRelated::getPrimaryKeys($class, $this->values, $this->related_records, $subject, $parameters[0]);
+ }
+ return fORMRelated::getPrimaryKeys($class, $this->values, $this->related_records, $subject);
case 'populate':
@@ -388,7 +391,7 @@
if (isset($parameters[0])) {
- return fORMRelated::populateRecords($this, $this->related_records, $subject, $parameters[0]);
- }
- return fORMRelated::populateRecords($this, $this->related_records, $subject);
+ return fORMRelated::populateRecords($class, $this->related_records, $subject, $parameters[0]);
+ }
+ return fORMRelated::populateRecords($class, $this->related_records, $subject);
case 'tally':
@@ -397,7 +400,7 @@
if (isset($parameters[1])) {
- return fORMRelated::setCount($this, $this->related_records, $subject, $parameters[0], $parameters[1]);
- }
- return fORMRelated::setCount($this, $this->related_records, $subject, $parameters[0]);
+ return fORMRelated::setCount($class, $this->related_records, $subject, $parameters[0], $parameters[1]);
+ }
+ return fORMRelated::setCount($class, $this->related_records, $subject, $parameters[0]);
// Error handler
@@ -426,4 +429,6 @@
public function __clone()
{
+ $class = get_class($this);
+
// Copy values and cache, making sure objects are cloned to prevent reference issues
$temp_values = $this->values;
@@ -431,5 +436,5 @@
$this->values =& $new_values;
foreach ($temp_values as $column => $value) {
- $this->values[$column] = fORM::replicate($this, $column, $value);
+ $this->values[$column] = fORM::replicate($class, $column, $value);
}
@@ -458,5 +463,5 @@
// If we have a single auto incrementing primary key, remove the value
- $table = fORM::tablize($this);
+ $table = fORM::tablize($class);
$pk_columns = fORMSchema::retrieve()->getKeys($table, 'primary');
@@ -500,5 +505,5 @@
}
- if (fORM::getActiveRecordMethod($this, '__construct')) {
+ if (fORM::getActiveRecordMethod($class, '__construct')) {
return $this->__call('__construct', array($key));
}
@@ -516,10 +521,11 @@
} elseif ($key !== NULL) {
- $pk_columns = fORMSchema::retrieve()->getKeys(fORM::tablize($this), 'primary');
+ $table = fORM::tablize($class);
+ $pk_columns = fORMSchema::retrieve()->getKeys($table, 'primary');
// If the primary key does not look properly formatted, check to see if it is a UNIQUE key
$is_unique_key = FALSE;
if (is_array($key) && (sizeof($pk_columns) == 1 || array_keys($key) != $pk_columns)) {
- $unique_keys = fORMSchema::retrieve()->getKeys(fORM::tablize($this), 'unique');
+ $unique_keys = fORMSchema::retrieve()->getKeys($table, 'unique');
$key_keys = array_keys($key);
foreach ($unique_keys as $unique_key) {
@@ -537,5 +543,5 @@
throw new fProgrammerException(
'An invalidly formatted primary or unique key was passed to this %s object',
- fORM::getRecordName($this)
+ fORM::getRecordName($class)
);
}
@@ -569,5 +575,5 @@
// Create an empty array for new objects
} else {
- $column_info = fORMSchema::retrieve()->getColumnInfo(fORM::tablize($this));
+ $column_info = fORMSchema::retrieve()->getColumnInfo(fORM::tablize($class));
foreach ($column_info as $column => $info) {
$this->values[$column] = NULL;
@@ -577,5 +583,5 @@
$this->old_values,
$column,
- fORM::objectify($this, $column, $info['default'])
+ fORM::objectify($class, $column, $info['default'])
);
}
@@ -584,5 +590,5 @@
fORM::callHookCallbacks(
- $this,
+ $class,
'post::__construct()',
$this->values,
@@ -646,5 +652,5 @@
protected function constructInsertSQL($sql_values)
{
- $sql = 'INSERT INTO ' . fORM::tablize($this) . ' (';
+ $sql = 'INSERT INTO ' . fORM::tablize(get_class($this)) . ' (';
$columns = '';
@@ -671,5 +677,5 @@
protected function constructUpdateSQL($sql_values)
{
- $table = fORM::tablize($this);
+ $table = fORM::tablize(get_class($this));
$sql = 'UPDATE ' . $table . ' SET ';
@@ -696,5 +702,7 @@
public function delete()
{
- if (fORM::getActiveRecordMethod($this, 'delete')) {
+ $class = get_class($this);
+
+ if (fORM::getActiveRecordMethod($class, 'delete')) {
return $this->__call('delete', array());
}
@@ -703,5 +711,5 @@
throw new fProgrammerException(
'This %s object does not yet exist in the database, and thus can not be deleted',
- fORM::getRecordName($this)
+ fORM::getRecordName($class)
);
}
@@ -715,5 +723,5 @@
);
- $table = fORM::tablize($this);
+ $table = fORM::tablize($class);
$inside_db_transaction = fORMDatabase::retrieve()->isInsideTransaction();
@@ -780,5 +788,5 @@
sprintf(
"
%1\$s
\n",
- self::compose('This %s can not be deleted because:', fORM::getRecordName($this)),
+ self::compose('This %s can not be deleted because:', fORM::getRecordName($class)),
join("\n", $restriction_messages)
)
@@ -825,7 +833,6 @@
// If we just deleted an object that has an auto-incrementing primary key,
// lets delete that value from the object since it is no longer valid
- $column_info = fORMSchema::retrieve()->getColumnInfo($table);
$pk_columns = fORMSchema::retrieve()->getKeys($table, 'primary');
- if (sizeof($pk_columns) == 1 && $column_info[$pk_columns[0]]['auto_increment']) {
+ if (sizeof($pk_columns) == 1 && fORMSchema::retrieve()->getColumnInfo($table, $pk_columns[0], 'auto_increment')) {
$this->values[$pk_columns[0]] = NULL;
unset($this->old_values[$pk_columns[0]]);
@@ -849,5 +856,5 @@
if ($e instanceof fValidationException) {
$message = $e->getMessage();
- $search = self::compose('This %s can not be deleted because:', fORM::getRecordName($this));
+ $search = self::compose('This %s can not be deleted because:', fORM::getRecordName($class));
if (stripos($message, $search) === FALSE) {
$regex = self::compose('This %s can not be deleted because:', '__');
@@ -855,5 +862,5 @@
$regex = '#(' . preg_quote($regex_parts[0], '#') . ').*?(' . preg_quote($regex_parts[0], '#') . ')#';
- $message = preg_replace($regex, '\1' . strtr(fORM::getRecordName($this), array('\\' => '\\\\', '$' => '\\$')) . '\2', $message);
+ $message = preg_replace($regex, '\1' . strtr(fORM::getRecordName($class), array('\\' => '\\\\', '$' => '\\$')) . '\2', $message);
$find = self::compose("One or more %s references it", '__');
@@ -909,5 +916,6 @@
}
- $column_type = fORMSchema::retrieve()->getColumnInfo(fORM::tablize($this), $column, 'type');
+ $table = fORM::tablize(get_class($this));
+ $column_type = fORMSchema::retrieve()->getColumnInfo($table, $column, 'type');
// Ensure the programmer is calling the function properly
@@ -950,5 +958,5 @@
// Make sure we don't mangle a non-float value
if ($column_type == 'float' && is_numeric($value)) {
- $column_decimal_places = fORMSchema::retrieve()->getColumnInfo(fORM::tablize($this), $column, 'decimal_places');
+ $column_decimal_places = fORMSchema::retrieve()->getColumnInfo($table, $column, 'decimal_places');
// If the user passed in a formatting value, use it
@@ -981,9 +989,11 @@
public function exists()
{
- if (fORM::getActiveRecordMethod($this, 'exists')) {
+ $class = get_class($this);
+
+ if (fORM::getActiveRecordMethod($class, 'exists')) {
return $this->__call('exists', array());
}
- $pk_columns = fORMSchema::retrieve()->getKeys(fORM::tablize($this), 'primary');
+ $pk_columns = fORMSchema::retrieve()->getKeys(fORM::tablize($class), 'primary');
$exists = FALSE;
@@ -1009,4 +1019,5 @@
protected function fetchResultFromUniqueKey($values)
{
+ $class = get_class($this);
try {
if ($values === array_combine(array_keys($values), array_fill(0, sizeof($values), NULL))) {
@@ -1014,5 +1025,5 @@
}
- $table = fORM::tablize($this);
+ $table = fORM::tablize($class);
$sql = 'SELECT * FROM ' . $table . ' WHERE ';
$conditions = array();
@@ -1028,5 +1039,5 @@
throw new fNotFoundException(
'The %s requested could not be found',
- fORM::getRecordName($this)
+ fORM::getRecordName($class)
);
}
@@ -1043,4 +1054,51 @@
*/
protected function get($column)
+ {
+ if (!isset($this->values[$column]) && !array_key_exists($column, $this->values)) {
+ throw new fProgrammerException(
+ 'The column specified, %s, does not exist',
+ $column
+ );
+ }
+ return $this->values[$column];
+ }
+
+
+ /**
+ * Takes a row of data or a primary key and makes a hash from the primary key
+ *
+ * @param mixed $data An array of the records data, an array of primary key data or a scalar primary key value
+ * @return string A hash of the record's primary key value
+ */
+ protected function hash($data)
+ {
+ $class = get_class($this);
+ $pk_columns = fORMSchema::retrieve()->getKeys(fORM::tablize(get_class($this)), 'primary');
+
+ // Build an array of just the primary key data
+ $pk_data = array();
+ foreach ($pk_columns as $pk_column) {
+ $pk_data[$pk_column] = fORM::scalarize(
+ $class,
+ $pk_column,
+ is_array($data) ? $data[$pk_column] : $data
+ );
+ if (is_numeric($pk_data[$pk_column]) || is_object($pk_data[$pk_column])) {
+ $pk_data[$pk_column] = (string) $pk_data[$pk_column];
+ }
+ }
+
+ return md5(serialize($pk_data));
+ }
+
+
+ /**
+ * Retrieves information about a column
+ *
+ * @param string $column The name of the column to inspect
+ * @param string $element The metadata element to retrieve
+ * @return mixed The metadata array for the column, or the metadata element specified
+ */
+ protected function inspect($column, $element=NULL)
{
if (!array_key_exists($column, $this->values)) {
@@ -1050,52 +1108,6 @@
);
}
- return $this->values[$column];
- }
-
-
- /**
- * Takes a row of data or a primary key and makes a hash from the primary key
- *
- * @param mixed $data An array of the records data, an array of primary key data or a scalar primary key value
- * @return string A hash of the record's primary key value
- */
- protected function hash($data)
- {
- $pk_columns = fORMSchema::retrieve()->getKeys(fORM::tablize($this), 'primary');
-
- // Build an array of just the primary key data
- $pk_data = array();
- foreach ($pk_columns as $pk_column) {
- $pk_data[$pk_column] = fORM::scalarize(
- $this,
- $pk_column,
- is_array($data) ? $data[$pk_column] : $data
- );
- if (is_numeric($pk_data[$pk_column]) || is_object($pk_data[$pk_column])) {
- $pk_data[$pk_column] = (string) $pk_data[$pk_column];
- }
- }
-
- return md5(serialize($pk_data));
- }
-
-
- /**
- * Retrieves information about a column
- *
- * @param string $column The name of the column to inspect
- * @param string $element The metadata element to retrieve
- * @return mixed The metadata array for the column, or the metadata element specified
- */
- protected function inspect($column, $element=NULL)
- {
- if (!array_key_exists($column, $this->values)) {
- throw new fProgrammerException(
- 'The column specified, %s, does not exist',
- $column
- );
- }
-
- $info = fORMSchema::retrieve()->getColumnInfo(fORM::tablize($this), $column);
+
+ $info = fORMSchema::retrieve()->getColumnInfo(fORM::tablize(get_class($this)), $column);
if (!in_array($info['type'], array('varchar', 'char', 'text'))) {
@@ -1138,10 +1150,12 @@
public function load()
{
- if (fORM::getActiveRecordMethod($this, 'load')) {
+ $class = get_class($this);
+
+ if (fORM::getActiveRecordMethod($class, 'load')) {
return $this->__call('load', array());
}
try {
- $table = fORM::tablize($this);
+ $table = fORM::tablize($class);
$sql = 'SELECT * FROM ' . $table . ' WHERE ' . fORMDatabase::createPrimaryKeyWhereClause($table, $table, $this->values, $this->old_values);
@@ -1152,5 +1166,5 @@
throw new fNotFoundException(
'The %s requested could not be found',
- fORM::getRecordName($this)
+ fORM::getRecordName($class)
);
}
@@ -1170,19 +1184,19 @@
protected function loadFromResult($result)
{
+ $class = get_class($this);
$row = $result->current();
- $column_info = fORMSchema::retrieve()->getColumnInfo(fORM::tablize($this));
+ $column_info = fORMSchema::retrieve()->getColumnInfo(fORM::tablize($class));
+
+ $db = fORMDatabase::retrieve();
foreach ($row as $column => $value) {
- if ($value === NULL) {
- $this->values[$column] = $value;
- } else {
- $this->values[$column] = fORMDatabase::retrieve()->unescape($column_info[$column]['type'], $value);
- }
-
- $this->values[$column] = fORM::objectify($this, $column, $this->values[$column]);
+ if ($value !== NULL) {
+ $value = $db->unescape($column_info[$column]['type'], $value);
+ }
+
+ $this->values[$column] = fORM::objectify($class, $column, $value);
}
// Save this object to the identity map
- $class = get_class($this);
$hash = $this->hash($row);
@@ -1247,5 +1261,7 @@
public function populate()
{
- if (fORM::getActiveRecordMethod($this, 'populate')) {
+ $class = get_class($this);
+
+ if (fORM::getActiveRecordMethod($class, 'populate')) {
return $this->__call('populate', array());
}
@@ -1260,5 +1276,5 @@
);
- $table = fORM::tablize($this);
+ $table = fORM::tablize($class);
$column_info = fORMSchema::retrieve()->getColumnInfo($table);
@@ -1308,9 +1324,9 @@
}
- $column_info = fORMSchema::retrieve()->getColumnInfo(fORM::tablize($this), $column);
+ $column_info = fORMSchema::retrieve()->getColumnInfo(fORM::tablize(get_class($this)), $column);
$column_type = $column_info['type'];
// Ensure the programmer is calling the function properly
- if (in_array($column_type, array('blob'))) {
+ if ($column_type == 'blob') {
throw new fProgrammerException(
'The column specified, %s, can not be prepared because it is a blob column',
@@ -1397,5 +1413,6 @@
$signatures = array();
- $columns_info = fORMSchema::retrieve()->getColumnInfo(fORM::tablize($this));
+ $class = get_class($this);
+ $columns_info = fORMSchema::retrieve()->getColumnInfo(fORM::tablize($class));
foreach ($columns_info as $column => $column_info) {
$camelized_column = fGrammar::camelize($column, TRUE);
@@ -1552,9 +1569,9 @@
}
- fORMRelated::reflect($this, $signatures, $include_doc_comments);
+ fORMRelated::reflect($class, $signatures, $include_doc_comments);
fORM::callReflectCallbacks($this, $signatures, $include_doc_comments);
- $reflection = new ReflectionClass(get_class($this));
+ $reflection = new ReflectionClass($class);
$methods = $reflection->getMethods();
@@ -1663,5 +1680,6 @@
$class = get_class($this);
$hash = self::hash($this->values);
-
+ $table = fORM::tablize($class);
+
// If the object has not been replicated yet, do it now
if (!isset(fActiveRecord::$replicate_map[$class])) {
@@ -1672,5 +1690,4 @@
// We need the primary key to get a hash, otherwise certain recursive relationships end up losing members
- $table = fORM::tablize($class);
$pk_columns = fORMSchema::retrieve()->getKeys($table, 'primary');
if (sizeof($pk_columns) == 1 && fORMSchema::retrieve()->getColumnInfo($table, $pk_columns[0], 'auto_increment')) {
@@ -1682,6 +1699,4 @@
$parameters = func_get_args();
-
- $table = fORM::tablize($this);
$recursive = FALSE;
@@ -1741,10 +1756,10 @@
'The related class specified, %1$s, does not appear to be in a many-to-many or one-to-many relationship with %$2s',
$parameter,
- fORM::getClass($this)
+ get_class($this)
);
}
// Get the related records
- $record_set = fORMRelated::buildRecords($this, $this->values, $this->related_records, $related_class, $route);
+ $record_set = fORMRelated::buildRecords($class, $this->values, $this->related_records, $related_class, $route);
// One-to-many records need to be replicated, possibly recursively
@@ -1763,5 +1778,5 @@
// Cause the related records to be associated with the new clone
- fORMRelated::associateRecords($this, $clone->related_records, $related_class, $record_set, $route);
+ fORMRelated::associateRecords($class, $clone->related_records, $related_class, $record_set, $route);
}
@@ -1807,9 +1822,10 @@
}
- $value = fORM::objectify($this, $column, $value);
+ $class = get_class($this);
+ $value = fORM::objectify($class, $column, $value);
// Float and int columns that look like numbers with commas will have the commas removed
if (is_string($value)) {
- $table = fORM::tablize($this);
+ $table = fORM::tablize($class);
$type = fORMSchema::retrieve()->getColumnInfo($table, $column, 'type');
if (in_array($type, array('integer', 'float')) && preg_match('#^(\d+,)+\d+(\.\d+)?$#', $value)) {
@@ -1834,5 +1850,7 @@
public function store()
{
- if (fORM::getActiveRecordMethod($this, 'store')) {
+ $class = get_class($this);
+
+ if (fORM::getActiveRecordMethod($class, 'store')) {
return $this->__call('store', array());
}
@@ -1848,5 +1866,5 @@
try {
- $table = fORM::tablize($this);
+ $table = fORM::tablize($class);
$column_info = fORMSchema::retrieve()->getColumnInfo($table);
@@ -1892,5 +1910,5 @@
$sql_values = array();
foreach ($column_info as $column => $info) {
- $value = fORM::scalarize($this, $column, $this->values[$column]);
+ $value = fORM::scalarize($class, $column, $this->values[$column]);
$sql_values[$column] = fORMDatabase::escapeBySchema($table, $column, $value);
}
@@ -1916,5 +1934,5 @@
// Storing *-to-many relationships
- fORMRelated::store($this, $this->values, $this->related_records);
+ fORMRelated::store($class, $this->values, $this->related_records);
@@ -1992,5 +2010,7 @@
public function validate($return_messages=FALSE)
{
- if (fORM::getActiveRecordMethod($this, 'validate')) {
+ $class = get_class($this);
+
+ if (fORM::getActiveRecordMethod($class, 'validate')) {
return $this->__call('validate', array($return_messages));
}
@@ -2012,5 +2032,5 @@
// Validate related records
- $related_validation_messages = fORMValidation::validateRelated($this, $this->related_records);
+ $related_validation_messages = fORMValidation::validateRelated($class, $this->related_records);
$validation_messages = array_merge($validation_messages, $local_validation_messages, $related_validation_messages);
@@ -2026,5 +2046,5 @@
);
- fORMValidation::reorderMessages($this, $validation_messages);
+ fORMValidation::reorderMessages($class, $validation_messages);
if ($return_messages) {
Index: /fORMSchema.php
===================================================================
--- /fORMSchema.php (revision 562)
+++ /fORMSchema.php (revision 603)
@@ -10,5 +10,6 @@
* @link http://flourishlib.com/fORMSchema
*
- * @version 1.0.0b2
+ * @version 1.0.0b3
+ * @changes 1.0.0b3 Added routes caching for performance [wb, 2009-06-15]
* @changes 1.0.0b2 Backwards Compatiblity Break - removed ::enableSmartCaching(), fORM::enableSchemaCaching() now provides equivalent functionality [wb, 2009-05-04]
* @changes 1.0.0b The initial implementation [wb, 2007-06-14]
@@ -27,4 +28,14 @@
/**
+ * A cache for computed information
+ *
+ * @var array
+ */
+ static private $cache = array(
+ 'getRoutes' => array()
+ );
+
+
+ /**
* The schema object to use for all ORM functionality
*
@@ -204,4 +215,9 @@
static public function getRoutes($table, $related_table, $relationship_type=NULL)
{
+ $key = $table . '::' . $related_table . '::' . $relationship_type;
+ if (isset(self::$cache['getRoutes'][$key])) {
+ return self::$cache['getRoutes'][$key];
+ }
+
$valid_relationship_types = array(
NULL,
@@ -249,4 +265,6 @@
}
+ self::$cache['getRoutes'][$key] = $routes;
+
return $routes;
}
Index: /fGrammar.php
===================================================================
--- /fGrammar.php (revision 600)
+++ /fGrammar.php (revision 603)
@@ -10,5 +10,6 @@
* @link http://flourishlib.com/fGrammar
*
- * @version 1.0.0b2
+ * @version 1.0.0b4
+ * @changes 1.0.0b4 Added caching for various methods - provided significant performance boost to ORM [wb, 2009-06-15]
* @changes 1.0.0b3 Changed replacement values in preg_replace() calls to be properly escaped [wb, 2009-06-11]
* @changes 1.0.0b2 Fixed a bug where some words would lose capitalization with ::pluralize() and ::singularize() [wb, 2009-01-25]
@@ -31,4 +32,17 @@
const underscorize = 'fGrammar::underscorize';
+
+ /**
+ * Cache for plural <-> singular and underscore <-> camelcase
+ *
+ * @var array
+ */
+ static private $cache = array(
+ 'camelize' => array(0 => array(), 1 => array()),
+ 'humanize' => array(),
+ 'pluralize' => array(),
+ 'singularize' => array(),
+ 'underscorize' => array()
+ );
/**
@@ -124,4 +138,6 @@
{
self::$humanize_rules[$non_humanized_string] = $humanized_string;
+
+ self::$cache['humanize'] = array();
}
@@ -139,4 +155,7 @@
self::$underscorize_rules[$camel_case] = $underscore_notation;
self::$camelize_rules[$underscore_notation] = $camel_case;
+
+ self::$cache['camelize'] = array(0 => array(), 1 => array());
+ self::$cache['underscorize'] = array();
}
@@ -165,4 +184,7 @@
self::$plural_to_singular_rules
);
+
+ self::$cache['pluralize'] = array();
+ self::$cache['singularize'] = array();
}
@@ -177,32 +199,39 @@
static public function camelize($string, $upper)
{
+ $upper = (int) $upper;
+ if (isset(self::$cache['camelize'][$upper][$string])) {
+ return self::$cache['camelize'][$upper][$string];
+ }
+
+ $original = $string;
+
// Handle custom rules
if (isset(self::$camelize_rules[$string])) {
- $camel = self::$camelize_rules[$string];
+ $string = self::$camelize_rules[$string];
if ($upper) {
- return strtoupper($camel[0]) . substr($camel, 1);
+ $string = strtoupper($camel[0]) . substr($camel, 1);
}
- return $camel;
- }
// Make a humanized string like underscore notation
- if (strpos($string, ' ') !== FALSE) {
+ } elseif (strpos($string, ' ') !== FALSE) {
$string = strtolower(preg_replace('#\s+#', '_', $string));
- }
// Check to make sure this is not already camel case
- if (strpos($string, '_') === FALSE) {
+ } elseif (strpos($string, '_') === FALSE) {
if ($upper) {
$string = strtoupper($string[0]) . substr($string, 1);
}
- return $string;
- }
-
+
// Handle underscore notation
- $string = strtolower($string);
- if ($upper) {
- $string = strtoupper($string[0]) . substr($string, 1);
- }
- return preg_replace('/(_([a-z0-9]))/e', 'strtoupper("\2")', $string);
+ } else {
+ $string = strtolower($string);
+ if ($upper) {
+ $string = strtoupper($string[0]) . substr($string, 1);
+ }
+ $string = preg_replace('/(_([a-z0-9]))/e', 'strtoupper("\2")', $string);
+ }
+
+ self::$cache['camelize'][$upper][$original] = $string;
+ return $string;
}
@@ -216,23 +245,31 @@
static public function humanize($string)
{
+ if (isset(self::$cache['humanize'][$string])) {
+ return self::$cache['humanize'][$string];
+ }
+
+ $original = $string;
+
if (isset(self::$humanize_rules[$string])) {
- return self::$humanize_rules[$string];
- }
-
- // If there is a space, it is already humanized
- if (strpos($string, ' ') !== FALSE) {
- return $string;
- }
-
- // If we don't have an underscore we probably have camelCase
- if (strpos($string, '_') === FALSE) {
- $string = self::underscorize($string);
- }
-
- return preg_replace(
- '/(\b(api|css|gif|html|id|jpg|js|mp3|pdf|php|png|sql|swf|url|xhtml|xml)\b|\b\w)/e',
- 'strtoupper("\1")',
- str_replace('_', ' ', $string)
- );
+ $string = self::$humanize_rules[$string];
+
+ // If there is no space, it isn't already humanized
+ } elseif (strpos($string, ' ') === FALSE) {
+
+ // If we don't have an underscore we probably have camelCase
+ if (strpos($string, '_') === FALSE) {
+ $string = self::underscorize($string);
+ }
+
+ $string = preg_replace(
+ '/(\b(api|css|gif|html|id|jpg|js|mp3|pdf|php|png|sql|swf|url|xhtml|xml)\b|\b\w)/e',
+ 'strtoupper("\1")',
+ str_replace('_', ' ', $string)
+ );
+ }
+
+ self::$cache['humanize'][$original] = $string;
+
+ return $string;
}
@@ -347,11 +384,26 @@
static public function pluralize($singular_noun)
{
+ if (isset(self::$cache['pluralize'][$singular_noun])) {
+ return self::$cache['pluralize'][$singular_noun];
+ }
+
+ $original = $singular_noun;
+ $plural_noun = NULL;
+
list ($beginning, $singular_noun) = self::splitLastWord($singular_noun);
foreach (self::$singular_to_plural_rules as $from => $to) {
if (preg_match('#' . $from . '#iD', $singular_noun)) {
- return $beginning . preg_replace('#' . $from . '#iD', $to, $singular_noun);
+ $plural_noun = $beginning . preg_replace('#' . $from . '#iD', $to, $singular_noun);
+ break;
}
}
- throw new fProgrammerException('The noun specified could not be pluralized');
+
+ if (!$plural_noun) {
+ throw new fProgrammerException('The noun specified could not be pluralized');
+ }
+
+ self::$cache['pluralize'][$original] = $plural_noun;
+
+ return $plural_noun;
}
@@ -384,5 +436,12 @@
static public function reset()
{
- self::$camelize_rules = array();
+ self::$cache = array(
+ 'camelize' => array(0 => array(), 1 => array()),
+ 'humanize' => array(),
+ 'pluralize' => array(),
+ 'singularize' => array(),
+ 'underscorize' => array()
+ );
+ self::$camelize_rules = array();
self::$humanize_rules = array();
self::$join_array_callback = NULL;
@@ -439,11 +498,26 @@
static public function singularize($plural_noun)
{
+ if (isset(self::$cache['singularize'][$plural_noun])) {
+ return self::$cache['singularize'][$plural_noun];
+ }
+
+ $original = $plural_noun;
+ $singular_noun = NULL;
+
list ($beginning, $plural_noun) = self::splitLastWord($plural_noun);
foreach (self::$plural_to_singular_rules as $from => $to) {
if (preg_match('#' . $from . '#iD', $plural_noun)) {
- return $beginning . preg_replace('#' . $from . '#iD', $to, $plural_noun);
+ $singular_noun = $beginning . preg_replace('#' . $from . '#iD', $to, $plural_noun);
+ break;
}
}
- throw new fProgrammerException('The noun specified could not be singularized');
+
+ if (!$singular_noun) {
+ throw new fProgrammerException('The noun specified could not be singularized');
+ }
+
+ self::$cache['singularize'][$original] = $singular_noun;
+
+ return $singular_noun;
}
@@ -485,28 +559,35 @@
static public function underscorize($string)
{
+ if (isset(self::$cache['underscorize'][$string])) {
+ return self::$cache['underscorize'][$string];
+ }
+
+ $original = $string;
$string = strtolower($string[0]) . substr($string, 1);
// Handle custom rules
if (isset(self::$underscorize_rules[$string])) {
- return self::$underscorize_rules[$string];
- }
+ $string = self::$underscorize_rules[$string];
// If the string is already underscore notation then leave it
- if (strpos($string, '_') !== FALSE) {
- return $string;
- }
+ } elseif (strpos($string, '_') !== FALSE) {
// Allow humanized string to be passed in
- if (strpos($string, ' ') !== FALSE) {
- return strtolower(preg_replace('#\s+#', '_', $string));
- }
-
- do {
- $old_string = $string;
- $string = preg_replace('/([a-zA-Z])([0-9])/', '\1_\2', $string);
- $string = preg_replace('/([a-z0-9A-Z])([A-Z])/', '\1_\2', $string);
- } while ($old_string != $string);
-
- return strtolower($string);
+ } elseif (strpos($string, ' ') !== FALSE) {
+ $string = strtolower(preg_replace('#\s+#', '_', $string));
+
+ } else {
+ do {
+ $old_string = $string;
+ $string = preg_replace('/([a-zA-Z])([0-9])/', '\1_\2', $string);
+ $string = preg_replace('/([a-z0-9A-Z])([A-Z])/', '\1_\2', $string);
+ } while ($old_string != $string);
+
+ $string = strtolower($string);
+ }
+
+ self::$cache['underscorize'][$original] = $string;
+
+ return $string;
}
Index: /fORMOrdering.php
===================================================================
--- /fORMOrdering.php (revision 602)
+++ /fORMOrdering.php (revision 603)
@@ -10,5 +10,6 @@
* @link http://flourishlib.com/fORMOrdering
*
- * @version 1.0.0b5
+ * @version 1.0.0b6
+ * @changes 1.0.0b6 Updated code for new fORM API [wb, 2009-06-15]
* @changes 1.0.0b5 Updated class to automatically correct ordering values that are too high [wb, 2009-06-14]
* @changes 1.0.0b4 Updated code to use new fValidationException::formatField() method [wb, 2009-06-04]
@@ -561,5 +562,5 @@
static public function validate($object, &$values, &$old_values, &$related_records, &$cache, &$validation_messages)
{
- $class = fORM::getClass($object);
+ $class = get_class($object);
$table = fORM::tablize($class);
Index: /fORMRelated.php
===================================================================
--- /fORMRelated.php (revision 598)
+++ /fORMRelated.php (revision 603)
@@ -13,5 +13,6 @@
* @link http://flourishlib.com/fORMRelated
*
- * @version 1.0.0b6
+ * @version 1.0.0b7
+ * @changes 1.0.0b7 Updated code for new fORM API, fixed API documentation bugs [wb, 2009-06-15]
* @changes 1.0.0b6 Updated code to use new fValidationException::formatField() method [wb, 2009-06-04]
* @changes 1.0.0b5 Added ::getPrimaryKeys() and ::setPrimaryKeys(), renamed ::setRecords() to ::setRecordSet() and ::tallyRecords() to ::setCount() [wb, 2009-06-02]
@@ -67,5 +68,5 @@
* @internal
*
- * @param mixed $class The class name or instance of the class to get the related values for
+ * @param string $class The class to get the related values for
* @param array &$related_records The related records existing for the fActiveRecord class
* @param string $related_class The class we are associating with the current record
@@ -111,5 +112,5 @@
* @internal
*
- * @param mixed $class The class name or instance of the class to get the related values for
+ * @param string $class The class to get the related values for
* @param array &$values The values for the fActiveRecord class
* @param array &$related_records The related records existing for the fActiveRecord class
@@ -186,5 +187,5 @@
* @internal
*
- * @param mixed $class The class name or instance of the class to get the related values for
+ * @param string $class The class to get the related values for
* @param array &$values The values for the fActiveRecord class
* @param array &$related_records The related records existing for the fActiveRecord class
@@ -242,5 +243,5 @@
* @internal
*
- * @param mixed $class The class name or instance of the class to get the related values for
+ * @param string $class The class to create the related record for
* @param array $values The values existing in the fActiveRecord class
* @param string $related_class The related class name
@@ -250,6 +251,5 @@
static public function createRecord($class, $values, $related_class, $route=NULL)
{
- $table = fORM::tablize($class);
-
+ $table = fORM::tablize($class);
$related_table = fORM::tablize($related_class);
@@ -265,5 +265,5 @@
* @internal
*
- * @param mixed $class The class name or instance of the main class
+ * @param string $class The class name of the main class
* @param string $related_class The related class being filtered for
* @param string $route The route to the related table
@@ -300,5 +300,5 @@
* @internal
*
- * @param mixed $class The class name or instance of the class to get the related values for
+ * @param string $class The class to associate the related records to
* @param array &$related_records The related records existing for the fActiveRecord class
* @param string $related_class The class we are associating with the current record
@@ -331,5 +331,5 @@
* @internal
*
- * @param mixed $class The class name or instance of the class this ordering rule applies to
+ * @param string $class The class to get the order bys for
* @param string $related_class The related class the ordering rules apply to
* @param string $route The route to the related table, should be a column name in the current table or a join table name
@@ -356,5 +356,5 @@
* @internal
*
- * @param mixed $class The class name or instance of the class to get the related values for
+ * @param string $class The class to get the related primary keys for
* @param array &$values The values for the fActiveRecord class
* @param array &$related_records The related records existing for the fActiveRecord class
@@ -448,13 +448,11 @@
* @internal
*
- * @param mixed $class The class name or instance of the class to get the related class name for
- * @param mixed $related_class The related class/class name to get the record name of
+ * @param string $class The class to get the related class name for
+ * @param string $related_class The related class to get the record name of
* @return string The record name for the related class specified
*/
static public function getRelatedRecordName($class, $related_class, $route=NULL)
{
- $table = fORM::tablize($class);
-
- $related_class = fORM::getClass($related_class);
+ $table = fORM::tablize($class);
$related_table = fORM::tablize($related_class);
@@ -476,5 +474,5 @@
* @internal
*
- * @param mixed $class The class name or instance of the class to get the related values for
+ * @param string $class The class to get link the related records to
* @param array &$related_records The related records existing for the fActiveRecord class
* @param string $related_class The related class to populate
@@ -551,6 +549,6 @@
static public function overrideRelatedRecordName($class, $related_class, $record_name, $route=NULL)
{
- $table = fORM::tablize($class);
-
+ $class = fORM::getClass($class);
+ $table = fORM::tablize($class);
$related_class = fORM::getClass($related_class);
$related_table = fORM::tablize($related_class);
@@ -575,5 +573,5 @@
* @internal
*
- * @param mixed $class The class name or instance of the class to get the related values for
+ * @param string $class The class to populate the related records of
* @param array &$related_records The related records existing for the fActiveRecord class
* @param string $related_class The related class to populate
@@ -583,4 +581,5 @@
static public function populateRecords($class, &$related_records, $related_class, $route=NULL)
{
+ $table = fORM::tablize($class);
$related_table = fORM::tablize($related_class);
$pk_columns = fORMSchema::retrieve()->getKeys($related_table, 'primary');
@@ -590,5 +589,5 @@
$first_pk_column = NULL;
- $relationships = fORMSchema::getRoutes($related_table, fORM::tablize($class), '*-to-one');
+ $relationships = fORMSchema::getRoutes($related_table, $table, '*-to-one');
foreach ($pk_columns as $pk_column) {
foreach ($relationships as $relationship) {
@@ -652,5 +651,5 @@
* @internal
*
- * @param mixed $class The class name or instance of the class this ordering rule applies to
+ * @param string $class The class to reflect the related record methods for
* @param array &$signatures The associative array of `{method_name} => {signature}`
* @param boolean $include_doc_comments If the doc block comments for each method should be included
@@ -882,4 +881,5 @@
static public function setOrderBys($class, $related_class, $order_bys, $route=NULL)
{
+ $class = fORM::getClass($class);
$table = fORM::tablize($class);
$related_table = fORM::tablize($related_class);
@@ -904,5 +904,5 @@
* @internal
*
- * @param mixed $class The class name or instance of the class to get the related values for
+ * @param string $class The class to set the related records count for
* @param array &$values The values for the fActiveRecord class
* @param array &$related_records The related records existing for the fActiveRecord class
@@ -942,5 +942,5 @@
* @internal
*
- * @param mixed $class The class name or instance of the class to get the related values for
+ * @param string $class The class to set the related primary keys for
* @param array &$related_records The related records existing for the fActiveRecord class
* @param string $related_class The class we are setting the records for
@@ -975,5 +975,5 @@
* @internal
*
- * @param mixed $class The class name or instance of the class to get the related values for
+ * @param string $class The class to set the related records for
* @param array &$related_records The related records existing for the fActiveRecord class
* @param string $related_class The class we are associating with the current record
@@ -1008,7 +1008,7 @@
* @internal
*
- * @param mixed $class The class name or instance of the class to store the related records for
- * @param array &$values The current values for the main record being stored
- * @param array &$related_records The related records array
+ * @param string $class The class to store the related records for
+ * @param array &$values The current values for the main record being stored
+ * @param array &$related_records The related records array
* @return void
*/
@@ -1156,11 +1156,10 @@
* @internal
*
- * @param mixed $class The class name or instance of the class to validate the related records for
- * @param array &$related_records The related records array
+ * @param string $class The class to validate the related records for
+ * @param array &$related_records The related records array
* @return void
*/
static public function validate($class, &$related_records)
{
- $class = fORM::getClass($class);
$table = fORM::tablize($class);
@@ -1196,5 +1195,5 @@
* @internal
*
- * @param mixed $class The class name or instance of the class these records are related to
+ * @param string $class The class to validate the related records for
* @param string $related_class The name of the class for this record set
* @param string $route The route between the table and related table
@@ -1254,5 +1253,5 @@
* @internal
*
- * @param mixed $class The class name or instance of the class these records are related to
+ * @param string $class The class to validate the related records for
* @param string $related_class The name of the class for this record set
* @param string $route The route between the table and related table
Index: /fSchema.php
===================================================================
--- /fSchema.php (revision 597)
+++ /fSchema.php (revision 603)
@@ -10,5 +10,6 @@
* @link http://flourishlib.com/fSchema
*
- * @version 1.0.0b19
+ * @version 1.0.0b20
+ * @changes 1.0.0b20 Add caching of merged info, improved performance of ::getColumnInfo() [wb, 2009-06-15]
* @changes 1.0.0b19 Fixed a couple of bugs with ::setKeysOverride() [wb, 2009-06-04]
* @changes 1.0.0b18 Added missing support for MySQL mediumint columns [wb, 2009-05-18]
@@ -176,4 +177,7 @@
$this->cache->delete($prefix . 'databases');
$this->cache->delete($prefix . 'keys');
+ $this->cache->delete($prefix . 'merged_column_info');
+ $this->cache->delete($prefix . 'merged_keys');
+ $this->cache->delete($prefix . 'relationships');
$this->cache->delete($prefix . 'tables');
}
@@ -192,8 +196,15 @@
$prefix = $this->makeCachePrefix();
- $this->column_info = $this->cache->get($prefix . 'column_info', array());
- $this->databases = $this->cache->get($prefix . 'databases', NULL);
- $this->keys = $this->cache->get($prefix . 'keys', array());
- $this->tables = $this->cache->get($prefix . 'tables', NULL);
+ $this->column_info = $this->cache->get($prefix . 'column_info', array());
+ $this->databases = $this->cache->get($prefix . 'databases', NULL);
+ $this->keys = $this->cache->get($prefix . 'keys', array());
+
+ if (!$this->column_info_override && !$this->keys_override) {
+ $this->merged_column_info = $this->cache->get($prefix . 'merged_column_info', array());
+ $this->merged_keys = $this->cache->get($prefix . 'merged_keys', array());
+ $this->relationships = $this->cache->get($prefix . 'relationships', array());
+ }
+
+ $this->tables = $this->cache->get($prefix . 'tables', NULL);
}
@@ -1714,4 +1725,8 @@
$this->findOneToManyRelationships($table);
}
+
+ if ($this->cache) {
+ $this->cache->set($this->makeCachePrefix() . 'relationships', $this->relationships);
+ }
}
@@ -1772,11 +1787,20 @@
public function getColumnInfo($table, $column=NULL, $element=NULL)
{
- $valid_elements = array('type', 'not_null', 'default', 'valid_values', 'max_length', 'decimal_places', 'auto_increment');
- if ($element && !in_array($element, $valid_elements)) {
- throw new fProgrammerException(
- 'The element specified, %1$s, is invalid. Must be one of: %2$s.',
- $element,
- join(', ', $valid_elements)
- );
+ // Return the saved column info if possible
+ if (!$column && isset($this->merged_column_info[$table])) {
+ return $this->merged_column_info[$table];
+ }
+ if ($column && isset($this->merged_column_info[$table][$column])) {
+ if ($element !== NULL) {
+ if (!isset($this->merged_column_info[$table][$column][$element]) && !array_key_exists($element, $this->merged_column_info[$table][$column])) {
+ throw new fProgrammerException(
+ 'The element specified, %1$s, is invalid. Must be one of: %2$s.',
+ $element,
+ join(', ', array('type', 'not_null', 'default', 'valid_values', 'max_length', 'decimal_places', 'auto_increment'))
+ );
+ }
+ return $this->merged_column_info[$table][$column][$element];
+ }
+ return $this->merged_column_info[$table][$column];
}
@@ -1786,15 +1810,4 @@
$table
);
- }
-
- // Return the saved column info if possible
- if (!$column && isset($this->merged_column_info[$table])) {
- return $this->merged_column_info[$table];
- }
- if ($column && isset($this->merged_column_info[$table][$column])) {
- if ($element !== NULL) {
- return $this->merged_column_info[$table][$column][$element];
- }
- return $this->merged_column_info[$table][$column];
}
@@ -2218,4 +2231,8 @@
}
}
+
+ if ($this->cache) {
+ $this->cache->set($this->makeCachePrefix() . 'merged_column_info', $this->merged_column_info);
+ }
}
@@ -2236,4 +2253,8 @@
}
$this->merged_keys[$table] = array_merge($this->merged_keys[$table], $info);
+ }
+
+ if ($this->cache) {
+ $this->cache->set($this->makeCachePrefix() . 'merged_keys', $this->merged_keys);
}
Index: /fORMValidation.php
===================================================================
--- /fORMValidation.php (revision 598)
+++ /fORMValidation.php (revision 603)
@@ -10,5 +10,6 @@
* @link http://flourishlib.com/fORMValidation
*
- * @version 1.0.0b8
+ * @version 1.0.0b9
+ * @changes 1.0.0b9 Updated code for new fORM API [wb, 2009-06-15]
* @changes 1.0.0b8 Updated code to use new fValidationException::formatField() method [wb, 2009-06-04]
* @changes 1.0.0b7 Updated ::validateRelated() to use new fORMRelated::validate() method and ::checkRelatedOneOrMoreRule() to use new `$related_records` structure [wb, 2009-06-02]
@@ -230,5 +231,5 @@
static private function checkAgainstSchema($object, $column, &$values, &$old_values)
{
- $class = fORM::getClass($object);
+ $class = get_class($object);
$table = fORM::tablize($class);
@@ -282,5 +283,5 @@
* Validates against a conditional validation rule
*
- * @param mixed $class The class name or instance of the class this validation rule applies to
+ * @param string $class The class this validation rule applies to
* @param array &$values An associative array of all values for the record
* @param string $main_column The column to check for a value
@@ -316,5 +317,5 @@
* Validates a value against the database data type
*
- * @param mixed $class The class name or instance of the class the column is part of
+ * @param string $class The class the column is part of
* @param string $column The column to check
* @param mixed $value The value to check
@@ -387,5 +388,5 @@
* Validates values against foreign key constraints
*
- * @param mixed $class The class name or instance of the class to check the foreign keys for
+ * @param string $class The class to check the foreign keys for
* @param string $column The column to check
* @param array &$values The values to check
@@ -426,5 +427,5 @@
* Validates against a one-or-more validation rule
*
- * @param mixed $class The class name or instance of the class the columns are part of
+ * @param string $class The class the columns are part of
* @param array &$values An associative array of all values for the record
* @param array $columns The columns to check
@@ -458,5 +459,5 @@
* Validates against an only-one validation rule
*
- * @param mixed $class The class name or instance of the class the columns are part of
+ * @param string $class The class the columns are part of
* @param array &$values An associative array of all values for the record
* @param array $columns The columns to check
@@ -504,5 +505,5 @@
static private function checkPrimaryKeys($object, &$values, &$old_values)
{
- $class = fORM::getClass($object);
+ $class = get_class($object);
$table = fORM::tablize($class);
@@ -570,5 +571,5 @@
* Validates against a *-to-many one or more validation rule
*
- * @param mixed $class The class name or instance of the class we are checking
+ * @param string $class The class we are checking
* @param array &$related_records The related records array to check
* @param string $related_class The name of the related class
@@ -604,5 +605,5 @@
static private function checkUniqueConstraints($object, $column, &$values, &$old_values)
{
- $class = fORM::getClass($object);
+ $class = get_class($object);
$table = fORM::tablize($class);
@@ -700,5 +701,5 @@
* @internal
*
- * @param mixed $class The class name or an instance of the class to initilize the arrays for
+ * @param string $class The class to initilize the arrays for
* @return void
*/
@@ -717,5 +718,5 @@
* @internal
*
- * @param mixed $class The class to check
+ * @param string $class The class to check
* @param string $column The column to check
* @return boolean If the column is set to be case insensitive
@@ -723,8 +724,5 @@
static private function isCaseInsensitive($class, $column)
{
- if (!isset(self::$case_insensitive_columns[$class][$column])) {
- return FALSE;
- }
- return TRUE;
+ return isset(self::$case_insensitive_columns[$class][$column]);
}
@@ -735,12 +733,10 @@
* @internal
*
- * @param mixed $class The class name or an instance of the class to reorder messages for
- * @param array &$validation_messages An array of one validation message per value
+ * @param string $class The class to reorder messages for
+ * @param array &$validation_messages An array of one validation message per value
* @return void
*/
static public function reorderMessages($class, &$validation_messages)
{
- $class = fORM::getClass($class);
-
if (!isset(self::$message_orders[$class])) {
return;
@@ -882,5 +878,5 @@
static public function validate($object, $values, $old_values)
{
- $class = fORM::getClass($object);
+ $class = get_class($object);
$table = fORM::tablize($class);
@@ -932,11 +928,10 @@
* @internal
*
- * @param mixed $class The class name or instance of the class to validate
- * @param array &$related_records The related records to validate
+ * @param string $class The class to validate
+ * @param array &$related_records The related records to validate
* @return array An array of validation messages
*/
static public function validateRelated($class, &$related_records)
{
- $class = fORM::getClass($class);
$table = fORM::tablize($class);
Index: /fORMColumn.php
===================================================================
--- /fORMColumn.php (revision 598)
+++ /fORMColumn.php (revision 603)
@@ -10,5 +10,6 @@
* @link http://flourishlib.com/fORMColumn
*
- * @version 1.0.0b3
+ * @version 1.0.0b4
+ * @changes 1.0.0b4 Updated code for new fORM API [wb, 2009-06-15]
* @changes 1.0.0b3 Updated code to use new fValidationException::formatField() method [wb, 2009-06-04]
* @changes 1.0.0b2 Fixed a bug with objectifying number columns [wb, 2008-11-24]
@@ -331,5 +332,6 @@
list ($action, $column) = fORM::parseMethod($method_name);
- $column_info = fORMSchema::retrieve()->getColumnInfo(fORM::tablize($object), $column);
+ $class = get_class($object);
+ $column_info = fORMSchema::retrieve()->getColumnInfo(fORM::tablize($class), $column);
$value = $values[$column];
@@ -365,5 +367,5 @@
list ($action, $column) = fORM::parseMethod($method_name);
- $class = fORM::getClass($object);
+ $class = get_class($object);
$table = fORM::tablize($class);
@@ -540,5 +542,6 @@
list ($action, $column) = fORM::parseMethod($method_name);
- $column_info = fORMSchema::retrieve()->getColumnInfo(fORM::tablize($object), $column);
+ $class = get_class($object);
+ $column_info = fORMSchema::retrieve()->getColumnInfo(fORM::tablize($class), $column);
$value = $values[$column];
@@ -594,7 +597,10 @@
if (isset(self::$number_columns[$class])) {
+
+ $table = fORM::tablize($class);
+
foreach(self::$number_columns[$class] as $column => $enabled) {
$camelized_column = fGrammar::camelize($column, TRUE);
- $type = fORMSchema::retrieve()->getColumnInfo(fORM::tablize($class), $column, 'type');
+ $type = fORMSchema::retrieve()->getColumnInfo($table, $column, 'type');
// Get and set methods