diff options
-rw-r--r-- | README.markdown | 12 | ||||
-rw-r--r-- | idiorm.php | 29 | ||||
-rw-r--r-- | test/test_queries.php | 4 |
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: @@ -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; |