Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sql::orderBy doesn't quote columns #84

Open
mrsoto opened this issue Dec 2, 2015 · 3 comments
Open

Sql::orderBy doesn't quote columns #84

mrsoto opened this issue Dec 2, 2015 · 3 comments

Comments

@mrsoto
Copy link

mrsoto commented Dec 2, 2015

I've this query which does not quote columns and then mysql retrieve an incorrect order. The table has timestamp column

$mapper->news->fetchAll(Sql::orderBy('timestamp', 'id')->desc()->limit($initial, $pageSize))

Resulting query:

SELECT news.* FROM news ORDER BY timestamp, id DESC LIMIT 0, 200

expected:

SELECT news.* FROM news ORDER BY `timestamp`, `id` DESC LIMIT 0, 200

Is there a way to instruct Sql to quote columns?

@mrsoto
Copy link
Author

mrsoto commented Dec 2, 2015

Actually, the real issue is that the order by should be :

ORDER BY `timestamp` DESC, `id` DESC

@felipecwb
Copy link
Member

To solve this issue now you can use this ugly way:

Sql::orderBy('`timestamp` DESC','`id` DESC'); // ORDER BY `timestamp` DESC, `id` DESC 

I'm seeing to improve this.

Something like:

Sql::orderBy(array('timestamp' => 'DESC', 'id' => 'DESC'));

I'm looking too for the identifier escape.

@alganet
Copy link
Member

alganet commented Dec 8, 2015

Unfortunately, quoting is dbms-specific. Each database has its own quoting model (for example, SQL Sever uses brackets to quote e.g. [column_name]).

The Sql class should be dbms independent, but you can extend it...

<?php
use Respect\Relational\Sql as RespectSql;
/**
 * The SQL dialect with extra statements
 */
class FooBarSql extends RespectSql
{
    /**
     * Method used to translate from php method calls to SQL instructions.
     * It is closely related to __call for the Respect\Relational\Sql class.
     */
    protected function build($operation, $parts)
    {
        switch ($operation) {
            case 'orderBy':
                return $this->buildParts($parts, '`%s` ');
            default:
                return parent::build($operation, $parts);
        }
    }
}

... and then use it on your Mapper or Db instance:

<?php
$pdo = new PDO(/* your own PDO config */);
$sqlPrototype = new FooBarSql(); // The class we've extended before
$db = new \Respect\Relational\Db($pdo, $sqlPrototype);
$mapper = new \Respect\Relational\Mapper($db);

Both the Mapper and the Db classes will now use the $sqlPrototype instance as a blueprint for building query expressions. When using them outside the Mapper or Db, you'll need to address it like FooBarSql::orderBy.

I've used this technique before to make Respect\Relational support CREATE TABLE instructions. You can find the implementation here for reference.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants