GNOME Bugzilla – Bug 779843
automatic_migrate_* funcs fails to migrate
Last modified: 2017-03-14 09:40:45 UTC
Created attachment 347618 [details] backtrace Even though the gom.js example runs flawlessly, I am unable to wrap the adapter -> repository logic within an object (in Gjs). It fails with the error: ** Gom:ERROR:gom/gom-command-builder.c:458:gom_command_builder_build_create: assertion failed: (primary_pspec) Aborted (core dumped)
Created attachment 347619 [details] ogom.js example
It turns out that the ItemClass (see example) _init method wasn't being called when setting the object_types for the migration method. The execution doesn't fail if I create an instance of the ItemClass, and in doing so I guarantee that the _init runs. let object_type = new ItemClass(); repo.automatic_migrate_async(1, [ object_type ], this._onMigrate.bind(this)); It doesn't seem to be a Gom bug though.
Let's see whether it is a gom bug, or a gjs one.
I don't know the GOM API, but it seems like you shouldn't be doing the set_table() and set_primary_key() calls in the _init() function of ItemClass. In C they would belong in the class_init function if I'm not mistaken. The equivalent in GJS here would be to put them outside of the class declaration. (_instance_init() is something different, it's called when initializing an instance, just like _init() is, but it's meant for metaclasses, you probably don't need it here) It seems like this ought to work: const ItemClass = new Lang.Class({ Name: 'Item', Extends: Gom.Resource, Properties: { ... }, }); Gom.Resource.set_table.call(ItemClass, 'items'); Gom.Resource.set_primary_key.call(ItemClass, 'id');
(In reply to Philip Chimento from comment #4) > I don't know the GOM API, but it seems like you shouldn't be doing the > set_table() and set_primary_key() calls in the _init() function of > ItemClass. In C they would belong in the class_init function if I'm not > mistaken. The equivalent in GJS here would be to put them outside of the > class declaration. This works, but the syntax is more awkward depending on where the object class is defined. For comparison, this works: https://git.gnome.org/browse/gom/tree/examples/gom.js
Well, yes that code you linked may work, but you're using the API in an unsupported way, which can (and did) break in an unexpected way. I for one did not know that you could bind an instance to a class method, where a class would have been expected. It's kind of the same thing as Signals.addSignalMethods(), you can just put it directly after your class definition and consider them one unit. An alternative would be to write your own Gom.Resource metaclass in your overrides file, which would look something like this: const ItemClass = new Gom.ResourceClass({ Name: 'Item', Extends: Gom.Resource, Properties: { ... } Table: 'items', PrimaryKey: 'id', }); See overrides/Gtk.js for an example on how to do this. I was hoping I could fix the crash nonetheless, since even if you use the API in a wrong way a segfault is not a good response in JS, but looking at the backtrace it seems I can't fix it from GJS. So I'll close this for now, but with the acknowledgement that we need better documentation on how to call class methods :-/ I might suggest changing https://github.com/GNOME/gom/blob/325a4e1827311a67b512df28cce08e4da5fc0837/gom/gom-command-builder.c#L456 to be a g_critical or g_return_if_fail, since the situation that's being asserted is apparently not an invariant, but that's up to you.
Fixed the example in a minimal way, and filed https://bugzilla.gnome.org/show_bug.cgi?id=780023 about Gtk.js