diff --git a/bin/libsqlite3_turso.dart b/bin/libsqlite3_turso.dart
new file mode 100644
index 0000000..57ec111
--- /dev/null
+++ b/bin/libsqlite3_turso.dart
@@ -0,0 +1,91 @@
+import 'dart:io';
+
+import '../lib/database.dart';
+import 'package:path/path.dart' as path;
+import 'package:drift/drift.dart';
+
+// ignore: public_member_api_docs
+void copyBinaryIfNecessary() {
+ const libraryName = 'libsqlite3.so';
+ final systemBinary = File('/lib/$libraryName')..createSync(recursive: true);
+
+ final customBinary = () {
+ file({required bool debug}) => File(path.join(Directory.current.path,
+ 'target', debug ? 'debug' : 'release', libraryName));
+
+ if (file(debug: false).existsSync()) {
+ return file(debug: false);
+ } else if (file(debug: true).existsSync()) {
+ return file(debug: true);
+ } else {
+ throw Exception('No custom SQLite binary found in target directory.');
+ }
+ }();
+
+ customBinary.copySync(systemBinary.path);
+}
+
+void main() async {
+ copyBinaryIfNecessary();
+
+ final database = AppDatabase();
+
+ await database.transaction(() async {
+ // Create the table if it doesn't exist
+ final result = await database.into(database.todoItems).insert(
+ TodoItemsCompanion.insert(
+ title: 'todo: setup drift',
+ content: 'We need to set up drift for our SQLite database.',
+ ),
+ );
+
+ await (database
+ .update(database.todoItems)
+ ..where((tbl) => tbl.id.equals(result)))
+ .write(TodoItemsCompanion(content: const Value('Updated content')));
+
+
+ print('Inserted item with ID: $result');
+ });
+
+ // final allItems = await database.select(database.todoItems).get();
+ // for (final item in allItems) {
+ // print('Item: ${item.title}, Content: ${item.content}');
+ // }
+
+ // final server = await HttpServer.bind(InternetAddress.anyIPv4, 8081);
+
+ // var index = 0;
+
+ // server.listen((request) async {
+ // final isEven = index % 2 == 0;
+
+ // final stopwatch = Stopwatch()..start();
+
+ // final result = await Future.wait([
+ // db.getAll('SELECT * FROM notes WHERE is_deleted = 0'),
+ // db.getAll(
+ // 'SELECT * FROM notes WHERE id = ?',
+ // ['8703e588-c847-4cb6-b250-726db8afb49a'],
+ // ),
+ // ]);
+ // stopwatch.stop();
+
+ // print('Query took ${stopwatch.elapsedMilliseconds} ms');
+
+ // request.response
+ // ..statusCode = HttpStatus.ok
+ // ..headers.contentType = ContentType.json
+ // ..write(isEven ? result[0] : result[1])
+ // ..close();
+
+ // index++;
+ // });
+
+ // print('Server running on http://${server.address.address}:${server.port}');
+ // ProcessSignal.sigterm.watch().listen((_) async {
+ // await server.close();
+ // await db.close();
+ // print('Server stopped.');
+ // });
+}
diff --git a/bin/proxy_server.dart b/bin/proxy_server.dart
deleted file mode 100644
index 31039a9..0000000
--- a/bin/proxy_server.dart
+++ /dev/null
@@ -1,44 +0,0 @@
-import 'dart:convert';
-import 'dart:io';
-
-void main() async {
- final server = await HttpServer.bind(InternetAddress.anyIPv4, 8080);
-
- server.listen((request) async {
- if (request.uri.path == '/db/auth') {
- final response = {
- 'db_url': 'staging-db-lhr-08c0519209-simple-tail-globe.turso.io',
- 'db_token':
- 'eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJhIjoicnciLCJleHAiOjE3NTQ2NzIwMDAsImlhdCI6MTc1NDU4NTYwMCwiaWQiOiJiMTZkZDkxMS05NmE4LTQzYTMtYTg3OC01ZGMzZjQ5MjVlZTkifQ.GrjdkI7SSLG3yTjpqFVzDGOdxs0PNlsvh3sVmkiQ-k0Rkvhv1h_-56tNmHLk_TYruW6vySmpr8UMhbKDN9tdBw',
- };
-
- request.response
- ..statusCode = HttpStatus.ok
- ..headers.contentType = ContentType.json
- ..write(json.encode(response))
- ..close();
- return;
- }
-
- // Handle the request
- if (request.method == 'GET') {
- request.response
- ..write('Hello from the proxy server!')
- ..close();
- } else {
- request.response
- ..statusCode = HttpStatus.methodNotAllowed
- ..write('Method not allowed')
- ..close();
- }
- });
-
- print(
- 'Proxy server running on http://${server.address.address}:${server.port}');
-
- // Handle server shutdown gracefully
- ProcessSignal.sigterm.watch().listen((_) async {
- await server.close();
- print('Proxy server stopped.');
- });
-}
diff --git a/bin/sqlite_test.dart b/bin/sqlite_test.dart
deleted file mode 100644
index e6fbcc4..0000000
--- a/bin/sqlite_test.dart
+++ /dev/null
@@ -1,50 +0,0 @@
-import 'dart:io';
-
-import 'package:sqlite_async/sqlite_async.dart';
-import 'package:path/path.dart' as path;
-
-final migrations = SqliteMigrations()
- ..add(SqliteMigration(1, (tx) async {
- await tx.execute(
- 'CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)',
- );
- }));
-
-// ignore: public_member_api_docs
-void copyBinaryIfNecessary() {
- const libraryName = 'libsqlite3.so';
- final systemBinary = File('/lib/$libraryName')..createSync(recursive: true);
-
- final customBinary =
- File(path.join(Directory.current.path, 'target', 'debug', libraryName));
- customBinary.copySync(systemBinary.path);
-}
-
-void main() async {
- copyBinaryIfNecessary();
- final db = SqliteDatabase(path: 'simple-nubian');
-
- await migrations.migrate(db);
-
- // // Use execute() or executeBatch() for INSERT/UPDATE/DELETE statements
- // await db.executeBatch('INSERT INTO users(name, email) values(?, ?)', [
- // ['Amen', 'oxy@gmail.com'],
- // ['Moron', 'moron@gmail.com']
- // ]);
-
- // var results = await db.getAll('SELECT * FROM users');
- // print('Results: $results');
-
- // await db.writeTransaction((tx) async {
- // await tx.execute(
- // 'INSERT INTO users(name, email) values(?, ?)',
- // ['Test3', 'test3@example.com'],
- // );
- // await tx.execute(
- // 'INSERT INTO users(name, email) values(?, ?)',
- // ['Test4', 'test4@example.com'],
- // );
- // });
-
- // await db.close();
-}
diff --git a/lib/database.dart b/lib/database.dart
new file mode 100644
index 0000000..a315bb0
--- /dev/null
+++ b/lib/database.dart
@@ -0,0 +1,24 @@
+import 'package:drift/drift.dart';
+import 'package:drift/native.dart';
+import 'package:sqlite3/sqlite3.dart';
+
+part 'database.g.dart';
+
+class TodoItems extends Table {
+ IntColumn get id => integer().autoIncrement()();
+ TextColumn get title => text().withLength(min: 6, max: 32)();
+ TextColumn get content => text().named('body')();
+ DateTimeColumn get createdAt => dateTime().nullable()();
+}
+
+@DriftDatabase(tables: [TodoItems])
+class AppDatabase extends _$AppDatabase {
+ AppDatabase() : super(_openConnection());
+
+ @override
+ int get schemaVersion => 1;
+
+ static QueryExecutor _openConnection() {
+ return NativeDatabase.opened(sqlite3.open('simple-nubian.db'));
+ }
+}
diff --git a/pubspec.lock b/pubspec.lock
index 24c3efe..8e4a723 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -41,6 +41,86 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.2"
+ build:
+ dependency: transitive
+ description:
+ name: build
+ sha256: "7174c5d84b0fed00a1f5e7543597b35d67560465ae3d909f0889b8b20419d5e3"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.0.1"
+ build_config:
+ dependency: transitive
+ description:
+ name: build_config
+ sha256: "4ae2de3e1e67ea270081eaee972e1bd8f027d459f249e0f1186730784c2e7e33"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.2"
+ build_daemon:
+ dependency: transitive
+ description:
+ name: build_daemon
+ sha256: "8e928697a82be082206edb0b9c99c5a4ad6bc31c9e9b8b2f291ae65cd4a25daa"
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.0.4"
+ build_resolvers:
+ dependency: transitive
+ description:
+ name: build_resolvers
+ sha256: "82730bf3d9043366ba8c02e4add05842a10739899520a6a22ddbd22d333bd5bb"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.0.1"
+ build_runner:
+ dependency: "direct dev"
+ description:
+ name: build_runner
+ sha256: "32c6b3d172f1f46b7c4df6bc4a47b8d88afb9e505dd4ace4af80b3c37e89832b"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.6.1"
+ build_runner_core:
+ dependency: transitive
+ description:
+ name: build_runner_core
+ sha256: "4b188774b369104ad96c0e4ca2471e5162f0566ce277771b179bed5eabf2d048"
+ url: "https://pub.dev"
+ source: hosted
+ version: "9.2.1"
+ built_collection:
+ dependency: transitive
+ description:
+ name: built_collection
+ sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100"
+ url: "https://pub.dev"
+ source: hosted
+ version: "5.1.1"
+ built_value:
+ dependency: transitive
+ description:
+ name: built_value
+ sha256: ba95c961bafcd8686d1cf63be864eb59447e795e124d98d6a27d91fcd13602fb
+ url: "https://pub.dev"
+ source: hosted
+ version: "8.11.1"
+ charcode:
+ dependency: transitive
+ description:
+ name: charcode
+ sha256: fb0f1107cac15a5ea6ef0a6ef71a807b9e4267c713bb93e00e92d737cc8dbd8a
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.4.0"
+ checked_yaml:
+ dependency: transitive
+ description:
+ name: checked_yaml
+ sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.3"
cli_config:
dependency: transitive
description:
@@ -49,6 +129,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.2.0"
+ cli_util:
+ dependency: transitive
+ description:
+ name: cli_util
+ sha256: ff6785f7e9e3c38ac98b2fb035701789de90154024a75b6cb926445e83197d1c
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.4.2"
+ code_builder:
+ dependency: transitive
+ description:
+ name: code_builder
+ sha256: "0ec10bf4a89e4c613960bf1e8b42c64127021740fb21640c29c909826a5eea3e"
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.10.1"
collection:
dependency: transitive
description:
@@ -81,6 +177,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.0.6"
+ dart_style:
+ dependency: transitive
+ description:
+ name: dart_style
+ sha256: "8a0e5fba27e8ee025d2ffb4ee820b4e6e2cf5e4246a6b1a477eb66866947e0bb"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.1.1"
+ drift:
+ dependency: "direct main"
+ description:
+ name: drift
+ sha256: "6aaea757f53bb035e8a3baedf3d1d53a79d6549a6c13d84f7546509da9372c7c"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.28.1"
+ drift_dev:
+ dependency: "direct dev"
+ description:
+ name: drift_dev
+ sha256: "2fc05ad458a7c562755bf0cae11178dfc58387a416829b78d4da5155a61465fd"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.28.1"
ffi:
dependency: transitive
description:
@@ -97,6 +217,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "7.0.1"
+ fixnum:
+ dependency: transitive
+ description:
+ name: fixnum
+ sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.1"
frontend_server_client:
dependency: transitive
description:
@@ -113,6 +241,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.3"
+ graphs:
+ dependency: transitive
+ description:
+ name: graphs
+ sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.3.2"
http_multi_server:
dependency: transitive
description:
@@ -145,6 +281,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.7.1"
+ json_annotation:
+ dependency: transitive
+ description:
+ name: json_annotation
+ sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1"
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.9.0"
lints:
dependency: "direct dev"
description:
@@ -173,10 +317,10 @@ packages:
dependency: transitive
description:
name: meta
- sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c
+ sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394"
url: "https://pub.dev"
source: hosted
- version: "1.16.0"
+ version: "1.17.0"
mime:
dependency: transitive
description:
@@ -185,14 +329,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.0"
- mutex:
- dependency: transitive
- description:
- name: mutex
- sha256: "8827da25de792088eb33e572115a5eb0d61d61a3c01acbc8bcbe76ed78f1a1f2"
- url: "https://pub.dev"
- source: hosted
- version: "3.1.0"
node_preamble:
dependency: transitive
description:
@@ -210,7 +346,7 @@ packages:
source: hosted
version: "2.2.0"
path:
- dependency: "direct main"
+ dependency: transitive
description:
name: path
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
@@ -233,6 +369,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.2.0"
+ pubspec_parse:
+ dependency: transitive
+ description:
+ name: pubspec_parse
+ sha256: "0560ba233314abbed0a48a2956f7f022cce7c3e1e73df540277da7544cad4082"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.5.0"
+ recase:
+ dependency: transitive
+ description:
+ name: recase
+ sha256: e4eb4ec2dcdee52dcf99cb4ceabaffc631d7424ee55e56f280bc039737f89213
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.1.0"
shelf:
dependency: transitive
description:
@@ -265,6 +417,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.1"
+ source_gen:
+ dependency: transitive
+ description:
+ name: source_gen
+ sha256: "7b19d6ba131c6eb98bfcbf8d56c1a7002eba438af2e7ae6f8398b2b0f4f381e3"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.1.0"
source_map_stack_trace:
dependency: transitive
description:
@@ -290,29 +450,21 @@ packages:
source: hosted
version: "1.10.1"
sqlite3:
- dependency: transitive
+ dependency: "direct main"
description:
name: sqlite3
sha256: f393d92c71bdcc118d6203d07c991b9be0f84b1a6f89dd4f7eed348131329924
url: "https://pub.dev"
source: hosted
version: "2.9.0"
- sqlite3_web:
+ sqlparser:
dependency: transitive
description:
- name: sqlite3_web
- sha256: "0f6ebcb4992d1892ac5c8b5ecd22a458ab9c5eb6428b11ae5ecb5d63545844da"
+ name: sqlparser
+ sha256: "7c859c803cf7e9a84d6db918bac824545045692bbe94a6386bd3a45132235d09"
url: "https://pub.dev"
source: hosted
- version: "0.3.2"
- sqlite_async:
- dependency: "direct main"
- description:
- name: sqlite_async
- sha256: "4da3b035bcce83d10beae879c6539e75230826bba95ed440565b6afbdd8b1550"
- url: "https://pub.dev"
- source: hosted
- version: "0.11.8"
+ version: "0.41.1"
stack_trace:
dependency: transitive
description:
@@ -329,6 +481,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.4"
+ stream_transform:
+ dependency: transitive
+ description:
+ name: stream_transform
+ sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.1"
string_scanner:
dependency: transitive
description:
@@ -369,6 +529,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.6.12"
+ timing:
+ dependency: transitive
+ description:
+ name: timing
+ sha256: "62ee18aca144e4a9f29d212f5a4c6a053be252b895ab14b5821996cff4ed90fe"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.2"
typed_data:
dependency: transitive
description:
@@ -434,4 +602,4 @@ packages:
source: hosted
version: "3.1.3"
sdks:
- dart: ">=3.5.0 <4.0.0"
+ dart: ">=3.7.0 <4.0.0"
diff --git a/pubspec.yaml b/pubspec.yaml
index c3dd30d..8f2e0fc 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -7,10 +7,11 @@ environment:
sdk: ^3.3.1
dependencies:
- path: ^1.9.1
- sqlite_async: ^0.11.8
-
+ drift: ^2.28.1
+ sqlite3: ^2.9.0
dev_dependencies:
+ build_runner: ^2.6.1
+ drift_dev: ^2.28.1
lints: ^3.0.0
test: ^1.25.8
diff --git a/src/lib.rs b/src/lib.rs
index 1b9204e..e6aaa23 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -89,6 +89,7 @@ pub unsafe extern "C" fn sqlite3_open_v2(
connection: connection.unwrap(),
transaction_baton: Mutex::new(None),
last_insert_rowid: Mutex::new(None),
+ rows_written: Mutex::new(None),
transaction_has_began: Mutex::new(false),
delete_hook: Mutex::new(None),
insert_hook: Mutex::new(None),
@@ -383,6 +384,22 @@ pub unsafe extern "C" fn sqlite3_extended_errcode(_: *mut SQLite3) -> c_int {
SQLITE_OK
}
+#[no_mangle]
+pub unsafe extern "C" fn sqlite3_changes(db: *mut SQLite3) -> c_int {
+ if !is_aligned(db) {
+ return SQLITE_OK;
+ }
+ let db = &mut *db;
+
+ if let Ok(rows_written) = db.rows_written.lock() {
+ if rows_written.is_some() {
+ return rows_written.unwrap() as c_int;
+ }
+ }
+
+ 0
+}
+
#[no_mangle]
pub unsafe extern "C" fn sqlite3_errmsg(_: *mut SQLite3) -> *const c_char {
if let Some(error_entry) = sqlite::get_latest_error() {
diff --git a/src/sqlite.rs b/src/sqlite.rs
index 3e1ed22..1cf1b8b 100644
--- a/src/sqlite.rs
+++ b/src/sqlite.rs
@@ -86,6 +86,7 @@ lazy_static! {
pub struct SQLite3 {
pub connection: transport::DatabaseConnection, // Connection to the database
pub last_insert_rowid: Mutex