Skip to content

Commit e312705

Browse files
committed
Introduced DrizzleAppSchema constructor.
1 parent 1a1dca7 commit e312705

File tree

3 files changed

+83
-3
lines changed

3 files changed

+83
-3
lines changed

packages/common/src/db/schema/Schema.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { RowType, Table } from './Table.js';
22

33
type SchemaType = Record<string, Table<any>>;
44

5-
type SchemaTableType<S extends SchemaType> = {
5+
export type SchemaTableType<S extends SchemaType> = {
66
[K in keyof S]: RowType<S[K]>;
77
};
88

packages/drizzle-driver/src/utils/schema.ts

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
1-
import { column, IndexShorthand, Schema, Table, type BaseColumnType, type TableV2Options } from '@powersync/common';
1+
import {
2+
column,
3+
IndexShorthand,
4+
Schema,
5+
SchemaTableType,
6+
Table,
7+
type BaseColumnType,
8+
type TableV2Options
9+
} from '@powersync/common';
210
import { InferSelectModel, isTable, Relations } from 'drizzle-orm';
311
import {
412
getTableConfig,
@@ -111,3 +119,40 @@ export function toPowerSyncSchema<
111119

112120
return new Schema(tables) as Schema<Expand<TablesFromSchemaEntries<T>>>;
113121
}
122+
123+
export function toPowerSyncTables<
124+
T extends Record<string, SQLiteTableWithColumns<any> | Relations | DrizzleTableWithPowerSyncOptions>
125+
>(schemaEntries: T) {
126+
const tables: Record<string, Table> = {};
127+
for (const schemaEntry of Object.values(schemaEntries)) {
128+
let maybeTable: SQLiteTableWithColumns<any> | Relations | undefined = undefined;
129+
let maybeOptions: DrizzleTablePowerSyncOptions | undefined = undefined;
130+
131+
if (typeof schemaEntry === 'object' && 'tableDefinition' in schemaEntry) {
132+
const tableWithOptions = schemaEntry as DrizzleTableWithPowerSyncOptions;
133+
maybeTable = tableWithOptions.tableDefinition;
134+
maybeOptions = tableWithOptions.options;
135+
} else {
136+
maybeTable = schemaEntry;
137+
}
138+
139+
if (isTable(maybeTable)) {
140+
const { name } = getTableConfig(maybeTable);
141+
tables[name] = toPowerSyncTable(maybeTable as SQLiteTableWithColumns<TableConfig>, maybeOptions);
142+
}
143+
}
144+
145+
return tables;
146+
}
147+
148+
export class DrizzleAppSchema<
149+
T extends Record<string, SQLiteTableWithColumns<any> | Relations | DrizzleTableWithPowerSyncOptions>
150+
> extends Schema {
151+
constructor(drizzleSchema: T) {
152+
super(toPowerSyncTables(drizzleSchema));
153+
// This is just used for typing
154+
this.types = {} as SchemaTableType<Expand<TablesFromSchemaEntries<T>>>;
155+
}
156+
157+
readonly types: SchemaTableType<Expand<TablesFromSchemaEntries<T>>>;
158+
}

packages/drizzle-driver/tests/sqlite/schema.test.ts

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
import { column, Schema, Table } from '@powersync/common';
22
import { index, integer, real, sqliteTable, text } from 'drizzle-orm/sqlite-core';
33
import { describe, expect, it } from 'vitest';
4-
import { DrizzleTableWithPowerSyncOptions, toPowerSyncSchema, toPowerSyncTable } from '../../src/utils/schema';
4+
import {
5+
DrizzleAppSchema,
6+
DrizzleTableWithPowerSyncOptions,
7+
toPowerSyncSchema,
8+
toPowerSyncTable
9+
} from '../../src/utils/schema';
510

611
describe('toPowerSyncTable', () => {
712
it('basic conversion', () => {
@@ -24,6 +29,36 @@ describe('toPowerSyncTable', () => {
2429
expect(convertedList).toEqual(expectedLists);
2530
});
2631

32+
it('basic conversion class', () => {
33+
const lists = sqliteTable('lists', {
34+
id: text('id').primaryKey(),
35+
name: text('name').notNull(),
36+
owner_id: text('owner_id'),
37+
counter: integer('counter'),
38+
completion: real('completion')
39+
});
40+
const convertedList = new DrizzleAppSchema({ lists });
41+
42+
const a: (typeof convertedList)['types']['lists'] = {
43+
name: 'd',
44+
completion: 1,
45+
counter: 0,
46+
id: '1',
47+
owner_id: null
48+
};
49+
});
50+
51+
it('classed based types', () => {
52+
const lists = sqliteTable('lists', {
53+
id: text('id').primaryKey(),
54+
name: text('name').notNull(),
55+
owner_id: text('owner_id'),
56+
counter: integer('counter'),
57+
completion: real('completion')
58+
});
59+
const drizzle = new DrizzleAppSchema({ lists });
60+
});
61+
2762
it('conversion with index', () => {
2863
const lists = sqliteTable(
2964
'lists',

0 commit comments

Comments
 (0)