Skip to content

Commit

Permalink
Merge pull request #1037 from tekartik/dart3a
Browse files Browse the repository at this point in the history
Dart3a
  • Loading branch information
alextekartik authored Aug 10, 2023
2 parents e3dd1db + 4e023f6 commit 0cda463
Show file tree
Hide file tree
Showing 22 changed files with 213 additions and 103 deletions.
3 changes: 3 additions & 0 deletions packages/console_test_app/bin/sqflite_ffi_simple_bin.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import 'package:sqflite_common_ffi/sqflite_ffi.dart';
Future<void> main(List<String> arguments) async {
sqfliteFfiInit();
var db = await databaseFactoryFfi.openDatabase(inMemoryDatabasePath);
var sqliteVersion =
(await db.rawQuery('select sqlite_version()')).first.values.first;
print('sqlite version: $sqliteVersion');
await db.setVersion(1);
await db.close();
}
3 changes: 0 additions & 3 deletions packages/console_test_app/lib/console_test_app.dart

This file was deleted.

1 change: 1 addition & 0 deletions packages_web/sqflite_common_ffi_web_test/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ build/
/web/sqlite3.wasm
/test/sqflite_sw.js
/test/sqlite3.wasm
/test/sqflite_sw_v1.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import 'package:sqflite_common_test/all_test.dart' as all;
import 'package:sqflite_common_test/sqflite_test.dart';
import 'package:test/test.dart';

var _factory = databaseFactoryFfiWeb;
var _factory = createDatabaseFactoryFfiWeb(
options:
SqfliteFfiWebOptions(sharedWorkerUri: Uri.parse('sqflite_sw_v1.js')));

