Skip to content

Commit 625fa83

Browse files
committed
Expand tests
1 parent 994a3a9 commit 625fa83

File tree

3 files changed

+61
-20
lines changed

3 files changed

+61
-20
lines changed

crates/core/src/sync/storage_adapter.rs

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use serde::Serialize;
55
use sqlite_nostd::{self as sqlite, Connection, ManagedStmt, ResultCode};
66

77
use crate::{
8-
error::PowerSyncError,
8+
error::{PSResult, PowerSyncError},
99
ext::SafeManagedStmt,
1010
operations::delete_bucket,
1111
schema::Schema,
@@ -31,10 +31,11 @@ pub struct StorageAdapter {
3131
}
3232

3333
impl StorageAdapter {
34-
pub fn new(db: *mut sqlite::sqlite3) -> Result<Self, ResultCode> {
34+
pub fn new(db: *mut sqlite::sqlite3) -> Result<Self, PowerSyncError> {
3535
// language=SQLite
36-
let progress =
37-
db.prepare_v2("SELECT name, count_at_last, count_since_last FROM ps_buckets")?;
36+
let progress = db
37+
.prepare_v2("SELECT name, count_at_last, count_since_last FROM ps_buckets")
38+
.into_db_result(db)?;
3839

3940
// language=SQLite
4041
let time = db.prepare_v2("SELECT unixepoch()")?;
@@ -46,11 +47,11 @@ impl StorageAdapter {
4647
})
4748
}
4849

49-
pub fn collect_bucket_requests(&self) -> Result<Vec<BucketRequest>, ResultCode> {
50+
pub fn collect_bucket_requests(&self) -> Result<Vec<BucketRequest>, PowerSyncError> {
5051
// language=SQLite
5152
let statement = self.db.prepare_v2(
5253
"SELECT name, last_op FROM ps_buckets WHERE pending_delete = 0 AND name != '$local'",
53-
)?;
54+
).into_db_result(self.db)?;
5455

5556
let mut requests = Vec::<BucketRequest>::new();
5657

@@ -97,23 +98,27 @@ impl StorageAdapter {
9798
}
9899
}
99100

100-
pub fn reset_progress(&self) -> Result<(), ResultCode> {
101+
pub fn reset_progress(&self) -> Result<(), PowerSyncError> {
101102
self.db
102-
.exec_safe("UPDATE ps_buckets SET count_since_last = 0, count_at_last = 0;")?;
103+
.exec_safe("UPDATE ps_buckets SET count_since_last = 0, count_at_last = 0;")
104+
.into_db_result(self.db)?;
103105
Ok(())
104106
}
105107

106-
pub fn lookup_bucket(&self, bucket: &str) -> Result<BucketInfo, ResultCode> {
108+
pub fn lookup_bucket(&self, bucket: &str) -> Result<BucketInfo, PowerSyncError> {
107109
// We do an ON CONFLICT UPDATE simply so that the RETURNING bit works for existing rows.
108110
// We can consider splitting this into separate SELECT and INSERT statements.
109111
// language=SQLite
110-
let bucket_statement = self.db.prepare_v2(
111-
"INSERT INTO ps_buckets(name)
112+
let bucket_statement = self
113+
.db
114+
.prepare_v2(
115+
"INSERT INTO ps_buckets(name)
112116
VALUES(?)
113117
ON CONFLICT DO UPDATE
114118
SET last_applied_op = last_applied_op
115119
RETURNING id, last_applied_op",
116-
)?;
120+
)
121+
.into_db_result(self.db)?;
117122
bucket_statement.bind_text(1, bucket, sqlite::Destructor::STATIC)?;
118123
let res = bucket_statement.step()?;
119124
debug_assert_matches!(res, ResultCode::ROW);
@@ -147,7 +152,8 @@ impl StorageAdapter {
147152

148153
let update_bucket = self
149154
.db
150-
.prepare_v2("UPDATE ps_buckets SET last_op = ? WHERE name = ?")?;
155+
.prepare_v2("UPDATE ps_buckets SET last_op = ? WHERE name = ?")
156+
.into_db_result(self.db)?;
151157

152158
for bucket in checkpoint.buckets.values() {
153159
if bucket.is_in_priority(priority) {
@@ -214,7 +220,7 @@ impl StorageAdapter {
214220
// partial completions.
215221
let update = self.db.prepare_v2(
216222
"UPDATE ps_buckets SET count_since_last = 0, count_at_last = ? WHERE name = ?",
217-
)?;
223+
).into_db_result(self.db)?;
218224

219225
for bucket in checkpoint.buckets.values() {
220226
if let Some(count) = bucket.count {

crates/core/src/sync/streaming_sync.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use futures_lite::FutureExt;
1717

1818
use crate::{
1919
bson,
20-
error::PowerSyncError,
20+
error::{PowerSyncError, PowerSyncErrorCause},
2121
kv::client_id,
2222
state::DatabaseState,
2323
sync::{checkpoint::OwnedBucketChecksum, interface::StartSyncStream},
@@ -130,7 +130,7 @@ impl SyncIterationHandle {
130130
db: *mut sqlite::sqlite3,
131131
options: StartSyncStream,
132132
state: Arc<DatabaseState>,
133-
) -> Result<Self, ResultCode> {
133+
) -> Result<Self, PowerSyncError> {
134134
let runner = StreamingSyncIteration {
135135
db,
136136
options,
@@ -307,8 +307,9 @@ impl StreamingSyncIteration {
307307
}
308308
SyncLine::CheckpointDiff(diff) => {
309309
let Some(target) = target.target_checkpoint_mut() else {
310-
return Err(PowerSyncError::argument_error(
310+
return Err(PowerSyncError::sync_protocol_error(
311311
"Received checkpoint_diff without previous checkpoint",
312+
PowerSyncErrorCause::Unknown,
312313
));
313314
};
314315

@@ -325,8 +326,9 @@ impl StreamingSyncIteration {
325326
}
326327
SyncLine::CheckpointComplete(_) => {
327328
let Some(target) = target.target_checkpoint_mut() else {
328-
return Err(PowerSyncError::argument_error(
329+
return Err(PowerSyncError::sync_protocol_error(
329330
"Received checkpoint complete without previous checkpoint",
331+
PowerSyncErrorCause::Unknown,
330332
));
331333
};
332334
let result =

dart/test/error_test.dart

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,47 @@ void main() {
2828
]),
2929
throwsA(isSqliteException(
3030
1,
31-
'powersync_replace_schema: internal SQLite call returned ERROR',
31+
'powersync_replace_schema: internal SQLite call returned ERROR: malformed JSON',
3232
)),
3333
);
3434
});
35+
36+
test('missing client id', () {
37+
db
38+
..execute('SELECT powersync_init()')
39+
..execute('DELETE FROM ps_kv;');
40+
41+
expect(
42+
() => db.execute('SELECT powersync_client_id()'),
43+
throwsA(isSqliteException(
44+
4,
45+
'powersync_client_id: No client_id found in ps_kv',
46+
)),
47+
);
48+
});
49+
50+
group('sync protocol', () {
51+
setUp(() => db.execute('SELECT powersync_init()'));
52+
53+
test('invalid json', () {
54+
const stmt = 'SELECT powersync_control(?,?)';
55+
db.execute('BEGIN');
56+
final control = db.prepare(stmt);
57+
58+
control.execute(['start', null]);
59+
expect(
60+
() => control.execute(['line_text', 'invalid sync line']),
61+
throwsA(isSqliteException(
62+
4,
63+
'powersync_control: Sync protocol error: invalid text line. cause: expected value at line 1 column 1',
64+
)),
65+
);
66+
});
67+
});
3568
});
3669
}
3770

38-
Matcher isSqliteException(int code, String message) {
71+
Matcher isSqliteException(int code, dynamic message) {
3972
return isA<SqliteException>()
4073
.having((e) => e.extendedResultCode, 'extendedResultCode', code)
4174
.having((e) => e.message, 'message', message);

0 commit comments

Comments
 (0)