mirror of https://github.com/AMT-Cheif/drift.git
Merge branch 'develop' into delightful-queries
This commit is contained in:
commit
2a5ede1c04
|
@ -27,7 +27,7 @@ part 'filename.g.dart';
|
|||
// be represented by a class called "Todo".
|
||||
class Todos extends Table {
|
||||
IntColumn get id => integer().autoIncrement()();
|
||||
TextColumn get title => text().withLength(min: 6, max: 10)();
|
||||
TextColumn get title => text().withLength(min: 6, max: 32)();
|
||||
TextColumn get content => text().named('body')();
|
||||
IntColumn get category => integer().nullable()();
|
||||
}
|
||||
|
|
|
@ -64,6 +64,7 @@ class $CategoriesTable extends Categories
|
|||
final GeneratedDatabase _db;
|
||||
final String _alias;
|
||||
$CategoriesTable(this._db, [this._alias]);
|
||||
final VerificationMeta _idMeta = const VerificationMeta('id');
|
||||
GeneratedIntColumn _id;
|
||||
@override
|
||||
GeneratedIntColumn get id => _id ??= _constructId();
|
||||
|
@ -71,6 +72,8 @@ class $CategoriesTable extends Categories
|
|||
return GeneratedIntColumn('id', $tableName, false, hasAutoIncrement: true);
|
||||
}
|
||||
|
||||
final VerificationMeta _descriptionMeta =
|
||||
const VerificationMeta('description');
|
||||
GeneratedTextColumn _description;
|
||||
@override
|
||||
GeneratedTextColumn get description =>
|
||||
|
@ -92,9 +95,14 @@ class $CategoriesTable extends Categories
|
|||
@override
|
||||
final String actualTableName = 'categories';
|
||||
@override
|
||||
bool validateIntegrity(Category instance, bool isInserting) =>
|
||||
id.isAcceptableValue(instance.id, isInserting) &&
|
||||
description.isAcceptableValue(instance.description, isInserting);
|
||||
VerificationContext validateIntegrity(Category instance, bool isInserting) =>
|
||||
VerificationContext()
|
||||
..handle(
|
||||
_idMeta, id.isAcceptableValue(instance.id, isInserting, _idMeta))
|
||||
..handle(
|
||||
_descriptionMeta,
|
||||
description.isAcceptableValue(
|
||||
instance.description, isInserting, _descriptionMeta));
|
||||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {id};
|
||||
@override
|
||||
|
@ -199,6 +207,7 @@ class $RecipesTable extends Recipes with TableInfo<$RecipesTable, Recipe> {
|
|||
final GeneratedDatabase _db;
|
||||
final String _alias;
|
||||
$RecipesTable(this._db, [this._alias]);
|
||||
final VerificationMeta _idMeta = const VerificationMeta('id');
|
||||
GeneratedIntColumn _id;
|
||||
@override
|
||||
GeneratedIntColumn get id => _id ??= _constructId();
|
||||
|
@ -206,6 +215,7 @@ class $RecipesTable extends Recipes with TableInfo<$RecipesTable, Recipe> {
|
|||
return GeneratedIntColumn('id', $tableName, false, hasAutoIncrement: true);
|
||||
}
|
||||
|
||||
final VerificationMeta _titleMeta = const VerificationMeta('title');
|
||||
GeneratedTextColumn _title;
|
||||
@override
|
||||
GeneratedTextColumn get title => _title ??= _constructTitle();
|
||||
|
@ -213,6 +223,8 @@ class $RecipesTable extends Recipes with TableInfo<$RecipesTable, Recipe> {
|
|||
return GeneratedTextColumn('title', $tableName, false, maxTextLength: 16);
|
||||
}
|
||||
|
||||
final VerificationMeta _instructionsMeta =
|
||||
const VerificationMeta('instructions');
|
||||
GeneratedTextColumn _instructions;
|
||||
@override
|
||||
GeneratedTextColumn get instructions =>
|
||||
|
@ -225,6 +237,7 @@ class $RecipesTable extends Recipes with TableInfo<$RecipesTable, Recipe> {
|
|||
);
|
||||
}
|
||||
|
||||
final VerificationMeta _categoryMeta = const VerificationMeta('category');
|
||||
GeneratedIntColumn _category;
|
||||
@override
|
||||
GeneratedIntColumn get category => _category ??= _constructCategory();
|
||||
|
@ -245,11 +258,20 @@ class $RecipesTable extends Recipes with TableInfo<$RecipesTable, Recipe> {
|
|||
@override
|
||||
final String actualTableName = 'recipes';
|
||||
@override
|
||||
bool validateIntegrity(Recipe instance, bool isInserting) =>
|
||||
id.isAcceptableValue(instance.id, isInserting) &&
|
||||
title.isAcceptableValue(instance.title, isInserting) &&
|
||||
instructions.isAcceptableValue(instance.instructions, isInserting) &&
|
||||
category.isAcceptableValue(instance.category, isInserting);
|
||||
VerificationContext validateIntegrity(Recipe instance, bool isInserting) =>
|
||||
VerificationContext()
|
||||
..handle(
|
||||
_idMeta, id.isAcceptableValue(instance.id, isInserting, _idMeta))
|
||||
..handle(_titleMeta,
|
||||
title.isAcceptableValue(instance.title, isInserting, _titleMeta))
|
||||
..handle(
|
||||
_instructionsMeta,
|
||||
instructions.isAcceptableValue(
|
||||
instance.instructions, isInserting, _instructionsMeta))
|
||||
..handle(
|
||||
_categoryMeta,
|
||||
category.isAcceptableValue(
|
||||
instance.category, isInserting, _categoryMeta));
|
||||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {id};
|
||||
@override
|
||||
|
@ -349,6 +371,7 @@ class $IngredientsTable extends Ingredients
|
|||
final GeneratedDatabase _db;
|
||||
final String _alias;
|
||||
$IngredientsTable(this._db, [this._alias]);
|
||||
final VerificationMeta _idMeta = const VerificationMeta('id');
|
||||
GeneratedIntColumn _id;
|
||||
@override
|
||||
GeneratedIntColumn get id => _id ??= _constructId();
|
||||
|
@ -356,6 +379,7 @@ class $IngredientsTable extends Ingredients
|
|||
return GeneratedIntColumn('id', $tableName, false, hasAutoIncrement: true);
|
||||
}
|
||||
|
||||
final VerificationMeta _nameMeta = const VerificationMeta('name');
|
||||
GeneratedTextColumn _name;
|
||||
@override
|
||||
GeneratedTextColumn get name => _name ??= _constructName();
|
||||
|
@ -367,6 +391,8 @@ class $IngredientsTable extends Ingredients
|
|||
);
|
||||
}
|
||||
|
||||
final VerificationMeta _caloriesPer100gMeta =
|
||||
const VerificationMeta('caloriesPer100g');
|
||||
GeneratedIntColumn _caloriesPer100g;
|
||||
@override
|
||||
GeneratedIntColumn get caloriesPer100g =>
|
||||
|
@ -388,10 +414,17 @@ class $IngredientsTable extends Ingredients
|
|||
@override
|
||||
final String actualTableName = 'ingredients';
|
||||
@override
|
||||
bool validateIntegrity(Ingredient instance, bool isInserting) =>
|
||||
id.isAcceptableValue(instance.id, isInserting) &&
|
||||
name.isAcceptableValue(instance.name, isInserting) &&
|
||||
caloriesPer100g.isAcceptableValue(instance.caloriesPer100g, isInserting);
|
||||
VerificationContext validateIntegrity(
|
||||
Ingredient instance, bool isInserting) =>
|
||||
VerificationContext()
|
||||
..handle(
|
||||
_idMeta, id.isAcceptableValue(instance.id, isInserting, _idMeta))
|
||||
..handle(_nameMeta,
|
||||
name.isAcceptableValue(instance.name, isInserting, _nameMeta))
|
||||
..handle(
|
||||
_caloriesPer100gMeta,
|
||||
caloriesPer100g.isAcceptableValue(
|
||||
instance.caloriesPer100g, isInserting, _caloriesPer100gMeta));
|
||||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {id};
|
||||
@override
|
||||
|
@ -492,6 +525,7 @@ class $IngredientInRecipesTable extends IngredientInRecipes
|
|||
final GeneratedDatabase _db;
|
||||
final String _alias;
|
||||
$IngredientInRecipesTable(this._db, [this._alias]);
|
||||
final VerificationMeta _recipeMeta = const VerificationMeta('recipe');
|
||||
GeneratedIntColumn _recipe;
|
||||
@override
|
||||
GeneratedIntColumn get recipe => _recipe ??= _constructRecipe();
|
||||
|
@ -503,6 +537,7 @@ class $IngredientInRecipesTable extends IngredientInRecipes
|
|||
);
|
||||
}
|
||||
|
||||
final VerificationMeta _ingredientMeta = const VerificationMeta('ingredient');
|
||||
GeneratedIntColumn _ingredient;
|
||||
@override
|
||||
GeneratedIntColumn get ingredient => _ingredient ??= _constructIngredient();
|
||||
|
@ -514,6 +549,8 @@ class $IngredientInRecipesTable extends IngredientInRecipes
|
|||
);
|
||||
}
|
||||
|
||||
final VerificationMeta _amountInGramsMeta =
|
||||
const VerificationMeta('amountInGrams');
|
||||
GeneratedIntColumn _amountInGrams;
|
||||
@override
|
||||
GeneratedIntColumn get amountInGrams =>
|
||||
|
@ -535,10 +572,19 @@ class $IngredientInRecipesTable extends IngredientInRecipes
|
|||
@override
|
||||
final String actualTableName = 'recipe_ingredients';
|
||||
@override
|
||||
bool validateIntegrity(IngredientInRecipe instance, bool isInserting) =>
|
||||
recipe.isAcceptableValue(instance.recipe, isInserting) &&
|
||||
ingredient.isAcceptableValue(instance.ingredient, isInserting) &&
|
||||
amountInGrams.isAcceptableValue(instance.amountInGrams, isInserting);
|
||||
VerificationContext validateIntegrity(
|
||||
IngredientInRecipe instance, bool isInserting) =>
|
||||
VerificationContext()
|
||||
..handle(_recipeMeta,
|
||||
recipe.isAcceptableValue(instance.recipe, isInserting, _recipeMeta))
|
||||
..handle(
|
||||
_ingredientMeta,
|
||||
ingredient.isAcceptableValue(
|
||||
instance.ingredient, isInserting, _ingredientMeta))
|
||||
..handle(
|
||||
_amountInGramsMeta,
|
||||
amountInGrams.isAcceptableValue(
|
||||
instance.amountInGrams, isInserting, _amountInGramsMeta));
|
||||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {recipe, ingredient};
|
||||
@override
|
||||
|
|
|
@ -21,6 +21,7 @@ export 'package:moor/src/runtime/statements/select.dart';
|
|||
export 'package:moor/src/runtime/statements/insert.dart';
|
||||
export 'package:moor/src/runtime/statements/delete.dart';
|
||||
export 'package:moor/src/runtime/structure/columns.dart';
|
||||
export 'package:moor/src/runtime/structure/error_handling.dart';
|
||||
export 'package:moor/src/runtime/structure/table_info.dart';
|
||||
export 'package:moor/src/runtime/data_class.dart';
|
||||
export 'package:moor/src/runtime/database.dart';
|
||||
|
|
|
@ -116,9 +116,7 @@ class InsertStatement<DataClass> {
|
|||
throw InvalidDataException(
|
||||
'Cannot writee null row into ${table.$tableName}');
|
||||
}
|
||||
if (!table.validateIntegrity(d, true)) {
|
||||
throw InvalidDataException(
|
||||
'Invalid data: $d cannot be written into ${table.$tableName}');
|
||||
}
|
||||
|
||||
table.validateIntegrity(d, true).throwIfInvalid(d);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,10 +56,7 @@ class UpdateStatement<T extends Table, D> extends Query<T, D>
|
|||
/// See also: [replace], which does not require [where] statements and
|
||||
/// supports setting fields back to null.
|
||||
Future<int> write(D entity) async {
|
||||
if (!table.validateIntegrity(entity, false)) {
|
||||
throw InvalidDataException(
|
||||
'Invalid data: $entity cannot be written into ${table.$tableName}');
|
||||
}
|
||||
table.validateIntegrity(entity, false).throwIfInvalid(entity);
|
||||
|
||||
_updatedFields = table.entityToSql(entity)
|
||||
..remove((_, value) => value == null);
|
||||
|
@ -93,10 +90,7 @@ class UpdateStatement<T extends Table, D> extends Query<T, D>
|
|||
// because all the fields from the entity will be written (as opposed to a
|
||||
// regular update, where only non-null fields will be written). If isInserted
|
||||
// was false, the null fields would not be validated.
|
||||
if (!table.validateIntegrity(entity, true)) {
|
||||
throw InvalidDataException('Invalid data: $entity cannot be used to '
|
||||
'replace another row as some required fields are null or invalid.');
|
||||
}
|
||||
table.validateIntegrity(entity, true).throwIfInvalid(entity);
|
||||
assert(
|
||||
whereExpr == null,
|
||||
'When using replace on an update statement, you may not use where(...)'
|
||||
|
|
|
@ -9,6 +9,12 @@ import 'package:moor/src/runtime/expressions/variables.dart';
|
|||
import 'package:moor/src/types/sql_types.dart';
|
||||
import 'package:moor/sqlite_keywords.dart';
|
||||
|
||||
import 'error_handling.dart';
|
||||
|
||||
const VerificationResult _invalidNull = VerificationResult.failure(
|
||||
"This column is not nullable and doesn't have a default value. "
|
||||
"Null fields thus can't be inserted.");
|
||||
|
||||
/// Base class for the implementation of [Column].
|
||||
abstract class GeneratedColumn<T, S extends SqlType<T>> extends Column<T, S> {
|
||||
/// The sql name of this column.
|
||||
|
@ -84,9 +90,14 @@ abstract class GeneratedColumn<T, S extends SqlType<T>> extends Column<T, S> {
|
|||
/// method should check whether the value is valid for an update. Null values
|
||||
/// should always be accepted for updates, as the describe a value that should
|
||||
/// not be replaced.
|
||||
bool isAcceptableValue(T value, bool duringInsert) {
|
||||
VerificationResult isAcceptableValue(
|
||||
T value, bool duringInsert, VerificationMeta meta) {
|
||||
final nullOk = !duringInsert || $nullable || defaultValue != null;
|
||||
return nullOk || value != null;
|
||||
if (!nullOk && value == null) {
|
||||
return _invalidNull;
|
||||
} else {
|
||||
return const VerificationResult.success();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -114,15 +125,22 @@ class GeneratedTextColumn extends GeneratedColumn<String, StringType>
|
|||
final String typeName = 'VARCHAR';
|
||||
|
||||
@override
|
||||
bool isAcceptableValue(String value, bool duringInsert) {
|
||||
VerificationResult isAcceptableValue(
|
||||
String value, bool duringInsert, VerificationMeta meta) {
|
||||
// handle nullability check in common column
|
||||
if (value == null) return super.isAcceptableValue(null, duringInsert);
|
||||
if (value == null) return super.isAcceptableValue(null, duringInsert, meta);
|
||||
|
||||
final length = value.length;
|
||||
if (minTextLength != null && minTextLength > length) return false;
|
||||
if (maxTextLength != null && maxTextLength < length) return false;
|
||||
if (minTextLength != null && minTextLength > length) {
|
||||
return VerificationResult.failure(
|
||||
'Must at least be $minTextLength characters long.');
|
||||
}
|
||||
if (maxTextLength != null && maxTextLength < length) {
|
||||
return VerificationResult.failure(
|
||||
'Must at most be $maxTextLength characters long.');
|
||||
}
|
||||
|
||||
return true;
|
||||
return const VerificationResult.success();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -171,8 +189,13 @@ class GeneratedIntColumn extends GeneratedColumn<int, IntType>
|
|||
}
|
||||
|
||||
@override
|
||||
bool isAcceptableValue(int value, bool duringInsert) =>
|
||||
hasAutoIncrement || super.isAcceptableValue(value, duringInsert);
|
||||
VerificationResult isAcceptableValue(
|
||||
int value, bool duringInsert, VerificationMeta meta) {
|
||||
if (hasAutoIncrement) {
|
||||
return const VerificationResult.success();
|
||||
}
|
||||
return super.isAcceptableValue(value, duringInsert, meta);
|
||||
}
|
||||
}
|
||||
|
||||
class GeneratedDateTimeColumn extends GeneratedColumn<DateTime, DateTimeType>
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
import 'package:moor/moor.dart';
|
||||
|
||||
/// Additional information that is passed to [GeneratedColumn]s when verifying
|
||||
/// data to provide more helpful error messages.
|
||||
class VerificationMeta {
|
||||
/// The dart getter name of the property being validated.
|
||||
final String dartGetterName;
|
||||
|
||||
const VerificationMeta(this.dartGetterName);
|
||||
}
|
||||
|
||||
/// Returned by [GeneratedColumn.isAcceptableValue] to provide a description
|
||||
/// when a valid is invalid.
|
||||
class VerificationResult {
|
||||
final bool success;
|
||||
final String message;
|
||||
|
||||
const VerificationResult(this.success, this.message);
|
||||
const VerificationResult.success()
|
||||
: success = true,
|
||||
message = null;
|
||||
const VerificationResult.failure(this.message) : success = false;
|
||||
}
|
||||
|
||||
class VerificationContext {
|
||||
final Map<VerificationMeta, VerificationResult> _errors = {};
|
||||
|
||||
bool get dataValid => _errors.isEmpty;
|
||||
|
||||
void handle(VerificationMeta meta, VerificationResult result) {
|
||||
if (!result.success) {
|
||||
_errors[meta] = result;
|
||||
}
|
||||
}
|
||||
|
||||
void throwIfInvalid(dynamic dataObject) {
|
||||
if (dataValid) return;
|
||||
|
||||
final messageBuilder =
|
||||
StringBuffer('Sorry, $dataObject cannot be used for that because: \n');
|
||||
|
||||
_errors.forEach((meta, result) {
|
||||
messageBuilder.write('• ${meta.dartGetterName}: ${result.message}\n');
|
||||
});
|
||||
|
||||
throw InvalidDataException(messageBuilder.toString());
|
||||
}
|
||||
}
|
|
@ -38,7 +38,7 @@ mixin TableInfo<TableDsl extends Table, DataClass> {
|
|||
/// that it respects all constraints (nullability, text length, etc.).
|
||||
/// During insertion mode, fields that have a default value or are
|
||||
/// auto-incrementing are allowed to be null as they will be set by sqlite.
|
||||
bool validateIntegrity(DataClass instance, bool isInserting);
|
||||
VerificationContext validateIntegrity(DataClass instance, bool isInserting);
|
||||
|
||||
/// Maps the given data class to a [Map] that can be inserted into sql. The
|
||||
/// keys should represent the column name in sql, the values the corresponding
|
||||
|
|
|
@ -102,6 +102,7 @@ class $TodosTableTable extends TodosTable
|
|||
final GeneratedDatabase _db;
|
||||
final String _alias;
|
||||
$TodosTableTable(this._db, [this._alias]);
|
||||
final VerificationMeta _idMeta = const VerificationMeta('id');
|
||||
GeneratedIntColumn _id;
|
||||
@override
|
||||
GeneratedIntColumn get id => _id ??= _constructId();
|
||||
|
@ -109,6 +110,7 @@ class $TodosTableTable extends TodosTable
|
|||
return GeneratedIntColumn('id', $tableName, false, hasAutoIncrement: true);
|
||||
}
|
||||
|
||||
final VerificationMeta _titleMeta = const VerificationMeta('title');
|
||||
GeneratedTextColumn _title;
|
||||
@override
|
||||
GeneratedTextColumn get title => _title ??= _constructTitle();
|
||||
|
@ -117,6 +119,7 @@ class $TodosTableTable extends TodosTable
|
|||
minTextLength: 4, maxTextLength: 16);
|
||||
}
|
||||
|
||||
final VerificationMeta _contentMeta = const VerificationMeta('content');
|
||||
GeneratedTextColumn _content;
|
||||
@override
|
||||
GeneratedTextColumn get content => _content ??= _constructContent();
|
||||
|
@ -128,6 +131,7 @@ class $TodosTableTable extends TodosTable
|
|||
);
|
||||
}
|
||||
|
||||
final VerificationMeta _targetDateMeta = const VerificationMeta('targetDate');
|
||||
GeneratedDateTimeColumn _targetDate;
|
||||
@override
|
||||
GeneratedDateTimeColumn get targetDate =>
|
||||
|
@ -140,6 +144,7 @@ class $TodosTableTable extends TodosTable
|
|||
);
|
||||
}
|
||||
|
||||
final VerificationMeta _categoryMeta = const VerificationMeta('category');
|
||||
GeneratedIntColumn _category;
|
||||
@override
|
||||
GeneratedIntColumn get category => _category ??= _constructCategory();
|
||||
|
@ -161,12 +166,24 @@ class $TodosTableTable extends TodosTable
|
|||
@override
|
||||
final String actualTableName = 'todos';
|
||||
@override
|
||||
bool validateIntegrity(TodoEntry instance, bool isInserting) =>
|
||||
id.isAcceptableValue(instance.id, isInserting) &&
|
||||
title.isAcceptableValue(instance.title, isInserting) &&
|
||||
content.isAcceptableValue(instance.content, isInserting) &&
|
||||
targetDate.isAcceptableValue(instance.targetDate, isInserting) &&
|
||||
category.isAcceptableValue(instance.category, isInserting);
|
||||
VerificationContext validateIntegrity(TodoEntry instance, bool isInserting) =>
|
||||
VerificationContext()
|
||||
..handle(
|
||||
_idMeta, id.isAcceptableValue(instance.id, isInserting, _idMeta))
|
||||
..handle(_titleMeta,
|
||||
title.isAcceptableValue(instance.title, isInserting, _titleMeta))
|
||||
..handle(
|
||||
_contentMeta,
|
||||
content.isAcceptableValue(
|
||||
instance.content, isInserting, _contentMeta))
|
||||
..handle(
|
||||
_targetDateMeta,
|
||||
targetDate.isAcceptableValue(
|
||||
instance.targetDate, isInserting, _targetDateMeta))
|
||||
..handle(
|
||||
_categoryMeta,
|
||||
category.isAcceptableValue(
|
||||
instance.category, isInserting, _categoryMeta));
|
||||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {id};
|
||||
@override
|
||||
|
@ -259,6 +276,7 @@ class $CategoriesTable extends Categories
|
|||
final GeneratedDatabase _db;
|
||||
final String _alias;
|
||||
$CategoriesTable(this._db, [this._alias]);
|
||||
final VerificationMeta _idMeta = const VerificationMeta('id');
|
||||
GeneratedIntColumn _id;
|
||||
@override
|
||||
GeneratedIntColumn get id => _id ??= _constructId();
|
||||
|
@ -266,6 +284,8 @@ class $CategoriesTable extends Categories
|
|||
return GeneratedIntColumn('id', $tableName, false, hasAutoIncrement: true);
|
||||
}
|
||||
|
||||
final VerificationMeta _descriptionMeta =
|
||||
const VerificationMeta('description');
|
||||
GeneratedTextColumn _description;
|
||||
@override
|
||||
GeneratedTextColumn get description =>
|
||||
|
@ -284,9 +304,14 @@ class $CategoriesTable extends Categories
|
|||
@override
|
||||
final String actualTableName = 'categories';
|
||||
@override
|
||||
bool validateIntegrity(Category instance, bool isInserting) =>
|
||||
id.isAcceptableValue(instance.id, isInserting) &&
|
||||
description.isAcceptableValue(instance.description, isInserting);
|
||||
VerificationContext validateIntegrity(Category instance, bool isInserting) =>
|
||||
VerificationContext()
|
||||
..handle(
|
||||
_idMeta, id.isAcceptableValue(instance.id, isInserting, _idMeta))
|
||||
..handle(
|
||||
_descriptionMeta,
|
||||
description.isAcceptableValue(
|
||||
instance.description, isInserting, _descriptionMeta));
|
||||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {id};
|
||||
@override
|
||||
|
@ -413,6 +438,7 @@ class $UsersTable extends Users with TableInfo<$UsersTable, User> {
|
|||
final GeneratedDatabase _db;
|
||||
final String _alias;
|
||||
$UsersTable(this._db, [this._alias]);
|
||||
final VerificationMeta _idMeta = const VerificationMeta('id');
|
||||
GeneratedIntColumn _id;
|
||||
@override
|
||||
GeneratedIntColumn get id => _id ??= _constructId();
|
||||
|
@ -420,6 +446,7 @@ class $UsersTable extends Users with TableInfo<$UsersTable, User> {
|
|||
return GeneratedIntColumn('id', $tableName, false, hasAutoIncrement: true);
|
||||
}
|
||||
|
||||
final VerificationMeta _nameMeta = const VerificationMeta('name');
|
||||
GeneratedTextColumn _name;
|
||||
@override
|
||||
GeneratedTextColumn get name => _name ??= _constructName();
|
||||
|
@ -428,6 +455,7 @@ class $UsersTable extends Users with TableInfo<$UsersTable, User> {
|
|||
minTextLength: 6, maxTextLength: 32);
|
||||
}
|
||||
|
||||
final VerificationMeta _isAwesomeMeta = const VerificationMeta('isAwesome');
|
||||
GeneratedBoolColumn _isAwesome;
|
||||
@override
|
||||
GeneratedBoolColumn get isAwesome => _isAwesome ??= _constructIsAwesome();
|
||||
|
@ -436,6 +464,8 @@ class $UsersTable extends Users with TableInfo<$UsersTable, User> {
|
|||
defaultValue: const Constant(true));
|
||||
}
|
||||
|
||||
final VerificationMeta _profilePictureMeta =
|
||||
const VerificationMeta('profilePicture');
|
||||
GeneratedBlobColumn _profilePicture;
|
||||
@override
|
||||
GeneratedBlobColumn get profilePicture =>
|
||||
|
@ -448,6 +478,8 @@ class $UsersTable extends Users with TableInfo<$UsersTable, User> {
|
|||
);
|
||||
}
|
||||
|
||||
final VerificationMeta _creationTimeMeta =
|
||||
const VerificationMeta('creationTime');
|
||||
GeneratedDateTimeColumn _creationTime;
|
||||
@override
|
||||
GeneratedDateTimeColumn get creationTime =>
|
||||
|
@ -467,12 +499,24 @@ class $UsersTable extends Users with TableInfo<$UsersTable, User> {
|
|||
@override
|
||||
final String actualTableName = 'users';
|
||||
@override
|
||||
bool validateIntegrity(User instance, bool isInserting) =>
|
||||
id.isAcceptableValue(instance.id, isInserting) &&
|
||||
name.isAcceptableValue(instance.name, isInserting) &&
|
||||
isAwesome.isAcceptableValue(instance.isAwesome, isInserting) &&
|
||||
profilePicture.isAcceptableValue(instance.profilePicture, isInserting) &&
|
||||
creationTime.isAcceptableValue(instance.creationTime, isInserting);
|
||||
VerificationContext validateIntegrity(User instance, bool isInserting) =>
|
||||
VerificationContext()
|
||||
..handle(
|
||||
_idMeta, id.isAcceptableValue(instance.id, isInserting, _idMeta))
|
||||
..handle(_nameMeta,
|
||||
name.isAcceptableValue(instance.name, isInserting, _nameMeta))
|
||||
..handle(
|
||||
_isAwesomeMeta,
|
||||
isAwesome.isAcceptableValue(
|
||||
instance.isAwesome, isInserting, _isAwesomeMeta))
|
||||
..handle(
|
||||
_profilePictureMeta,
|
||||
profilePicture.isAcceptableValue(
|
||||
instance.profilePicture, isInserting, _profilePictureMeta))
|
||||
..handle(
|
||||
_creationTimeMeta,
|
||||
creationTime.isAcceptableValue(
|
||||
instance.creationTime, isInserting, _creationTimeMeta));
|
||||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {id};
|
||||
@override
|
||||
|
@ -563,6 +607,7 @@ class $SharedTodosTable extends SharedTodos
|
|||
final GeneratedDatabase _db;
|
||||
final String _alias;
|
||||
$SharedTodosTable(this._db, [this._alias]);
|
||||
final VerificationMeta _todoMeta = const VerificationMeta('todo');
|
||||
GeneratedIntColumn _todo;
|
||||
@override
|
||||
GeneratedIntColumn get todo => _todo ??= _constructTodo();
|
||||
|
@ -574,6 +619,7 @@ class $SharedTodosTable extends SharedTodos
|
|||
);
|
||||
}
|
||||
|
||||
final VerificationMeta _userMeta = const VerificationMeta('user');
|
||||
GeneratedIntColumn _user;
|
||||
@override
|
||||
GeneratedIntColumn get user => _user ??= _constructUser();
|
||||
|
@ -594,9 +640,13 @@ class $SharedTodosTable extends SharedTodos
|
|||
@override
|
||||
final String actualTableName = 'shared_todos';
|
||||
@override
|
||||
bool validateIntegrity(SharedTodo instance, bool isInserting) =>
|
||||
todo.isAcceptableValue(instance.todo, isInserting) &&
|
||||
user.isAcceptableValue(instance.user, isInserting);
|
||||
VerificationContext validateIntegrity(
|
||||
SharedTodo instance, bool isInserting) =>
|
||||
VerificationContext()
|
||||
..handle(_todoMeta,
|
||||
todo.isAcceptableValue(instance.todo, isInserting, _todoMeta))
|
||||
..handle(_userMeta,
|
||||
user.isAcceptableValue(instance.user, isInserting, _userMeta));
|
||||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {todo, user};
|
||||
@override
|
||||
|
@ -686,6 +736,8 @@ class $TableWithoutPKTable extends TableWithoutPK
|
|||
final GeneratedDatabase _db;
|
||||
final String _alias;
|
||||
$TableWithoutPKTable(this._db, [this._alias]);
|
||||
final VerificationMeta _notReallyAnIdMeta =
|
||||
const VerificationMeta('notReallyAnId');
|
||||
GeneratedIntColumn _notReallyAnId;
|
||||
@override
|
||||
GeneratedIntColumn get notReallyAnId =>
|
||||
|
@ -698,6 +750,7 @@ class $TableWithoutPKTable extends TableWithoutPK
|
|||
);
|
||||
}
|
||||
|
||||
final VerificationMeta _someFloatMeta = const VerificationMeta('someFloat');
|
||||
GeneratedRealColumn _someFloat;
|
||||
@override
|
||||
GeneratedRealColumn get someFloat => _someFloat ??= _constructSomeFloat();
|
||||
|
@ -718,9 +771,17 @@ class $TableWithoutPKTable extends TableWithoutPK
|
|||
@override
|
||||
final String actualTableName = 'table_without_p_k';
|
||||
@override
|
||||
bool validateIntegrity(TableWithoutPKData instance, bool isInserting) =>
|
||||
notReallyAnId.isAcceptableValue(instance.notReallyAnId, isInserting) &&
|
||||
someFloat.isAcceptableValue(instance.someFloat, isInserting);
|
||||
VerificationContext validateIntegrity(
|
||||
TableWithoutPKData instance, bool isInserting) =>
|
||||
VerificationContext()
|
||||
..handle(
|
||||
_notReallyAnIdMeta,
|
||||
notReallyAnId.isAcceptableValue(
|
||||
instance.notReallyAnId, isInserting, _notReallyAnIdMeta))
|
||||
..handle(
|
||||
_someFloatMeta,
|
||||
someFloat.isAcceptableValue(
|
||||
instance.someFloat, isInserting, _someFloatMeta));
|
||||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => <GeneratedColumn>{};
|
||||
@override
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
import 'package:moor/moor.dart';
|
||||
import 'package:test_api/test_api.dart';
|
||||
|
||||
import 'data/tables/todos.dart';
|
||||
import 'data/utils/mocks.dart';
|
||||
|
||||
// the content is set to non-null and the title must be between 4 and 16 chars
|
||||
// long
|
||||
final nullContent = TodoEntry(title: 'Test', content: null);
|
||||
final shortTitle = TodoEntry(title: 'A', content: 'content');
|
||||
final longTitle = TodoEntry(title: 'A ${'very' * 5} long title', content: 'hi');
|
||||
final valid = TodoEntry(title: 'Test', content: 'Some content');
|
||||
|
||||
void main() {
|
||||
TodoDb db;
|
||||
MockExecutor executor;
|
||||
|
||||
setUp(() {
|
||||
executor = MockExecutor();
|
||||
db = TodoDb(executor);
|
||||
});
|
||||
|
||||
test('detects errors on insert', () {
|
||||
expect(
|
||||
() => db.into(db.todosTable).insert(nullContent),
|
||||
throwsA(predicate<InvalidDataException>(
|
||||
(e) => e.message.contains('not nullable'))),
|
||||
);
|
||||
expect(
|
||||
() => db.into(db.todosTable).insert(shortTitle),
|
||||
throwsA(predicate<InvalidDataException>(
|
||||
(e) => e.message.contains('Must at least be'))),
|
||||
);
|
||||
expect(
|
||||
() => db.into(db.todosTable).insert(longTitle),
|
||||
throwsA(predicate<InvalidDataException>(
|
||||
(e) => e.message.contains('Must at most be'))),
|
||||
);
|
||||
|
||||
expect(db.into(db.todosTable).insert(valid), completes);
|
||||
});
|
||||
}
|
|
@ -34,6 +34,7 @@ class TableWriter {
|
|||
|
||||
// Generate the columns
|
||||
for (var column in table.columns) {
|
||||
_writeColumnVerificationMeta(buffer, column);
|
||||
_writeColumnGetter(buffer, column);
|
||||
}
|
||||
|
||||
|
@ -147,22 +148,42 @@ class TableWriter {
|
|||
);
|
||||
}
|
||||
|
||||
void _writeColumnVerificationMeta(
|
||||
StringBuffer buffer, SpecifiedColumn column) {
|
||||
// final VerificationMeta _targetDateMeta = const VerificationMeta('targetDate');
|
||||
buffer
|
||||
..write('final VerificationMeta ${_fieldNameForColumnMeta(column)} = ')
|
||||
..write("const VerificationMeta('${column.dartGetterName}');\n");
|
||||
}
|
||||
|
||||
void _writeValidityCheckMethod(StringBuffer buffer) {
|
||||
final dataClass = table.dartTypeName;
|
||||
|
||||
buffer.write(
|
||||
'@override\nbool validateIntegrity($dataClass instance, bool isInserting) => ');
|
||||
buffer.write('@override\nVerificationContext validateIntegrity'
|
||||
'($dataClass instance, bool isInserting) => VerificationContext()');
|
||||
|
||||
final validationCode = table.columns.map((column) {
|
||||
/*
|
||||
return VerificationContext()
|
||||
..handle(
|
||||
_categoryMeta,
|
||||
category.isAcceptableValue(
|
||||
instance.category, isInserting, _categoryMeta));
|
||||
*/
|
||||
|
||||
for (var column in table.columns) {
|
||||
final getterName = column.dartGetterName;
|
||||
final metaName = _fieldNameForColumnMeta(column);
|
||||
|
||||
// generated columns have a isAcceptableValue(T value, bool duringInsert)
|
||||
// method
|
||||
// ..handle(_meta, c.isAcceptableValue(instance.c, insert, _meta))
|
||||
buffer.write('..handle($metaName, $getterName.isAcceptableValue('
|
||||
'instance.$getterName, isInserting, $metaName))');
|
||||
}
|
||||
|
||||
return '$getterName.isAcceptableValue(instance.$getterName, isInserting)';
|
||||
}).join('&&');
|
||||
buffer.write(';\n');
|
||||
}
|
||||
|
||||
buffer..write(validationCode)..write(';\n');
|
||||
String _fieldNameForColumnMeta(SpecifiedColumn column) {
|
||||
return '_${column.dartGetterName}Meta';
|
||||
}
|
||||
|
||||
void _writePrimaryKeyOverride(StringBuffer buffer) {
|
||||
|
|
Loading…
Reference in New Issue