Simplify DBAdapter interface and query result types#995
Draft
simolus3 wants to merge 4 commits into
Draft
Conversation
🦋 Changeset detectedLatest commit: 4fdc836 The changes in this PR will be included in the next version bump. This PR includes changesets to release 9 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
DBAdapteris the interface we implement to give a PowerSync SDK access to SQLite. It's a public interface, which means that users can implement it too if they want a custom SDK. However, it's also very annoying to implement, since one needs to write allget(),getOptional(),getAll(),execute(), ... methods by hand. We introduced mixins to help with those classes, but that's still kind of awkward to use since it splits the type hierarchy (one class + another one applying the mixin).Really, what we want is for users to implement a minimal amount of methods and then get all the others by default. Now that we can afford a breaking change, we can use the right tool for the job: This changes
DBAdapterandLockContextto be abstract classes, meaning that users only really need to implement a single method (executeRaw) and get the rest for free.Specifically, this PR makes three changes:
Result set restructuring
Our current
QueryResultinterface is heavily inspired from RNQS, which I don't think is the most convenient representation: Rows are represented as JS objects, and accessed on results through a field called_array. There's also alengthgetter and anitem()method to get the nth row (a convenient API for those not knowing arrays exist /s).Instead, this adds a
RawResultSetinterface, consisting of acolumnNames: string[]field and arawRows: SqliteValue[][]array (no moreany!). This is returned byexecuteRawnow, giving users access to column names. It also allows a default implementation ofexecutethat groups by column names into JS objects (done lazily in theResultSetclass extendingRawResultSet). This replaces a few implementations we had of that in the existing adapter implementations.For backwards-compatibility, I've kept
_arrayandlength. But they're deprecated now.Table update notifications
On a type level, we had three different representations of update notifications and helpers to convert between them. This normalizes them into a single format,
changedTables: string[]. Information about the type of updates (insert, update, delete) was only provided by the OP-SQLite implementation and isn't used anywhere in the SDK.Migration to abstract classes
The previous mixins used to implement
DBAdapterwere introduced to share implementation details without a breaking change. Using abstract classes instead gives us a much simpler implementation and avoids having to split everything into two classes to apply the mixin.One minor caveat is that
TriggerDiffHandlerContext(an interface) can no longer implementLockContext, it now exports the context as a field instead.