class SqfliteFfiWebTestContext extends SqfliteLocalTestContext {
SqfliteFfiWebTestContext() : super(databaseFactory: _factory);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import 'package:sqflite_common_ffi_web/src/setup/setup.dart';

Future<void> main() async {
await setupBinaries(options: SetupOptions(verbose: true, dir: 'test'));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import 'package:sqflite_common_ffi_web/src/setup/setup.dart';

Future<void> main() async {
await setupBinaries(
options: SetupOptions(verbose: true, dir: 'test', force: true));
}
4 changes: 2 additions & 2 deletions sqflite/doc/opening_asset_db.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ if (!exists) {
} catch (_) {}
// Copy from asset
ByteData data = await rootBundle.load(join("assets", "example.db"));
ByteData data = await rootBundle.load(url.join("assets", "example.db"));
List<int> bytes =
data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
Expand Down Expand Up @@ -87,7 +87,7 @@ try {
} catch (_) {}
// Copy from asset
ByteData data = await rootBundle.load(join("assets", "example.db"));
ByteData data = await rootBundle.load(url.join("assets", "example.db"));
List<int> bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
await new File(path).writeAsBytes(bytes, flush: true);
Expand Down
4 changes: 2 additions & 2 deletions sqflite/example/lib/exp_test_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -345,10 +345,10 @@ class ExpTestPage extends TestPage {
await deleteDatabase(path);

// Copy from asset
final data = await rootBundle.load(join('assets', 'issue_64.db'));
final data = await rootBundle.load(url.join('assets', 'issue_64.db'));
final bytes =
data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
await writeFileAsBytes(path, bytes);
await databaseFactory.writeDatabaseBytes(path, bytes);

// open the database
final db = await openDatabase(path);
Expand Down
11 changes: 5 additions & 6 deletions sqflite/example/lib/open_test_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -345,12 +345,11 @@ class OpenTestPage extends TestPage {
await createDirectory(path);
} catch (_) {}

// Copy from asset
final data = await rootBundle.load(join('assets', 'example.db'));
final List<int> bytes =
// Copy from asset to a database file.
final data = await rootBundle.load(url.join('assets', 'example.db'));
final bytes =
data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
// Write and flush the bytes written
await writeFileAsBytes(path, bytes, flush: true);
await databaseFactory.writeDatabaseBytes(path, bytes);

// open the database
final db = await openDatabase(path);
Expand Down Expand Up @@ -643,7 +642,7 @@ class OpenTestPage extends TestPage {
print('Creating new copy from asset');

// Copy from asset
final data = await rootBundle.load(join('assets', 'example.db'));
final data = await rootBundle.load(url.join('assets', 'example.db'));
final bytes =
data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
await writeFileAsBytes(path, bytes);
Expand Down
3 changes: 2 additions & 1 deletion sqflite_common_ffi/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## 2.3.0
## 2.3.0+2

* Dart 3 only.
* Bundle Windows sqlite3.dll 3.42.0

## 2.2.5

Expand Down
10 changes: 10 additions & 0 deletions sqflite_common_ffi/doc/updating_sqlite_dll.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Updating SQLite DLL

This projects ships with a precompiled version of the SQLite DLL for Windows that allows running dart and flutter app
without additional setup. This version might not be the latest available at https://www.sqlite.org/download.html.

You should grab and copy a fresh version of sqlite3.dll for your released app to bundle with your app.

## Upgrading SQLite dll

`sqlite3_info.dart` can be modified to download a new version of the SQLite DLL by running `tool/windows_setup.dart`.
3 changes: 3 additions & 0 deletions sqflite_common_ffi/lib/src/windows/setup.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import 'package:sqflite_common_ffi/src/windows/setup_impl.dart';
import 'package:sqlite3/open.dart';
import 'package:sqlite3/sqlite3.dart';

/// Local info file name.
const sqflite3InfoJsonFileName = 'sqflite3_info.json';

/// Get the dll path from our package path.
String packageGetSqlite3DllPath(String packagePath) {
var path = join(packagePath, 'src', 'windows', 'sqlite3.dll');
Expand Down
Binary file modified sqflite_common_ffi/lib/src/windows/sqlite3.dll
Binary file not shown.
48 changes: 48 additions & 0 deletions sqflite_common_ffi/lib/src/windows/sqlite3_info.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/// Information about the bundled sqlite3.dll
/// https://www.sqlite.org/download.html
class Sqlite3DllInfo {
/// Version string.
final String version;

/// Src zip.
final String srcZip;

/// Sha3.
final String sha3;

/// Sqflite3DllInfo.
Sqlite3DllInfo(this.version, this.srcZip, this.sha3);

/// Sqflite3DllInfo from map.
factory Sqlite3DllInfo.fromMap(Map map) => Sqlite3DllInfo(
map['version']!.toString(),
map['srcZip']!.toString(),
map['sha3']!.toString());

/// To map.
Map<String, Object?> toMap() => <String, Object?>{
'version': version,
'srcZip': srcZip,
'sha3': sha3,
};
@override
String toString() => '$version $srcZip $sha3';
}

/// 3.38.2 info
var sqlite3_38_2Info = Sqlite3DllInfo(
'3.38.2',
'https://www.sqlite.org/2022/sqlite-dll-win64-x64-3380200.zip',
'9f71eec9a2c7f12602eaa2af76bd7c052e540502ae7a89dac540e10962e2fa35');

// sqlite-dll-win64-x64-3420000.zip
// (1.16 MiB) 64-bit DLL (x64) for SQLite version 3.42.0.
// (SHA3-256: 2425efa95556793a20761dfdab0d3b56a52e61716e8bb65e6a0a3590d41c97c0)
/// 3.42.0 info
var sqlite3_42_0Info = Sqlite3DllInfo(
'3.42.0',
'https://www.sqlite.org/2023/sqlite-dll-win64-x64-3420000.zip',
'2425efa95556793a20761dfdab0d3b56a52e61716e8bb65e6a0a3590d41c97c0');

/// Current info
var sqlite3Info = sqlite3_42_0Info;
1 change: 1 addition & 0 deletions sqflite_common_ffi/lib/src/windows/sqlite3_info.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"version":"3.42.0","srcZip":"https://www.sqlite.org/2023/sqlite-dll-win64-x64-3420000.zip","sha3":"2425efa95556793a20761dfdab0d3b56a52e61716e8bb65e6a0a3590d41c97c0"}
3 changes: 0 additions & 3 deletions sqflite_common_ffi/lib/src/windows/sqlite3_version.md

This file was deleted.

2 changes: 1 addition & 1 deletion sqflite_common_ffi/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: sqflite_common_ffi
homepage: https://github.com/tekartik/sqflite/tree/master/sqflite_common_ffi
description: sqflite ffi based implementation, for desktop and units tests.
version: 2.3.0
version: 2.3.0+2
funding:
- https://github.com/sponsors/alextekartik

Expand Down
32 changes: 8 additions & 24 deletions sqflite_common_ffi/test/sqflite_ffi_windows_setup_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,13 @@
import 'dart:io';

import 'package:archive/archive_io.dart';
import 'package:http/http.dart';
import 'package:path/path.dart';
import 'package:process_run/shell.dart';
import 'package:sqflite_common_ffi/src/windows/setup.dart';
import 'package:sqflite_common_ffi/src/windows/sqlite3_info.dart';
import 'package:test/test.dart';

var windowsSqliteVersion = '3.38.2';
var windowsZipSrc =
'https://www.sqlite.org/2022/sqlite-dll-win64-x64-3380200.zip';
var windowsZipSha3 =
'9f71eec9a2c7f12602eaa2af76bd7c052e540502ae7a89dac540e10962e2fa35';
import '../tool/windows_setup.dart';

Future<String> computeSha3(String file, {String openssl = 'openssl'}) async {
var line = (await run(
Expand Down Expand Up @@ -45,21 +41,9 @@ Future<String?> windowsFindOpenssl() async {
}

void main() {
var localZip = join('.local', basename(windowsZipSrc));
Future<bool> getZip() async {
if (!File(localZip).existsSync()) {
await Directory(dirname(localZip)).create(recursive: true);
try {
await File(localZip)
.writeAsBytes(await readBytes(Uri.parse(windowsZipSrc)));
} catch (e) {
stderr.writeln(
'Fail to fetch sqlite.zip version $windowsSqliteVersion at $windowsZipSrc');
return false;
}
}
return true;
}
var helper = Sqlite3DllSetupHelper(sqlite3Info);
var srcZip = sqlite3Info.srcZip;
var localZip = join('.local', basename(srcZip));

group('sqlite3.dll', () {
test('sha3', () async {
Expand All @@ -69,16 +53,16 @@ void main() {
openssl = await windowsFindOpenssl();
}
if (openssl != null) {
if (await getZip()) {
if (await helper.getZip()) {
var computed = await computeSha3(localZip, openssl: openssl);
expect(computed, windowsZipSha3);
expect(computed, sqlite3Info.sha3);
}
}
});

test('checkDll', () async {
var dllPath = findWindowsDllPath()!;
if (await getZip()) {
if (await helper.getZip()) {
final inputStream = InputFileStream(localZip);
final archive = ZipDecoder().decodeBuffer(inputStream);
extractArchiveToDisk(archive, dirname(localZip));
Expand Down
5 changes: 2 additions & 3 deletions sqflite_common_ffi/test/sqflite_ffi_windows_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@
import 'dart:io';

import 'package:sqflite_common_ffi/sqflite_ffi.dart';
import 'package:sqflite_common_ffi/src/windows/sqlite3_info.dart';
import 'package:test/test.dart';

import 'sqflite_ffi_windows_setup_test.dart';

void main() {
if (Platform.isWindows) {
sqfliteFfiInit();
Expand All @@ -15,7 +14,7 @@ void main() {
final results = await db.rawQuery('select sqlite_version()');

var version = results.first.values.first;
expect(version, windowsSqliteVersion);
expect(version, sqlite3Info.version);
});
});
}
Expand Down
97 changes: 97 additions & 0 deletions sqflite_common_ffi/tool/windows_setup.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import 'dart:convert';
import 'dart:io';
import 'package:archive/archive_io.dart';
import 'package:http/http.dart';
import 'package:path/path.dart';
import 'package:sqflite_common_ffi/src/windows/setup.dart';
import 'package:sqflite_common_ffi/src/windows/setup_impl.dart';
import 'package:sqflite_common_ffi/src/windows/sqlite3_info.dart';

class Sqlite3DllSetupHelper {
final Sqlite3DllInfo sqlite3Info;
// This tests does actually the actual install of the dll

late var srcZip = sqlite3Info.srcZip;
late var localZip = join('.local', basename(srcZip));
late var localExtractedZipDir =
join('.local', basenameWithoutExtension(srcZip));
late var localExtractedJsonInfoFile =
join(localExtractedZipDir, sqflite3InfoJsonFileName);
var bundledDir = join('lib', dirname(packageGetSqlite3DllPath('.')));
late var bundledJsonInfoFilePath = join(bundledDir, 'sqlite3_info.json');
late var bundledSqlite3DllFilePath = join(bundledDir, 'sqlite3.dll');
late var localInfoZip = join('.local', basename(srcZip));

Sqlite3DllSetupHelper(this.sqlite3Info);

/// For tools and test only. not exported.
/// Returns null on failure, don't care about the failure...
Future<Sqlite3DllInfo?> readBundleInfo() async {
try {
var map = pathGetJson(bundledJsonInfoFilePath);
var sqlite3Info = Sqlite3DllInfo.fromMap(map);
print('sqlite3Info $sqlite3Info');
} catch (_) {}
return null;
}

Future<bool> getZip() async {
if (!File(localZip).existsSync()) {
print('Downloading sqlite3 $sqlite3Info');
await Directory(dirname(localZip)).create(recursive: true);
try {
await File(localZip).writeAsBytes(await readBytes(Uri.parse(srcZip)));
} catch (e) {
stderr.writeln(
'Fail to fetch sqlite.zip version $sqlite3_38_2Info at $srcZip');
return false;
}
}
return true;
}

Future<void> extractZip() async {
var jsonInfo = File(localExtractedJsonInfoFile);
if (!jsonInfo.existsSync()) {
// Extract the zip
print('Extracting $localZip to $localExtractedZipDir');
final inputStream = InputFileStream(localZip);
final archive = ZipDecoder().decodeBuffer(inputStream);
extractArchiveToDisk(archive, localExtractedZipDir);
await jsonInfo.writeAsString(jsonEncode(sqlite3Info.toMap()));
}
}

Future<void> copyToBundle() async {
var srcFile = join(localExtractedZipDir, 'sqlite3.dll');
var dstFile = bundledSqlite3DllFilePath;
print('Copying $srcZip to $dstFile');
//await File(dstFile).delete(recursive: true);
await File(srcFile).copy(dstFile);
await File(bundledJsonInfoFilePath)
.writeAsString(jsonEncode(sqlite3Info.toMap()));
//await File()
}
}

/// This tool is actually ran on linux to download install the updated dll
Future main() async {
await setupSqliteDll();
}

Future setupSqliteDll() async {
// Tested only on linux for now.
if (Platform.isLinux) {
var helper = Sqlite3DllSetupHelper(sqlite3Info);
var info = await helper.readBundleInfo();
if (info?.version != sqlite3Info.version) {
await helper.getZip();
await helper.extractZip();
await helper.copyToBundle();
} else {
print('sqlite3 $sqlite3Info already up to date');
}
} else {
stderr.writeln('To run on linux!');
}
}
Loading

0 comments on commit 0cda463

Please sign in to comment.