summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.markdown12
-rw-r--r--idiorm.php29
-rw-r--r--test/test_queries.php4
3 files changed, 43 insertions, 2 deletions
diff --git a/README.markdown b/README.markdown
index c85139a..2b90921 100644
--- a/README.markdown
+++ b/README.markdown
@@ -21,9 +21,7 @@ Features
TODO
----
-* Implement raw queries.
* Improve documentation.
-* Proper testing.
* More features.
Philosophy
@@ -112,6 +110,16 @@ Two methods are provided to add `ORDER BY` clauses to your query. These are `ord
ORM::for_table('person')->order_by_asc('gender')->order_by_desc('name')->find_many();
+#### Raw queries ####
+
+If you need to perform more complex queries, you can completely specify the query to execute by using the `raw_query` method. This method takes a string and an array of parameters. The string should contain placeholders, either in question mark or named placeholder syntax, which will be used to bind the parameters to the query.
+
+ ORM::for_table('person')->raw_query('SELECT p.* FROM person p JOIN role r ON p.role_id = r.id WHERE r.name = :role', array('role' => 'janitor')->find_many();
+
+The ORM class instance(s) returned will contain data for all the columns returned by the query. Note that you still must call `for_table` to bind the instances to a particular table, even though there is nothing to stop you from specifying a completely different table in the query. This is because if you wish to later called `save`, the ORM will need to know which table to update.
+
+Note that using `raw_query` is advanced and possibly dangerous, and Idiorm does not make any attempt to protect you from making errors when using this method. If you find yourself calling `raw_query` often, you may have misunderstood the purpose of using an ORM, or your application may be too complex for Idiorm. Consider using a more full-featured database abstraction system.
+
### Getting data from objects ###
Once you've got a set of records (objects) back from a query, you can access properties on those objects (the values stored in the columns in its corresponding table) in two ways: by using the `get` method, or simply by accessing the property on the object directly:
diff --git a/idiorm.php b/idiorm.php
index e92dc42..96b9b1d 100644
--- a/idiorm.php
+++ b/idiorm.php
@@ -102,6 +102,15 @@
// Values to be bound to the query
private $values = array();
+ // Is this a raw query?
+ private $is_raw_query = false;
+
+ // The raw query
+ private $raw_query = '';
+
+ // The raw query parameters
+ private $raw_parameters = array();
+
// Array of WHERE clauses
private $where = array();
@@ -275,6 +284,20 @@
}
/**
+ * Perform a raw query. The query should contain placeholders,
+ * in either named or question mark style, and the parameters
+ * should be an array of values which will be bound to the
+ * placeholders in the query. If this method is called, all
+ * other query building methods will be ignored.
+ */
+ public function raw_query($query, $parameters) {
+ $this->is_raw_query = true;
+ $this->raw_query = $query;
+ $this->raw_parameters = $parameters;
+ return $this;
+ }
+
+ /**
* Add a WHERE clause to your query. Each time this is called
* in the chain, an additional WHERE will be added, and these
* will be ANDed together when the final query is built.
@@ -350,6 +373,12 @@
* been passed to this instance by chaining method calls.
*/
private function build_select() {
+
+ if ($this->is_raw_query) {
+ $this->values = $this->raw_parameters;
+ return $this->raw_query;
+ }
+
$query = array();
$query[] = 'SELECT * FROM ' . $this->table_name;
diff --git a/test/test_queries.php b/test/test_queries.php
index 86e4a60..144be56 100644
--- a/test/test_queries.php
+++ b/test/test_queries.php
@@ -58,6 +58,10 @@
$expected = 'SELECT * FROM widget WHERE name = "Fred" AND (age = "5" OR age = "10")';
Tester::check_equal("Raw WHERE clause", $expected);
+ ORM::for_table('widget')->raw_query('SELECT w.* FROM widget w WHERE name = ? AND age = ?', array('Fred', 5))->find_many();
+ $expected = 'SELECT w.* FROM widget w WHERE name = "Fred" AND age = "5"';
+ Tester::check_equal("Raw query", $expected);
+
$widget = ORM::for_table('widget')->create();
$widget->name = "Fred";
$widget->age = 10;