← Back to team overview

anewt-developers team mailing list archive

[Branch ~uws/anewt/anewt.uws] Rev 1749: [autorecord] Implement ::db_find_{one, all}_by_columns()

 

------------------------------------------------------------
revno: 1749
committer: Wouter Bolsterlee <uws@xxxxxxxxx>
branch nick: anewt.uws
timestamp: Tue 2010-02-16 00:40:39 +0100
message:
  [autorecord] Implement ::db_find_{one,all}_by_columns()
  
  These methods takes an associative array of column names and
  values and returns the records that match all values, using
  AND in the WHERE clause.
  
  This is a generalization of the existing functionality
  offered by the ::db_find_{one,all}_by_column methods, but
  extended to support multiple columns instead of just one.
  The _by_column() methods now invoke their _by_columns()
  counterparts instead of duplicating the SQL building logic.
  
  Also extended the unit tests to test the new functionality.
  
  Fixes bug #503551.
modified:
  autorecord/autorecord.lib.php
  autorecord/autorecord.test.php


--
lp:anewt
https://code.launchpad.net/~uws/anewt/anewt.uws

Your team Anewt developers is subscribed to branch lp:anewt.
To unsubscribe from this branch go to https://code.launchpad.net/~uws/anewt/anewt.uws/+edit-subscription.
=== modified file 'autorecord/autorecord.lib.php'
--- autorecord/autorecord.lib.php	2010-01-05 20:07:27 +0000
+++ autorecord/autorecord.lib.php	2010-02-15 23:40:39 +0000
@@ -29,6 +29,9 @@
  * - db_find_all_by_column() and
  *   db_find_one_by_column() return records where a specified
  *   column has the specified value.
+ * - db_find_all_by_columns() and
+ *   db_find_one_by_columns() return records where specified
+ *   columns have the specified values.
  *
  * The data manipulation methods are instance methods that operate on object
  * instances themselves:
