Skip to content

Commit 29afe5b

Browse files
committed
test for table not in schema scenario
1 parent 5e15029 commit 29afe5b

3 files changed

Lines changed: 28 additions & 30 deletions

File tree

crates/core/src/schema/mod.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use crate::{
2323
schema::raw_table::{InferredTableStructure, generate_raw_table_trigger},
2424
state::DatabaseState,
2525
sync::RawTableWithCachedStatements,
26-
utils::{SqlBuffer, WriteType},
26+
utils::{SqlBuffer, WriteType, verify_in_transaction},
2727
views::table_columns_to_json_object,
2828
};
2929

@@ -92,11 +92,8 @@ fn raw_table_migration(
9292
args: &[*mut sqlite::value],
9393
) -> Result<(), PowerSyncError> {
9494
let db = context.db_handle();
95-
if db.get_autocommit() {
96-
return Err(PowerSyncError::argument_error(
97-
"powersync_raw_table_migrate must be called within a transaction",
98-
));
99-
}
95+
verify_in_transaction(db)?;
96+
10097
let context = unsafe { DatabaseState::from_context(&context) };
10198
let action = RawTableMigration::from_args(args)?;
10299

@@ -159,7 +156,7 @@ fn raw_table_migration(
159156
// Generate an INSERT INTO ps_untyped with a SELECT source transforming existing
160157
// rows into JSON objects.
161158
let mut buffer = SqlBuffer::new();
162-
let fragment = table_columns_to_json_object(&local_table_name, &as_schema_table)?;
159+
let fragment = table_columns_to_json_object(local_table_name, &as_schema_table)?;
163160
buffer.push_str("INSERT INTO ps_untyped (type, id, data) SELECT ?, id, ");
164161
buffer.push_str(&fragment);
165162
buffer.push_str(" FROM ");

dart/test/error_test.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ void main() {
4040
'SELECT powersync_clear(?)', 'powersync_clear', [0]);
4141
expectErrorOutsideOfTransaction(
4242
'SELECT powersync_trigger_resync(TRUE)', 'powersync_trigger_resync');
43+
expectErrorOutsideOfTransaction('SELECT powersync_raw_table_migrate(?,?)',
44+
'powersync_raw_table_migrate', ['create', 'a']);
4345
});
4446

4547
test('contain inner SQLite descriptions', () {

dart/test/schema_test.dart

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -333,15 +333,7 @@ END''',
333333
};
334334
}
335335

336-
setUp(() => db.execute('SELECT powersync_init();'));
337-
338-
test('requires a transaction', () {
339-
expect(
340-
() => db.execute(
341-
'SELECT powersync_raw_table_migrate(?, ?)', ['create', syncName]),
342-
throwsA(isA<SqliteException>()),
343-
);
344-
});
336+
setUp(() => db.executeInTx('SELECT powersync_init();'));
345337

346338
group('create', () {
347339
void createUntypedItem(String id, Object? json) {
@@ -355,17 +347,15 @@ END''',
355347
createUntypedItem('foo', {'hello': 'world'});
356348
createUntypedItem('bar', {'hello': 'again'});
357349

358-
db.execute('SELECT powersync_replace_schema(?)', [
350+
db.executeInTx('SELECT powersync_replace_schema(?)', [
359351
json.encode(singleRawTableSchema(
360352
{'name': syncName, 'table_name': 'greetings'})),
361353
]);
362354
db.execute(
363355
'CREATE TABLE greetings (id TEXT PRIMARY KEY, hello TEXT) STRICT;');
364356

365-
db.execute('BEGIN');
366-
db.execute(
357+
db.executeInTx(
367358
'SELECT powersync_raw_table_migrate(?, ?)', ['create', syncName]);
368-
db.execute('COMMIT');
369359
expect(db.select('select * from ps_untyped'), isEmpty);
370360
expect(db.select('select * from greetings'), [
371361
{'id': 'foo', 'hello': 'world'},
@@ -377,7 +367,7 @@ END''',
377367
createUntypedItem('foo', {'hello': 'world'});
378368
createUntypedItem('bar', {'hello': 'again'});
379369

380-
db.execute('SELECT powersync_replace_schema(?)', [
370+
db.executeInTx('SELECT powersync_replace_schema(?)', [
381371
json.encode(singleRawTableSchema({
382372
'name': syncName,
383373
'put': {
@@ -393,16 +383,27 @@ END''',
393383
db.execute(
394384
'CREATE TABLE greetings (id TEXT PRIMARY KEY, hello TEXT) STRICT;');
395385

396-
db.execute('BEGIN');
397-
db.execute(
386+
db.executeInTx(
398387
'SELECT powersync_raw_table_migrate(?, ?)', ['create', syncName]);
399-
db.execute('COMMIT');
400388
expect(db.select('select * from ps_untyped'), isEmpty);
401389
expect(db.select('select * from greetings'), [
402390
{'id': 'foo', 'hello': 'world'},
403391
{'id': 'bar', 'hello': 'again'},
404392
]);
405393
});
394+
395+
test('errors when table is not in schema', () {
396+
db.executeInTx('SELECT powersync_replace_schema(?)', [
397+
json.encode(singleRawTableSchema(
398+
{'name': syncName, 'table_name': 'greetings'})),
399+
]);
400+
401+
expect(
402+
() => db.executeInTx('SELECT powersync_raw_table_migrate(?, ?)',
403+
['create', 'unknown_table']),
404+
throwsA(isA<SqliteException>()),
405+
);
406+
});
406407
});
407408

408409
test('drop', () {
@@ -417,28 +418,26 @@ END''',
417418
'INSERT INTO greetings (id, hello, local) VALUES (?, ?, uuid())',
418419
['id_1', 'second'],
419420
)
420-
..execute('BEGIN')
421-
..execute('SELECT powersync_raw_table_migrate(?, ?)', [
421+
..executeInTx('SELECT powersync_raw_table_migrate(?, ?)', [
422422
'drop',
423423
json.encode({
424424
'name': syncName,
425425
'table_name': 'greetings',
426426
'synced_columns': ['hello']
427427
})
428-
])
429-
..execute('COMMIT');
430-
428+
]);
431429
expect(db.select('select * from ps_untyped'), [
432430
{'type': 'synced_table', 'id': 'id_0', 'data': '{"hello":"first"}'},
433431
{'type': 'synced_table', 'id': 'id_1', 'data': '{"hello":"second"}'},
434432
]);
433+
expect(db.select('select * from greetings'), isEmpty);
435434
});
436435

437436
test('crud triggers are not invoked during migration', () {
438437
final tableJson =
439438
json.encode({'name': syncName, 'table_name': 'greetings'});
440439

441-
db.execute('SELECT powersync_replace_schema(?)', [
440+
db.executeInTx('SELECT powersync_replace_schema(?)', [
442441
json.encode(singleRawTableSchema(
443442
{'name': syncName, 'table_name': 'greetings'})),
444443
]);

0 commit comments

Comments
 (0)