Apply pedantic to angel_orm

This commit is contained in:
Tobe O 2019-07-04 17:30:21 -04:00
parent ed34ea0a2f
commit 68a349c877
8 changed files with 130 additions and 117 deletions

View file

@ -8,13 +8,13 @@ part 'main.g.dart';
part 'main.serializer.g.dart';
main() async {
var query = new EmployeeQuery()
var query = EmployeeQuery()
..where.firstName.equals('Rich')
..where.lastName.equals('Person')
..orWhere((w) => w.salary.greaterThanOrEqualTo(75000))
..join('companies', 'company_id', 'id');
var richPerson = await query.getOne(new _FakeExecutor());
var richPerson = await query.getOne(_FakeExecutor());
print(richPerson.toJson());
}
@ -25,7 +25,7 @@ class _FakeExecutor extends QueryExecutor {
Future<List<List>> query(
String tableName, String query, Map<String, dynamic> substitutionValues,
[returningFields]) async {
var now = new DateTime.now();
var now = DateTime.now();
print(
'_FakeExecutor received query: $query and values: $substitutionValues');
return [
@ -35,7 +35,7 @@ class _FakeExecutor extends QueryExecutor {
@override
Future<T> transaction<T>(FutureOr<T> Function() f) {
throw new UnsupportedError('Transactions are not supported.');
throw UnsupportedError('Transactions are not supported.');
}
}
@ -51,12 +51,12 @@ abstract class _Employee extends Model {
class EmployeeQuery extends Query<Employee, EmployeeQueryWhere> {
@override
final QueryValues values = new MapQueryValues();
final QueryValues values = MapQueryValues();
EmployeeQueryWhere _where;
EmployeeQuery() {
_where = new EmployeeQueryWhere(this);
_where = EmployeeQueryWhere(this);
}
@override
@ -70,11 +70,11 @@ class EmployeeQuery extends Query<Employee, EmployeeQueryWhere> {
['id', 'first_name', 'last_name', 'salary', 'created_at', 'updated_at'];
@override
EmployeeQueryWhere newWhereClause() => new EmployeeQueryWhere(this);
EmployeeQueryWhere newWhereClause() => EmployeeQueryWhere(this);
@override
Employee deserialize(List row) {
return new Employee(
return Employee(
id: row[0].toString(),
firstName: row[1] as String,
lastName: row[2] as String,
@ -86,12 +86,12 @@ class EmployeeQuery extends Query<Employee, EmployeeQueryWhere> {
class EmployeeQueryWhere extends QueryWhere {
EmployeeQueryWhere(EmployeeQuery query)
: id = new NumericSqlExpressionBuilder(query, 'id'),
firstName = new StringSqlExpressionBuilder(query, 'first_name'),
lastName = new StringSqlExpressionBuilder(query, 'last_name'),
salary = new NumericSqlExpressionBuilder(query, 'salary'),
createdAt = new DateTimeSqlExpressionBuilder(query, 'created_at'),
updatedAt = new DateTimeSqlExpressionBuilder(query, 'updated_at');
: id = NumericSqlExpressionBuilder(query, 'id'),
firstName = StringSqlExpressionBuilder(query, 'first_name'),
lastName = StringSqlExpressionBuilder(query, 'last_name'),
salary = NumericSqlExpressionBuilder(query, 'salary'),
createdAt = DateTimeSqlExpressionBuilder(query, 'created_at'),
updatedAt = DateTimeSqlExpressionBuilder(query, 'updated_at');
@override
Iterable<SqlExpressionBuilder> get expressionBuilders {

View file

@ -41,7 +41,7 @@ class Employee extends _Employee {
double salary,
DateTime createdAt,
DateTime updatedAt}) {
return new Employee(
return Employee(
id: id ?? this.id,
firstName: firstName ?? this.firstName,
lastName: lastName ?? this.lastName,

View file

@ -8,7 +8,7 @@ part of 'main.dart';
abstract class EmployeeSerializer {
static Employee fromMap(Map map) {
return new Employee(
return Employee(
id: map['id'] as String,
firstName: map['first_name'] as String,
lastName: map['last_name'] as String,
@ -41,7 +41,7 @@ abstract class EmployeeSerializer {
}
abstract class EmployeeFields {
static const List<String> allFields = const <String>[
static const List<String> allFields = <String>[
id,
firstName,
lastName,

View file

@ -1,6 +1,6 @@
/// A raw SQL statement that specifies a date/time default to the
/// current time.
const RawSql currentTimestamp = const RawSql('CURRENT_TIMESTAMP');
const RawSql currentTimestamp = RawSql('CURRENT_TIMESTAMP');
/// Can passed to a [MigrationColumn] to default to a raw SQL expression.
class RawSql {
@ -11,7 +11,7 @@ class RawSql {
}
/// Canonical instance of [ORM]. Implies all defaults.
const Orm orm = const Orm();
const Orm orm = Orm();
class Orm {
/// The name of the table to query.

View file

@ -5,29 +5,32 @@ import 'package:intl/intl.dart' show DateFormat;
import 'package:string_scanner/string_scanner.dart';
import 'query.dart';
final DateFormat dateYmd = new DateFormat('yyyy-MM-dd');
final DateFormat dateYmdHms = new DateFormat('yyyy-MM-dd HH:mm:ss');
final DateFormat dateYmd = DateFormat('yyyy-MM-dd');
final DateFormat dateYmdHms = DateFormat('yyyy-MM-dd HH:mm:ss');
/// The ORM prefers using substitution values, which allow for prepared queries,
/// and prevent SQL injection attacks.
@deprecated
String sanitizeExpression(String unsafe) {
var buf = new StringBuffer();
var scanner = new StringScanner(unsafe);
var buf = StringBuffer();
var scanner = StringScanner(unsafe);
int ch;
while (!scanner.isDone) {
// Ignore comment starts
if (scanner.scan('--') || scanner.scan('/*'))
if (scanner.scan('--') || scanner.scan('/*')) {
continue;
}
// Ignore all single quotes and attempted escape sequences
else if (scanner.scan("'") || scanner.scan('\\'))
else if (scanner.scan("'") || scanner.scan('\\')) {
continue;
}
// Otherwise, add the next char, unless it's a null byte.
else if ((ch = scanner.readChar()) != $nul && ch != null)
else if ((ch = scanner.readChar()) != $nul && ch != null) {
buf.writeCharCode(ch);
}
}
return toSql(buf.toString(), withQuotes: false);
@ -372,17 +375,17 @@ class DateTimeSqlExpressionBuilder extends SqlExpressionBuilder<DateTime> {
: super(query, columnName);
NumericSqlExpressionBuilder<int> get year =>
_year ??= new NumericSqlExpressionBuilder(query, 'year');
_year ??= NumericSqlExpressionBuilder(query, 'year');
NumericSqlExpressionBuilder<int> get month =>
_month ??= new NumericSqlExpressionBuilder(query, 'month');
_month ??= NumericSqlExpressionBuilder(query, 'month');
NumericSqlExpressionBuilder<int> get day =>
_day ??= new NumericSqlExpressionBuilder(query, 'day');
_day ??= NumericSqlExpressionBuilder(query, 'day');
NumericSqlExpressionBuilder<int> get hour =>
_hour ??= new NumericSqlExpressionBuilder(query, 'hour');
_hour ??= NumericSqlExpressionBuilder(query, 'hour');
NumericSqlExpressionBuilder<int> get minute =>
_minute ??= new NumericSqlExpressionBuilder(query, 'minute');
_minute ??= NumericSqlExpressionBuilder(query, 'minute');
NumericSqlExpressionBuilder<int> get second =>
_second ??= new NumericSqlExpressionBuilder(query, 'second');
_second ??= NumericSqlExpressionBuilder(query, 'second');
@override
bool get hasValue =>
@ -462,17 +465,24 @@ class DateTimeSqlExpressionBuilder extends SqlExpressionBuilder<DateTime> {
String compile() {
if (_raw?.isNotEmpty == true) return _raw;
List<String> parts = [];
if (year?.hasValue == true)
if (year?.hasValue == true) {
parts.add('YEAR($columnName) ${year.compile()}');
if (month?.hasValue == true)
}
if (month?.hasValue == true) {
parts.add('MONTH($columnName) ${month.compile()}');
if (day?.hasValue == true) parts.add('DAY($columnName) ${day.compile()}');
if (hour?.hasValue == true)
}
if (day?.hasValue == true) {
parts.add('DAY($columnName) ${day.compile()}');
}
if (hour?.hasValue == true) {
parts.add('HOUR($columnName) ${hour.compile()}');
if (minute?.hasValue == true)
}
if (minute?.hasValue == true) {
parts.add('MINUTE($columnName) ${minute.compile()}');
if (second?.hasValue == true)
}
if (second?.hasValue == true) {
parts.add('SECOND($columnName) ${second.compile()}');
}
return parts.isEmpty ? null : parts.join(' AND ');
}

View file

@ -1,4 +1,4 @@
const List<String> SQL_RESERVED_WORDS = const [
const List<String> SQL_RESERVED_WORDS = [
'SELECT',
'UPDATE',
'INSERT',
@ -40,7 +40,7 @@ class PrimaryKey extends Column {
indexType: IndexType.primaryKey);
}
const Column primaryKey = const PrimaryKey();
const Column primaryKey = PrimaryKey();
/// Maps to SQL index types.
enum IndexType {
@ -65,61 +65,60 @@ class ColumnType {
const ColumnType(this.name);
static const ColumnType boolean = const ColumnType('boolean');
static const ColumnType boolean = ColumnType('boolean');
static const ColumnType smallSerial = const ColumnType('smallserial');
static const ColumnType serial = const ColumnType('serial');
static const ColumnType bigSerial = const ColumnType('bigserial');
static const ColumnType smallSerial = ColumnType('smallserial');
static const ColumnType serial = ColumnType('serial');
static const ColumnType bigSerial = ColumnType('bigserial');
// Numbers
static const ColumnType bigInt = const ColumnType('bigint');
static const ColumnType int = const ColumnType('int');
static const ColumnType smallInt = const ColumnType('smallint');
static const ColumnType tinyInt = const ColumnType('tinyint');
static const ColumnType bit = const ColumnType('bit');
static const ColumnType decimal = const ColumnType('decimal');
static const ColumnType numeric = const ColumnType('numeric');
static const ColumnType money = const ColumnType('money');
static const ColumnType smallMoney = const ColumnType('smallmoney');
static const ColumnType float = const ColumnType('float');
static const ColumnType real = const ColumnType('real');
static const ColumnType bigInt = ColumnType('bigint');
static const ColumnType int = ColumnType('int');
static const ColumnType smallInt = ColumnType('smallint');
static const ColumnType tinyInt = ColumnType('tinyint');
static const ColumnType bit = ColumnType('bit');
static const ColumnType decimal = ColumnType('decimal');
static const ColumnType numeric = ColumnType('numeric');
static const ColumnType money = ColumnType('money');
static const ColumnType smallMoney = ColumnType('smallmoney');
static const ColumnType float = ColumnType('float');
static const ColumnType real = ColumnType('real');
// Dates and times
static const ColumnType dateTime = const ColumnType('datetime');
static const ColumnType smallDateTime = const ColumnType('smalldatetime');
static const ColumnType date = const ColumnType('date');
static const ColumnType time = const ColumnType('time');
static const ColumnType timeStamp = const ColumnType('timestamp');
static const ColumnType dateTime = ColumnType('datetime');
static const ColumnType smallDateTime = ColumnType('smalldatetime');
static const ColumnType date = ColumnType('date');
static const ColumnType time = ColumnType('time');
static const ColumnType timeStamp = ColumnType('timestamp');
static const ColumnType timeStampWithTimeZone =
const ColumnType('timestamp with time zone');
ColumnType('timestamp with time zone');
// Strings
static const ColumnType char = const ColumnType('char');
static const ColumnType varChar = const ColumnType('varchar');
static const ColumnType varCharMax = const ColumnType('varchar(max)');
static const ColumnType text = const ColumnType('text');
static const ColumnType char = ColumnType('char');
static const ColumnType varChar = ColumnType('varchar');
static const ColumnType varCharMax = ColumnType('varchar(max)');
static const ColumnType text = ColumnType('text');
// Unicode strings
static const ColumnType nChar = const ColumnType('nchar');
static const ColumnType nVarChar = const ColumnType('nvarchar');
static const ColumnType nVarCharMax = const ColumnType('nvarchar(max)');
static const ColumnType nText = const ColumnType('ntext');
static const ColumnType nChar = ColumnType('nchar');
static const ColumnType nVarChar = ColumnType('nvarchar');
static const ColumnType nVarCharMax = ColumnType('nvarchar(max)');
static const ColumnType nText = ColumnType('ntext');
// Binary
static const ColumnType binary = const ColumnType('binary');
static const ColumnType varBinary = const ColumnType('varbinary');
static const ColumnType varBinaryMax = const ColumnType('varbinary(max)');
static const ColumnType image = const ColumnType('image');
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 = const ColumnType('json');
static const ColumnType jsonb = const ColumnType('jsonb');
static const ColumnType json = ColumnType('json');
static const ColumnType jsonb = ColumnType('jsonb');
// Misc.
static const ColumnType sqlVariant = const ColumnType('sql_variant');
static const ColumnType uniqueIdentifier =
const ColumnType('uniqueidentifier');
static const ColumnType xml = const ColumnType('xml');
static const ColumnType cursor = const ColumnType('cursor');
static const ColumnType table = const ColumnType('table');
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

@ -44,11 +44,11 @@ abstract class QueryBase<T> {
}
Union<T> union(QueryBase<T> other) {
return new Union(this, other);
return Union(this, other);
}
Union<T> unionAll(QueryBase<T> other) {
return new Union(this, other, all: true);
return Union(this, other, all: true);
}
}
@ -72,14 +72,14 @@ String toSql(Object obj, {bool withQuotes = true}) {
} else if (obj == null) {
return 'NULL';
} else if (obj is String) {
var b = new StringBuffer();
var b = StringBuffer();
var escaped = false;
var it = obj.runes.iterator;
while (it.moveNext()) {
if (it.current == $nul)
if (it.current == $nul) {
continue; // Skip null byte
else if (it.current == $single_quote) {
} else if (it.current == $single_quote) {
escaped = true;
b.write('\\x');
b.write(it.current.toRadixString(16).padLeft(2, '0'));
@ -94,17 +94,18 @@ String toSql(Object obj, {bool withQuotes = true}) {
b.write('\\U');
b.write(it.current.toRadixString(16).padLeft(8, '0'));
} else {
throw new UnsupportedError(
throw UnsupportedError(
'toSql() cannot encode a rune of size (${it.currentSize})');
}
}
if (!withQuotes)
if (!withQuotes) {
return b.toString();
else if (escaped)
} else if (escaped) {
return "E'$b'";
else
} else {
return "'$b'";
}
} else {
return obj.toString();
}
@ -140,10 +141,10 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
return n == 0 ? name : '${name}$n';
}
/// Makes a new [Where] clause.
/// Makes a [Where] clause.
Where newWhereClause() {
throw new UnsupportedError(
'This instance does not support creating new WHERE clauses.');
throw UnsupportedError(
'This instance does not support creating WHERE clauses.');
}
/// Determines whether this query can be compiled.
@ -151,21 +152,21 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
/// Used to prevent ambiguities in joins.
bool canCompile(Set<String> trampoline) => true;
/// Shorthand for calling [where].or with a new [Where] clause.
/// Shorthand for calling [where].or with a [Where] clause.
void andWhere(void Function(Where) f) {
var w = newWhereClause();
f(w);
where.and(w);
}
/// Shorthand for calling [where].or with a new [Where] clause.
/// Shorthand for calling [where].or with a [Where] clause.
void notWhere(void Function(Where) f) {
var w = newWhereClause();
f(w);
where.not(w);
}
/// Shorthand for calling [where].or with a new [Where] clause.
/// Shorthand for calling [where].or with a [Where] clause.
void orWhere(void Function(Where) f) {
var w = newWhereClause();
f(w);
@ -189,7 +190,7 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
/// Sorts the results by a key.
void orderBy(String key, {bool descending = false}) {
_orderBy.add(new OrderBy(key, descending: descending));
_orderBy.add(OrderBy(key, descending: descending));
}
/// Execute a `CROSS JOIN` (Cartesian product) against another table.
@ -204,15 +205,16 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
var a = 'a$i';
if (trampoline.add(a)) {
return a;
} else
} else {
i++;
}
}
}
String _compileJoin(tableName, Set<String> trampoline) {
if (tableName is String)
if (tableName is String) {
return tableName;
else if (tableName is Query) {
} else if (tableName is Query) {
var c = tableName.compile(trampoline);
if (c == null) return c;
return '($c)';
@ -241,7 +243,7 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
var to = _compileJoin(tableName, trampoline);
if (to != null) {
_joins.add(new JoinBuilder(type, this, to, localKey, foreignKey,
_joins.add(JoinBuilder(type, this, to, localKey, foreignKey,
op: op,
alias: _joinAlias(trampoline),
additionalFields: additionalFields));
@ -305,14 +307,14 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
}
includeTableName = includeTableName || _joins.isNotEmpty;
var b = new StringBuffer(preamble ?? 'SELECT');
var b = StringBuffer(preamble ?? 'SELECT');
b.write(' ');
List<String> f;
if (fields == null) {
f = ['*'];
} else {
f = new List<String>.from(fields.map((s) {
f = List<String>.from(fields.map((s) {
var ss = includeTableName ? '$tableName.$s' : s;
var cast = casts[s];
if (cast != null) ss = 'CAST ($ss AS $cast)';
@ -344,7 +346,9 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
if (_limit != null) b.write(' LIMIT $_limit');
if (_offset != null) b.write(' OFFSET $_offset');
if (_groupBy != null) b.write(' GROUP BY $_groupBy');
for (var item in _orderBy) b.write(' ORDER BY ${item.compile()}');
for (var item in _orderBy) {
b.write(' ORDER BY ${item.compile()}');
}
return b.toString();
}
@ -382,7 +386,7 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
var insertion = values.compileInsert(this, tableName);
if (insertion == null) {
throw new StateError('No values have been specified for update.');
throw StateError('No values have been specified for update.');
} else {
// TODO: How to do this in a non-Postgres DB?
var returning = fields.map(adornWithTableName).join(', ');
@ -395,11 +399,11 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
}
Future<List<T>> update(QueryExecutor executor) async {
var updateSql = new StringBuffer('UPDATE $tableName ');
var updateSql = StringBuffer('UPDATE $tableName ');
var valuesClause = values.compileForUpdate(this);
if (valuesClause == null) {
throw new StateError('No values have been specified for update.');
throw StateError('No values have been specified for update.');
} else {
updateSql.write(' $valuesClause');
var whereClause = where.compile();
@ -442,7 +446,7 @@ abstract class QueryValues {
if (data.isEmpty) return null;
var fieldSet = data.keys.join(', ');
var b = new StringBuffer('INSERT INTO $tableName ($fieldSet) VALUES (');
var b = StringBuffer('INSERT INTO $tableName ($fieldSet) VALUES (');
int i = 0;
for (var entry in data.entries) {
@ -461,7 +465,7 @@ abstract class QueryValues {
String compileForUpdate(Query query) {
var data = toMap();
if (data.isEmpty) return null;
var b = new StringBuffer('SET');
var b = StringBuffer('SET');
int i = 0;
for (var entry in data.entries) {
@ -489,9 +493,9 @@ class MapQueryValues extends QueryValues {
/// Builds a SQL `WHERE` clause.
abstract class QueryWhere {
final Set<QueryWhere> _and = new Set();
final Set<QueryWhere> _not = new Set();
final Set<QueryWhere> _or = new Set();
final Set<QueryWhere> _and = Set();
final Set<QueryWhere> _not = Set();
final Set<QueryWhere> _or = Set();
Iterable<SqlExpressionBuilder> get expressionBuilders;
@ -508,7 +512,7 @@ abstract class QueryWhere {
}
String compile({String tableName}) {
var b = new StringBuffer();
var b = StringBuffer();
int i = 0;
for (var builder in expressionBuilders) {
@ -608,7 +612,7 @@ class JoinBuilder {
String compile(Set<String> trampoline) {
if (to == null) return null;
var b = new StringBuffer();
var b = StringBuffer();
var left = '${from.tableName}.$key';
var right = fieldName;

View file

@ -32,7 +32,7 @@ class HasMany extends Relationship {
cascadeOnDelete: cascadeOnDelete == true);
}
const HasMany hasMany = const HasMany();
const HasMany hasMany = HasMany();
class HasOne extends Relationship {
const HasOne(
@ -47,7 +47,7 @@ class HasOne extends Relationship {
cascadeOnDelete: cascadeOnDelete == true);
}
const HasOne hasOne = const HasOne();
const HasOne hasOne = HasOne();
class BelongsTo extends Relationship {
const BelongsTo({String localKey, String foreignKey, String foreignTable})
@ -57,7 +57,7 @@ class BelongsTo extends Relationship {
foreignTable: foreignTable);
}
const BelongsTo belongsTo = const BelongsTo();
const BelongsTo belongsTo = BelongsTo();
class ManyToMany extends Relationship {
final Type through;