More documentation

This commit is contained in:
Simon Binder 2019-04-02 22:06:41 +02:00
parent cc46cd9a5b
commit dec4558236
No known key found for this signature in database
GPG Key ID: B807FDF954BA00CF
13 changed files with 143 additions and 25 deletions

View File

@ -9,4 +9,23 @@ exclude: true
<h1>Page not found</h1>
<p>The page you requested could not be found. Try using the navigation {% if site.search_enabled %}or search {% endif %}to find what you're looking for or go to this <a href="{{ site.url }}{{ site.baseurl }}">site's home page</a>.</p>
<p>The page you requested could not be found. Try using the navigation {% if site.search_enabled %}or search {% endif %}to find what you're looking for or go to this <a href="{{ site.url }}{{ site.baseurl }}">site's home page</a>.</p>
<h2>Check out these features</h2>
{% assign posts = site.pages | sort:"nav_order" %}
<ul>
{% for post in posts %}
{% if post.layout == "feature" %}
<li><a href="{{post.url | absolute_url}}">{{post.title}}</a></li>
{% endif %}
{% endfor %}
</ul>
<h2>Or these in-depth guides</h2>
<ul>
{% for post in posts %}
{% if post.layout == "guide" %}
<li><a href="{{post.url | absolute_url}}">{{post.title}}</a></li>
{% endif %}
{% endfor %}
</ul>

View File

@ -24,6 +24,8 @@ github_link: https://github.com/simolus3/moor
search_enabled: true
common_links:
getting_started: "/getting-started"
# Build settings
markdown: kramdown

View File

@ -70,9 +70,10 @@
<hr>
<span class="fs-2">
Was this page helpful? Please
{% assign body= "From documentation site " %}
<a href="{{site.github_link}}/issues/new?body={{ body | url_encode }}{{page.path | url_encode}}">report an issue</a>
if you have questions or problems.
{% assign url = page.url | absolute_url %}
{% assign body = 'From documentation URL: ' | append: url %}
<a href="{{site.github_link}}/issues/new?body={{body | url_encode}}">report an issue</a>
if you have questions or run into problems.
</span>
</div>
</div>

5
docs/_layouts/guide.html Normal file
View File

@ -0,0 +1,5 @@
---
layout: default
---
{{ content }}

View File

@ -0,0 +1,12 @@
---
---
{
{% for page in site.html_pages %}"{{ forloop.index0 }}": {
"id": "{{ forloop.index0 }}",
"title": "{{ page.title | xml_escape }}",
"content": "{{ page.content | markdownify | strip_html | xml_escape | remove: 'Table of contents' | strip_newlines | replace: '\', ' ' }}",
"url": "{{ page.url | absolute_url | xml_escape }}",
"relUrl": "{{ page.url | xml_escape }}"
}{% if forloop.last %}{% else %},
{% endif %}{% endfor %}
}

View File

