-
-
Notifications
You must be signed in to change notification settings - Fork 231
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature: add Drizzle support @effect/sql-drizzle #2896
Conversation
🦋 Changeset detectedLatest commit: 81748f0 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
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 |
let makeClient: Effect.Effect<Pg.client.PgClient, never, Scope> | ||
|
||
beforeAll(async () => { | ||
pgContainer = await new PostgreSqlContainer("postgres:alpine").start() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
using testcontainer, not sure that's the standard way to test db in effect. tell me if it's ok.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
testcontainer is really great, I usually wrap it in a layer so I can have a TestDb that spins up and down automatically, but this looks fine too
options: { | ||
parsers: [], | ||
serializers: [] | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is to make drizzle patching of postgres-js client instance working. drizzle patching is not used in our case, since db instance is just used to convert query builder postgres dialect to sql
Seems like the above file creates a global map Dialect<->Client but the Client is scoped and we might have many different clients in the same project. Additionally, patching the global drizzle type would make every client effectable, even if registration didn't happen. I think a better idea would be to yes make every drizzle query effectable but use |
This is explained in the comment of the code. We store the
Nice idea, it would indeed remove this global registry. i'll try it to see if it works and report back ASAP. |
Ok so it isn't the dialect itself but a specific instance created with it's own client, then I think it could work, it might even be better compared to Also small note, |
I have a solution for that, patch SQLiteSelectBase, SQLiteInsertBase... types directly. that's what i did first. but the types are ugly :)
Indeed. |
/** | ||
* QueryPromise class is used for every Drizzle QueryBuilders, it's what allows Builders to be awaitable | ||
* So since we need all QueryBuilders to also be effectable, we patch it's interface to extend Effect | ||
* We don't however monkey patch the QueryPromise class itself, but the QueryBuilders that extend it to be able to attach the right client to them |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Patching QueryPromise might be cleaner. Is it exposed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, it's exposed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But patching QueryPromise with dependency injecting the client will patch all instances (not just for the client we declared), it's indeed doable, but @mikearnaldi has concerns about patching globally the types, so patching the propotype globally would be even more intrusive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But patching QueryPromise with dependency injecting the client will patch all instances (not just for the client we declared), it's indeed doable, but @mikearnaldi has concerns about patching globally the types, so patching the propotype globally would be even more intrusive.
I don't really have concerns if the patching is valid, the issue would be patching instances globally that can't be used in an effect environment, if the patch adds Effect<X, SqlError, Client>
it is valid because the client will need to be provided so as long as augmentation and patching are done at the same time it should work
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So i tested it, and patching QueryPromise does not work. No idea why, i get this error :
Unknown Error: TypeError: yield* (intermediate value)(intermediate value)(intermediate value)(intermediate value)(intermediate value)(intermediate value) is not iterable
❯ test/sqlite.test.ts:31:43
29| const inserted = yield* db.insert(users).values({ name: "Alice" }).returning()
30| assert.deepStrictEqual(inserted, [{ id: 1, name: "Alice" }])
31| const selected = yield* db.select().from(users)
| ^
have you ever seen it ? from what i read it's usually when detructuring undefined values.
QueryPromise patching must break something in drizzle
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have another idea, will try it out and report back if it works.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated #2860
So, i updated the PR. I feal that the best combination is to :
what do you think ? do i revert back to QueryPromise type Patching ? |
closing, since tim re-took the lead on this. |
Type
Description
This PR add support for drizzle in effect.
It uses internal Drizzle DB, and disable drizzle runtime execution (execute and transaction) to leverage on effect sql client
example
Related