mirror of https://github.com/AMT-Cheif/drift.git
Add README
This commit is contained in:
parent
e93f98e26c
commit
a0b6053172
125
README.md
125
README.md
|
@ -1,22 +1,127 @@
|
|||
A library for Dart developers.
|
||||
# Sally
|
||||
[](https://travis-ci.com/simolus3/sally)
|
||||
|
||||
Created from templates made available by Stagehand under a BSD-style
|
||||
[license](https://github.com/dart-lang/stagehand/blob/master/LICENSE).
|
||||
Sally is an easy to use and safe way to persist data for Flutter apps. It features
|
||||
a fluent Dart DSL to describe tables and will generate matching database code that
|
||||
can be used to easily read and store your app's data.
|
||||
|
||||
## Usage
|
||||
__Note:__ This library is in development and not yet available for general use on `pub`.
|
||||
|
||||
A simple usage example:
|
||||
## Using this library
|
||||
#### Adding the dependency
|
||||
First, let's add sally to your prooject's `pubspec.yaml`:
|
||||
```yaml
|
||||
dependencies:
|
||||
sally:
|
||||
git:
|
||||
url:
|
||||
path: sally/
|
||||
|
||||
dev_dependencies:
|
||||
sally_generator:
|
||||
git:
|
||||
url:
|
||||
path: sally_generator/
|
||||
build_runner:
|
||||
```
|
||||
We're going to use the `sally` library to specify tables and write data. The
|
||||
`sally_generator` library will take care of generating the necessary code so the
|
||||
library knows how your table structure looks like.
|
||||
|
||||
#### Declaring tables
|
||||
You can use the DSL included with this library to specify your libraries with simple
|
||||
dart code:
|
||||
```dart
|
||||
import 'package:sally/sally.dart';
|
||||
|
||||
main() {
|
||||
var awesome = new Awesome();
|
||||
// assuming that your file is called filename.dart. This will give an error at first,
|
||||
// but it's needed for sally to know about the generated code
|
||||
part 'filename.g.dart';
|
||||
|
||||
class Todos extends Table {
|
||||
IntColumn get id => integer().autoIncrement()();
|
||||
TextColumn get name => text().withLength(min: 6, max: 10)();
|
||||
TextColumn get content => text().named('body')();
|
||||
IntColumn get category => integer()();
|
||||
}
|
||||
|
||||
class Categories extends Table {
|
||||
@override
|
||||
String get tableName => 'todo_categories';
|
||||
|
||||
IntColumn get id => integer().autoIncrement()();
|
||||
TextColumn get description => text()();
|
||||
}
|
||||
|
||||
@UseSally(tables: [Todos, Categories])
|
||||
class MyDatabase {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## Features and bugs
|
||||
__⚠️ Warning:__ Even though it might look like it, the content of a `Table` class does not support full Dart code. It can only
|
||||
be used to declare the table name, it's primary keys and columns. The code inside of a table class will never be
|
||||
executed. Instead, the generator will take a look at your table classes to figure out how their structure looks like.
|
||||
This won't work if the body of your tables is not constant. This should not be problem, but please be aware of this.
|
||||
|
||||
Please file feature requests and bugs at the [issue tracker][tracker].
|
||||
#### Generating the code
|
||||
Sally integrates with the dart `build` system, so you can generate all the code needed with
|
||||
`flutter packages pub run build_runner build`. If you want to continously rebuild the code
|
||||
whever you change your code, run `flutter packages pub run build_runner watch` instead.
|
||||
After running either command once, sally 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
|
||||
@UseSally(tables: [Todos, Categories])
|
||||
class MyDatabase extends _$MyDatabase {
|
||||
@override
|
||||
int get schemaVersion => 1;
|
||||
@override
|
||||
MigrationStrategy get migration => MigrationStrategy();
|
||||
}
|
||||
```
|
||||
You can ignore these two getters there at the moment, the imporant part is that you can
|
||||
now run your queries with fluent Dart code:
|
||||
```dart
|
||||
class MyDatabase extends _$MyDatabase {
|
||||
// .. the getters that have been defined above still need to be here
|
||||
|
||||
[tracker]: http://example.com/issues/replaceme
|
||||
Future<List<Todo>> get allTodoEntries => select(todos).get();
|
||||
|
||||
Future<void> deleteCategory(Category toDelete) async {
|
||||
await (delete(todos)..where((entry) => entry.category.equalsVal(category.id))).go();
|
||||
await (delete(categories)..where((cat) => cat.id.equalsVal(toDelete.id))).go();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## TODO-List
|
||||
If you have suggestions for new features or any other questions, feel free to
|
||||
create an issue.
|
||||
|
||||
##### Before this library can be released
|
||||
- Insert and update statements
|
||||
- Custom primary keys
|
||||
- Stabilize all end-user APIs
|
||||
- Support default values and expressions, auto-increment
|
||||
- Implement `==` and `hashCode` in data classes
|
||||
- Allow custom table names for the generated dart types
|
||||
##### Definitely planned for the future
|
||||
- Allow using DAOs instead of having to put everything in the main database
|
||||
class.
|
||||
- Auto-updating streams
|
||||
- Support more Datatypes: We should at least support `DateTime` and `Uint8List`,
|
||||
supporting floating point numbers as well would be awesome
|
||||
- Nullable / non-nullable datatypes
|
||||
- DSL API
|
||||
- Support in generator
|
||||
- Use in queries (`IS NOT NULL`)
|
||||
- Verify constraints (text length, nullability, etc.) before inserting or
|
||||
deleting data.
|
||||
- Support Dart VM apps
|
||||
- References
|
||||
- Table joins
|
||||
##### Interesting stuff that would be nice to have
|
||||
- `GROUP BY` grouping functions
|
||||
- Support for different database engines
|
||||
- Support webapps via `AlaSQL` or a different engine
|
|
@ -12,7 +12,15 @@ class Users extends Table {
|
|||
TextColumn get name => text().withLength(min: 6, max: 32)();
|
||||
}
|
||||
|
||||
@UseSally(tables: [Products, Users])
|
||||
class Todos extends Table {
|
||||
|
||||
IntColumn get id => integer().autoIncrement()();
|
||||
TextColumn get name => text().withLength(min: 6, max: 10)();
|
||||
TextColumn get content => text().named('body')();
|
||||
|
||||
}
|
||||
|
||||
@UseSally(tables: [Products, Users, Todos])
|
||||
class ShopDb extends _$ShopDb {
|
||||
Future<List<User>> allUsers() => select(users).get();
|
||||
Future<List<User>> userByName(String name) =>
|
||||
|
|
|
@ -70,10 +70,47 @@ class _$UsersTable extends Users implements TableInfo<Users, User> {
|
|||
}
|
||||
}
|
||||
|
||||
class Todo {
|
||||
final int id;
|
||||
final String name;
|
||||
final String content;
|
||||
Todo({this.id, this.name, this.content});
|
||||
}
|
||||
|
||||
class _$TodosTable extends Todos implements TableInfo<Todos, Todo> {
|
||||
final GeneratedDatabase db;
|
||||
_$TodosTable(this.db);
|
||||
@override
|
||||
GeneratedIntColumn get id => GeneratedIntColumn('id', false);
|
||||
@override
|
||||
GeneratedTextColumn get name => GeneratedTextColumn('name', false);
|
||||
@override
|
||||
GeneratedTextColumn get content => GeneratedTextColumn('content', false);
|
||||
@override
|
||||
List<GeneratedColumn> get $columns => [id, name, content];
|
||||
@override
|
||||
Todos get asDslTable => this;
|
||||
@override
|
||||
String get $tableName => 'todos';
|
||||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => Set();
|
||||
@override
|
||||
Todo map(Map<String, dynamic> data) {
|
||||
final intType = db.typeSystem.forDartType<int>();
|
||||
final stringType = db.typeSystem.forDartType<String>();
|
||||
return Todo(
|
||||
id: intType.mapFromDatabaseResponse(data['id']),
|
||||
name: stringType.mapFromDatabaseResponse(data['name']),
|
||||
content: stringType.mapFromDatabaseResponse(data['content']),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _$ShopDb extends GeneratedDatabase {
|
||||
_$ShopDb() : super(const SqlTypeSystem.withDefaults(), null);
|
||||
_$ProductsTable get products => _$ProductsTable(this);
|
||||
_$UsersTable get users => _$UsersTable(this);
|
||||
_$TodosTable get todos => _$TodosTable(this);
|
||||
@override
|
||||
List<TableInfo> get allTables => [products, users];
|
||||
List<TableInfo> get allTables => [products, users, todos];
|
||||
}
|
||||
|
|
|
@ -44,7 +44,8 @@ class StringType extends SqlType<String> {
|
|||
|
||||
@override
|
||||
String mapToSqlConstant(String content) {
|
||||
// TODO: implement mapToSqlConstant
|
||||
// TODO: implement mapToSqlConstant, we would probably have to take care
|
||||
// of sql injection vulnerabilities here
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
#!/bin/bash
|
||||
|
||||
rm -f example/LICENSE
|
||||
rm -f sally/LICENSE
|
||||
rm -f sally_flutter/LICENSE
|
||||
rm -f sally_generator/LICENSE
|
||||
|
||||
cp LICENSE example/LICENSE
|
||||
cp LICENSE sally/LICENSE
|
||||
cp LICENSE sally_flutter/LICENSE
|
||||
cp LICENSE sally_generator/LICENSE
|
Loading…
Reference in New Issue