mirror of https://github.com/AMT-Cheif/drift.git
Write more documentation about advanced features
This commit is contained in:
parent
b2a06cbe1c
commit
a19e3413e8
|
@ -56,8 +56,8 @@ anchor = "smart"
|
|||
|
||||
[languages]
|
||||
[languages.en]
|
||||
title = "Goldydocs"
|
||||
description = "A Docsy example site"
|
||||
title = "Moor"
|
||||
description = "A typesafe persistence library for Dart apps"
|
||||
languageName ="English"
|
||||
# Weight used for sorting.
|
||||
weight = 1
|
||||
|
@ -69,6 +69,15 @@ weight = 1
|
|||
#time_format_default = "02.01.2006"
|
||||
#time_format_blog = "02.01.2006"
|
||||
|
||||
# Additional menu items to GitHub and pub
|
||||
[[menu.main]]
|
||||
name = "Pub"
|
||||
weight = 100
|
||||
url = "https://pub.dev/packages/moor_flutter"
|
||||
[[menu.main]]
|
||||
name = "GitHub"
|
||||
weight = 110
|
||||
url = "https://github.com/simolus3/moor/"
|
||||
|
||||
# Everything below this are Site Params
|
||||
|
||||
|
@ -103,34 +112,17 @@ navbar_logo = false
|
|||
[params.links]
|
||||
# End user relevant links. These will show up on left side of footer and in the community page if you have one.
|
||||
[[params.links.user]]
|
||||
name = "User mailing list"
|
||||
url = "https://example.org/mail"
|
||||
name = "Contact me via e-mail"
|
||||
url = "mailto:oss@simonbinder.eu"
|
||||
icon = "fa fa-envelope"
|
||||
desc = "Discussion and help from your fellow users"
|
||||
[[params.links.user]]
|
||||
name ="Twitter"
|
||||
url = "https://example.org/twitter"
|
||||
icon = "fab fa-twitter"
|
||||
desc = "Follow us on Twitter to get the latest news!"
|
||||
name = "Contact me via gitter"
|
||||
url = "https://gitter.im/simolus3"
|
||||
icon = "fab fa-gitter"
|
||||
[[params.links.user]]
|
||||
name = "Stack Overflow"
|
||||
url = "https://example.org/stack"
|
||||
icon = "fab fa-stack-overflow"
|
||||
desc = "Practical questions and curated answers"
|
||||
# Developer relevant links. These will show up on right side of footer and in the community page if you have one.
|
||||
[[params.links.developer]]
|
||||
name = "GitHub"
|
||||
url = "https://github.com/google/docsy"
|
||||
url = "https://github.com/simolus3/moor"
|
||||
icon = "fab fa-github"
|
||||
desc = "Development takes place here!"
|
||||
[[params.links.developer]]
|
||||
name = "Slack"
|
||||
url = "https://example.org/slack"
|
||||
icon = "fab fa-slack"
|
||||
desc = "Chat with other project developers"
|
||||
[[params.links.developer]]
|
||||
name = "Developer mailing list"
|
||||
url = "https://example.org/mail"
|
||||
icon = "fa fa-envelope"
|
||||
desc = "Discuss development issues around the project"
|
||||
|
||||
# could also add another with params.links.developer. They appear on the right
|
|
@ -1,38 +0,0 @@
|
|||
---
|
||||
title: About Goldydocs
|
||||
linkTitle: About
|
||||
menu:
|
||||
main:
|
||||
weight: 10
|
||||
|
||||
---
|
||||
|
||||
|
||||
{{< blocks/cover title="About Goldydocs" image_anchor="bottom" height="min" >}}
|
||||
|
||||
<p class="lead mt-5">A sample site using the Docsy Hugo theme.
|
||||
</p>
|
||||
|
||||
{{< /blocks/cover >}}
|
||||
|
||||
{{% blocks/lead %}}
|
||||
Goldydocs is a sample site using the <a href="https://github.com/google/docsy">Docsy</a> Hugo theme that shows what it can do and provides you with a template site structure. It’s designed for you to clone and edit as much as you like. See the different sections of the documentation and site for more ideas.
|
||||
{{% /blocks/lead %}}
|
||||
|
||||
|
||||
{{< blocks/section >}}
|
||||
<div class="col-12">
|
||||
<h1 class="text-center">This is another section</h1>
|
||||
</div>
|
||||
|
||||
{{< /blocks/section >}}
|
||||
|
||||
|
||||
|
||||
{{< blocks/section >}}
|
||||
|
||||
<div class="col-12">
|
||||
<h1 class="text-center">This is another section</h1>
|
||||
</div>
|
||||
|
||||
{{< /blocks/section >}}
|
|
@ -1,4 +1,5 @@
|
|||
---
|
||||
title: "Advanced features"
|
||||
weight: 20
|
||||
description: Learn about some advanced features of moor
|
||||
---
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
title: "Joins"
|
||||
weight: 1
|
||||
description: >
|
||||
Use joins to write queries that read from more than one table
|
||||
aliases:
|
||||
|
@ -9,7 +10,7 @@ aliases:
|
|||
Moor supports sql joins to write queries that operate on more than one table. To use that feature, start
|
||||
a select regular select statement with `select(table)` and then add a list of joins using `.join()`. For
|
||||
inner and left outer joins, a `ON` expression needs to be specified. Here's an example using the tables
|
||||
defined in the [example]({{< ref "docs/Getting Started/_index.md" >}}).
|
||||
defined in the [example]({{< ref "/docs/Getting Started/_index.md" >}}).
|
||||
|
||||
```dart
|
||||
// we define a data class to contain both a todo entry and the associated category
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
title: "Migrations"
|
||||
weight: 10
|
||||
description: >
|
||||
Define what happens when your database gets created or updated
|
||||
aliases:
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
---
|
||||
title: "Type converters"
|
||||
description: >
|
||||
Store more complex data in columns with type converters
|
||||
---
|
||||
|
||||
Moor supports a variety of types out of the box, but sometimes you need to store more complex data.
|
||||
You can achieve this by using `TypeConverters`. In this example, we'll use the the
|
||||
[json_serializable](https://pub.dev/packages/json_annotation) package to store a custom object in a
|
||||
text column. Moor supports any Dart type for which you provide a `TypeConverter`, we're using that
|
||||
package here to make the example simpler.
|
||||
```dart
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:json_annotation/json_annotation.dart' as j;
|
||||
import 'package:moor/moor.dart';
|
||||
|
||||
part 'database.g.dart';
|
||||
|
||||
@j.JsonSerializable()
|
||||
class Preferences {
|
||||
bool receiveEmails;
|
||||
String selectedTheme;
|
||||
|
||||
Preferences(this.receiveEmails, this.selectedTheme);
|
||||
|
||||
factory Preferences.fromJson(Map<String, dynamic> json) =>
|
||||
_$PreferencesFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$PreferencesToJson(this);
|
||||
}
|
||||
```
|
||||
|
||||
Next, we have to tell moor how to store a `Preferences` object in the database. We write
|
||||
a `TypeConverter` for that:
|
||||
```dart
|
||||
// stores preferences as strings
|
||||
class PreferenceConverter extends TypeConverter<Preferences, String> {
|
||||
const PreferenceConverter();
|
||||
@override
|
||||
Preferences mapToDart(String fromDb) {
|
||||
if (fromDb == null) {
|
||||
return null;
|
||||
}
|
||||
return Preferences.fromJson(json.decode(fromDb) as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
@override
|
||||
String mapToSql(Preferences value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return json.encode(value.toJson());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Finally, we can use that converter in a table declaration:
|
||||
```dart
|
||||
class Users extends Table {
|
||||
IntColumn get id => integer().autoIncrement()();
|
||||
TextColumn get name => text()();
|
||||
|
||||
TextColumn get preferences =>
|
||||
text().map(const PreferenceConverter()).nullable()();
|
||||
}
|
||||
```
|
||||
|
||||
The generated `User` class will then have a `preferences` column of type
|
||||
`Preferences`. Moor will automatically take care of storing and loading
|
||||
the object in `select`, `update` and `insert` statements. This feature
|
||||
also works with [compiled custom queries]({{ "/queries/custom" | absolute_url }}).
|
|
@ -1,38 +0,0 @@
|
|||
---
|
||||
title: "Overview"
|
||||
linkTitle: "Overview"
|
||||
weight: 1
|
||||
description: >
|
||||
Here's where your user finds out if your project is for them.
|
||||
---
|
||||
|
||||
{{% pageinfo %}}
|
||||
This is a placeholder page that shows you how to use this template site.
|
||||
{{% /pageinfo %}}
|
||||
|
||||
|
||||
The Overview is where your users find out about your project. Depending on the size of your docset, you can have a separate overview page (like this one) or put your overview contents in the Documentation landing page (like in the Docsy User Guide).
|
||||
|
||||
Try answering these questions for your user in this page:
|
||||
|
||||
## What is it?
|
||||
|
||||
Introduce your project, including what it does or lets you do, why you would use it, and its primary goal (and how it achieves it). This should be similar to your README description, though you can go into a little more detail here if you want.
|
||||
|
||||
## Why do I want it?
|
||||
|
||||
Help your user know if your project will help them. Useful information can include:
|
||||
|
||||
* **What is it good for?**: What types of problems does your project solve? What are the benefits of using it?
|
||||
|
||||
* **What is it not good for?**: For example, point out situations that might intuitively seem suited for your project, but aren't for some reason. Also mention known limitations, scaling issues, or anything else that might let your users know if the project is not for them.
|
||||
|
||||
* **What is it *not yet* good for?**: Highlight any useful features that are coming soon.
|
||||
|
||||
## Where should I go next?
|
||||
|
||||
Give your users next steps from the Overview. For example:
|
||||
|
||||
* [Getting Started](/getting-started/): Get started with $project
|
||||
* [Examples](/examples/): Check out some example code!
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
title: "Using SQL"
|
||||
weight: 30
|
||||
description: Write typesafe sql with moor
|
||||
---
|
||||
|
||||
Moor let's you express a variety of queries in pure Dart. However, you don't have to miss out
|
||||
on its features when you need more complex queries or simply prefer sql. Moor has a builtin
|
||||
sql parser and analyzer, so it can generate a typesafe API for sql statements you write.
|
||||
It can also warn about errors in your sql at build time.
|
|
@ -0,0 +1,87 @@
|
|||
---
|
||||
title: "Custom queries"
|
||||
weight: 10
|
||||
description: Let moor generate Dart from your SQL statements
|
||||
aliases:
|
||||
- /queries/custom
|
||||
---
|
||||
|
||||
Altough moor includes a fluent api that can be used to model most statements, advanced
|
||||
features like `GROUP BY` statements or window functions are not yet supported. You can
|
||||
use these features with custom statements. You don't have to miss out on other benefits
|
||||
moor brings, though: Moor helps you parse the result rows and qustom queries also
|
||||
support auto-updating streams.
|
||||
|
||||
## Statements with a generated api
|
||||
Starting from version `1.5`, you can instruct moor to automatically generate a typesafe
|
||||
API for your select, update and delete statements. Of course, you can still write custom
|
||||
sql manually. See the sections below for details.
|
||||
|
||||
To use this feature, all you need to is define your queries in your `UseMoor` annotation:
|
||||
```dart
|
||||
@UseMoor(
|
||||
tables: [Todos, Categories],
|
||||
queries: {
|
||||
'categoriesWithCount':
|
||||
'SELECT *, (SELECT COUNT(*) FROM todos WHERE category = c.id) AS "amount" FROM categories c;'
|
||||
},
|
||||
)
|
||||
class MyDatabase extends _$MyDatabase {
|
||||
// rest of class stays the same
|
||||
}
|
||||
```
|
||||
After running the build step again, moor will have written the `CategoriesWithCountResult` class for you -
|
||||
it will hold the result of your query. Also, the `_$MyDatabase` class from which you inherit will have the
|
||||
methods `categoriesWithCount` (which runs the query once) and `watchCategoriesWithCount` (which returns
|
||||
an auto-updating stream).
|
||||
|
||||
Queries can have parameters in them by using the `?` or `:name` syntax. When your queries contains parameters,
|
||||
moor will figure out an appropriate type for them and include them in the generated methods. For instance,
|
||||
`'categoryById': 'SELECT * FROM categories WHERE id = :id'` will generate the method `categoryById(int id)`.
|
||||
|
||||
You can also use `UPDATE` or `DELETE` statements here. Of course, this feature is also available for
|
||||
[daos]({{< ref "/docs/Advanced features/daos.md" >}}),
|
||||
and it perfectly integrates with auto-updating streams by analyzing what tables you're reading from or
|
||||
writing to.
|
||||
|
||||
## Custom select statements
|
||||
If you don't want to use the statements with an generated api, you can
|
||||
still send custom queries by calling `customSelect` for a one-time query or
|
||||
`customSelectStream` for a query stream that automatically emits a new set of items when
|
||||
the underlying data changes. Using the todo example introduced in the
|
||||
[getting started guide]({{< ref "/docs/Getting started/_index.md" >}}), we can
|
||||
write this query which will load the amount of todo entries in each category:
|
||||
```dart
|
||||
class CategoryWithCount {
|
||||
final Category category;
|
||||
final int count; // amount of entries in this category
|
||||
|
||||
CategoryWithCount(this.category, this.count);
|
||||
}
|
||||
|
||||
// then, in the database class:
|
||||
Stream<List<CategoryWithCount>> categoriesWithCount() {
|
||||
// select all categories and load how many associated entries there are for
|
||||
// each category
|
||||
return customSelectStream(
|
||||
'SELECT *, (SELECT COUNT(*) FROM todos WHERE category = c.id) AS "amount" FROM categories c;',
|
||||
readsFrom: {todos, categories}, // used for the stream: the stream will update when either table changes
|
||||
).map((rows) {
|
||||
// we get list of rows here. We just have to turn the raw data from the row into a
|
||||
// CategoryWithCount. As we defined the Category table earlier, moor knows how to parse
|
||||
// a category. The only thing left to do manually is extracting the amount
|
||||
return rows
|
||||
.map((row) => CategoryWithCount(Category.fromData(row.data, this), row.readInt('amount')))
|
||||
.toList();
|
||||
});
|
||||
}
|
||||
```
|
||||
For custom selects, you should use the `readsFrom` parameter to specify from which tables the query is
|
||||
reading. When using a `Stream`, moor will be able to know after which updates the stream should emit
|
||||
items.
|
||||
|
||||
## Custom update statements
|
||||
For update and delete statements, you can use `customUpdate`. Just like `customSelect`, that method
|
||||
also takes a sql statement and optional variables. You can also tell moor which tables will be
|
||||
affected by your query using the optional `updates` parameter. That will help with other select
|
||||
streams, which will then update automatically.
|
|
@ -0,0 +1,42 @@
|
|||
---
|
||||
title: "Tables from SQL"
|
||||
weight: 20
|
||||
description: Generate tables from `CREATE TABLE` statements.
|
||||
---
|
||||
|
||||
{{% alert title="Experimental feature" %}}
|
||||
At the moment, creating table classes from `CREATE TABLE` statements is an experimental feature.
|
||||
If you run into any issues, please create an issue and let us know, thanks!
|
||||
{{% /alert %}}
|
||||
|
||||
With moor, you can specify your table classes in Dart and it will generate matching
|
||||
`CREATE TABLE` statements for you. But if you prefer to write `CREATE TABLE` statements and have
|
||||
moor generating fitting Dart classes, that works too.
|
||||
|
||||
To use this feature, create a (or multiple) `.moor` file somewhere in your project. You can fill
|
||||
them with create table statements:
|
||||
```sql
|
||||
CREATE TABLE states (
|
||||
id INT NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE experiments (
|
||||
id INT NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
description TEXT NOT NULL,
|
||||
state INT REFERENCES states(id) ON UPDATE CASCADE ON DELETE SET NULL
|
||||
)
|
||||
```
|
||||
|
||||
Then, import these tables to your database with:
|
||||
```dart
|
||||
@UseMoor(include: {'experiments.moor'})
|
||||
class ExperimentsDb extends _$ExperimentsDb {
|
||||
```
|
||||
|
||||
All the tables will then be available inside your database class, just like they
|
||||
would be if you wrote them in Dart. If you want to use this feature on an DAO,
|
||||
you'll also need to `include` the .moor file on that class. Moor supports both
|
||||
relative imports (like above) and absolute imports (like `package:your_app/src/tables/experiments.moor`)
|
||||
Of course, this feature works perfectly together with features like generated
|
||||
custom queries and query-streams.
|
|
@ -1,24 +1,32 @@
|
|||
|
||||
---
|
||||
title: "Documentation"
|
||||
title: "Welcome to Moor"
|
||||
linkTitle: "Documentation"
|
||||
weight: 20
|
||||
menu:
|
||||
main:
|
||||
weight: 20
|
||||
description: >
|
||||
Welcome to the moor documentation. This site shows you what moor can do and how to use it.
|
||||
---
|
||||
|
||||
{{% pageinfo %}}
|
||||
This is a placeholder page that shows you how to use this template site.
|
||||
{{% /pageinfo %}}
|
||||
## So what's moor?
|
||||
Moor is a reactive persistence library for Dart and Flutter applications. It's built ontop
|
||||
of database libraries like [sqflite](https://pub.dev/packages/sqflite) or [sql.js](https://github.com/kripken/sql.js/)
|
||||
and provides additional featues, like
|
||||
|
||||
- __Type safety__: Instead of writing sql queries manually and parsing the `List<Map<String, dynamic>>` that they
|
||||
return, moor turns rows into object of your choice.
|
||||
- __Stream queries__: Moor let's you "watch" your queries with zero additional effort. Any query can be turned into
|
||||
an auto-updating stream that emits new items when the underlying data changes.
|
||||
- __Fluent queries__: Moor generates a Dart api that you can use to write queries and automatically get their results.
|
||||
Keep an updated list of all users with `select(users).watch()`. That's it! No sql to write, no rows to parse.
|
||||
- __Typesafe sql__: If you prefer to write sql, that's fine! Moor has an sql parser and analyzer built in. It can parse
|
||||
your queries at compile time, figure out what columns they're going to return and generate Dart code to represent your
|
||||
rows.
|
||||
- __Migration utils__: Moor makes writing migrations easier thanks to utility functions like `.createAllTables()`.
|
||||
You don't need to manually write your `CREATE TABLE` statements and keep them updated.
|
||||
|
||||
This section is where the user documentation for your project lives - all the information your users need to understand and successfully use your project.
|
||||
|
||||
For large documentation sets we recommend adding content under the headings in this section, though if some or all of them don’t apply to your project feel free to remove them or add your own. You can see an example of a smaller Docsy documentation site in the [Docsy User Guide](https://docsy.dev/docs/), which lives in the [Docsy theme repo](https://github.com/google/docsy/tree/master/userguide) if you'd like to copy its docs section.
|
||||
|
||||
Other content such as marketing material, case studies, and community updates should live in the [About](/about/) and [Community](/community/) pages.
|
||||
|
||||
Find out how to use the Docsy theme in the [Docsy User Guide](https://docsy.dev/docs/). You can learn more about how to organize your documentation (and how we organized this site) in [Organizing Your Content](https://docsy.dev/docs/best-practices/organizing-content/).
|
||||
|
||||
And much more! Moor validates data before inserting it, so you can get helpful error messages instead of just an
|
||||
sql error code. Of course, it supports transactions. And DAOs. And efficient batched insert statements. The list goes on.
|
||||
|
||||
Check out these in-depth articles to learn about moor and how to use its features.
|
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
title: "Transactions"
|
||||
weight: 70
|
||||
description: Run multiple queries atomically
|
||||
|
||||
aliases:
|
||||
|
|
Loading…
Reference in New Issue