mirror of https://github.com/AMT-Cheif/drift.git
Remove fluttercommunity mentions for now, parse PK
This commit is contained in:
parent
0de6005ad7
commit
83f12a71b6
13
pubspec.yaml
13
pubspec.yaml
|
@ -1,13 +0,0 @@
|
||||||
# This pubspec file exists so that this repository can show up in the generated list of community
|
|
||||||
# repositories. It's not meant to serve as an actual pub file.
|
|
||||||
|
|
||||||
name: sally
|
|
||||||
description: Sally is a safe and reactive persistence library for Dart applications
|
|
||||||
homepage: https://github.com/simolus3/sally
|
|
||||||
authors:
|
|
||||||
- Flutter Community <community@flutter.zone>
|
|
||||||
- Simon Binder <simolus3@gmail.com>
|
|
||||||
maintainer: Simon Binder (@simolus3)
|
|
||||||
|
|
||||||
environment:
|
|
||||||
sdk: '>=2.0.0 <3.0.0'
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
import 'package:sally/sally.dart';
|
||||||
|
|
||||||
|
// Define tables that can model a database of recipes.
|
||||||
|
|
||||||
|
@DataClassName('Category')
|
||||||
|
class Categories extends Table {
|
||||||
|
IntColumn get id => integer().autoIncrement()();
|
||||||
|
TextColumn get description => text().nullable()();
|
||||||
|
}
|
||||||
|
|
||||||
|
class Recipes extends Table {
|
||||||
|
IntColumn get id => integer().autoIncrement()();
|
||||||
|
TextColumn get title => text().withLength(max: 16)();
|
||||||
|
TextColumn get instructions => text()();
|
||||||
|
IntColumn get category => integer().nullable()();
|
||||||
|
}
|
||||||
|
|
||||||
|
class Ingredients extends Table {
|
||||||
|
IntColumn get id => integer().autoIncrement()();
|
||||||
|
TextColumn get name => text()();
|
||||||
|
IntColumn get caloriesPer100g => integer().named('calories')();
|
||||||
|
}
|
||||||
|
|
||||||
|
class IngredientInRecipes extends Table {
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get tableName => 'recipe_ingredients';
|
||||||
|
|
||||||
|
// We can also specify custom primary keys
|
||||||
|
@override
|
||||||
|
Set<Column> get primaryKey => {recipe, ingredient};
|
||||||
|
|
||||||
|
IntColumn get recipe => integer().autoIncrement()();
|
||||||
|
IntColumn get ingredient => integer().autoIncrement()();
|
||||||
|
|
||||||
|
IntColumn get amountInGrams => integer().named('amount')();
|
||||||
|
}
|
|
@ -40,8 +40,8 @@ class ColumnBuilder<Builder, ResultColumn> {
|
||||||
/// `IntColumn get id = integer((c) => c.named('user_id'))`.
|
/// `IntColumn get id = integer((c) => c.named('user_id'))`.
|
||||||
Builder named(String name) => null;
|
Builder named(String name) => null;
|
||||||
|
|
||||||
/// Marks this column as being part of a primary key. This is not yet
|
@Deprecated('Ignored by the generator. Please override primaryKey in your '
|
||||||
/// supported by sally.
|
'table class instead')
|
||||||
Builder primaryKey() => null;
|
Builder primaryKey() => null;
|
||||||
|
|
||||||
/// Marks this column as nullable. Nullable columns should not appear in a
|
/// Marks this column as nullable. Nullable columns should not appear in a
|
||||||
|
|
|
@ -20,8 +20,7 @@ abstract class Table {
|
||||||
/// In the future, you can override this to specify a custom primary key. This
|
/// In the future, you can override this to specify a custom primary key. This
|
||||||
/// is not supported by sally at the moment.
|
/// is not supported by sally at the moment.
|
||||||
@visibleForOverriding
|
@visibleForOverriding
|
||||||
// todo allow custom primary key
|
Set<Column> get primaryKey => null;
|
||||||
PrimaryKey get primaryKey => null;
|
|
||||||
|
|
||||||
/// Use this as the body of a getter to declare a column that holds integers.
|
/// Use this as the body of a getter to declare a column that holds integers.
|
||||||
/// Example (inside the body of a table class):
|
/// Example (inside the body of a table class):
|
||||||
|
@ -57,8 +56,6 @@ abstract class Table {
|
||||||
DateTimeColumnBuilder dateTime() => null;
|
DateTimeColumnBuilder dateTime() => null;
|
||||||
}
|
}
|
||||||
|
|
||||||
class PrimaryKey {}
|
|
||||||
|
|
||||||
/// A class to to be used as an annotation on [Table] classes to customize the
|
/// A class to to be used as an annotation on [Table] classes to customize the
|
||||||
/// name for the data class that will be generated for the table class. The data
|
/// name for the data class that will be generated for the table class. The data
|
||||||
/// class is a dart object that will be used to represent a row in the table.
|
/// class is a dart object that will be used to represent a row in the table.
|
||||||
|
|
|
@ -3,7 +3,6 @@ description: Sally is a safe and reactive persistence library for Dart applicati
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
homepage: https://github.com/simolus3/sally
|
homepage: https://github.com/simolus3/sally
|
||||||
authors:
|
authors:
|
||||||
- Flutter Community <community@flutter.zone>
|
|
||||||
- Simon Binder <simolus3@gmail.com>
|
- Simon Binder <simolus3@gmail.com>
|
||||||
maintainer: Simon Binder (@simolus3)
|
maintainer: Simon Binder (@simolus3)
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ name: sally_flutter
|
||||||
description: Flutter implementation of sally, a safe and reactive persistence library for Dart applications
|
description: Flutter implementation of sally, a safe and reactive persistence library for Dart applications
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
authors:
|
authors:
|
||||||
- Flutter Community <community@flutter.zone>
|
|
||||||
- Simon Binder <simolus3@gmail.com>
|
- Simon Binder <simolus3@gmail.com>
|
||||||
maintainer: Simon Binder (@simolus3)
|
maintainer: Simon Binder (@simolus3)
|
||||||
|
|
||||||
|
|
|
@ -11,11 +11,13 @@ class SpecifiedTable {
|
||||||
|
|
||||||
String get tableInfoName => tableInfoNameForTableClass(fromClass);
|
String get tableInfoName => tableInfoNameForTableClass(fromClass);
|
||||||
|
|
||||||
// todo support primary keys
|
/// The set of primary keys, if they have been explicitly defined by
|
||||||
Set<SpecifiedColumn> get primaryKey => <SpecifiedColumn>{};
|
/// overriding `primaryKey` in the table class. `null` if the primary key has
|
||||||
|
/// not been defined that way.
|
||||||
|
final Set<SpecifiedColumn> primaryKey;
|
||||||
|
|
||||||
const SpecifiedTable(
|
const SpecifiedTable(
|
||||||
{this.fromClass, this.columns, this.sqlName, this.dartTypeName});
|
{this.fromClass, this.columns, this.sqlName, this.dartTypeName, this.primaryKey});
|
||||||
}
|
}
|
||||||
|
|
||||||
String tableInfoNameForTableClass(ClassElement fromClass) =>
|
String tableInfoNameForTableClass(ClassElement fromClass) =>
|
||||||
|
|
|
@ -17,11 +17,15 @@ class TableParser extends ParserBase {
|
||||||
final sqlName = _parseTableName(element);
|
final sqlName = _parseTableName(element);
|
||||||
if (sqlName == null) return null;
|
if (sqlName == null) return null;
|
||||||
|
|
||||||
|
final columns = _parseColumns(element);
|
||||||
|
|
||||||
return SpecifiedTable(
|
return SpecifiedTable(
|
||||||
fromClass: element,
|
fromClass: element,
|
||||||
columns: _parseColumns(element),
|
columns: columns,
|
||||||
sqlName: escapeIfNeeded(sqlName),
|
sqlName: escapeIfNeeded(sqlName),
|
||||||
dartTypeName: _readDartTypeName(element));
|
dartTypeName: _readDartTypeName(element),
|
||||||
|
primaryKey: _readPrimaryKey(element, columns),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
String _readDartTypeName(ClassElement element) {
|
String _readDartTypeName(ClassElement element) {
|
||||||
|
@ -64,6 +68,39 @@ class TableParser extends ParserBase {
|
||||||
return tableName;
|
return tableName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Set<SpecifiedColumn> _readPrimaryKey(ClassElement element, List<SpecifiedColumn> columns) {
|
||||||
|
final primaryKeyGetter = element.getGetter('primaryKey');
|
||||||
|
if (primaryKeyGetter == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final ast = generator.loadElementDeclaration(primaryKeyGetter).node as MethodDeclaration;
|
||||||
|
final body = ast.body;
|
||||||
|
if (body is! ExpressionFunctionBody) {
|
||||||
|
generator.errors.add(SallyError(affectedElement: primaryKeyGetter, message: 'This must return a set literal using the => syntax!'));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final expression = (body as ExpressionFunctionBody).expression;
|
||||||
|
// set expressions {x, y} are parsed as map literals whose values are an empty
|
||||||
|
// identifier {x: , y: }. yeah.
|
||||||
|
// todo should we support MapLiteral2 to support the experiments discussed there?
|
||||||
|
if (expression is! MapLiteral) {
|
||||||
|
generator.errors.add(SallyError(affectedElement: primaryKeyGetter, message: 'This must return a set literal!'));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final mapLiteral = expression as MapLiteral;
|
||||||
|
|
||||||
|
final parsedPrimaryKey = <SpecifiedColumn>{};
|
||||||
|
|
||||||
|
for (var entry in mapLiteral.entries) {
|
||||||
|
final key = entry.key as Identifier;
|
||||||
|
final column = columns.singleWhere((column) => column.dartGetterName == key.name);
|
||||||
|
parsedPrimaryKey.add(column);
|
||||||
|
}
|
||||||
|
|
||||||
|
return parsedPrimaryKey;
|
||||||
|
}
|
||||||
|
|
||||||
Iterable<MethodDeclaration> _findColumnGetters(ClassElement element) {
|
Iterable<MethodDeclaration> _findColumnGetters(ClassElement element) {
|
||||||
return element.fields
|
return element.fields
|
||||||
.where((field) => isColumn(field.type) && field.getter != null)
|
.where((field) => isColumn(field.type) && field.getter != null)
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
name: sally_generator
|
name: sally_generator
|
||||||
description: Sally generator generated database code from your table classes
|
description: Sally generator generates database code from your table classes
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
homepage: https://github.com/simolus3/sally
|
homepage: https://github.com/simolus3/sally
|
||||||
authors:
|
authors:
|
||||||
- Flutter Community <community@flutter.zone>
|
|
||||||
- Simon Binder <simolus3@gmail.com>
|
- Simon Binder <simolus3@gmail.com>
|
||||||
maintainer: Simon Binder (@simolus3)
|
maintainer: Simon Binder (@simolus3)
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,14 @@ void main() async {
|
||||||
TextColumn get onlyMax => text().withLength(max: 100)();
|
TextColumn get onlyMax => text().withLength(max: 100)();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class CustomPrimaryKey extends Table {
|
||||||
|
IntColumn get partA => integer()();
|
||||||
|
IntColumn get partB => integer()();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Set<Column> get primaryKey => {partA, partB};
|
||||||
|
}
|
||||||
|
|
||||||
class WrongName extends Table {
|
class WrongName extends Table {
|
||||||
|
|
||||||
String constructTableName() {
|
String constructTableName() {
|
||||||
|
@ -34,7 +42,7 @@ void main() async {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get tableName => constructTableName();"
|
String get tableName => constructTableName();
|
||||||
}
|
}
|
||||||
''', (r) => r.findLibraryByName('test_parser'));
|
''', (r) => r.findLibraryByName('test_parser'));
|
||||||
});
|
});
|
||||||
|
@ -102,4 +110,10 @@ void main() async {
|
||||||
idColumn.features, contains(LimitingTextLength.withLength(max: 100)));
|
idColumn.features, contains(LimitingTextLength.withLength(max: 100)));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('parses custom primary keys', () {
|
||||||
|
final table = TableParser(generator).parse(testLib.getType('CustomPrimaryKey'));
|
||||||
|
|
||||||
|
expect(table.primaryKey, containsAll(table.columns));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue