GNOME Bugzilla – Bug 742925
A resource can't be updated just after saved for the first time
Last modified: 2015-04-01 10:38:41 UTC
Given an "item" resource with an "id" primary key, configured to store the resource into "items" table, after a new "item" has been created and saved to the database it is not possible to save any other changes occurring the following error: Failed to execute statement: UNIQUE constraint failed: items.id i.e.: ... it = g_object_new (ITEM_TYPE_RESOURCE, "repository", repository, "id", "My identifier", "first-name", "First name", "surname", "Surname", NULL); ret = gom_resource_save_sync(GOM_RESOURCE(it), &error); g_assert(ret); g_assert_no_error(error); g_object_set (G_OBJECT (it), "surname", "Doe", NULL); ret = gom_resource_save_sync(GOM_RESOURCE(it), &error); g_assert_no_error(error); g_assert(ret); ... I have created a simple test attached.
Created attachment 294534 [details] Test case
I have been reading the GOM source code and looks like the problem is around the "is-from-table" attached data to the resource. When the second "gom_resource_save_sync" is called, the "gom_resource_build_save_cmd" function understand that the command is an insert, not an update https://git.gnome.org/browse/gom/tree/gom/gom-resource.c#n601 (sorry, I don't know how to reference a given commit, so if gom-resource.c changed, the link can be broken) I don't know the idea about "is-from-table" so I have no clear how to create a patch, could somebody explain it?
Did you test this with gom from git master?
Yes. I have created a patch instead just a simple c code. (attached)
Created attachment 294573 [details] [review] Update test case
I have tested that you can't save a resource more than one time in every scenario (after create it for the first time or after a query from database). In gom_resource:set_post_save_properties "is-from-table" is set to NULL always, so the next call to gom_resource_set_is_from_table turns GomResource::is_from_table to false and the next save command is taken as an insert, not an update. I'm guessing that is required to set "is-from-table" every time that a save is executed, but that seems kind of redundant...
Created attachment 300646 [details] [review] resource: Setting the "is-from-table" data when a resource is saved If the resource has been saved correctly in the database we set to TRUE the "is-from-table" data related to the GomResource object. This data is used in subsequent save functions to create an UPDATE or an INSERT SQL query.
Created attachment 300647 [details] [review] tests: Update an object after created This test ensures that an object that has been saved can be updated with the same reference.
Created attachment 300648 [details] [review] resource: Setting the "is-from-table" data when a resource is saved If the resource has been saved correctly in the database we set to TRUE the "is-from-table" data related to the GomResource object. This data is used in subsequent save functions to create an UPDATE or an INSERT SQL query.
Review of attachment 294573 [details] [review]: This is an old patch.
I have created a patch that fix this problem. I think that something based in the SQLite "rowid" would be better, but I don't know which kind of dependency with SQLite is desired...
Committed with a few style changes. Thanks! Attachment 300647 [details] pushed as 9748e26 - tests: Update an object after created