Skip to content

Commit

Permalink
Dropped toPowerSyncSchema in favour of DrizzleAppSchema constructor.
Browse files Browse the repository at this point in the history
  • Loading branch information
Chriztiaan committed Dec 2, 2024
1 parent e312705 commit 3238948
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 82 deletions.
2 changes: 1 addition & 1 deletion .changeset/tender-mugs-deliver.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
'@powersync/drizzle-driver': minor
---

Added `toPowersyncTable` and `toPowerSyncSchema` helper functions to convert a Drizzle schema into a PowerSync app schema
Added helper `toPowersyncTable` function and `DrizzleAppSchema` constructor to convert a Drizzle schema into a PowerSync app schema.
20 changes: 10 additions & 10 deletions packages/drizzle-driver/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ export const drizzleSchema = {
todosRelations
};

// As an alternative to manually defining a PowerSync schema, generate the local PowerSync schema from the Drizzle schema with `toPowerSyncSchema`:
// import { toPowerSyncSchema } from '@powersync/drizzle-driver';
// export const AppSchema = toPowerSyncSchema(drizzleSchema);
// As an alternative to manually defining a PowerSync schema, generate the local PowerSync schema from the Drizzle schema with the `DrizzleAppSchema` constructor:
// import { DrizzleAppSchema } from '@powersync/drizzle-driver';
// export const AppSchema = new DrizzleAppSchema(drizzleSchema);
//
// This is optional, but recommended, since you will only need to maintain one schema on the client-side
// Read on to learn more.
Expand All @@ -69,14 +69,14 @@ export const db = wrapPowerSyncWithDrizzle(powerSyncDb, {

## Schema Conversion

The `toPowerSyncSchema` function simplifies the process of integrating Drizzle with PowerSync. It infers the local [PowerSync schema](https://docs.powersync.com/installation/client-side-setup/define-your-schema) from your Drizzle schema definition, providing a unified development experience.
The `DrizzleAppSchema` constructor simplifies the process of integrating Drizzle with PowerSync. It infers the local [PowerSync schema](https://docs.powersync.com/installation/client-side-setup/define-your-schema) from your Drizzle schema definition, providing a unified development experience.

As the PowerSync schema only supports SQLite types (`text`, `integer`, and `real`), the same limitation extends to the Drizzle table definitions.

To use it, define your Drizzle tables and supply the schema to the `toPowerSyncSchema` function:
To use it, define your Drizzle tables and supply the schema to the `DrizzleAppSchema` function:

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

// Define a Drizzle table
Expand All @@ -92,7 +92,7 @@ export const drizzleSchema = {
};

// Infer the PowerSync schema from your Drizzle schema
export const AppSchema = toPowerSyncSchema(drizzleSchema);
export const AppSchema = new DrizzleAppSchema(drizzleSchema);
```

### Defining PowerSync Options
Expand All @@ -101,8 +101,8 @@ The PowerSync table definition allows additional options supported by PowerSync'
They can be specified as follows. Note that these options exclude indexes as they can be specified in a Drizzle table.

```js
import { toPowerSyncSchema } from '@powersync/drizzle-driver';
// import { toPowerSyncSchema, type DrizzleTableWithPowerSyncOptions} from '@powersync/drizzle-driver'; for TypeScript
import { DrizzleAppSchema } from '@powersync/drizzle-driver';
// import { DrizzleAppSchema, type DrizzleTableWithPowerSyncOptions} from '@powersync/drizzle-driver'; for TypeScript

const listsWithOptions = { tableDefinition: logs, options: { localOnly: true } };
// const listsWithOptions: DrizzleTableWithPowerSyncOptions = { tableDefinition: logs, options: { localOnly: true } }; for TypeScript
Expand All @@ -111,7 +111,7 @@ export const drizzleSchemaWithOptions = {
lists: listsWithOptions
};

export const AppSchema = toPowerSyncSchema(drizzleSchemaWithOptions);
export const AppSchema = new DrizzleAppSchema(drizzleSchemaWithOptions);
```

### Converting a Single Table From Drizzle to PowerSync
Expand Down
4 changes: 2 additions & 2 deletions packages/drizzle-driver/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { wrapPowerSyncWithDrizzle, type PowerSyncSQLiteDatabase } from './sqlite/db';
import { toCompilableQuery } from './utils/compilableQuery';
import {
toPowerSyncSchema,
DrizzleAppSchema,
toPowerSyncTable,
type DrizzleTablePowerSyncOptions,
type DrizzleTableWithPowerSyncOptions,
Expand All @@ -12,6 +12,7 @@ import {
} from './utils/schema';

export {
DrizzleAppSchema,
DrizzleTablePowerSyncOptions,
DrizzleTableWithPowerSyncOptions,
Expand,
Expand All @@ -20,7 +21,6 @@ export {
TableName,
TablesFromSchemaEntries,
toCompilableQuery,
toPowerSyncSchema,
toPowerSyncTable,
wrapPowerSyncWithDrizzle
};
27 changes: 1 addition & 26 deletions packages/drizzle-driver/src/utils/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,32 +95,7 @@ export type TablesFromSchemaEntries<T> = {
: never;
};

export function toPowerSyncSchema<
T extends Record<string, SQLiteTableWithColumns<any> | Relations | DrizzleTableWithPowerSyncOptions>
>(schemaEntries: T): Schema<Expand<TablesFromSchemaEntries<T>>> {
const tables: Record<string, Table> = {};
for (const schemaEntry of Object.values(schemaEntries)) {
let maybeTable: SQLiteTableWithColumns<any> | Relations | undefined = undefined;
let maybeOptions: DrizzleTablePowerSyncOptions | undefined = undefined;

if (typeof schemaEntry === 'object' && 'tableDefinition' in schemaEntry) {
const tableWithOptions = schemaEntry as DrizzleTableWithPowerSyncOptions;
maybeTable = tableWithOptions.tableDefinition;
maybeOptions = tableWithOptions.options;
} else {
maybeTable = schemaEntry;
}

if (isTable(maybeTable)) {
const { name } = getTableConfig(maybeTable);
tables[name] = toPowerSyncTable(maybeTable as SQLiteTableWithColumns<TableConfig>, maybeOptions);
}
}

return new Schema(tables) as Schema<Expand<TablesFromSchemaEntries<T>>>;
}

export function toPowerSyncTables<
function toPowerSyncTables<
T extends Record<string, SQLiteTableWithColumns<any> | Relations | DrizzleTableWithPowerSyncOptions>
>(schemaEntries: T) {
const tables: Record<string, Table> = {};
Expand Down
52 changes: 9 additions & 43 deletions packages/drizzle-driver/tests/sqlite/schema.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
import { column, Schema, Table } from '@powersync/common';
import { index, integer, real, sqliteTable, text } from 'drizzle-orm/sqlite-core';
import { describe, expect, it } from 'vitest';
import {
DrizzleAppSchema,
DrizzleTableWithPowerSyncOptions,
toPowerSyncSchema,
toPowerSyncTable
} from '../../src/utils/schema';
import { DrizzleAppSchema, DrizzleTableWithPowerSyncOptions, toPowerSyncTable } from '../../src/utils/schema';

describe('toPowerSyncTable', () => {
it('basic conversion', () => {
Expand All @@ -29,36 +24,6 @@ describe('toPowerSyncTable', () => {
expect(convertedList).toEqual(expectedLists);
});

it('basic conversion class', () => {
const lists = sqliteTable('lists', {
id: text('id').primaryKey(),
name: text('name').notNull(),
owner_id: text('owner_id'),
counter: integer('counter'),
completion: real('completion')
});
const convertedList = new DrizzleAppSchema({ lists });

const a: (typeof convertedList)['types']['lists'] = {
name: 'd',
completion: 1,
counter: 0,
id: '1',
owner_id: null
};
});

it('classed based types', () => {
const lists = sqliteTable('lists', {
id: text('id').primaryKey(),
name: text('name').notNull(),
owner_id: text('owner_id'),
counter: integer('counter'),
completion: real('completion')
});
const drizzle = new DrizzleAppSchema({ lists });
});

it('conversion with index', () => {
const lists = sqliteTable(
'lists',
Expand Down Expand Up @@ -103,7 +68,7 @@ describe('toPowerSyncTable', () => {
});
});

describe('toPowerSyncSchema', () => {
describe('DrizzleAppSchema constructor', () => {
it('basic conversion', () => {
const lists = sqliteTable('lists', {
id: text('id').primaryKey(),
Expand All @@ -123,7 +88,8 @@ describe('toPowerSyncSchema', () => {
lists,
todos
};
const convertedSchema = toPowerSyncSchema(drizzleSchema);

const convertedSchema = new DrizzleAppSchema(drizzleSchema);

const expectedSchema = new Schema({
lists: new Table({
Expand All @@ -138,7 +104,7 @@ describe('toPowerSyncSchema', () => {
})
});

expect(convertedSchema).toEqual(expectedSchema);
expect(convertedSchema.tables).toEqual(expectedSchema.tables);
});

it('conversion with options', () => {
Expand All @@ -164,7 +130,7 @@ describe('toPowerSyncSchema', () => {
todos
};

const convertedSchema = toPowerSyncSchema(drizzleSchemaWithOptions);
const convertedSchema = new DrizzleAppSchema(drizzleSchemaWithOptions);

const expectedSchema = new Schema({
lists: new Table(
Expand All @@ -182,7 +148,7 @@ describe('toPowerSyncSchema', () => {
})
});

expect(convertedSchema).toEqual(expectedSchema);
expect(convertedSchema.tables).toEqual(expectedSchema.tables);
});

it('conversion with index', () => {
Expand Down Expand Up @@ -211,7 +177,7 @@ describe('toPowerSyncSchema', () => {
todos
};

const convertedSchema = toPowerSyncSchema(drizzleSchemaWithOptions);
const convertedSchema = new DrizzleAppSchema(drizzleSchemaWithOptions);

const expectedSchema = new Schema({
lists: new Table({
Expand All @@ -229,6 +195,6 @@ describe('toPowerSyncSchema', () => {
)
});

expect(convertedSchema).toEqual(expectedSchema);
expect(convertedSchema.tables).toEqual(expectedSchema.tables);
});
});

0 comments on commit 3238948

Please sign in to comment.