@ -1,12 +1,12 @@
---
layout: post
layout: guide
title: Modularity with DAOs
nav_order: 5
permalink: /daos/
---
# Extracting functionality with DAOs
When you have a lot of queries, putting them all into one class quickly becomes
When you have a lot of queries, putting them all into one class might become
tedious. You can avoid this by extracting some queries into classes that are
available from your main database class. Consider the following code:
```dart

View File

@ -1,5 +1,5 @@
---
layout: post
layout: guide
title: Getting started
nav_order: 1
permalink: /getting-started/

View File

@ -1,5 +1,5 @@
---
layout: post
layout: feature
title: Migrations
nav_order: 4
permalink: /migrations/

View File

@ -3,7 +3,60 @@ layout: feature
title: Transactions
nav_order: 3
since: 1.1
permalink: /transactions
---
# Transactions
TBD
Moor has support for transactions and allows multiple queries to run atomically.
To begin a transaction, call the `transaction` method on your database or a DAO.
It takes a function as an argument that will be run on the transaction. In the
following example, which deals with deleting a category, we move all todo entries
in that category back to the default category:
```dart
Future deleteCategory(Category category) {
return transaction((t) async {
// first, move the affected todo entries back to the default category
await t.customUpdate(
'UPDATE todos SET category = NULL WHERE category = ?',
updates: {todos},
variables: [Variable.withInt(category.id)],
);
// then, delete the category
await t.delete(categories).delete(category);
});
}
```
## ⚠️ Gotchas
There are a couple of things that should be kept in mind when working with transactions:
1. __Await all calls__: All queries inside the transaction must be `await`-ed. The transaction
will complete when the inner method completes. Without `await`, some queries might be operating
on the transaction after it has been closed!
2. __Don't run calls on your database__: Inside a transaction function, all queries must
be on the transaction itself.
```dart
await transaction((t) async {
// BAD - this will run on the database itself!
await delete(categories).delete(category);
});
await transaction((t) async {
// GOOD!
await t.delete(categories).delete(category);
});
```
The reason behind this is that no calls can operate on the database while it's in a transaction,
they will run after the transaction has completed. When the completion of the transaction can only
happen after a call to the database completes, as in the fist example, the database will reach a
dead lock!
## Transactions and query streams
Query streams that have been created outside a transaction work nicely together with
updates made in a transaction: All changes to tables will only be reported after the
transaction completes. Updates inside a transaction don't have an immediate effect on
streams.
However, streams cannot be created inside transactions! The reason behind that decision
is that it's unclear what should happen to the stream after the transaction completes.
Should the stream complete as well? Begin to the updated data outside the transaction?
To not make things confusing here, this is forbidden.

View File

@ -1,14 +1,21 @@
---
layout: post
layout: feature
title: Custom queries
parent: Writing queries
---
# Custom statements
You can also issue custom queries by calling `customUpdate` for update and deletes and
`customSelect` or `customSelectStream` for select statements. Using the todo example
above, here is a simple custom query that loads all categories and how many items are
in each category:
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: Parsing the rows and query-streams also work on custom statements.
## Custom select statements
You can issue 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]({{site.common_links.getting_started | absolute_url}}), we can
write this query which will load the amount of todo entries in each category:
```dart
class CategoryWithCount {
final Category category;
@ -22,10 +29,13 @@ 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}).map((rows) {
// when we have the result set, map each row to the data class
return rows
'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();
});
@ -33,5 +43,10 @@ Stream<List<CategoryWithCount>> categoriesWithCount() {
```
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. If you're using a custom query for updates or deletes with `customUpdate`, you should also
use the `updates` parameter to let moor know which tables you're touching.
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.

View File

@ -0,0 +1,10 @@
---
layout: feature
title: Table joins
parent: Writing queries
since: 1.3
permalink: /queries/joins
---
# Joins
TBD

View File

@ -1,9 +1,9 @@
---
layout: post
layout: guide
title: Writing queries
nav_order: 2
has_children: true
permalink: /writing-queries/
permalink: /queries/
---
__Note__: This assumes that you already have your database class ready.
@ -104,4 +104,4 @@ If a column is nullable or has a default value (this includes auto-increments),
can be omitted. All other fields must be set and non-null. The `insert` method will throw
otherwise.
[getting-started]: {{ "/getting-started" | absolute_url }}
[getting-started]: {{ site.common_links.getting_started | absolute_url }}

View File

@ -1,6 +1,7 @@
---
layout: home
title: Home
description: Moor is an easy to use, reactive persistence library for Flutter apps.
nav_order: 0
---
@ -15,7 +16,7 @@ and more!
[![Build Status](https://travis-ci.com/simolus3/moor.svg?token=u4VnFEE5xnWVvkE6QsqL&branch=master)](https://travis-ci.com/simolus3/moor)
[![codecov](https://codecov.io/gh/simolus3/moor/branch/master/graph/badge.svg)](https://codecov.io/gh/simolus3/moor)
[Get started now]({{site.url}}/getting-started/){: .btn .btn-green .fs-5 .mb-4 .mb-md-0 .mr-2 }
[Get started now]({{ site.common_links.getting_started | absolute_url }}){: .btn .btn-green .fs-5 .mb-4 .mb-md-0 .mr-2 }
[View on GitHub]({{site.github_link}}){: .btn .btn-outline .fs-5 .mb-4 .mb-md-0 .mr-2 }
---
@ -34,7 +35,7 @@ Please note that a workaround for most on this list exists with custom statement
### Planned for the future
These aren't sorted by priority. If you have more ideas or want some features happening soon,
let me know by creating an issue!
let me know by [creating an issue]({{site.github_link}}/issues/new)!
- Simple `COUNT(*)` operations (group operations will be much more complicated)
- Support Dart VM apps
- References