Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
1 change: 0 additions & 1 deletion packages/powersync_core/lib/powersync_core.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ export 'src/database/powersync_database.dart';
export 'src/exceptions.dart';
export 'src/log.dart';
export 'src/open_factory.dart';
export 'src/powersync_database.dart';
export 'src/schema.dart';
export 'src/sync_status.dart';
export 'src/uuid.dart';
65 changes: 65 additions & 0 deletions packages/powersync_core/lib/src/database/core_version.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import 'package:sqlite_async/sqlite3_common.dart';

/// A parsed (major, minor, patch) version triple representing a version of the
/// loaded core extension.
extension type const PowerSyncCoreVersion((int, int, int) _tuple) {
int get major => _tuple.$1;
int get minor => _tuple.$2;
int get patch => _tuple.$3;

int compareTo(PowerSyncCoreVersion other) {
return switch (major.compareTo(other.major)) {
0 => switch (minor.compareTo(other.minor)) {
0 => patch.compareTo(other.patch),
var other => other,
},
var other => other,
};
}

bool operator <(PowerSyncCoreVersion other) => compareTo(other) < 0;
bool operator >=(PowerSyncCoreVersion other) => compareTo(other) >= 0;

String get versionString => '$major.$minor.$patch';

void checkSupported() {
const isWeb = bool.fromEnvironment('dart.library.js_interop');

if (this < minimum || this >= maximumExclusive) {
var message =
'Unsupported powersync extension version. This version of the '
'PowerSync SDK needs >=${minimum.versionString} '
'<${maximumExclusive.versionString}, '
'but detected version $versionString.';
if (isWeb) {
message +=
'\nTry downloading the updated assets: https://docs.powersync.com/client-sdk-references/flutter/flutter-web-support#assets';
}

throw SqliteException(1, message);
}
}

/// Parses the output of `powersync_rs_version()`, e.g. `0.3.9/5d64f366`, into
/// a [PowerSyncCoreVersion].
static PowerSyncCoreVersion parse(String version) {
try {
final [major, minor, patch] =
version.split(RegExp(r'[./]')).take(3).map(int.parse).toList();

return PowerSyncCoreVersion((major, minor, patch));
} catch (e) {
throw SqliteException(1,
'Unsupported powersync extension version. Need >=0.2.0 <1.0.0, got: $version. Details: $e');
}
}

/// The minimum version of the sqlite core extensions we support. We check
/// this version when opening databases to fail early and with an actionable
/// error message.
static const minimum = PowerSyncCoreVersion((0, 3, 11));

/// The first version of the core extensions that this version of the Dart
/// SDK doesn't support.
static const maximumExclusive = PowerSyncCoreVersion((1, 0, 0));
}
19 changes: 2 additions & 17 deletions packages/powersync_core/lib/src/database/powersync_db_mixin.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:powersync_core/sqlite_async.dart';
import 'package:powersync_core/src/abort_controller.dart';
import 'package:powersync_core/src/connector.dart';
import 'package:powersync_core/src/crud.dart';
import 'package:powersync_core/src/database/core_version.dart';
import 'package:powersync_core/src/powersync_update_notification.dart';
import 'package:powersync_core/src/schema.dart';
import 'package:powersync_core/src/schema_logic.dart';
Expand Down Expand Up @@ -93,23 +94,7 @@ mixin PowerSyncDatabaseMixin implements SqliteConnection {
1, 'The powersync extension is not loaded correctly. Details: $e');
}

// Parse version
List<int> versionInts;
try {
versionInts =
version.split(RegExp(r'[./]')).take(3).map(int.parse).toList();
} catch (e) {
throw SqliteException(1,
'Unsupported powersync extension version. Need >=0.2.0 <1.0.0, got: $version. Details: $e');
}

// Validate >=0.2.0 <1.0.0
if (versionInts[0] != 0 ||
(versionInts[1] < 2) ||
(versionInts[1] == 2 && versionInts[2] < 0)) {
throw SqliteException(1,
'Unsupported powersync extension version. Need >=0.2.0 <1.0.0, got: $version');
}
PowerSyncCoreVersion.parse(version).checkSupported();
}

/// Wait for initialization to complete.
Expand Down
1 change: 0 additions & 1 deletion packages/powersync_core/lib/src/powersync_database.dart

This file was deleted.

39 changes: 39 additions & 0 deletions packages/powersync_core/test/database/core_version_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import 'package:powersync_core/src/database/core_version.dart';
import 'package:sqlite3/sqlite3.dart';
import 'package:test/test.dart';

void main() {
group('PowerSyncCoreVersion', () {
test('parse', () {
expect(PowerSyncCoreVersion.parse('0.3.9/5d64f366'), (0, 3, 9));
});

test('compare', () {
void expectLess(String a, String b) {
final parsedA = PowerSyncCoreVersion.parse(a);
final parsedB = PowerSyncCoreVersion.parse(b);

expect(parsedA.compareTo(parsedB), -1);
expect(parsedB.compareTo(parsedA), 1);

expect(parsedA.compareTo(parsedA), 0);
expect(parsedB.compareTo(parsedB), 0);
}

expectLess('0.1.0', '1.0.0');
expectLess('1.0.0', '1.2.0');
expectLess('0.3.9', '0.3.11');
});

test('checkSupported', () {
expect(PowerSyncCoreVersion.parse('0.3.10').checkSupported,
throwsA(isA<SqliteException>()));
expect(PowerSyncCoreVersion.parse('1.0.0').checkSupported,
throwsA(isA<SqliteException>()));

PowerSyncCoreVersion.minimum.checkSupported();
expect(PowerSyncCoreVersion.maximumExclusive.checkSupported,
throwsA(isA<SqliteException>()));
});
});
}
Loading