Fixed issue 70

This commit is contained in:
thomashii 2022-06-11 14:39:29 +08:00
parent da5b87043d
commit 224d2be026
17 changed files with 92 additions and 55 deletions

View file

@ -3,6 +3,7 @@
## 6.0.2
* Upgraded to `lints` 2.x.x
* Fixed issue #70. Incorrectly generated SQL for `defaultsTo('Default Value')`
## 6.0.1

View file

@ -6,7 +6,7 @@ import 'package:charcode/ascii.dart';
abstract class MariaDbGenerator {
static String columnType(MigrationColumn column) {
var str = column.type.name;
if (column.type.hasSize) {
if (column.type.hasLength) {
return '$str(${column.length})';
} else {
return str;

View file

@ -6,7 +6,7 @@ import 'package:charcode/ascii.dart';
abstract class MySqlGenerator {
static String columnType(MigrationColumn column) {
var str = column.type.name;
if (column.type.hasSize) {
if (column.type.hasLength) {
return '$str(${column.length})';
} else {
return str;

View file

@ -6,7 +6,7 @@ import 'package:charcode/ascii.dart';
abstract class PostgresGenerator {
static String columnType(MigrationColumn column) {
var str = column.type.name;
if (column.type.hasSize) {
if (column.type.hasLength) {
return '$str(${column.length})';
} else {
return str;
@ -31,11 +31,10 @@ abstract class PostgresGenerator {
b.writeCharCode(ch);
}
}
s = b.toString();
s = '\'${b.toString()}\'';
} else {
s = value.toString();
}
buf.write(' DEFAULT $s');
}
@ -46,7 +45,7 @@ abstract class PostgresGenerator {
}
for (var ref in column.externalReferences) {
buf.write(' ' + compileReference(ref));
buf.write(' ${compileReference(ref)}');
}
return buf.toString();
@ -55,7 +54,7 @@ abstract class PostgresGenerator {
static String compileReference(MigrationColumnReference ref) {
var buf =
StringBuffer('REFERENCES "${ref.foreignTable}"("${ref.foreignKey}")');
if (ref.behavior != null) buf.write(' ' + ref.behavior!);
if (ref.behavior != null) buf.write(' ${ref.behavior!}');
return buf.toString();
}
}
@ -147,9 +146,9 @@ class PostgresAlterTable extends Table implements MutableTable {
}
@override
void changeColumnType(String name, ColumnType type, {int length = 256}) {
_stack.add('ALTER COLUMN "$name" TYPE ' +
PostgresGenerator.columnType(MigrationColumn(type, length: length)));
void changeColumnType(String name, ColumnType type, {int length = 255}) {
_stack.add(
'ALTER COLUMN "$name" TYPE ${PostgresGenerator.columnType(MigrationColumn(type, length: length))}');
}
@override

View file

@ -16,8 +16,8 @@ dependencies:
logging: ^1.0.0
dev_dependencies:
lints: ^2.0.0
# dependency_overrides:
# angel3_orm:
# path: ../angel_orm
# angel3_migration:
# path: ../angel_migration
dependency_overrides:
angel3_orm:
path: ../angel_orm
angel3_migration:
path: ../angel_migration

View file

@ -129,32 +129,28 @@ class ColumnType {
static const ColumnType char = ColumnType('char', hasLength: true);
static const ColumnType varChar = ColumnType('varchar', hasLength: true);
static const ColumnType varCharMax = ColumnType('varchar(max)');
static const ColumnType text = ColumnType('text', hasLength: true);
static const ColumnType text = ColumnType('text');
// Unicode strings
static const ColumnType nChar = ColumnType('nchar', hasLength: true);
static const ColumnType nVarChar = ColumnType('nvarchar', hasLength: true);
static const ColumnType nVarCharMax =
ColumnType('nvarchar(max)', hasLength: true);
static const ColumnType nVarCharMax = ColumnType('nvarchar(max)');
static const ColumnType nText = ColumnType('ntext', hasLength: true);
// Binary
static const ColumnType binary = ColumnType('binary', hasLength: true);
static const ColumnType varBinary = ColumnType('varbinary', hasLength: true);
static const ColumnType varBinaryMax =
ColumnType('varbinary(max)', hasLength: true);
static const ColumnType image = ColumnType('image', hasLength: true);
static const ColumnType binary = ColumnType('binary');
static const ColumnType varBinary = ColumnType('varbinary');
static const ColumnType varBinaryMax = ColumnType('varbinary(max)');
static const ColumnType image = ColumnType('image');
// JSON.
static const ColumnType json = ColumnType('json', hasLength: true);
static const ColumnType jsonb = ColumnType('jsonb', hasLength: true);
static const ColumnType json = ColumnType('json');
static const ColumnType jsonb = ColumnType('jsonb');
// Misc.
static const ColumnType sqlVariant =
ColumnType('sql_variant', hasLength: true);
static const ColumnType uniqueIdentifier =
ColumnType('uniqueidentifier', hasLength: true);
static const ColumnType xml = ColumnType('xml', hasLength: true);
static const ColumnType cursor = ColumnType('cursor', hasLength: true);
static const ColumnType table = ColumnType('table', hasLength: true);
static const ColumnType sqlVariant = ColumnType('sql_variant');
static const ColumnType uniqueIdentifier = ColumnType('uniqueidentifier');
static const ColumnType xml = ColumnType('xml');
static const ColumnType cursor = ColumnType('cursor');
static const ColumnType table = ColumnType('table');
}

View file

@ -148,6 +148,9 @@ class MigrationGenerator extends GeneratorForAnnotation<Orm> {
case ColumnType.float:
methodName = 'float';
break;
case ColumnType.double:
methodName = 'double';
break;
case ColumnType.numeric:
methodName = 'numeric';
if (col.type.hasPrecision) {}
@ -233,7 +236,7 @@ class MigrationGenerator extends GeneratorForAnnotation<Orm> {
cascade.add(refer('unique').call([]));
}
if (col.isNullable != true) {
if (!col.isNullable) {
cascade.add(refer('notNull').call([]));
}

View file

@ -105,7 +105,9 @@ Future<OrmBuildContext?> buildOrmContext(
// Check for column annotation...
var element = _findElement(field);
var columnAnnotation = columnTypeChecker.firstAnnotationOf(element);
// print('${element.name} => $columnAnnotation');
if (columnAnnotation != null) {
print('[ORM_BUILD_CONTEXT] ${element.name} => $columnAnnotation');
}
Column? column;
if (columnAnnotation != null) {
@ -334,6 +336,7 @@ Future<OrmBuildContext?> buildOrmContext(
return ctx;
}
// Detect and return the correct column type
ColumnType inferColumnType(DartType type) {
if (const TypeChecker.fromRuntime(String).isAssignableFromType(type)) {
return ColumnType.varChar;
@ -342,7 +345,7 @@ ColumnType inferColumnType(DartType type) {
return ColumnType.int;
}
if (const TypeChecker.fromRuntime(double).isAssignableFromType(type)) {
return ColumnType.float;
return ColumnType.double;
}
if (const TypeChecker.fromRuntime(num).isAssignableFromType(type)) {
return ColumnType.float;
@ -401,6 +404,7 @@ Column reviveColumn(ConstantReader cr) {
const TypeChecker relationshipTypeChecker =
TypeChecker.fromRuntime(Relationship);
// ORM builder context
class OrmBuildContext {
final BuildContext buildContext;
final Orm ormAnnotation;

View file

@ -18,6 +18,9 @@ abstract class _Asset extends Model {
String get name;
@Column(type: ColumnType.numeric, precision: 17, scale: 3)
double get price;
@hasMany
List<_Item> get items;
}

View file

@ -32,6 +32,7 @@ class AssetMigration extends Migration {
table.timeStamp('updated_at');
table.varChar('description', length: 255);
table.varChar('name', length: 255);
table.double('price');
});
}
@ -191,7 +192,7 @@ class AssetQuery extends Query<Asset, AssetQueryWhere> {
@override
Map<String, String> get casts {
return {};
return {'price': 'char'};
}
@override
@ -201,7 +202,14 @@ class AssetQuery extends Query<Asset, AssetQueryWhere> {
@override
List<String> get fields {
const _fields = ['id', 'created_at', 'updated_at', 'description', 'name'];
const _fields = [
'id',
'created_at',
'updated_at',
'description',
'name',
'price'
];
return _selectedFields.isEmpty
? _fields
: _fields.where((field) => _selectedFields.contains(field)).toList();
@ -231,9 +239,10 @@ class AssetQuery extends Query<Asset, AssetQueryWhere> {
createdAt: fields.contains('created_at') ? mapToDateTime(row[1]) : null,
updatedAt: fields.contains('updated_at') ? mapToDateTime(row[2]) : null,
description: fields.contains('description') ? (row[3] as String) : '',
name: fields.contains('name') ? (row[4] as String) : '');
if (row.length > 5) {
var modelOpt = ItemQuery().parseRow(row.skip(5).take(4).toList());
name: fields.contains('name') ? (row[4] as String) : '',
price: fields.contains('price') ? mapToDouble(row[5]) : 0.0);
if (row.length > 6) {
var modelOpt = ItemQuery().parseRow(row.skip(6).take(4).toList());
modelOpt.ifPresent((m) {
model = model.copyWith(items: [m]);
});
@ -311,7 +320,8 @@ class AssetQueryWhere extends QueryWhere {
createdAt = DateTimeSqlExpressionBuilder(query, 'created_at'),
updatedAt = DateTimeSqlExpressionBuilder(query, 'updated_at'),
description = StringSqlExpressionBuilder(query, 'description'),
name = StringSqlExpressionBuilder(query, 'name');
name = StringSqlExpressionBuilder(query, 'name'),
price = NumericSqlExpressionBuilder<double>(query, 'price');
final NumericSqlExpressionBuilder<int> id;
@ -323,16 +333,18 @@ class AssetQueryWhere extends QueryWhere {
final StringSqlExpressionBuilder name;
final NumericSqlExpressionBuilder<double> price;
@override
List<SqlExpressionBuilder> get expressionBuilders {
return [id, createdAt, updatedAt, description, name];
return [id, createdAt, updatedAt, description, name, price];
}
}
class AssetQueryValues extends MapQueryValues {
@override
Map<String, String> get casts {
return {};
return {'price': 'double precision'};
}
String? get id {
@ -360,11 +372,17 @@ class AssetQueryValues extends MapQueryValues {
}
set name(String value) => values['name'] = value;
double get price {
return double.tryParse((values['price'] as String)) ?? 0.0;
}
set price(double value) => values['price'] = value.toString();
void copyFrom(Asset model) {
createdAt = model.createdAt;
updatedAt = model.updatedAt;
description = model.description;
name = model.name;
price = model.price;
}
}
@ -435,6 +453,7 @@ class Asset extends _Asset {
this.updatedAt,
required this.description,
required this.name,
required this.price,
List<_Item> items = const []})
: items = List.unmodifiable(items);
@ -456,6 +475,9 @@ class Asset extends _Asset {
@override
String name;
@override
double price;
@override
List<_Item> items;
@ -465,6 +487,7 @@ class Asset extends _Asset {
DateTime? updatedAt,
String? description,
String? name,
double? price,
List<_Item>? items}) {
return Asset(
id: id ?? this.id,
@ -472,6 +495,7 @@ class Asset extends _Asset {
updatedAt: updatedAt ?? this.updatedAt,
description: description ?? this.description,
name: name ?? this.name,
price: price ?? this.price,
items: items ?? this.items);
}
@ -483,18 +507,20 @@ class Asset extends _Asset {
other.updatedAt == updatedAt &&
other.description == description &&
other.name == name &&
other.price == price &&
ListEquality<_Item>(DefaultEquality<_Item>())
.equals(other.items, items);
}
@override
int get hashCode {
return hashObjects([id, createdAt, updatedAt, description, name, items]);
return hashObjects(
[id, createdAt, updatedAt, description, name, price, items]);
}
@override
String toString() {
return 'Asset(id=$id, createdAt=$createdAt, updatedAt=$updatedAt, description=$description, name=$name, items=$items)';
return 'Asset(id=$id, createdAt=$createdAt, updatedAt=$updatedAt, description=$description, name=$name, price=$price, items=$items)';
}
Map<String, dynamic> toJson() {
@ -613,6 +639,7 @@ class AssetSerializer extends Codec<Asset, Map> {
: null,
description: map['description'] as String,
name: map['name'] as String,
price: map['price'] as double,
items: map['items'] is Iterable
? List.unmodifiable(((map['items'] as Iterable).whereType<Map>())
.map(ItemSerializer.fromMap))
@ -629,6 +656,7 @@ class AssetSerializer extends Codec<Asset, Map> {
'updated_at': model.updatedAt?.toIso8601String(),
'description': model.description,
'name': model.name,
'price': model.price,
'items': model.items.map((m) => ItemSerializer.toMap(m)).toList()
};
}
@ -641,6 +669,7 @@ abstract class AssetFields {
updatedAt,
description,
name,
price,
items
];
@ -654,5 +683,7 @@ abstract class AssetFields {
static const String name = 'name';
static const String price = 'price';
static const String items = 'items';
}

View file

@ -17,7 +17,7 @@ class BikeMigration extends Migration {
table.varChar('description', length: 255);
table.boolean('family_friendly');
table.timeStamp('recalled_at');
table.float('price');
table.double('price');
table.integer('width');
});
}
@ -164,7 +164,7 @@ class BikeQueryWhere extends QueryWhere {
class BikeQueryValues extends MapQueryValues {
@override
Map<String, String> get casts {
return {'price': 'float'};
return {'price': 'double precision'};
}
String? get id {

View file

@ -17,7 +17,7 @@ class BoatMigration extends Migration {
table.varChar('description', length: 255).defaultsTo('none');
table.boolean('family_friendly').defaultsTo(false);
table.timeStamp('recalled_at');
table.float('price').defaultsTo(0.0);
table.double('price').defaultsTo(0.0);
table.integer('width').defaultsTo(0);
});
}
@ -164,7 +164,7 @@ class BoatQueryWhere extends QueryWhere {
class BoatQueryValues extends MapQueryValues {
@override
Map<String, String> get casts {
return {'price': 'float'};
return {'price': 'double precision'};
}
String? get id {

View file

@ -31,7 +31,7 @@ class FootMigration extends Migration {
table.timeStamp('created_at');
table.timeStamp('updated_at');
table.integer('leg_id');
table.float('n_toes');
table.double('n_toes');
});
}
@ -279,7 +279,7 @@ class FootQueryWhere extends QueryWhere {
class FootQueryValues extends MapQueryValues {
@override
Map<String, String> get casts {
return {'n_toes': 'float'};
return {'n_toes': 'double precision'};
}
String? get id {

View file

@ -244,7 +244,7 @@ class PersonWithLastOrderQueryWhere extends QueryWhere {
class PersonWithLastOrderQueryValues extends MapQueryValues {
@override
Map<String, String> get casts {
return {'last_order_price': 'float'};
return {'last_order_price': 'double precision'};
}
String? get name {

View file

@ -15,7 +15,7 @@ class PersonOrderMigration extends Migration {
table.timeStamp('updated_at');
table.integer('person_id');
table.varChar('name', length: 255);
table.float('price');
table.double('price');
table.boolean('deleted');
});
}
@ -140,7 +140,7 @@ class PersonOrderQueryWhere extends QueryWhere {
class PersonOrderQueryValues extends MapQueryValues {
@override
Map<String, String> get casts {
return {'price': 'float'};
return {'price': 'double precision'};
}
String? get id {
@ -301,7 +301,7 @@ class OrderWithPersonInfoQueryWhere extends QueryWhere {
class OrderWithPersonInfoQueryValues extends MapQueryValues {
@override
Map<String, String> get casts {
return {'price': 'float'};
return {'price': 'double precision'};
}
String? get id {