@@ -173,13 +176,25 @@
 		$methods['db_find_all_by_column'] =
 			'final public static function db_find_all_by_column($column, $value)
 			{
-				return AnewtAutoRecord::_db_find_by_column(\'@@CLASS@@\', false, $column, $value, @@CLASS@@::db_connection());
+				return AnewtAutoRecord::_db_find_by_columns(\'@@CLASS@@\', false, array($column => $value), @@CLASS@@::db_connection());
 			}';
 
 		$methods['db_find_one_by_column'] =
 			'final public static function db_find_one_by_column($column, $value)
 			{
-				return AnewtAutoRecord::_db_find_by_column(\'@@CLASS@@\', true, $column, $value, @@CLASS@@::db_connection());
+				return AnewtAutoRecord::_db_find_by_columns(\'@@CLASS@@\', true, array($column => $value), @@CLASS@@::db_connection());
+			}';
+
+		$methods['db_find_all_by_columns'] =
+			'final public static function db_find_all_by_columns($columns_with_values)
+			{
+				return AnewtAutoRecord::_db_find_by_columns(\'@@CLASS@@\', false, $columns_with_values, @@CLASS@@::db_connection());
+			}';
+
+		$methods['db_find_one_by_columns'] =
+			'final public static function db_find_one_by_columns($columns_with_values)
+			{
+				return AnewtAutoRecord::_db_find_by_columns(\'@@CLASS@@\', true, $columns_with_values, @@CLASS@@::db_connection());
 			}';
 
 
@@ -646,7 +661,7 @@
 
 	/**
 	 * Find records by column value. This is a shorthand to find records based
-	 * on the value of a single column, e.g. a unique key.
+	 * on the value of a single column.
 	 *
 	 * \param $column
 	 *   The name of the column to use
@@ -666,7 +681,7 @@
 
 	/**
 	 * Find a single record by column value. This is a shorthand to find a record
-	 * based on the value of a single column, e.g. a unique key.
+	 * based on the value of a single column.
 	 *
 	 * \param $column
 	 *   The name of the column to use
@@ -685,6 +700,43 @@
 	}
 
 	/**
+	 * Find records by column values. This is a shorthand to find records based
+	 * on the value of multiple column (using \c AND in the \c WHERE clause).
+	 *
+	 * \param $columns_with_values
+	 *   Associative array with column names as keys, and column values as
+	 *   values.
+	 *
+	 * \return
+	 *   Array of AnewtAutoRecord instances (may be empty)
+	 *
+	 * \see db_find_one_by_column
+	 */
+	public static function db_find_all_by_columns($columns_with_values)
+	{
+		/* Implemented in register() */
+	}
+
+	/**
+	 * Find a single record by column values. This is a shorthand to find a record
+	 * based on the value of multiple columns (using \c AND in the \c WHERE
+	 * clause).
+	 *
+	 * \param $columns_with_values
+	 *   Associative array with column names as keys, and column values as
+	 *   values.
+	 *
+	 * \return
+	 *   AnewtAutoRecord instance (or NULL)
+	 *
+	 * \see db_find_all_by_column
+	 */
+	public static function db_find_one_by_columns($columns_with_values)
+	{
+		/* Implemented in register() */
+	}
+
+	/**
 	 * Find one or more records by primary key value.
 	 *
 	 * \param $class  Class name
@@ -908,37 +960,44 @@
 	 *   Whether to return just one instance (or null) or an array of instances
 	 *   (possibly empty)
 	 *
-	 * \param $column
-	 *   The column to match
-	 *
-	 * \param $value
-	 *   The value to match
+	 * \param $columns_with_values
+	 *   Associative array with column names as keys, and column values as
+	 *   values.
 	 *
 	 * \param $connection  AnewtDatabaseConnection instance
 	 */
-	final protected static function _db_find_by_column($class, $just_one_result, $column, $value, $connection)
+	final protected static function _db_find_by_columns($class, $just_one_result, $columns_with_values, $connection)
 	{
 		assert('is_string($class)');
 		assert('is_bool($just_one_result)');
-		assert('is_string($column)');
+		assert('is_assoc_array($columns_with_values)');
 		assert('$connection instanceof AnewtDatabaseConnection');
 
 		$columns = call_user_func(array($class, 'db_columns'));
 
-		if (!array_key_exists($column, $columns))
-			throw new AnewtException('Class "%s" does not have a column named "%s"', $class, $column);
-
-		if (is_null($value))
-		{
-			$sql_where = '?column? IS NULL';
-			$placeholder_values = array($column);
-		} else
-		{
-			$column_type = $columns[$column];
-			$sql_where = sprintf('?column? = ?%s?', $column_type);
-			$placeholder_values = array($column, $value);
+		$sql_where_parts = array();
+
+		foreach ($columns_with_values as $column => $value)
+		{
+			if (!array_key_exists($column, $columns))
+				throw new AnewtException('Class "%s" does not have a column named "%s"', $class, $column);
+
+			if (is_null($value))
+			{
+				$sql_where_parts[] = '?column? IS NULL';
+				$placeholder_values[] = $column;
+			}
+			else
+			{
+				$column_type = $columns[$column];
+				$sql_where_parts[] = sprintf('?column? = ?%s?', $column_type);
+				$placeholder_values[] = $column;
+				$placeholder_values[] = $value;
+			}
 		}
 
+		$sql_where = join(' AND ', $sql_where_parts);
+
 		return AnewtAutoRecord::_db_find_by_sql($class, $just_one_result,
 			array('where' => $sql_where), $placeholder_values, $connection);
 	}

=== modified file 'autorecord/autorecord.test.php'
--- autorecord/autorecord.test.php	2010-01-05 20:07:27 +0000
+++ autorecord/autorecord.test.php	2010-02-15 23:40:39 +0000
@@ -136,7 +136,24 @@
 		$this->assertNull($result);
 
 		$result = Person::db_find_one_by_column('age', 10);
+		$this->assertNotNull($result);
+		$this->assertType('Person', $result);
+
 		$result = Person::db_find_all_by_column('is_happy', NULL);
+		$this->assertEquals(1, count($result));
+
+		$result = Person::db_find_one_by_columns(array(
+			'name' => 'B',
+			'age' => 11,
+		));
+		$this->assertNotNull($result);
+		$this->assertType('Person', $result);
+
+		$result = Person::db_find_all_by_columns(array(
+			'name' => 'something that does not exist',
+			'age' => 12,
+		));
+		$this->assertEquals(0, count($result));
 	}
 
 	/**