Skip to content

Commit

Permalink
Added mechanism to map Drizzle table to a PowerSync table.
Browse files Browse the repository at this point in the history
  • Loading branch information
Chriztiaan committed Nov 15, 2024
1 parent b153571 commit 01039ba
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 7 deletions.
28 changes: 27 additions & 1 deletion packages/drizzle-driver/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,36 @@ export const db = wrapPowerSyncWithDrizzle(powerSyncDb, {
});
```

## Converting Drizzle Tables to PowerSync Tables

The `toPowerSyncTable` function simplifies the process of integrating Drizzle with PowerSync. Define your Drizzle tables, convert each using `toPowerSyncTable`, and supply the converted table definitions into your PowerSync schema for a unified development experience.

As the PowerSync table only supports `text`, `integer`, and `real`, the same limitation extends to the Drizzle table definitions.

```js
import { toPowerSyncTable } from '@powersync/drizzle-driver';
import { Schema } from '@powersync/web';
import { sqliteTable, text } from 'drizzle-orm/sqlite-core';

// Define a Drizzle table
const lists = sqliteTable('lists', {
id: text('id').primaryKey().notNull(),
created_at: text('created_at'),
name: text('name').notNull(),
owner_id: text('owner_id')
});

const psLists = toPowerSyncTable(lists); // converts the Drizzle table to a PowerSync table
// toPowerSyncTable(lists, { localOnly: true }); - th allows for PowerSync table configuration

export const AppSchema = new Schema({
lists: psLists // names the table `lists` in the PowerSync schema
});
```

## Known limitations

- The integration does not currently support nested transactions (also known as `savepoints`).
- The Drizzle schema needs to be created manually, and it should match the table definitions of your PowerSync schema.

### Compilable queries

Expand Down
3 changes: 3 additions & 0 deletions packages/drizzle-driver/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
"@powersync/common": "workspace:^1.19.0",
"drizzle-orm": "<1.0.0"
},
"dependencies": {
"@powersync/common": "workspace:*"
},
"devDependencies": {
"@powersync/web": "workspace:*",
"@journeyapps/wa-sqlite": "^0.4.1",
Expand Down
3 changes: 2 additions & 1 deletion packages/drizzle-driver/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { wrapPowerSyncWithDrizzle, type PowerSyncSQLiteDatabase } from './sqlite/db';
import { toCompilableQuery } from './utils/compilableQuery';
import { toPowerSyncTable } from './utils/schema';

export { wrapPowerSyncWithDrizzle, toCompilableQuery, PowerSyncSQLiteDatabase };
export { wrapPowerSyncWithDrizzle, toCompilableQuery, toPowerSyncTable, PowerSyncSQLiteDatabase };
35 changes: 35 additions & 0 deletions packages/drizzle-driver/src/utils/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { column, Table, type BaseColumnType, type TableV2Options } from '@powersync/common';
import {
SQLiteInteger,
SQLiteReal,
SQLiteText,
type SQLiteTableWithColumns,
type TableConfig
} from 'drizzle-orm/sqlite-core';

export function toPowerSyncTable<T extends TableConfig>(table: SQLiteTableWithColumns<T>, options?: TableV2Options) {
const columns: { [key: string]: BaseColumnType<number | string | null> } = {};
for (const [columnName, columnValue] of Object.entries(table)) {
// Skip the id column
if (columnName === 'id') {
continue;
}

let mappedType: BaseColumnType<number | string | null>;
switch (columnValue.columnType) {
case SQLiteText.name:
mappedType = column.text;
break;
case SQLiteInteger.name:
mappedType = column.integer;
break;
case SQLiteReal.name:
mappedType = column.real;
break;
default:
throw new Error(`Unsupported column type: ${columnValue.columnType}`);
}
columns[columnName] = mappedType;
}
return new Table(columns, options);
}
10 changes: 5 additions & 5 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 01039ba

Please sign in to comment.