From c12d4e13e944bc414ec9edc8f355dd76d24f31e5 Mon Sep 17 00:00:00 2001 From: Simon Binder Date: Wed, 8 Oct 2025 22:26:46 +0200 Subject: [PATCH] Port tabs and anotations --- docs/web/compatibility.dart | 40 ------------------- drift_website/build.yaml | 1 + drift_website/content/dart_api/tables.md | 12 ++---- drift_website/content/migrations/index.md | 6 +-- drift_website/content/migrations/tests.md | 23 ++++++----- drift_website/content/platforms/web.md | 40 ++++++++++--------- drift_website/content/testing.md | 37 +++++------------ drift_website/lib/_style.scss | 1 + .../lib/src/components/web_compatibility.dart | 8 ++-- drift_website/lib/src/generated_snippets.dart | 1 + .../lib/src/snippets/setup/testing.dart | 22 ++++++++++ drift_website/lib/src/styles/_ui.scss | 4 ++ 12 files changed, 84 insertions(+), 111 deletions(-) delete mode 100644 docs/web/compatibility.dart create mode 100644 drift_website/lib/src/snippets/setup/testing.dart create mode 100644 drift_website/lib/src/styles/_ui.scss diff --git a/docs/web/compatibility.dart b/docs/web/compatibility.dart deleted file mode 100644 index 5b774ec6e..000000000 --- a/docs/web/compatibility.dart +++ /dev/null @@ -1,40 +0,0 @@ -import 'dart:js_interop'; -import 'dart:js_interop_unsafe'; - -import 'package:drift/wasm.dart'; -import 'package:web/web.dart'; - -void main() async { - window.setProperty( - 'start_compat_check'.toJS, - () { - Future(() async { - final btn = document.querySelector('#drift-compat-btn')!; - final results = - document.querySelector('#drift-compat-results') as HTMLElement; - - btn.attributes['disabled'] = 'true'.toJS; - results.innerText = ''; - - try { - final db = await WasmDatabase.open( - databaseName: 'test_db', - // These URLs need to be absolute because we're serving this JS file - // under `/web`. - sqlite3Uri: Uri.parse('/sqlite3.wasm'), - driftWorkerUri: Uri.parse('/drift_worker.dart.js'), - ); - - results.innerText += ''' -Chosen implementation: ${db.chosenImplementation} -Features missing: ${db.missingFeatures} -'''; - await db.resolvedExecutor.close(); - } catch (e, s) { - results.innerText += 'Error: $e, Trace: \n$s'; - } finally { - btn.attributes['disabled'] = 'false'.toJS; - } - }); - }.toJS); -} diff --git a/drift_website/build.yaml b/drift_website/build.yaml index df578f4f3..949b31aa3 100644 --- a/drift_website/build.yaml +++ b/drift_website/build.yaml @@ -76,6 +76,7 @@ targets: - "web/drift_worker.dart" builders: build_web_compilers:entrypoint: + enabled: true options: compiler: dart2js build_web_compilers:dart2js_archive_extractor: diff --git a/drift_website/content/dart_api/tables.md b/drift_website/content/dart_api/tables.md index 8e6208966..49d8703b1 100644 --- a/drift_website/content/dart_api/tables.md +++ b/drift_website/content/dart_api/tables.md @@ -41,17 +41,15 @@ The SQL equivalent of this table would be: CREATE TABLE todo_items ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, title TEXT, - created_at INTEGER -- (1)! + created_at INTEGER -- Drift stores `dateTime()` columns as unix timestamps by default ); ``` -{.annotate } - -1. By default, `dateTime()` columns are stored as Unix timestamps. To store them as ISO-8601 strings, see [DateTime options](#datetime-options). Some technical notes: - The name of the table, `todo_items` is automatically derived from the class name. This can be customized by overriding the `tableName` getter. See [Table Names](#changing-sql-names) for more information. - The `id` column is automatically set as the primary key because it is an auto-incrementing integer. See [Primary Keys](#primary-keys) for more information. +- By default, `dateTime()` columns are stored as Unix timestamps. To store them as ISO-8601 strings, see [DateTime options](#datetime-options). ## Add to database @@ -180,10 +178,8 @@ for inserts, as the database will use the default as a fallback. Similarly to `withDefault()`, this sets a default value for columns. Unlike `withDefault()` however, this value is computed in Dart instead of in the database (1). -This means that adding, removing, or changing the default value does not require a database migration: -{ .annotate } - -1. Because this default value is only applied in your Dart code, it is not applied when interacting with the database outside of Drift. +This means that adding, removing, or changing the default value does not require a database migration, +However, because this default value is only applied in your Dart code, it is not applied when interacting with the database outside of Drift. diff --git a/drift_website/content/migrations/index.md b/drift_website/content/migrations/index.md index 41b1ba435..cc1203357 100644 --- a/drift_website/content/migrations/index.md +++ b/drift_website/content/migrations/index.md @@ -31,10 +31,8 @@ targets: another_db: lib/database2.dart ``` -You can also optionally specify the directory where the test files and schema (1) files are stored. -{ .annotate } - -1. Drift will generate multiple schema files, one for each version of your database schema. These files are used to compare the current schema with the previous schema and generate the migration code. +You can also optionally specify the directory where the test files and schema files are stored. +Drift will generate multiple schema files, one for each version of your database schema. These files are used to compare the current schema with the previous schema and generate the migration code. ```yaml title="build.yaml" targets: diff --git a/drift_website/content/migrations/tests.md b/drift_website/content/migrations/tests.md index 70d9e5ef3..ffafac458 100644 --- a/drift_website/content/migrations/tests.md +++ b/drift_website/content/migrations/tests.md @@ -95,22 +95,27 @@ This can then be used to manually create and verify data at a specific version: Instead (or in addition to) [writing tests](#verifying-a-database-schema-at-runtime) to ensure your migrations work as they should, `drift_dev` provides an API to verify the current schema at runtime without any additional setup on native platforms. + -=== "Native" + - {{ load_snippet('native','lib/snippets/migrations/runtime_verification.dart.excerpt.json', indent=4) }} + + -=== "Web (since drift 2.22)" + - Starting from drift version 2.22, this functionality is also available on the web. Since the method internally - opens another database to create the expected schema, the web variant needs to be configured explicitly: +Starting from drift version 2.22, this functionality is also available on the web. Since the method internally +opens another database to create the expected schema, the web variant needs to be configured explicitly: - {{ load_snippet('web','lib/snippets/migrations/runtime_verification_web.dart.excerpt.json', indent=4) }} + - It's also possible to re-use code between your native and web checks with conditional imports. - You can check the [example app](https://github.com/simolus3/drift/tree/develop/examples/app/lib/database/connection) for - inspiration. +It's also possible to re-use code between your native and web checks with conditional imports. +You can check the [example app](https://github.com/simolus3/drift/tree/develop/examples/app/lib/database/connection) for +inspiration. + + + When you use `validateDatabaseSchema`, drift will transparently: diff --git a/drift_website/content/platforms/web.md b/drift_website/content/platforms/web.md index 096b819c6..c03806d97 100644 --- a/drift_website/content/platforms/web.md +++ b/drift_website/content/platforms/web.md @@ -1,13 +1,9 @@ --- - title: Web description: Drift support in Flutter and Dart web apps. - --- - - -!!! success "" +!!! success "Stable web support" __Good news__: With drift 2.9.0, web support is stable and officially supported! The `WasmDatabase.open` API is the preferred way to run drift on the web. While older @@ -104,8 +100,6 @@ web/ correct `Content-Type` header for wasm files. - - #### Additional headers On browsers that support it, drift uses the origin-private part of the [FileSystem Access API](https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API) to store databases efficiently. @@ -146,25 +140,33 @@ Also, note that the `sqlite3.wasm` file needs to be served with a `Content-Type` From a perspective of the Dart code used, drift on the web is similar to drift on other platforms. You can follow the [getting started guide](../setup.md) as a general setup guide. -=== "Flutter (sqlite3)" + - If you're using `package:drift_flutter` to setup your database, you enable web support by passing - `DriftWebOptions` with URIs to the WebAssembly module and the drift worker: + - {{ load_snippet('flutter','lib/snippets/platforms/web.dart.excerpt.json',indent=4) }} +If you're using `package:drift_flutter` to setup your database, you enable web support by passing +`DriftWebOptions` with URIs to the WebAssembly module and the drift worker: - If you need more control on how you're opening web databases (e.g. to prefer certain storage - APIs, see the manual setup for Dart in the next tab). + -=== "Dart (sqlite3)" +If you need more control on how you're opening web databases (e.g. to prefer certain storage +APIs, see the manual setup for Dart in the next tab). - Instead of using a `NativeDatabase` in your database classes, you can use the `WasmDatabase` optimized - for the web: + - {{ load_snippet('connect','lib/snippets/platforms/web.dart.excerpt.json',indent=4) }} + + +Instead of using a `NativeDatabase` in your database classes, you can use the `WasmDatabase` optimized +for the web: + + + +When you call `WasmDatabase.open`, drift will automatically find a suitable persistence implementation +supported by the current browser. + + + - When you call `WasmDatabase.open`, drift will automatically find a suitable persistence implementation - supported by the current browser. A full example that works on the web (and all other platforms supported by drift) is available [here](https://github.com/simolus3/drift/tree/develop/examples/app). diff --git a/drift_website/content/testing.md b/drift_website/content/testing.md index 0cc3738f4..0e67500fa 100644 --- a/drift_website/content/testing.md +++ b/drift_website/content/testing.md @@ -83,35 +83,16 @@ We can create an in-memory version of the database by using a place to open the database is the `setUp` and `tearDown` methods from `package:test`: -```dart -import 'package:drift/drift.dart'; -import 'package:drift/native.dart'; -import 'package:test/test.dart'; -// the file defined above, you can test any drift database of course -import 'database.dart'; + -void main() { - late MyDatabase database; +!!! note "Closing streams synchronously" - setUp(() { - database = MyDatabase(DatabaseConnection( - NativeDatabase.memory(), - closeStreamsSynchronously: true, // (1)! - )); - }); - tearDown(() async { - await database.close(); - }); -} -``` -{.annotate } - -1. By default, unsubscribing from a query stream created by drift will keep the stream open for one event - loop iteration. This is useful for e.g. Flutter apps, where rebuilds may cause a `StreamBuilder` to - re-subscribe to streams frequently. - In Flutter widget tests however, it's illegal to keep these timers open after a test concludes. - To avoid issues with Drift in that setups, pass a `DatabaseConnection` with `closeStreamsSynchronously: true` - to your database. + By default, unsubscribing from a query stream created by drift will keep the stream open for one event + loop iteration. This is useful for e.g. Flutter apps, where rebuilds may cause a `StreamBuilder` to + re-subscribe to streams frequently. + In Flutter widget tests however, it's illegal to keep these timers open after a test concludes. + To avoid issues with Drift in that setups, pass a `DatabaseConnection` with `closeStreamsSynchronously: true` + to your database. With that setup in place, we can finally write some tests: ```dart @@ -138,4 +119,4 @@ test('stream emits a new user when the name updates', () async { ## Testing migrations Drift can help you generate code for schema migrations. For more details, see -[this guide](Migrations/tests.md). +[this guide](migrations/tests.md). diff --git a/drift_website/lib/_style.scss b/drift_website/lib/_style.scss index 08ad21768..db6e8e249 100644 --- a/drift_website/lib/_style.scss +++ b/drift_website/lib/_style.scss @@ -5,6 +5,7 @@ @use "src/styles/details"; @use "src/styles/header"; @use "src/styles/sidebar"; +@use "src/styles/ui"; @use "src/styles/constants" as c; @use "src/jaspr"; diff --git a/drift_website/lib/src/components/web_compatibility.dart b/drift_website/lib/src/components/web_compatibility.dart index 483cbcdd7..f9c965cc7 100644 --- a/drift_website/lib/src/components/web_compatibility.dart +++ b/drift_website/lib/src/components/web_compatibility.dart @@ -25,10 +25,12 @@ final class _WebCompatibilityCheckState extends State { builder: (context, snapshot) { return div([ if (_compatibilityResult == null) ...[ - button([text('Check compatibility')]), + button(classes: 'compat', [ + text('Check compatibility'), + ], onClick: startCheck), pre([text('Compatibility check not started yet.')]), - ] else if (snapshot.connectionState == ConnectionState.active) - progress([]) + ] else if (snapshot.connectionState == ConnectionState.waiting) + text('Loading...') else if (snapshot.hasError) pre([ text('Error: ${snapshot.error}, Trace:\n${snapshot.stackTrace}'), diff --git a/drift_website/lib/src/generated_snippets.dart b/drift_website/lib/src/generated_snippets.dart index 89a8357eb..4a07ff9d3 100644 --- a/drift_website/lib/src/generated_snippets.dart +++ b/drift_website/lib/src/generated_snippets.dart @@ -84,4 +84,5 @@ const generatedSnippets = { 'lib/src/snippets/modular/custom_types/table.dart.types.temp.dart.snippet.json': {'(full)': 'typedef T0 = Duration;\n',}, 'lib/src/snippets/modular/custom_types/drift_table.drift.types.temp.dart.snippet.json': {'(full)': 'typedef T0 = Duration;\n',}, 'lib/src/snippets/modular/drift/with_existing.drift.types.temp.dart.snippet.json': {'(full)': 'import \'package:drift_website/src/snippets/modular/drift/row_class.dart\' as i0;\ntypedef T0 = i0.User;\ntypedef T1 = i0.UserWithFriends;\n',}, +'lib/src/snippets/setup/testing.dart.snippet.json': {'(full)': 'import \'package:drift/drift.dart\';\nimport \'package:drift/native.dart\';\nimport \'package:test/test.dart\';\n// the file defined above, you can test any drift database of course\nimport \'database.dart\';\n\nvoid main() {\n late AppDatabase database;\n\n setUp(() {\n database = AppDatabase(\n DatabaseConnection(\n NativeDatabase.memory(),\n // Recommended for widget tests to avoid test errors.\n closeStreamsSynchronously: true,\n ),\n );\n });\n tearDown(() async {\n await database.close();\n });\n}\n',}, }; diff --git a/drift_website/lib/src/snippets/setup/testing.dart b/drift_website/lib/src/snippets/setup/testing.dart new file mode 100644 index 000000000..04ef7c7bc --- /dev/null +++ b/drift_website/lib/src/snippets/setup/testing.dart @@ -0,0 +1,22 @@ +import 'package:drift/drift.dart'; +import 'package:drift/native.dart'; +import 'package:test/test.dart'; +// the file defined above, you can test any drift database of course +import 'database.dart'; + +void main() { + late AppDatabase database; + + setUp(() { + database = AppDatabase( + DatabaseConnection( + NativeDatabase.memory(), + // Recommended for widget tests to avoid test errors. + closeStreamsSynchronously: true, + ), + ); + }); + tearDown(() async { + await database.close(); + }); +} diff --git a/drift_website/lib/src/styles/_ui.scss b/drift_website/lib/src/styles/_ui.scss new file mode 100644 index 000000000..562b463bc --- /dev/null +++ b/drift_website/lib/src/styles/_ui.scss @@ -0,0 +1,4 @@ +button.compat { + border: 2px solid var(--primary); + padding: 0.25em; +}