diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index c20d8770..4b9dd8cd 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -12,6 +12,9 @@ jobs: - name: Get dependencies run: dart pub get working-directory: docs + - name: Analyze Dart sources + working-directory: docs + run: dart analyze --fatal-infos --fatal-warnings - name: Run build env: IS_RELEASE: ${{ github.event_name == 'push' && github.event.ref == 'refs/heads/latest-release' }} diff --git a/.gitignore b/.gitignore index 52f07f0d..f7f9ba44 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,5 @@ benchmark_results.json flutter_export_environment.sh # Local Netlify folder .netlify + +docs/**/*.g.dart diff --git a/docs/assets/path_provider/lib/path_provider.dart b/docs/assets/path_provider/lib/path_provider.dart new file mode 100644 index 00000000..73d86f30 --- /dev/null +++ b/docs/assets/path_provider/lib/path_provider.dart @@ -0,0 +1,5 @@ +import 'dart:io'; + +Future getApplicationDocumentsDirectory() { + throw UnsupportedError('stub!'); +} diff --git a/docs/assets/path_provider/pubspec.yaml b/docs/assets/path_provider/pubspec.yaml new file mode 100644 index 00000000..a25aaaa8 --- /dev/null +++ b/docs/assets/path_provider/pubspec.yaml @@ -0,0 +1,6 @@ +name: path_provider +publish_to: none +description: Fake "path_provider" package so that we can import it in snippets without depending on Flutter. + +environment: + sdk: ^2.16.0 diff --git a/docs/build.yaml b/docs/build.yaml index 243221fa..e9c0c8e9 100644 --- a/docs/build.yaml +++ b/docs/build.yaml @@ -10,10 +10,16 @@ targets: builders: "|versions": enabled: true + code_snippets: + enabled: true + generate_for: + - "lib/snippets/**/*.dart" + - "lib/snippets/*.dart" auto_apply_builders: false sources: - "$package$" - "lib/versions.json" + - "lib/snippets/**" - "tool/write_versions.dart" $default: @@ -32,6 +38,8 @@ targets: - "--csp" moor_generator: enabled: false + code_snippets: + enabled: false sources: - "lib/**" - "pages/**" diff --git a/docs/lib/_highlight.scss b/docs/lib/_highlight.scss index 76fb8865..878e7f7f 100644 --- a/docs/lib/_highlight.scss +++ b/docs/lib/_highlight.scss @@ -22,6 +22,7 @@ .hljs-number, .hljs-literal, .hljs-variable, +.hljs-title.function_.invoked__, .hljs-template-variable, .hljs-tag .hljs-attr { color: #008081; @@ -44,7 +45,7 @@ } .hljs-type, -.hljs-class .hljs-title { +.hljs-title.class_ { color: #458; font-weight: bold; } diff --git a/docs/lib/snippets/platforms.dart b/docs/lib/snippets/platforms.dart new file mode 100644 index 00000000..49326bbe --- /dev/null +++ b/docs/lib/snippets/platforms.dart @@ -0,0 +1,18 @@ +// #docregion +import 'dart:ffi'; +import 'dart:io'; +import 'package:sqlite3/open.dart'; + +void main() { + open.overrideFor(OperatingSystem.linux, _openOnLinux); + + // After setting all the overrides, you can use drift! +} + +DynamicLibrary _openOnLinux() { + final scriptDir = File(Platform.script.toFilePath()).parent; + final libraryNextToScript = File('${scriptDir.path}/sqlite3.so'); + return DynamicLibrary.open(libraryNextToScript.path); +} +// _openOnWindows could be implemented similarly by opening `sqlite3.dll` +// #enddocregion diff --git a/docs/lib/snippets/tables/filename.dart b/docs/lib/snippets/tables/filename.dart new file mode 100644 index 00000000..99c506cb --- /dev/null +++ b/docs/lib/snippets/tables/filename.dart @@ -0,0 +1,64 @@ +// ignore_for_file: directives_ordering + +// #docregion open +// These imports are only needed to open the database +import 'dart:io'; + +import 'package:drift/native.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:path/path.dart' as p; + +// #enddocregion open + +// #docregion overview +import 'package:drift/drift.dart'; + +// assuming that your file is called filename.dart. This will give an error at +// first, but it's needed for drift to know about the generated code +part 'filename.g.dart'; + +// this will generate a table called "todos" for us. The rows of that table will +// be represented by a class called "Todo". +class Todos extends Table { + IntColumn get id => integer().autoIncrement()(); + TextColumn get title => text().withLength(min: 6, max: 32)(); + TextColumn get content => text().named('body')(); + IntColumn get category => integer().nullable()(); +} + +// This will make drift generate a class called "Category" to represent a row in +// this table. By default, "Categorie" would have been used because it only +//strips away the trailing "s" in the table name. +@DataClassName('Category') +class Categories extends Table { + IntColumn get id => integer().autoIncrement()(); + TextColumn get description => text()(); +} + +// this annotation tells drift to prepare a database class that uses both of the +// tables we just defined. We'll see how to use that database class in a moment. +// #docregion open +@DriftDatabase(tables: [Todos, Categories]) +class MyDatabase extends _$MyDatabase { + // #enddocregion overview + // we tell the database where to store the data with this constructor + MyDatabase() : super(_openConnection()); + + // you should bump this number whenever you change or add a table definition. + // Migrations are covered later in the documentation. + @override + int get schemaVersion => 1; +// #docregion overview +} +// #enddocregion overview + +LazyDatabase _openConnection() { + // the LazyDatabase util lets us find the right location for the file async. + return LazyDatabase(() async { + // put the database file, called db.sqlite here, into the documents folder + // for your app. + final dbFolder = await getApplicationDocumentsDirectory(); + final file = File(p.join(dbFolder.path, 'db.sqlite')); + return NativeDatabase(file); + }); +} diff --git a/docs/pages/docs/Getting started/index.md b/docs/pages/docs/Getting started/index.md index 3bf10645..8205b833 100644 --- a/docs/pages/docs/Getting started/index.md +++ b/docs/pages/docs/Getting started/index.md @@ -18,6 +18,7 @@ At the moment, the current version of `drift` is [![Drift version](https://img.s and the latest version of `drift_dev` is [![Generator version](https://img.shields.io/pub/v/drift_dev.svg)](https://pub.dev/packages/drift_dev). {% assign versions = 'package:moor_documentation/versions.json' | readString | json_decode %} +{% assign snippets = 'package:moor_documentation/snippets/tables/filename.dart.excerpt.json' | readString | json_decode %} ```yaml dependencies: @@ -43,40 +44,10 @@ If you're wondering why so many packages are necessary, here's a quick overview {% include "partials/changed_to_ffi" %} ### Declaring tables + Using drift, you can model the structure of your tables with simple dart code: -```dart -import 'package:drift/drift.dart'; -// assuming that your file is called filename.dart. This will give an error at first, -// but it's needed for drift to know about the generated code -part 'filename.g.dart'; - -// this will generate a table called "todos" for us. The rows of that table will -// be represented by a class called "Todo". -class Todos extends Table { - IntColumn get id => integer().autoIncrement()(); - TextColumn get title => text().withLength(min: 6, max: 32)(); - TextColumn get content => text().named('body')(); - IntColumn get category => integer().nullable()(); -} - -// This will make drift generate a class called "Category" to represent a row in this table. -// By default, "Categorie" would have been used because it only strips away the trailing "s" -// in the table name. -@DataClassName("Category") -class Categories extends Table { - - IntColumn get id => integer().autoIncrement()(); - TextColumn get description => text()(); -} - -// this annotation tells drift to prepare a database class that uses both of the -// tables we just defined. We'll see how to use that database class in a moment. -@DriftDatabase(tables: [Todos, Categories]) -class MyDatabase { - -} -``` +{% include "blocks/snippet" snippets = snippets name = "overview" %} __⚠️ Note:__ The column definitions, the table name and the primary key must be known at compile time. For column definitions and the primary key, the function must use the `=>` @@ -90,36 +61,8 @@ where you change your code, run `flutter pub run build_runner watch` instead. After running either command once, the drift generator will have created a class for your database and data classes for your entities. To use it, change the `MyDatabase` class as follows: -```dart -// These imports are only needed to open the database -import 'package:drift/native.dart'; -import 'package:path_provider/path_provider.dart'; -import 'package:path/path.dart' as p; -import 'package:drift/drift.dart'; -import 'dart:io'; -LazyDatabase _openConnection() { - // the LazyDatabase util lets us find the right location for the file async. - return LazyDatabase(() async { - // put the database file, called db.sqlite here, into the documents folder - // for your app. - final dbFolder = await getApplicationDocumentsDirectory(); - final file = File(p.join(dbFolder.path, 'db.sqlite')); - return NativeDatabase(file); - }); -} - -@DriftDatabase(tables: [Todos, Categories]) -class MyDatabase extends _$MyDatabase { - // we tell the database where to store the data with this constructor - MyDatabase() : super(_openConnection()); - - // you should bump this number whenever you change or add a table definition. Migrations - // are covered later in this readme. - @override - int get schemaVersion => 1; -} -``` +{% include "blocks/snippet" snippets = snippets name = "open" %} ## Next steps diff --git a/docs/pages/docs/platforms.md b/docs/pages/docs/platforms.md index 2ec48fdd..521f6ba2 100644 --- a/docs/pages/docs/platforms.md +++ b/docs/pages/docs/platforms.md @@ -104,27 +104,10 @@ install the dynamic library for `sqlite` next to your application executable. This example shows how to do that on Linux, by using a custom `sqlite3.so` that we assume lives next to your application: -```dart -import 'dart:ffi'; -import 'dart:io'; -import 'package:sqlite3/sqlite3.dart'; -import 'package:sqlite3/open.dart'; - -void main() { - open.overrideFor(OperatingSystem.linux, _openOnLinux); - - // After setting all the overrides, you can use drift! -} - -DynamicLibrary _openOnLinux() { - final scriptDir = File(Platform.script.toFilePath()).parent; - final libraryNextToScript = File('${scriptDir.path}/sqlite3.so'); - return DynamicLibrary.open(libraryNextToScript.path); -} -// _openOnWindows could be implemented similarly by opening `sqlite3.dll` -``` +{% assign snippets = 'package:moor_documentation/snippets/platforms.dart.excerpt.json' | readString | json_decode %} +{% include "blocks/snippet" snippets = snippets %} Be sure to use drift _after_ you set the platform-specific overrides. -When you usedrift in [another isolate]({{ 'Advanced Features/isolates.md' | pageUrl }}), +When you use drift in [another isolate]({{ 'Advanced Features/isolates.md' | pageUrl }}), you'll also need to apply the opening overrides on that background isolate. You can call them in the isolate's entrypoint before using any drift apis. diff --git a/docs/pubspec.yaml b/docs/pubspec.yaml index 9e766545..86fcdccb 100644 --- a/docs/pubspec.yaml +++ b/docs/pubspec.yaml @@ -20,6 +20,13 @@ dev_dependencies: linkcheck: ^2.0.19 shelf: ^1.2.0 shelf_static: ^1.1.0 + code_snippets: + hosted: https://simonbinder.eu + version: ^0.0.2 + + # Fake path_provider for snippets + path_provider: + path: assets/path_provider moor: moor_generator: diff --git a/docs/templates/blocks/snippet.html b/docs/templates/blocks/snippet.html new file mode 100644 index 00000000..a8f4bcf5 --- /dev/null +++ b/docs/templates/blocks/snippet.html @@ -0,0 +1,4 @@ +{% assign excerpt = args.name | default: '(full)' %} +
+{{ args.snippets | get: excerpt }}
+
diff --git a/docs/templates/partials/changed_to_ffi.html b/docs/templates/partials/changed_to_ffi.html index 45aa4d5b..9129ae86 100644 --- a/docs/templates/partials/changed_to_ffi.html +++ b/docs/templates/partials/changed_to_ffi.html @@ -1,9 +1,9 @@ -Some versions of the Flutter tool create a broken `settings.gradle` on Android, which can cause problems with `moor_ffi`. +Some versions of the Flutter tool create a broken `settings.gradle` on Android, which can cause problems with `drift/native.dart`. If you get a "Failed to load dynamic library" exception, see [this comment](https://github.com/flutter/flutter/issues/55827#issuecomment-623779910). \ No newline at end of file diff --git a/tool/generate_all.sh b/tool/generate_all.sh index ce3707b5..aff03c71 100755 --- a/tool/generate_all.sh +++ b/tool/generate_all.sh @@ -2,6 +2,8 @@ set -e echo "- Generate drift" (cd ../drift && dart pub get && dart run build_runner build --delete-conflicting-outputs) +echo "- Generate docs" +(cd ../docs && dart pub get && dart run build_runner build --delete-conflicting-outputs) echo "- Generate benchmarks" (cd ../extras/benchmarks && dart pub get && dart run build_runner build --delete-conflicting-outputs) echo "- Generate integration_tests/tests"