Skip to content

Commit 3fe3cd9

Browse files
committed
Restore web schema test
1 parent 6376f8e commit 3fe3cd9

2 files changed

Lines changed: 74 additions & 94 deletions

File tree

packages/attachments/src/Schema.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ export interface AttachmentTableOptions extends Omit<TableOptions, 'name' | 'col
2727

2828
export class AttachmentTable extends Table {
2929
constructor(options?: AttachmentTableOptions) {
30+
const { additionalColumns = {}, ...tableOptions } = options ?? {};
31+
3032
super(
3133
{
3234
filename: column.text,
@@ -35,11 +37,11 @@ export class AttachmentTable extends Table {
3537
size: column.integer,
3638
media_type: column.text,
3739
state: column.integer,
38-
...options?.additionalColumns
40+
...additionalColumns
3941
},
4042
{
4143
name: ATTACHMENT_TABLE,
42-
...options,
44+
...tableOptions,
4345
localOnly: true,
4446
insertOnly: false
4547
}

packages/web/tests/schema.test.ts

Lines changed: 70 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,70 @@
1-
import { CommonPowerSyncDatabase, Schema, Table, column } from '@powersync/common';
1+
import { CommonPowerSyncDatabase, IndexedColumn, Schema, Table, column } from '@powersync/common';
22
import { PowerSyncDatabase } from '@powersync/web';
33
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
44

55
type SchemaVersionResult = {
66
schema_version: number;
77
};
88

9-
const assets = new Table(
10-
{
11-
created_at: column.text,
12-
make: column.text,
13-
model: column.text,
14-
serial_number: column.text,
15-
quantity: column.integer,
16-
user_id: column.text,
17-
weightColumnName: column.real,
18-
description: column.text
19-
},
20-
{
21-
indexes: { makemodel: ['make', 'model'] }
22-
}
23-
);
24-
const assetsNoIndex = new Table({
25-
created_at: column.text,
26-
make: column.text,
27-
model: column.text,
28-
serial_number: column.text,
29-
quantity: column.integer,
30-
user_id: column.text,
31-
weightColumnName: column.real,
32-
description: column.text
33-
});
34-
const customers = new Table({
35-
name: column.text,
36-
email: column.text
37-
});
38-
const logs = new Table(
39-
{
40-
level: column.text,
41-
content: column.text
42-
},
43-
{ insertOnly: true }
44-
);
45-
const credentials = new Table(
46-
{
47-
key: column.text,
48-
value: column.text
49-
},
50-
{ localOnly: true }
51-
);
52-
const aliased = new Table({ name: column.text }, { viewName: 'test1' });
9+
/**
10+
* Generates the Asset table with configurable options which
11+
* will be modified later.
12+
*/
13+
const generateAssetsTable = (weightColumnName: string = 'weight', includeIndexes = true, indexAscending = true) => {
14+
return new Table(
15+
{
16+
created_at: column.text,
17+
make: column.text,
18+
model: column.text,
19+
serial_number: column.text,
20+
quantity: column.integer,
21+
user_id: column.text,
22+
[weightColumnName]: column.real,
23+
description: column.text
24+
},
25+
{
26+
indexes: includeIndexes
27+
? {
28+
makemodel: ['make', new IndexedColumn({ name: 'model', ascending: indexAscending })]
29+
}
30+
: {}
31+
}
32+
);
33+
};
34+
35+
/**
36+
* Generates all the schema tables.
37+
* Allows for a custom assets table generator to be supplied.
38+
*/
39+
const generateSchema = (assetsTableGenerator: () => Table = generateAssetsTable) => {
40+
return new Schema({
41+
assets: assetsTableGenerator(),
42+
customers: new Table({
43+
name: column.text,
44+
email: column.text
45+
}),
46+
logs: new Table(
47+
{
48+
level: column.text,
49+
content: column.text
50+
},
51+
{ insertOnly: true }
52+
),
53+
credentials: new Table(
54+
{
55+
key: column.text,
56+
value: column.text
57+
},
58+
{ localOnly: true }
59+
),
60+
aliased: new Table({ name: column.text }, { viewName: 'test1' })
61+
});
62+
};
5363

5464
/**
5565
* The default schema
5666
*/
57-
const schema = new Schema({ assets, customers, logs, credentials, aliased });
67+
const schema = generateSchema();
5868

5969
describe('Schema Tests', { sequential: true }, () => {
6070
let powersync: CommonPowerSyncDatabase;
@@ -86,15 +96,25 @@ describe('Schema Tests', { sequential: true }, () => {
8696
// No change
8797
expect(versionAfter['schema_version']).equals(versionBefore['schema_version']);
8898

89-
// Remove a table
90-
const schema2 = new Schema({ assets, customers, logs, credentials });
99+
// The `weight` columns is now `weights`
100+
const schema2 = generateSchema(() => generateAssetsTable('weights'));
91101

92102
await powersync.updateSchema(schema2);
93103

94104
const versionAfter2 = await powersync.get<SchemaVersionResult>('PRAGMA schema_version');
95105

96106
// Updated
97107
expect(versionAfter2['schema_version']).greaterThan(versionAfter['schema_version']);
108+
109+
// The index is now descending
110+
const schema3 = generateSchema(() => generateAssetsTable('weights', true, false));
111+
112+
await powersync.updateSchema(schema3);
113+
114+
const versionAfter3 = await powersync.get<SchemaVersionResult>('PRAGMA schema_version');
115+
116+
// Updated
117+
expect(versionAfter3['schema_version']).greaterThan(versionAfter2['schema_version']);
98118
});
99119

100120
it('Indexing', async () => {
@@ -103,55 +123,13 @@ describe('Schema Tests', { sequential: true }, () => {
103123
expect(results.rows?._array?.[0]['detail']).contains('USING INDEX ps_data__assets__makemodel');
104124

105125
// Now drop the index
106-
const schema2 = new Schema({ assetsNoIndex, customers, logs, credentials, aliased });
126+
const schema2 = generateSchema(() => generateAssetsTable('weight', false));
107127
await powersync.updateSchema(schema2);
108128

109129
// Execute instead of getAll so that we don't get a cached query plan
110130
// from a different connection
111-
const results2 = await powersync.execute('EXPLAIN QUERY PLAN SELECT * FROM assetsNoIndex WHERE make = ?', ['test']);
131+
const results2 = await powersync.execute('EXPLAIN QUERY PLAN SELECT * FROM assets WHERE make = ?', ['test']);
112132

113133
expect(results2.rows?._array?.[0]['detail']).contains('SCAN');
114134
});
115-
116-
it('Local Only', async () => {
117-
const pscrudBeforeInsert = await powersync.getAll('SELECT * FROM ps_crud');
118-
expect(pscrudBeforeInsert.length).toEqual(0);
119-
120-
await powersync.execute('INSERT INTO credentials (id, key, value) VALUES(uuid(),?,?)', ['test', 'test']);
121-
122-
const pscrudAfterInsert = await powersync.getAll('SELECT * FROM ps_crud');
123-
expect(pscrudAfterInsert.length).toEqual(0);
124-
});
125-
126-
it('Insert Only', async () => {
127-
const pscrudBeforeInsert = await powersync.getAll('SELECT * FROM ps_crud');
128-
expect(pscrudBeforeInsert.length).toEqual(0);
129-
const logsBeforeInsert = await powersync.getAll('SELECT * FROM logs');
130-
expect(logsBeforeInsert.length).toEqual(0);
131-
132-
await powersync.execute('INSERT INTO logs (id, level, content) VALUES(uuid(),?,?)', ['test', 'test']);
133-
134-
const pscrudAfterInsert = await powersync.getAll('SELECT * FROM ps_crud');
135-
expect(pscrudAfterInsert.length).toEqual(1);
136-
const logsAfterInsert = await powersync.getAll('SELECT * FROM logs');
137-
expect(logsAfterInsert.length).toEqual(0);
138-
});
139-
140-
it('ViewName', async () => {
141-
const aliasedTable = await powersync.getAll('SELECT * FROM test1');
142-
expect(Array.isArray(aliasedTable)).toBe(true);
143-
});
144-
145-
it('should have table names present in schema props', async () => {
146-
// The table names aren't present when creating the Table instances.
147-
// Passing Tables into a Schema should populate the table name based
148-
// off the key of the prop
149-
expect(schema.props.aliased.name).eq('aliased');
150-
expect(schema.props.aliased.internalName).eq('ps_data__aliased');
151-
expect(schema.props.aliased.viewName).eq('test1');
152-
153-
expect(schema.props.assets.name).eq('assets');
154-
expect(schema.props.assets.internalName).eq('ps_data__assets');
155-
expect(schema.props.assets.viewName).eq('assets');
156-
});
157135
});

0 commit comments

Comments
 (0)