tags:

views:

416

answers:

2

I have a collection of items to save to database, but I want the record to be inserted only if not exists.

I think the most effective way would be to filter the collection before saving. Can Doctrine do it automatically?

Or shall I get all id's of all items in the collection, then query the database for items which do not exists on the list of these id's, then in foreach remove all collection items which we do not need, and finally save collection?

Any better approach suggested?

(Doctrine 1.2)

A: 

I don't know anything about Doctrine, but the MySQL REPLACE query does just what you want - updates existing rows & creates new rows if no primary key matches were found.

Pickle
Thanks. But I don't want to update existing rows. Just do nothing if it exists. Besides, I'm using PostgreSQL.
takeshin
In Doctrine you may use replace() method, but this method deletes existing record, and then inserts new.This means that the ID of the row is not preserved.
takeshin
The more appropriate MYSQL operation would be INSERT IGNORE, not REPLACE. But it looks like PostgreSQL doesn't support these.
Sam
A: 

This is the save function from the Doctrine_Collection class

 public function save(Doctrine_Connection $conn = null, $processDiff = true)
    {
        if ($conn == null) {
            $conn = $this->_table->getConnection();
        }

        try {
            $conn->beginInternalTransaction();

            $conn->transaction->addCollection($this);

            if ($processDiff) {
                $this->processDiff();
            }

            foreach ($this->getData() as $key => $record) {
                $record->save($conn);
            }

            $conn->commit();
        } catch (Exception $e) {
            $conn->rollback();
            throw $e;
        }

        return $this;
    }

I'm not sure where you are getting your collection from, or if you are manually building it, but you might want to try extending the Doctrine_Collection class and overloading the save function like this

<?php

class My_Collection extends Doctrine Collection
{

  public function save(Doctrine_Connection $conn = null, $processDiff = true, $createOnly = true)
    {
        if ($conn == null) {
            $conn = $this->_table->getConnection();
        }

        try {
            $conn->beginInternalTransaction();

            $conn->transaction->addCollection($this);

            if ($processDiff) {
                $this->processDiff();
            }

            foreach ($this->getData() as $key => $record) {

                if($createOnly)
                {
                    if ($record->exists())
                    {
                        $record->save($conn);
                    }
                }else{
                    $record->save($conn);
                }
            }

            $conn->commit();
        } catch (Exception $e) {
            $conn->rollback();
            throw $e;
        }

        return $this;
    }

}
Travis