Neel Basu
Neel Basu

Reputation: 12904

ORM Solution for really complex queries

Can/should One use any ORM Solution is a Complex Situation like this ? can this even be done with Propel or Doctrine ? at the moment I am using Propel. So I'd be glad If there is Propel solution for it.
If I do a direct query with propel what are the suggestion ?

SELECT I.*,((I.width*175)/I.height) as relativeWidth FROM 
(SELECT * FROM Image WHERE owner = 1 LIMIT 5, 10) I
order by relativeWidth asc

and additionally What is the standard solution for the scenario where one needs to exequte really complex queries in most of the places in the application ?

There is a LIMIT 5, 10 that I use for Pagination. and its in inner Query. If its in View how can I control Pagination ?

Upvotes: 2

Views: 2730

Answers (2)

William Durand
William Durand

Reputation: 5519

Your query can be written as following with Propel 1.6.3:

<?php

// SELECT * FROM Image WHERE owner = 1 LIMIT 5, 10
$subQuery = ImageQuery::create()
    ->filterByOwner(1)
    ->limit(10)
    ->offset(5)
    ;

$query = ImageQuery::create()
    ->addSelectQuery($subQuery, 'I', true)
    ->withColumn('((I.WIDTH*175)/I.HEIGHT)', 'relativeWidth') // ((I.width*175)/I.height) as relativeWidth
    ->orderBy('relativeWidth') // default is 'asc'
    ;

$params = array();
var_dump(\BasePeer::createSelectSql($query, $params));

Output is:

SELECT I.ID, I.WIDTH, I.HEIGHT, I.OWNER, ((I.WIDTH*175)/I.HEIGHT) AS relativeWidth
FROM (
    SELECT image.ID, image.WIDTH, image.HEIGHT, image.OWNER
    FROM `image`
    WHERE image.OWNER=:p1 LIMIT 5, 10
) AS I
ORDER BY relativeWidth ASC

Note the :p1 is the binding parameter related to the owner value.

So it's really easy to create complex queries using Propel :)

William

Upvotes: 2

halfer
halfer

Reputation: 20439

Some queries are best fixed with views, imo. True, this isn't for ORM purists, but I've found it a very maintainable approach whilst reaping the benefits of an ORM. I would say that, within a single project, you should only do this 10% of the time or so; if you find that you are writing a view for most of your ORM statements, then perhaps another approach is required.

That all said, the example you cite is quite simple. I would be inclined to write a special method using raw SQL in the peer class, and hydrate it manually, as per my example on your related question. Just remember that when running raw sql, it is easier to fall prey to SQL injection - remember to escape, clean or parameterise your variables.

Upvotes: 0

Related Questions