1- import { CommonPowerSyncDatabase , Schema , Table , column } from '@powersync/common' ;
1+ import { CommonPowerSyncDatabase , IndexedColumn , Schema , Table , column } from '@powersync/common' ;
22import { PowerSyncDatabase } from '@powersync/web' ;
33import { afterEach , beforeEach , describe , expect , it } from 'vitest' ;
44
55type 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
5969describe ( '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