Hello,

I have a suggestion for making DataMapper more efficient by changing
the way that duplicate values in unique colums are caught. I would
implement it myself, but I am not familiar enough with the DM codebase
to do so, so I offer it here in the hopes that someone will pick it
up.

The situation: I have a model with a unique varchar column "foo". I
was told on IRC that the currenty-correct way to implement this is to
do something like:

property :foo, String, :length => 1..1000, :unique_index =>
true, :unique => true

The :unique_index => true causes auto_migrate! to create a unique
index on the column at the database level. If I try to #save an object
that has a duplicate value, I get an exception ( ERROR:  duplicate key
value violates unique constraint "unique_index_foo" - (PostgresError))
rather than a false return value, as I expected. My options are to
either catch exceptions every time I do a #save (which defeats the
purpose of having #save separate from #save!), or else add a :unique
=> true validation to the model.

The :unique => true causes DataMapper to do an additional SELECT
before trying to write the data to the database to see if the given
value already exists. This works as expected (i.e. #save returns
false), but at the price of another entire SELECT every single time I
do a create or update.

This cost is negligible in development, but the overhead will add up
very quickly in a high-volume app that tries to do tens of thousands
of records a minute and cause a severe performance impact. It is
additionally redundant, since the database is always going to do
exactly the same check itself (due to the unique index) again when the
CREATE/UPDATE is subsequently done after the app-level SELECT doesn't
find a match.

So I would like to propose the following: #save should catch and
identify exceptions from the DB layer related to inserting a duplicate
value into the database, and return false, rather than requiring the
validation with the extra redundant SELECT at the app-level. Let the
database constraints handle that; that's what they're for, and they're
going to execute anyway even if such a check is done.

As I said, I would do it myself, but I don't know DM well enough to do
so. I hope this suggestion is useful to someone. Please feel free to
contact me with any questions or feedback.

Cheers,
Paul




--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"DataMapper" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/datamapper?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to