Implementing new features for queries Warning BC BREAK #663

wants to merge 1 commit into

4 participants

Union of RAD member

BC break:

  • the 'constraint' option is now 'constraints' (i.e with an extra 's')
  • the constraints now behave like conditions (i.e the right hand side are automagically escaped, use (object) casting to avoid this behavior)
  • Query::constraints() has been removed (see Database::on() for PDO datasources)

New Features :

  • Queries are now exported according a datasource strategy (Acutally only the joined strategy (i.e. LEFT JOIN) have been implemented).

Experimental :

  • If such notation : Post::find('all', array('with' => array('Tagging.Tags'))); would now works on PDO datasources, the lacks of "fixtures" (#603) makes tests impossible (for me at least) for this part.
  • Feel free to comment this PR if you notice something wrong.

Next step :

  • Allow Queries to contain subqueries.
  • Allow Datasource to manage queries with subqueries.
  • Implements the "subquery strategy" for both PDO and NoSql datasource.

hello jails, I currently trying to implement this too more in this style Post::find('all', array('with' => array('Tagging' => array('with' => 'Tags'))));

Here I am a bit stuck about NoSQL, and some regressions.

So... i'm triying to find a way to help ^^.

Union of RAD member

Well, I currently choose the "dotted notation" for clarity since it tends to reduce the level of nesting of the 'with'`option array :

Galleries::find('all', array(
    'with' => array(
        'Images.ImagesTags' => array('conditions' => array(....)), 
        'Images.ImagesTags.Tags' => array('conditions' => array(....)), 
        'Images.ImagesTags.Tags.Authors' => array('conditions' => array(....)),
        'Images.ImagesTags.Tags.Authors.Tags'  => array('conditions' => array(....))

I didn't find a better and/or compact way.

In this PR strategies are used to configure queries (i.e to solve the SQL/NoSQL differences).

  • Strategy 1 is the one implemented in this PR. It consists of using the "LEFT JOIN capability" of SQL database to join the relationships of a query (ie. the 'with' option);

  • Strategy 2 will consists of splitting the relationships of a query (ie. the 'with' option) into sub queries (one for each relationship). So this strategy will also work on NoSQL datasources. Of course the results will not always be the same as the strategy 1 but it's a kind of "workaround" for NoSQL datasources.

Long story short, the strategy is applied to a query during the export step. So according to the 'with' option of the query, the strategy configures the query to do joins or subqueries or a mix of both.

You can test it if you want to help (git clone -b data_dev should work) and to give me your feedback according your own experience on this topic. ;-)

The above dotted syntax should work fine on PDO datasources but since this PR is a assembly of a lot of "personnal tweaking", I only make this PR pass on the current tests yet. So don't hesitate if you find some bugs.


yep, i'm ok with you about these 2 strategy and i'm just thinking we can probably made a sequential querying and populate the datamap in the same time for nosql database.

feedback tomorrow ! ;-)
good night

Union of RAD member

@jails Remind me, what's the purpose of changing 'constraints' to act like 'conditions'? The whole purpose of having separate keys was that one was to allow key-to-key constraints instead of key-to-value constraints.

Union of RAD member

I forgot the last time I need a query with a key-to-value constraints inside the ON clause but you can see a theoretical example here : (the two last examples of the section " Joined Tables" show the difference by using a key-to-value constraints in the ON and the WHERE clause).
That's why I think 'constraints' and 'conditions' should behave in a similar way and 'constraints' should also allow key-to-value constraints.


+1 on accepting key to value constraints.

A simplified, but real life example of what I had to do just a couple of days ago:
I have a table of study groups related to courses and a table of study groups members. I needed to list all groups related to a course from the first table and also fetch the joined date (if any) from the second table for the currently logged in user.

Basically, it's something like this:

| id | course_id | name    |
|  1 |         1 | Group 1 |
|  2 |         1 | Group 2 |
|  3 |         1 | Group 3 |
|  4 |         2 | Group 4 |

| group_id | user_id |  joined_on |
|        1 |       1 | 2012-11-11 |
|        1 |       2 | 2012-11-11 |
|        2 |       2 | 2012-11-12 |
|        3 |       2 | 2012-11-13 |

...the query would be:

SELECT `sg`.`id`, `sg`.`name`, `sgm`.`joined_on`
FROM `study_groups` AS `sg`
LEFT JOIN `study_groups_members` AS `sgm` 
       ON `sgm`.`group_id` = `sg`.`id`
      AND `sgm`.`user_id` = 1
WHERE `sg`.`course_id` = 1

and the result should be:

| id |    name |  joined_on |
|  1 | Group 1 | 2012-11-11 |
|  2 | Group 2 |       NULL |
|  3 | Group 3 |       NULL |
Union of RAD member

closed in favor of #705

@jails jails closed this Dec 4, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment