Support PostgreSQL database backend#3167
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds PostgreSQL as a supported self-hosted database backend for Puter, integrating a native pg client, Postgres-specific migrations, and a set of cross-engine SQL helpers so existing stores/controllers can run against Postgres without broad query rewrites.
Changes:
- Introduces
PostgresDatabaseClientwith SQL preparation (?→$n, backticks → quotes), statement splitting for migrations, and int8 normalization. - Adds Postgres-native schema bootstrap (
migrations/postgres) plus configuration/docs updates to enableengine: "postgres". - Updates multiple stores/controllers to use shared SQL helpers for booleans, identifier quoting, upserts, COALESCE, INSERT IGNORE semantics, and
RETURNING idsupport.
Reviewed changes
Copilot reviewed 30 out of 31 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/backend/util/userProvisioning.ts | Uses engine-specific boolean literals for seeded fsentries rows. |
| src/backend/types.ts | Extends DB config typing to include postgres and connection-string options. |
| src/backend/stores/user/UserStore.ts | Adds boolean column normalization + RETURNING id support for Postgres. |
| src/backend/stores/session/SessionStore.js | Reworks INSERT-IGNORE and NULL-coalescing comparisons for Postgres compatibility. |
| src/backend/stores/permission/PermissionStore.ts | Switches to shared upsert helper for MySQL vs Postgres/SQLite. |
| src/backend/stores/oidc/OIDCStore.js | Treats Postgres unique violations as idempotent conflicts where applicable. |
| src/backend/stores/oidc/OIDCStore.test.ts | Adds targeted unit tests for Postgres unique-constraint behavior. |
| src/backend/stores/group/GroupStore.ts | Adds Postgres-compatible interval expression in rate-limit window query. |
| src/backend/stores/fs/FSEntryStore.ts | Updates boolean handling, INSERT-IGNORE semantics, JSON aggregation, and string concatenation for Postgres. |
| src/backend/stores/fs/FSEntryStore.test.ts | Adds coverage for quoting camelCase aliases (important for Postgres). |
| src/backend/stores/app/AppStore.js | Adds RETURNING id, boolean normalization, and Postgres date-grouping formatting. |
| src/backend/services/fs/FSService.ts | Replaces hardcoded 0/1 comparisons with engine boolean literals. |
| src/backend/package.json | Adds pg and @types/pg dependencies. |
| src/backend/core/http/middleware/privateAppGate.ts | Uses engine boolean literal when filtering private apps. |
| src/backend/controllers/static/StaticPagesController.ts | Uses engine boolean literals for sitemap and email checks. |
| src/backend/controllers/auth/AuthController.ts | Writes boolean fields via DB boolean-value helper. |
| src/backend/clients/database/splitPostgresStatements.ts | Adds Postgres-aware SQL statement splitting for migrations. |
| src/backend/clients/database/preparePostgresSql.ts | Adds Postgres SQL preparation (placeholder + identifier quoting). |
| src/backend/clients/database/preparePostgresSql.test.ts | Adds unit tests for placeholder/identifier conversion edge cases. |
| src/backend/clients/database/PostgresDatabaseClient.ts | Implements Postgres DB client, migrations runner, and int8 normalization. |
| src/backend/clients/database/PostgresDatabaseClient.test.ts | Adds unit tests for write-result mapping, batching, and int8 normalization. |
| src/backend/clients/database/PostgresDatabaseClient.integration.test.ts | Adds disposable-schema integration coverage against a real Postgres instance. |
| src/backend/clients/database/MySQLDatabaseClient.ts | Extracts migration filename comparator to a shared module. |
| src/backend/clients/database/migrations/postgres/postgres_mig_1.sql | Introduces initial Postgres schema + seed data. |
| src/backend/clients/database/migrationFilenames.ts | Adds shared numeric migration filename sorter. |
| src/backend/clients/database/index.ts | Wires Postgres client into the DB factory export/selection. |
| src/backend/clients/database/DatabaseClient.ts | Adds shared SQL helpers (identifier quoting, booleans, upsert/ignore/returning). |
| extensions/appTelemetry.ts | Quotes reserved identifier user to be Postgres-safe. |
| doc/self-hosting.md | Documents configuring Puter to use PostgreSQL + migration path. |
| config.template.jsonc | Updates template config to include postgres engine and connection-string guidance. |
| package-lock.json | Locks pg and its transitive dependencies. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Hi @rhernaus could you look into adding pgmock to be able to run those postgres tests more easily, and if possible, add a configuration path to have setupTestServer run the test suite with pgmock as an in memory postgres? I realize we don't have this for mysql (mostly out of lack of good in memory mocks) but as we won't have an active environment to test changes against postgres im worried it might degrade and rot overtime without a test harness we can configure to run frequently |
bffdaa1 to
f005f69
Compare
|
Hi @Salazareo this is addressed now. I added |
Adds the PostgreSQL database client, native bootstrap migration, SQL preparation helpers, and database config/factory wiring.\n\nRefs HeyPuter#3165.
Updates runtime SQL call sites for database-specific booleans, identifiers, insert-ignore, upserts, JSON extraction, intervals, and Postgres insert ids.\n\nRefs HeyPuter#3165.
Adds unit coverage for SQL preparation, factory selection, write-result mapping, and transaction rollback/commit ordering, plus an env-gated PostgreSQL integration flow.\n\nRefs HeyPuter#3165.
Adds PostgreSQL configuration examples and migration path guidance for self-hosted deployments.\n\nRefs HeyPuter#3165.
f005f69 to
e1ec3b4
Compare
Summary
Closes #3165.
This adds PostgreSQL as a supported database backend for self-hosted Puter. It includes a native Postgres client, native migrations, SQL preparation for Postgres syntax, and the compatibility fixes needed for normal backend flows to work against a real Postgres database.
What's included:
int8results so session timestamps and quota values match existing expectationsTesting
npm run test:backend -- src/backend/clients/database/preparePostgresSql.test.ts src/backend/clients/database/PostgresDatabaseClient.test.ts src/backend/stores/fs/FSEntryStore.test.tsPUTER_TEST_POSTGRES_URL='postgres://postgres:[email protected]:54329/puter_test' npm run test:backend -- src/backend/clients/database/PostgresDatabaseClient.integration.test.tsnpm run build:ts