Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/sharp-donuts-push.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@powersync/common': minor
---

Merge `Table` and `TableV2` but kept `TableV2` to avoid making this a breaking change.
4 changes: 3 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@
**/android/**
**/assets/**
**/bin/**
**/ios/**
**/ios/**

pnpm-lock.yaml
6 changes: 3 additions & 3 deletions demos/example-vite/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ class DummyConnector {
async uploadData(database) {}
}

export const AppSchema = new Schema([
new Table({ name: 'customers', columns: [new Column({ name: 'name', type: ColumnType.TEXT })] })
]);
const customers = new Table({ name: column.text })

export const AppSchema = new Schema({ customers });

let PowerSync;

Expand Down
8 changes: 4 additions & 4 deletions demos/example-webpack/src/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Column, ColumnType, Schema, Table, PowerSyncDatabase } from '@powersync/web';
import { Column, ColumnType, Schema, Table, PowerSyncDatabase, column } from '@powersync/web';
import Logger from 'js-logger';

Logger.useDefaults();
Expand All @@ -19,9 +19,9 @@ class DummyConnector {
async uploadData(database) {}
}

export const AppSchema = new Schema([
new Table({ name: 'customers', columns: [new Column({ name: 'name', type: ColumnType.TEXT })] })
]);
const customers = new Table({ name: column.text })

export const AppSchema = new Schema({ customers });

let PowerSync;

Expand Down
2 changes: 1 addition & 1 deletion demos/react-multi-client/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,4 @@ yarn-error.log*
.vercel

# typescript
*.tsbuildinfo
*.tsbuildinfo
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { column, Schema, TableV2 } from '@powersync/web';
import { column, Schema, Table } from '@powersync/web';

export const LISTS_TABLE = 'lists';
export const TODOS_TABLE = 'todos';

const todos = new TableV2(
const todos = new Table(
{
list_id: column.text,
created_at: column.text,
Expand All @@ -16,7 +16,7 @@ const todos = new TableV2(
{ indexes: { list: ['list_id'] } }
);

const lists = new TableV2({
const lists = new Table({
created_at: column.text,
name: column.text,
owner_id: column.text
Expand Down
30 changes: 0 additions & 30 deletions packages/common/src/db/Column.ts

This file was deleted.

60 changes: 60 additions & 0 deletions packages/common/src/db/schema/Column.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// https://www.sqlite.org/lang_expr.html#castexpr
export enum ColumnType {
TEXT = 'TEXT',
INTEGER = 'INTEGER',
REAL = 'REAL'
}

export interface ColumnOptions {
name: string;
type?: ColumnType;
}

export type BaseColumnType<T extends number | string | null> = {
type: ColumnType;
};

export type ColumnsType = Record<string, BaseColumnType<any>>;

export type ExtractColumnValueType<T extends BaseColumnType<any>> = T extends BaseColumnType<infer R> ? R : unknown;

const text: BaseColumnType<string | null> = {
type: ColumnType.TEXT
};

const integer: BaseColumnType<number | null> = {
type: ColumnType.INTEGER
};

const real: BaseColumnType<number | null> = {
type: ColumnType.REAL
};

// There is maximum of 127 arguments for any function in SQLite. Currently we use json_object which uses 1 arg per key (column name)
// and one per value, which limits it to 63 arguments.
export const MAX_AMOUNT_OF_COLUMNS = 63;

export const column = {
text,
integer,
real
};

export class Column {
constructor(protected options: ColumnOptions) {}

get name() {
return this.options.name;
}

get type() {
return this.options.type;
}

toJSON() {
return {
name: this.name,
type: this.type
};
}
}
2 changes: 1 addition & 1 deletion packages/common/src/db/schema/IndexedColumn.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ColumnType } from '../Column';
import { ColumnType } from './Column';
import { Table } from './Table';

export interface IndexColumnOptions {
Expand Down
24 changes: 16 additions & 8 deletions packages/common/src/db/schema/Schema.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Table as ClassicTable } from './Table';
import { RowType, TableV2 } from './TableV2';
import { RowType, Table } from './Table';

type SchemaType = Record<string, TableV2<any>>;
type SchemaType = Record<string, Table<any>>;

type SchemaTableType<S extends SchemaType> = {
[K in keyof S]: RowType<S[K]>;
Expand All @@ -16,9 +15,9 @@ export class Schema<S extends SchemaType = SchemaType> {
*/
readonly types: SchemaTableType<S>;
readonly props: S;
readonly tables: ClassicTable[];
readonly tables: Table[];

constructor(tables: ClassicTable[] | S) {
constructor(tables: Table[] | S) {
if (Array.isArray(tables)) {
this.tables = tables;
} else {
Expand All @@ -28,20 +27,29 @@ export class Schema<S extends SchemaType = SchemaType> {
}

validate() {
for (const table of this.tables as ClassicTable[]) {
for (const table of this.tables) {
table.validate();
}
}

toJSON() {
return {
tables: (this.tables as ClassicTable[]).map((t) => t.toJSON())
// This is required because "name" field is not present in TableV2
tables: this.tables.map((t) => t.toJSON())
};
}

private convertToClassicTables(props: S) {
return Object.entries(props).map(([name, table]) => {
return ClassicTable.createTable(name, table);
const convertedTable = new Table({
name,
columns: table.columns,
indexes: table.indexes,
localOnly: table.localOnly,
insertOnly: table.insertOnly,
viewName: table.viewNameOverride || name
});
return convertedTable;
});
}
}
Loading
Loading