diff --git a/docs/06-concepts/02-models/01-models.md b/docs/06-concepts/02-models/01-models.md index 67609f43..68f659cc 100644 --- a/docs/06-concepts/02-models/01-models.md +++ b/docs/06-concepts/02-models/01-models.md @@ -5,7 +5,7 @@ sidebar_label: Working with models # Working with models -Models are Yaml files used to define serializable classes in Serverpod. They are used to generate Dart code for the server and client, and, if a database table is defined, to generate database code for the server. +Models are Yaml files used to define serializable classes in Serverpod. They are used to generate Dart code for the server and client, and, if a database table is defined, to generate database code for the server and/or client. Using regular `.yaml` files within `lib/src/models` is supported, but it is recommended to use `.spy.yaml` (.spy stands for "Serverpod YAML"). Using this file type allows placing the model files anywhere in your servers `lib` directory and enables syntax highlighting provided by the [Serverpod Extension](https://marketplace.visualstudio.com/items?itemName=serverpod.serverpod) for VS Code. diff --git a/docs/06-concepts/06-database/02-models.md b/docs/06-concepts/06-database/02-models.md index 4283cf84..986b2603 100644 --- a/docs/06-concepts/06-database/02-models.md +++ b/docs/06-concepts/06-database/02-models.md @@ -12,11 +12,27 @@ fields: When the `table` keyword is added to the model, the `serverpod generate` command will generate new methods for [interacting](crud) with the database. The addition of the keyword will also be detected by the `serverpod create-migration` command that will generate the necessary [migrations](migrations) needed to update the database. :::info - When you add a `table` to a serializable class, Serverpod will automatically add an `id` field of type `int?` to the class. You should not define this field yourself. The `id` is set when you interact with an object stored in the database. - ::: +## Client-side database + +Models with the `table` keyword can also generate a client-side database with the `database` keyword: + +```yaml +class: Company +table: company +database: client +``` + +| Value | Description | +| ------- | ----------- | +| `server` | Generates tables only on the server, and a non-table model on the client package (default). | +| `client` | Generates tables only on the client, and a non-table model on the server package. | +| `all` | Generates table models on both server and client. | + +For how to use the client-side database, see the [Client-side database](client-side-database) section. + ## Non persistent fields You can opt out of creating a column in the database for a specific field by using the `!persist` keyword. diff --git a/docs/06-concepts/06-database/14-client-side-database.md b/docs/06-concepts/06-database/14-client-side-database.md new file mode 100644 index 00000000..89f44fdd --- /dev/null +++ b/docs/06-concepts/06-database/14-client-side-database.md @@ -0,0 +1,79 @@ +# Client-side database + +When at least one table model has `database: client` or `database: all`, the generated `Client` class gets a `createSession` method that returns a `ClientDatabaseSession` for a SQLite database file. + +```dart + /// Creates a new client-side database session for the given path. + /// + /// The [path] is the file path to the SQLite database file. Since SQLite uses + /// WAL mode, note that `[path]-shm` and `[path]-wal` files might also exist + /// transiently for the database while the session is open. + /// + /// If [runMigrations] is true, pending migrations will be applied when + /// opening the database. Be careful when setting this to false, as it might + /// lead to inconsistencies between the models and the database. + /// + /// If [isDebugMode] is true, the database integrity will be verified after + /// the migrations are applied to provide feedback of possible issues. On a + /// Flutter application, this should be set to [kDebugMode]. + Future createSession( + String path, { + bool runMigrations = true, + bool isDebugMode = false, + }) async { + /* Generated implementation */ + } +``` + +:::info +When generating with client-side database support, the `serverpod_database` package is required as a dependency in your client package. Make sure to add it to your `pubspec.yaml` file. +::: + +## Creating a client-side database session + +On Flutter, create a client-side database session by resolving a file path and calling `createSession`: + +```dart +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:path/path.dart' as p; +import 'package:path_provider/path_provider.dart'; +import 'package:my_project_client/my_project_client.dart'; + +void main() async { + WidgetsFlutterBinding.ensureInitialized(); + + // Set the client URL to the server URL as normal. + final client = Client(clientUrl); + + // Resolve the database path. + final path = await resolveDatabasePath('app.db'); + + // Create the session to use in database operations. + final session = await client.createSession(path, isDebugMode: kDebugMode); + + // Store the session in your state manager to use it all database operations. + // Since the session opens and closes the database when created, it is not + // recommended to create a new session for each database operation. +} + +Future resolveDatabasePath(String fileName) async { + if (kIsWeb) return fileName; + final dir = await getApplicationSupportDirectory(); + return p.join(dir.path, fileName); +} +``` + +## Using the client-side database + +The client-side database session provides access to the database methods for the generated models. It can be used normally as with the server-side database session. + +```dart +var companies = await Company.db.find( + session, + where: (t) => t.name.like('%Ltd'), + orderBy: (t) => t.name, +); +``` + +All ORM features supported by SQLite are available on the client-side as well, including full CRUD support, relations, transactions, and more.