Gom is a very old object mapper I wrote to bridge GObject to SQLite. It made a lot of assumptions about the world based on when it was prototyped.
The past couple years had me using it again for the documentation search in Manuals. Typically, I would have just built Manuals to parse all the XML files on disk and hold them in memory. That’s how both Devhelp and Builder always did things. Once we started supporting Flatpak SDKs that was no longer realistic. You could have numerous SDKs all with copies of the overlapping data and it just became easier to have a query model.
One of the more performance critical limitations was the locking model. When gom-1.0 was written, it was not common for distributions to compile SQLite with locking support. So you just created a single thread and did your work over there.
Bolting fulltext search and many other missing features onto the old ABI just wasn’t realistic. Especially when I’ve wanted to make the thing properly async for years. One of my other projects, Libdex is just right over there and perfect for this sort of problem.
The landscape changed and so do our horizons.
A new informed ABIIn the years after Gom was prototyped, I worked at a commercial database company and learned a great deal about implementing the internals of both that database and more traditional RDBMS. That left a certain cringe on my mouth whenever looking at my code predating it. Knowing how things get done inside the database allows for building better APIs to interact with it.
This time everything is async. Queries are modeled like you do with a compiler. Lowered into the back-end specific implementation. There can be an entity map and real transactions which allows you to read back the same instance despite which query inflated it.
The CenterYour early stage objects are the GomRepository, GomDriver, and GomRegistry.
The registry describes the entities that can exist within the repository. This is handy because it allows us to pre-compile information into a model that is both immutable and fast at runtime. Compare that to methods like g_object_class_list_properties() which is a performance bottleneck of its own.
The driver is very obvious. It is our abstraction layer for the database engines. Currently we have support for SQLite and PostgreSQL.
The repository is the center of the center. It is how you query, insert, update, delete, transact, and more. It is likely your application instance owns one of these unless of course you use Gom as your file format in which case you’ll have one per “document”.
Two Access ModelsThis new version of Gom can support either the entity mapping you’re used to or; optionally, raw access to relations/projections via the GomCursor.
As the cursor moves through the resulting rows you will have access to all the projections requested in the query. Though it holds enough information to allow you to gom_cursor_materialize() the row into an GomEntity subclass.
If you want a snapshot of that cursor row without materializing, you can use GomRecord which can also conveniently be used in GListModel for integration into GTK applications.
Most of the time, you’ll use materialization. And even then it is likely to happen through automated collections rather than with a cursor directly. More on that later.
SessionsAs I mentioned, there was no concept of transactions previously.
In this iteration we have GomSession. It is your standard identity-map layer with transaction-scoping. If you perform multiple queries for the same record, the session will ensure you get the same instance back. hat is essential when you do local mutations on an instance and what to see that reflected in followup queries.
Additionally, it makes it nice to have multiple views of an object with an editor or listview and needing them to stay in sync.
Relationship ModelingSupport for relationships was adhoc previously. We had some functions named in ways that made you think you could, but I assure you, they were not well tested.
This time around you can model your GomEntity with 1:1, 1:M, M:M, inverse, self-referencing, all while handling proper delete rules. Combing this with the session support mentioned previously is crucial.
So now you should be able to show related models easily in GtkListView while keeping the paginated-and-lazy model beneath it transactional.
MigrationsIn the previous version migrations were dynamic, but largely controlled by Gom itself. Very inflexible.
This time around we have things broken down into Migrator and Migration.
You can use built-in implementations like the EntityMigrator or implement your own. CustomMigrator makes that easy. Especially since you can inject your own migrations at just the right point.
Internally, libgom-2 can snapshot your GomRegistry at specific versions based on the provided metadata. Then it performs a diff between two versions of the registry to determine what migration work must be done.
You can just as easily use a SqlMigration with custom SQL scripts. This stuff is all highly composable now to get exactly what you need.
Live List ModelsI’ve written many ways to get live SQLite results into GTK over the past two decades. I think one of the first was a GtkTreeModel implementation for GTK 2 which could do it. With that in mind, it was still rather annoying when making Manuals so I set off to make that convenient.
We have GomRecordListModel, GomEntityListModel, GomRelatedListModel, GomQueryModel all of which have practical uses based on application needs.
But in short, most of those are lazy and support transaction-backed stable identities for entities. Very useful when you have a list of items and an editor loaded in another frame, both of which must reflect the same data.
Expression TreesThis time around I implemented proper expression trees. They model the query, relations, and projections in a manner that allows the driver to lower into a query much more accurately.
You can model things like function-calls cleanly all of which required writing manual SQL before. If you did anything outside of what gom could generate previously, it became madness to maintain.
VectorsThis version of libgom embeds the vec1 extension for SQLite. That means we can store vectors in your records and query them. GomVector makes that easier to manage as a property within your application entity.
I can think of a few things this will be useful for, maybe you can too.
ProfilingThis version of libgom has profiling support with another project of mine, Sysprof. The whole library emits profiler marks about what is going on so that it is easy for you to figure out why something might be slow in your application.
Since we’ve already done the integration of Sysprof into GLib/GObject, GTK, Pango, Libdex, and GNOME Shell/Mutter you can very quickly get an idea with details of what is going on in your application. Click record, select the problem area, zoom, and it is often pretty clear. You can have flamegraphs, callgraphs, and timing marks all in one place.
Local First with Sync CoordinationOne of my personal motivations for this is around building a native sync protocol for applications I’m building. I wrote numerous SQLite-based sync protocols for the now defuct catch.com before they were acquired by apple. That means I know multiple wrong ways to do it.
This time around, I want to put it right in the data-mapper at the point where you have the most insight. So libgom has the right abstractions in place to build that. The GomSyncCoordinator manages the process and GomSyncTransport is the abstraction-point for service integration.
You work with GomDelta at this layer. The application can provide you with a GomMergePolicy to help make decisions which allow for contextually doing the right thing.
This part is still very new. I’m still building the other side of it but landing the shape early allows me to mock and test things comprehensively before committing to the ABI.
My goal is building a practical, robust, and correct implementation for personal local first features.
A small personal note: as I wrote in my recent update from France, I am no longer employed by Red Hat. Work like this is currently self-funded, out of pocket, while my family and I settle into a new chapter. If you find it useful, a note of encouragement or a contribution means a lot right now. It helps make it possible to keep improving the free software infrastructure many of us rely on.
Read more of this story at Slashdot.
Read more of this story at Slashdot.
Read more of this story at Slashdot.
Read more of this story at Slashdot.
Read more of this story at Slashdot.
Read more of this story at Slashdot.
Read more of this story at Slashdot.
Read more of this story at Slashdot.
Read more of this story at Slashdot.
Many GNOME projects have adopted a policy banning all contributions generated by LLMs. This policy was originally developed by Sophie for Loupe, but is now used in many other notable places:
This project does not allow contributions generated by large languages models (LLMs) and chatbots. This ban includes, but is not limited to, tools like ChatGPT, Claude, Copilot, DeepSeek, and Devin AI. We are taking these steps as precaution due to the potential negative influence of AI generated content on quality, as well as likely copyright violations.
This ban of AI generated content applies to all parts of the projects, including, but not limited to, code, documentation, issues, and artworks. An exception applies for purely translating texts for issues and comments to English.
AI tools can be used to answer questions and find information. However, we encourage contributors to avoid them in favor of using existing documentation and our chats and forums. Since AI generated information is frequently misleading or false, we cannot supply support on anything referencing AI output.
I won’t attempt to argue that you should allow use of AI for writing code. If you wish to ban LLM-generated code, fine. That’s probably inadvisable, but I am not going to object.
But this policy is far stricter than that. Notably, it strictly prohibits AI-generated content in issue reports (except to translate text). Don’t do this! Prohibiting bug reports is stupid and just makes your software worse. Please make sure your project’s AI policy allows for at least AI-generated static analysis results and AI-generated vulnerability reports. Otherwise, you prohibit entirely unobjectionable problem reports.
It’s hard to imagine what could possibly be the value of prohibiting valid bug reports. AI-generated static analysis works well: the AI is able to think about your code, follow execution paths, and automatically discard most false positives to avoid bothering you with them, and the quality of reports is generally pretty high. They are far from perfect, but the same is true of humans.
Here is a typical example of an AI-generated static analysis finding:
2. Resource leak in update_credentials_cb on gnutls_credentials_set failurePasting this into an issue report clearly violates the ban on AI-generated content. And yet, why would you not want to receive a clear and concrete bug report for memory leak?
I understand not all maintainers are fond of AI, but is your dislike really so extreme that you would choose to ignore valid problems and intentionally make your software worse? If not, then your AI policy should thoughtfully consider how to handle AI-generated content in issue reports. Certainly do not adopt a policy that outright bans all AI-generated content in issue reports.
As an issue reporter, you could theoretically take the problem found by the AI and rephrase all the words, then claim that it is no longer AI-generated content because it is rewritten it. This is a waste of time and usually results in a lower-quality, less-detailed result, but you could plausibly do that. Or, if you want to go above and beyond, you could just jump ahead to creating a merge request. But realistically, if your project does not allow any use of AI in issue reports, it’s more likely that either (a) you won’t receive the issue report in the first place, or (b) you won’t receive such issue reports from experienced developers who read and respect your policy, while users who do not read your policy will continue to submit them.
What about security vulnerability reports? Since the start of this year, I have reviewed well over 100 vulnerability reports that I strongly suspect were generated by AI. To reach the “over 100” claim, I sadly only considered vulnerability reports submitted during a particularly heavy four week period, so this is an extremely loose lower bound. Suffice to say, I have seen a lot of them. The quality varies dramatically. Vulnerability reports are now often better or worse than before: better because an experienced human working with a good AI is able to find vulnerabilities that would have surely gone unnoticed without AI, and worse because an inexperienced human with a bad AI might create some pretty terrible issue reports, a significant proportion of which are just outright spam. Low-quality reports remain a problem, but nowadays most AI-generated issue reports are quite good.
Maintainers do not need to tolerate spammy vulnerability reports. If an issue report is bad, of course go ahead and close it. If it’s really bad, then I sometimes don’t even bother replying. But banning good vulnerability reports solely because some portion of the report was generated by AI is unacceptable. AI-assisted vulnerability reports are the new industry standard, and this is not likely to change. Prohibiting issue reports reduces the quality and safety of your software, punishing your users. This is too extreme.
Read more of this story at Slashdot.
Read more of this story at Slashdot.
Read more of this story at Slashdot.
Read more of this story at Slashdot.
Read more of this story at Slashdot.