Skip to content

refactor: shared internal postgres package that wraps slonik#7887

Open
Copilot wants to merge 45 commits intomainfrom
copilot/update-slonik-connection-usage
Open

refactor: shared internal postgres package that wraps slonik#7887
Copilot wants to merge 45 commits intomainfrom
copilot/update-slonik-connection-usage

Conversation

Copy link

Copilot AI commented Mar 19, 2026

Background

See #7811

Description

Note: this started as a copilot thing, but I (@n1ru4l), quickly took over and did a lot of manual work.

This PR updates all usages of slonik to go through our internal package @hive/postgres.

Because slonik frequently introduces breaking changes, this creates a single abstraction layer around it. This allows us to centralize how the library is used and makes it easier to adopt future major versions in a backward-compatible way.

This PR exploded a bit, since I initially only started with introducing zod model parsing to existing database calls that still used unsafe as typecasts via the generic parameter.

While working on that I realized that we could benefit from having a single slonik entrypoint shared in the whole repository.

Summary:

  • Import anything postgres related from @hive/postgres
  • Dedupe database utilities shattered and duplicated around the code base (e.g. createDatabaseQueryString, traced transactions)
  • Rename sql to psql, to avoid confusion and conflicts with our in-house clickhouse sql tag
  • Add new class PostgresDatabasePool, that has the query methods with unknown hard-coded so you are forced to use zod to decode the result
  • Update the whole code-base to use psql instead of sql
  • Update the whole code-base to use PostgresDatabasePool
  • Update the whole code-base to decode database results instead of casting them

Whether we keep or remove slonik as a dependency (still uncovering things bit by bit that we need to address in case we update in #7897), I see benefit of having a single entrypoint nevertheless.

… I/O decoding

Co-authored-by: n1ru4l <14338007+n1ru4l@users.noreply.github.com>
Copilot AI changed the title [WIP] Update Slonik database connections to use unknown and zod decoding Replace Slonik query generic parameters with unknown + Zod parsing in storage Mar 19, 2026
Copilot AI changed the title Replace Slonik query generic parameters with unknown + Zod parsing in storage refactor(storage): Replace Slonik<T> generics with unknown + Zod I/O decoding Mar 19, 2026
@n1ru4l

This comment was marked as resolved.

Copilot AI and others added 2 commits March 20, 2026 09:26
…llable().parse

- Replace `r => r ? Model.parse(r) : null` with `Model.nullable().parse` (point-free)
- Replace `v => Model.nullable().parse(v)` with `Model.nullable().parse`
- Replace `.query<unknown>(...).then(r => ({ ...r, rows: r.rows.map(...) }))`
  with `.any<unknown>(...).then(z.array(Model).parse)`
- Update all downstream `.rows` array accesses after the above changes
- Replace `.then(rows => rows.map(row => Model.parse(row)))`
  with `.then(z.array(Model).parse)`

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… query to any

Co-authored-by: n1ru4l <14338007+n1ru4l@users.noreply.github.com>

This comment was marked as resolved.

Copilot AI changed the title refactor(storage): Replace Slonik<T> generics with unknown + Zod I/O decoding refactor(storage): Replace Slonik generics with unknown + Zod I/O decoding Mar 20, 2026
Copilot stopped work on behalf of n1ru4l due to an error March 20, 2026 09:37
… parsing

Co-authored-by: n1ru4l <14338007+n1ru4l@users.noreply.github.com>
Copilot AI changed the title refactor(storage): Replace Slonik generics with unknown + Zod I/O decoding refactor(storage): eliminate transform helpers via SQL aliases and Zod schema reshaping Mar 20, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Mar 20, 2026

🚀 Snapshot Release (alpha)

The latest changes of this PR are available as alpha on npm (based on the declared changesets):

Package Version Info
hive 11.0.1-alpha-20260325104308-b1359556eceaf03441901c8ab490555134fd3e38 npm ↗︎ unpkg ↗︎

@n1ru4l
Copy link
Contributor

n1ru4l commented Mar 20, 2026

@copilot There is more functions like transformOrganization, transformProject, transformOrganizationInvitation, transformMember and transformSchemaPolicy that should be replaced by updating the SQL queries to use aliases and adjusting the corresponding zod models.

@n1ru4l n1ru4l force-pushed the copilot/update-slonik-connection-usage branch from 6e75a5a to 7bff3e4 Compare March 23, 2026 09:41
@n1ru4l n1ru4l force-pushed the copilot/update-slonik-connection-usage branch from 3320f21 to 21ec7e2 Compare March 23, 2026 10:23
@n1ru4l n1ru4l force-pushed the copilot/update-slonik-connection-usage branch from 6c4aa68 to ab14763 Compare March 23, 2026 10:30
@n1ru4l n1ru4l force-pushed the copilot/update-slonik-connection-usage branch from 95e4f72 to 212ac08 Compare March 23, 2026 12:34
@n1ru4l n1ru4l mentioned this pull request Mar 23, 2026
14 tasks
@n1ru4l n1ru4l force-pushed the copilot/update-slonik-connection-usage branch 2 times, most recently from 8e5a011 to a24dba9 Compare March 25, 2026 09:22
@n1ru4l n1ru4l force-pushed the copilot/update-slonik-connection-usage branch from a24dba9 to 4a99486 Compare March 25, 2026 10:24
@n1ru4l n1ru4l requested review from dotansimha and jdolle March 25, 2026 13:48
@n1ru4l n1ru4l marked this pull request as ready for review March 25, 2026 15:01
private taskScheduler: TaskScheduler,
private rateLimiter: InMemoryRateLimiter,
@Inject(WEB_APP_URL) private appBaseUrl: string,
@Inject(PG_POOL_CONFIG) private pool: DatabasePool,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the small side-effect that we now have a class and this @Inject(PG_POOL_CONFIG) thingy is no longer needed.

delete process.env.CLICKHOUSE_TTL_HOURLY_MV_TABLES;
delete process.env.CLICKHOUSE_TTL_MINUTELY_MV_TABLES;

vi.resetModules();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is already being imported on line 25. The reset looks to be necessary to reset the environment variables on import

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does not seem to be necessary. Everyyhing works without it. 😓 Keeping it raised an exception.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's odd. What was the error? I don't see any big changes with the code.

RETURNING ${schemaPolicyFields(psql``)};
`,
)
.then(SchemaPolicyModel.parse);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we use the returned fields from the update calls?
I'd expect we already have that information and by returning everything we're wasting bandwidth. Prefer returning void where it makes sense.

RETURNING
"organization_id" AS "organizationId",
"external_billing_reference_id" AS "externalBillingReference",
"billing_email_address" AS "billingEmailAddress"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this also be abstracted to a const to be used in other calls?

return results.rows;
return pool
.any(
psql`/* getGetOrganizationsAndTargetsWithLimitInfo */
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: prefer moving to snake case to be consistent

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants