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

Raw update queries #40

Closed
Htarlov opened this issue Aug 23, 2011 · 6 comments
Closed

Raw update queries #40

Htarlov opened this issue Aug 23, 2011 · 6 comments
Milestone

Comments

@Htarlov
Copy link

Htarlov commented Aug 23, 2011

I'm not sure if it should be posted as an issue or as a feature request. I have problem to use raw queries to send update query to the database. For example I need to change many rows at once with simple where condition.
It would be great if one could use it like that:

ORM::for_table('person')->raw_query('UPDATE worker SET income = :income WHERE job = :job',array('job' => $job, 'income' => $income))->save();

But save doesn't send it.
find_one / find_many runs that query, but with problems with null parameters (I had to set null and it set 0) and with PDO error at the end.

I think this feature will help those who need to update on many rows - without refactoring much in the library.

@Htarlov
Copy link
Author

Htarlov commented Aug 24, 2011

There is a simple modification that gives this possibility and works well for me.

One needs to add a method like that:

public function raw_merge() {
    if ($this->_is_raw_query) {
        self::_log_query($this->_raw_query, $this->_raw_parameters);
        $statement = self::$_db->prepare($this->_raw_query);
        if (is_array($this->_raw_parameters) && count($this->_raw_parameters) > 0)
            $success = $statement->execute($this->_raw_parameters);
        else
            $success = $statement->execute();
        return $success;
    }
}

I also add a factory method for instances used only to use raw update/delete/"custom" queries:

public static function raw_instance() {
    self::_setup_db();
    return new self(NULL);
}

Then I can use it like that (queries presented I thought out right now "from cosmos" - not very real ones but present possibilities that this change gives):

ORM::raw_instance()->raw_query('UPDATE worker SET income = :income WHERE job = :job',array('job' => $job, 'income' => $income))->raw_merge();

or like that:

ORM::raw_instance()->raw_query('UPDATE document SET md5 = MD5(text) WHERE group = ?',array($group))->raw_merge();

or:

ORM::raw_instance()->raw_query('DELETE FROM page WHERE NOT EXISTS (SELECT ID FROM page_group WHERE page_group.page_id = page.id) OR page.delete_me = 1')->raw_merge();

etc.

I thought of putting this code into save method but "save" on delete query doesnt sound well.
This could be improved so method would return FALSE on fail and number of changed rows on success. But I didn't have time nor need to put this improvement.

@jasonsocha
Copy link

Thanks for this! Works perfectly for running a mass-update query (or any SQL for which you don't care about the result).

@MaximKeegan
Copy link

Great solution, but how to fix log?
ORM::for_table('apns_messages_recepients')->raw_query('UPDATE apns_messages_recepientsSETstatus= :status WHEREid = :id', array('id' => $error['MESSAGE']->getCustomIdentifier(), 'status'=> 'failed'))->raw_merge();

And in ORM::get_query_log() i see ``[5] => UPDATE apns_messages_recepients SET `status` = :status WHERE `id` = :id`

@treffynnon
Copy link
Collaborator

I am still not sure I see the advantage here of adding this complexity. Seems to me that using the PDO instance directly for these operations would work. I can't even really see any keystrokes being saved here. Is there something I am missing?

The following code is quite neat and tidy:

$pdo = ORM::get_db();
$raw_query = ''UPDATE document SET md5 = MD5(text) WHERE group = ?'';
$raw_parameters = array($group);
$statement = $pdo->prepare($raw_query);
$statement->execute($raw_parameters);

If this is to make it into Idiorm's core then it needs to become a whole lot more elegant in its implementation. So that you end up with something like:

ORM::raw_exec(
    'UPDATE document SET md5 = MD5(text) WHERE group = ?',
    array($group)
);

Then again maybe I am missing something that you guys are gaining by having ORM::raw_instance->raw_query->raw_merge. If I am then please do say otherwise please comment on the acceptability of the aforementioned raw_exec construct.

@tag
Copy link
Contributor

tag commented Nov 22, 2012

@treffynnon, I think you're correct about implementation, and put something together along those lines, complete with query logging and a (somewhat farcical) unit test.

tag/idiorm@13d291f

@treffynnon
Copy link
Collaborator

Closed in commit f6d7861

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

No branches or pull requests

5 participants