Apply pedantic to angel_orm
This commit is contained in:
parent
ed34ea0a2f
commit
68a349c877
8 changed files with 130 additions and 117 deletions
|
@ -8,13 +8,13 @@ part 'main.g.dart';
|
||||||
part 'main.serializer.g.dart';
|
part 'main.serializer.g.dart';
|
||||||
|
|
||||||
main() async {
|
main() async {
|
||||||
var query = new EmployeeQuery()
|
var query = EmployeeQuery()
|
||||||
..where.firstName.equals('Rich')
|
..where.firstName.equals('Rich')
|
||||||
..where.lastName.equals('Person')
|
..where.lastName.equals('Person')
|
||||||
..orWhere((w) => w.salary.greaterThanOrEqualTo(75000))
|
..orWhere((w) => w.salary.greaterThanOrEqualTo(75000))
|
||||||
..join('companies', 'company_id', 'id');
|
..join('companies', 'company_id', 'id');
|
||||||
|
|
||||||
var richPerson = await query.getOne(new _FakeExecutor());
|
var richPerson = await query.getOne(_FakeExecutor());
|
||||||
print(richPerson.toJson());
|
print(richPerson.toJson());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ class _FakeExecutor extends QueryExecutor {
|
||||||
Future<List<List>> query(
|
Future<List<List>> query(
|
||||||
String tableName, String query, Map<String, dynamic> substitutionValues,
|
String tableName, String query, Map<String, dynamic> substitutionValues,
|
||||||
[returningFields]) async {
|
[returningFields]) async {
|
||||||
var now = new DateTime.now();
|
var now = DateTime.now();
|
||||||
print(
|
print(
|
||||||
'_FakeExecutor received query: $query and values: $substitutionValues');
|
'_FakeExecutor received query: $query and values: $substitutionValues');
|
||||||
return [
|
return [
|
||||||
|
@ -35,7 +35,7 @@ class _FakeExecutor extends QueryExecutor {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<T> transaction<T>(FutureOr<T> Function() f) {
|
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> {
|
class EmployeeQuery extends Query<Employee, EmployeeQueryWhere> {
|
||||||
@override
|
@override
|
||||||
final QueryValues values = new MapQueryValues();
|
final QueryValues values = MapQueryValues();
|
||||||
|
|
||||||
EmployeeQueryWhere _where;
|
EmployeeQueryWhere _where;
|
||||||
|
|
||||||
EmployeeQuery() {
|
EmployeeQuery() {
|
||||||
_where = new EmployeeQueryWhere(this);
|
_where = EmployeeQueryWhere(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -70,11 +70,11 @@ class EmployeeQuery extends Query<Employee, EmployeeQueryWhere> {
|
||||||
['id', 'first_name', 'last_name', 'salary', 'created_at', 'updated_at'];
|
['id', 'first_name', 'last_name', 'salary', 'created_at', 'updated_at'];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
EmployeeQueryWhere newWhereClause() => new EmployeeQueryWhere(this);
|
EmployeeQueryWhere newWhereClause() => EmployeeQueryWhere(this);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Employee deserialize(List row) {
|
Employee deserialize(List row) {
|
||||||
return new Employee(
|
return Employee(
|
||||||
id: row[0].toString(),
|
id: row[0].toString(),
|
||||||
firstName: row[1] as String,
|
firstName: row[1] as String,
|
||||||
lastName: row[2] as String,
|
lastName: row[2] as String,
|
||||||
|
@ -86,12 +86,12 @@ class EmployeeQuery extends Query<Employee, EmployeeQueryWhere> {
|
||||||
|
|
||||||
class EmployeeQueryWhere extends QueryWhere {
|
class EmployeeQueryWhere extends QueryWhere {
|
||||||
EmployeeQueryWhere(EmployeeQuery query)
|
EmployeeQueryWhere(EmployeeQuery query)
|
||||||
: id = new NumericSqlExpressionBuilder(query, 'id'),
|
: id = NumericSqlExpressionBuilder(query, 'id'),
|
||||||
firstName = new StringSqlExpressionBuilder(query, 'first_name'),
|
firstName = StringSqlExpressionBuilder(query, 'first_name'),
|
||||||
lastName = new StringSqlExpressionBuilder(query, 'last_name'),
|
lastName = StringSqlExpressionBuilder(query, 'last_name'),
|
||||||
salary = new NumericSqlExpressionBuilder(query, 'salary'),
|
salary = NumericSqlExpressionBuilder(query, 'salary'),
|
||||||
createdAt = new DateTimeSqlExpressionBuilder(query, 'created_at'),
|
createdAt = DateTimeSqlExpressionBuilder(query, 'created_at'),
|
||||||
updatedAt = new DateTimeSqlExpressionBuilder(query, 'updated_at');
|
updatedAt = DateTimeSqlExpressionBuilder(query, 'updated_at');
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Iterable<SqlExpressionBuilder> get expressionBuilders {
|
Iterable<SqlExpressionBuilder> get expressionBuilders {
|
||||||
|
|
|
@ -41,7 +41,7 @@ class Employee extends _Employee {
|
||||||
double salary,
|
double salary,
|
||||||
DateTime createdAt,
|
DateTime createdAt,
|
||||||
DateTime updatedAt}) {
|
DateTime updatedAt}) {
|
||||||
return new Employee(
|
return Employee(
|
||||||
id: id ?? this.id,
|
id: id ?? this.id,
|
||||||
firstName: firstName ?? this.firstName,
|
firstName: firstName ?? this.firstName,
|
||||||
lastName: lastName ?? this.lastName,
|
lastName: lastName ?? this.lastName,
|
||||||
|
|
|
@ -8,7 +8,7 @@ part of 'main.dart';
|
||||||
|
|
||||||
abstract class EmployeeSerializer {
|
abstract class EmployeeSerializer {
|
||||||
static Employee fromMap(Map map) {
|
static Employee fromMap(Map map) {
|
||||||
return new Employee(
|
return Employee(
|
||||||
id: map['id'] as String,
|
id: map['id'] as String,
|
||||||
firstName: map['first_name'] as String,
|
firstName: map['first_name'] as String,
|
||||||
lastName: map['last_name'] as String,
|
lastName: map['last_name'] as String,
|
||||||
|
@ -41,7 +41,7 @@ abstract class EmployeeSerializer {
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class EmployeeFields {
|
abstract class EmployeeFields {
|
||||||
static const List<String> allFields = const <String>[
|
static const List<String> allFields = <String>[
|
||||||
id,
|
id,
|
||||||
firstName,
|
firstName,
|
||||||
lastName,
|
lastName,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/// A raw SQL statement that specifies a date/time default to the
|
/// A raw SQL statement that specifies a date/time default to the
|
||||||
/// current time.
|
/// 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.
|
/// Can passed to a [MigrationColumn] to default to a raw SQL expression.
|
||||||
class RawSql {
|
class RawSql {
|
||||||
|
@ -11,7 +11,7 @@ class RawSql {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Canonical instance of [ORM]. Implies all defaults.
|
/// Canonical instance of [ORM]. Implies all defaults.
|
||||||
const Orm orm = const Orm();
|
const Orm orm = Orm();
|
||||||
|
|
||||||
class Orm {
|
class Orm {
|
||||||
/// The name of the table to query.
|
/// The name of the table to query.
|
||||||
|
|
|
@ -5,29 +5,32 @@ import 'package:intl/intl.dart' show DateFormat;
|
||||||
import 'package:string_scanner/string_scanner.dart';
|
import 'package:string_scanner/string_scanner.dart';
|
||||||
import 'query.dart';
|
import 'query.dart';
|
||||||
|
|
||||||
final DateFormat dateYmd = new DateFormat('yyyy-MM-dd');
|
final DateFormat dateYmd = DateFormat('yyyy-MM-dd');
|
||||||
final DateFormat dateYmdHms = new DateFormat('yyyy-MM-dd HH:mm:ss');
|
final DateFormat dateYmdHms = DateFormat('yyyy-MM-dd HH:mm:ss');
|
||||||
|
|
||||||
/// The ORM prefers using substitution values, which allow for prepared queries,
|
/// The ORM prefers using substitution values, which allow for prepared queries,
|
||||||
/// and prevent SQL injection attacks.
|
/// and prevent SQL injection attacks.
|
||||||
@deprecated
|
@deprecated
|
||||||
String sanitizeExpression(String unsafe) {
|
String sanitizeExpression(String unsafe) {
|
||||||
var buf = new StringBuffer();
|
var buf = StringBuffer();
|
||||||
var scanner = new StringScanner(unsafe);
|
var scanner = StringScanner(unsafe);
|
||||||
int ch;
|
int ch;
|
||||||
|
|
||||||
while (!scanner.isDone) {
|
while (!scanner.isDone) {
|
||||||
// Ignore comment starts
|
// Ignore comment starts
|
||||||
if (scanner.scan('--') || scanner.scan('/*'))
|
if (scanner.scan('--') || scanner.scan('/*')) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Ignore all single quotes and attempted escape sequences
|
// Ignore all single quotes and attempted escape sequences
|
||||||
else if (scanner.scan("'") || scanner.scan('\\'))
|
else if (scanner.scan("'") || scanner.scan('\\')) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Otherwise, add the next char, unless it's a null byte.
|
// 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);
|
buf.writeCharCode(ch);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return toSql(buf.toString(), withQuotes: false);
|
return toSql(buf.toString(), withQuotes: false);
|
||||||
|
@ -372,17 +375,17 @@ class DateTimeSqlExpressionBuilder extends SqlExpressionBuilder<DateTime> {
|
||||||
: super(query, columnName);
|
: super(query, columnName);
|
||||||
|
|
||||||
NumericSqlExpressionBuilder<int> get year =>
|
NumericSqlExpressionBuilder<int> get year =>
|
||||||
_year ??= new NumericSqlExpressionBuilder(query, 'year');
|
_year ??= NumericSqlExpressionBuilder(query, 'year');
|
||||||
NumericSqlExpressionBuilder<int> get month =>
|
NumericSqlExpressionBuilder<int> get month =>
|
||||||
_month ??= new NumericSqlExpressionBuilder(query, 'month');
|
_month ??= NumericSqlExpressionBuilder(query, 'month');
|
||||||
NumericSqlExpressionBuilder<int> get day =>
|
NumericSqlExpressionBuilder<int> get day =>
|
||||||
_day ??= new NumericSqlExpressionBuilder(query, 'day');
|
_day ??= NumericSqlExpressionBuilder(query, 'day');
|
||||||
NumericSqlExpressionBuilder<int> get hour =>
|
NumericSqlExpressionBuilder<int> get hour =>
|
||||||
_hour ??= new NumericSqlExpressionBuilder(query, 'hour');
|
_hour ??= NumericSqlExpressionBuilder(query, 'hour');
|
||||||
NumericSqlExpressionBuilder<int> get minute =>
|
NumericSqlExpressionBuilder<int> get minute =>
|
||||||
_minute ??= new NumericSqlExpressionBuilder(query, 'minute');
|
_minute ??= NumericSqlExpressionBuilder(query, 'minute');
|
||||||
NumericSqlExpressionBuilder<int> get second =>
|
NumericSqlExpressionBuilder<int> get second =>
|
||||||
_second ??= new NumericSqlExpressionBuilder(query, 'second');
|
_second ??= NumericSqlExpressionBuilder(query, 'second');
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool get hasValue =>
|
bool get hasValue =>
|
||||||
|
@ -462,17 +465,24 @@ class DateTimeSqlExpressionBuilder extends SqlExpressionBuilder<DateTime> {
|
||||||
String compile() {
|
String compile() {
|
||||||
if (_raw?.isNotEmpty == true) return _raw;
|
if (_raw?.isNotEmpty == true) return _raw;
|
||||||
List<String> parts = [];
|
List<String> parts = [];
|
||||||
if (year?.hasValue == true)
|
if (year?.hasValue == true) {
|
||||||
parts.add('YEAR($columnName) ${year.compile()}');
|
parts.add('YEAR($columnName) ${year.compile()}');
|
||||||
if (month?.hasValue == true)
|
}
|
||||||
|
if (month?.hasValue == true) {
|
||||||
parts.add('MONTH($columnName) ${month.compile()}');
|
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()}');
|
parts.add('HOUR($columnName) ${hour.compile()}');
|
||||||
if (minute?.hasValue == true)
|
}
|
||||||
|
if (minute?.hasValue == true) {
|
||||||
parts.add('MINUTE($columnName) ${minute.compile()}');
|
parts.add('MINUTE($columnName) ${minute.compile()}');
|
||||||
if (second?.hasValue == true)
|
}
|
||||||
|
if (second?.hasValue == true) {
|
||||||
parts.add('SECOND($columnName) ${second.compile()}');
|
parts.add('SECOND($columnName) ${second.compile()}');
|
||||||
|
}
|
||||||
|
|
||||||
return parts.isEmpty ? null : parts.join(' AND ');
|
return parts.isEmpty ? null : parts.join(' AND ');
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const List<String> SQL_RESERVED_WORDS = const [
|
const List<String> SQL_RESERVED_WORDS = [
|
||||||
'SELECT',
|
'SELECT',
|
||||||
'UPDATE',
|
'UPDATE',
|
||||||
'INSERT',
|
'INSERT',
|
||||||
|
@ -40,7 +40,7 @@ class PrimaryKey extends Column {
|
||||||
indexType: IndexType.primaryKey);
|
indexType: IndexType.primaryKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Column primaryKey = const PrimaryKey();
|
const Column primaryKey = PrimaryKey();
|
||||||
|
|
||||||
/// Maps to SQL index types.
|
/// Maps to SQL index types.
|
||||||
enum IndexType {
|
enum IndexType {
|
||||||
|
@ -65,61 +65,60 @@ class ColumnType {
|
||||||
|
|
||||||
const ColumnType(this.name);
|
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 smallSerial = ColumnType('smallserial');
|
||||||
static const ColumnType serial = const ColumnType('serial');
|
static const ColumnType serial = ColumnType('serial');
|
||||||
static const ColumnType bigSerial = const ColumnType('bigserial');
|
static const ColumnType bigSerial = ColumnType('bigserial');
|
||||||
|
|
||||||
// Numbers
|
// Numbers
|
||||||
static const ColumnType bigInt = const ColumnType('bigint');
|
static const ColumnType bigInt = ColumnType('bigint');
|
||||||
static const ColumnType int = const ColumnType('int');
|
static const ColumnType int = ColumnType('int');
|
||||||
static const ColumnType smallInt = const ColumnType('smallint');
|
static const ColumnType smallInt = ColumnType('smallint');
|
||||||
static const ColumnType tinyInt = const ColumnType('tinyint');
|
static const ColumnType tinyInt = ColumnType('tinyint');
|
||||||
static const ColumnType bit = const ColumnType('bit');
|
static const ColumnType bit = ColumnType('bit');
|
||||||
static const ColumnType decimal = const ColumnType('decimal');
|
static const ColumnType decimal = ColumnType('decimal');
|
||||||
static const ColumnType numeric = const ColumnType('numeric');
|
static const ColumnType numeric = ColumnType('numeric');
|
||||||
static const ColumnType money = const ColumnType('money');
|
static const ColumnType money = ColumnType('money');
|
||||||
static const ColumnType smallMoney = const ColumnType('smallmoney');
|
static const ColumnType smallMoney = ColumnType('smallmoney');
|
||||||
static const ColumnType float = const ColumnType('float');
|
static const ColumnType float = ColumnType('float');
|
||||||
static const ColumnType real = const ColumnType('real');
|
static const ColumnType real = ColumnType('real');
|
||||||
|
|
||||||
// Dates and times
|
// Dates and times
|
||||||
static const ColumnType dateTime = const ColumnType('datetime');
|
static const ColumnType dateTime = ColumnType('datetime');
|
||||||
static const ColumnType smallDateTime = const ColumnType('smalldatetime');
|
static const ColumnType smallDateTime = ColumnType('smalldatetime');
|
||||||
static const ColumnType date = const ColumnType('date');
|
static const ColumnType date = ColumnType('date');
|
||||||
static const ColumnType time = const ColumnType('time');
|
static const ColumnType time = ColumnType('time');
|
||||||
static const ColumnType timeStamp = const ColumnType('timestamp');
|
static const ColumnType timeStamp = ColumnType('timestamp');
|
||||||
static const ColumnType timeStampWithTimeZone =
|
static const ColumnType timeStampWithTimeZone =
|
||||||
const ColumnType('timestamp with time zone');
|
ColumnType('timestamp with time zone');
|
||||||
|
|
||||||
// Strings
|
// Strings
|
||||||
static const ColumnType char = const ColumnType('char');
|
static const ColumnType char = ColumnType('char');
|
||||||
static const ColumnType varChar = const ColumnType('varchar');
|
static const ColumnType varChar = ColumnType('varchar');
|
||||||
static const ColumnType varCharMax = const ColumnType('varchar(max)');
|
static const ColumnType varCharMax = ColumnType('varchar(max)');
|
||||||
static const ColumnType text = const ColumnType('text');
|
static const ColumnType text = ColumnType('text');
|
||||||
|
|
||||||
// Unicode strings
|
// Unicode strings
|
||||||
static const ColumnType nChar = const ColumnType('nchar');
|
static const ColumnType nChar = ColumnType('nchar');
|
||||||
static const ColumnType nVarChar = const ColumnType('nvarchar');
|
static const ColumnType nVarChar = ColumnType('nvarchar');
|
||||||
static const ColumnType nVarCharMax = const ColumnType('nvarchar(max)');
|
static const ColumnType nVarCharMax = ColumnType('nvarchar(max)');
|
||||||
static const ColumnType nText = const ColumnType('ntext');
|
static const ColumnType nText = ColumnType('ntext');
|
||||||
|
|
||||||
// Binary
|
// Binary
|
||||||
static const ColumnType binary = const ColumnType('binary');
|
static const ColumnType binary = ColumnType('binary');
|
||||||
static const ColumnType varBinary = const ColumnType('varbinary');
|
static const ColumnType varBinary = ColumnType('varbinary');
|
||||||
static const ColumnType varBinaryMax = const ColumnType('varbinary(max)');
|
static const ColumnType varBinaryMax = ColumnType('varbinary(max)');
|
||||||
static const ColumnType image = const ColumnType('image');
|
static const ColumnType image = ColumnType('image');
|
||||||
|
|
||||||
// JSON.
|
// JSON.
|
||||||
static const ColumnType json = const ColumnType('json');
|
static const ColumnType json = ColumnType('json');
|
||||||
static const ColumnType jsonb = const ColumnType('jsonb');
|
static const ColumnType jsonb = ColumnType('jsonb');
|
||||||
|
|
||||||
// Misc.
|
// Misc.
|
||||||
static const ColumnType sqlVariant = const ColumnType('sql_variant');
|
static const ColumnType sqlVariant = ColumnType('sql_variant');
|
||||||
static const ColumnType uniqueIdentifier =
|
static const ColumnType uniqueIdentifier = ColumnType('uniqueidentifier');
|
||||||
const ColumnType('uniqueidentifier');
|
static const ColumnType xml = ColumnType('xml');
|
||||||
static const ColumnType xml = const ColumnType('xml');
|
static const ColumnType cursor = ColumnType('cursor');
|
||||||
static const ColumnType cursor = const ColumnType('cursor');
|
static const ColumnType table = ColumnType('table');
|
||||||
static const ColumnType table = const ColumnType('table');
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,11 +44,11 @@ abstract class QueryBase<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Union<T> union(QueryBase<T> other) {
|
Union<T> union(QueryBase<T> other) {
|
||||||
return new Union(this, other);
|
return Union(this, other);
|
||||||
}
|
}
|
||||||
|
|
||||||
Union<T> unionAll(QueryBase<T> 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) {
|
} else if (obj == null) {
|
||||||
return 'NULL';
|
return 'NULL';
|
||||||
} else if (obj is String) {
|
} else if (obj is String) {
|
||||||
var b = new StringBuffer();
|
var b = StringBuffer();
|
||||||
var escaped = false;
|
var escaped = false;
|
||||||
var it = obj.runes.iterator;
|
var it = obj.runes.iterator;
|
||||||
|
|
||||||
while (it.moveNext()) {
|
while (it.moveNext()) {
|
||||||
if (it.current == $nul)
|
if (it.current == $nul) {
|
||||||
continue; // Skip null byte
|
continue; // Skip null byte
|
||||||
else if (it.current == $single_quote) {
|
} else if (it.current == $single_quote) {
|
||||||
escaped = true;
|
escaped = true;
|
||||||
b.write('\\x');
|
b.write('\\x');
|
||||||
b.write(it.current.toRadixString(16).padLeft(2, '0'));
|
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('\\U');
|
||||||
b.write(it.current.toRadixString(16).padLeft(8, '0'));
|
b.write(it.current.toRadixString(16).padLeft(8, '0'));
|
||||||
} else {
|
} else {
|
||||||
throw new UnsupportedError(
|
throw UnsupportedError(
|
||||||
'toSql() cannot encode a rune of size (${it.currentSize})');
|
'toSql() cannot encode a rune of size (${it.currentSize})');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!withQuotes)
|
if (!withQuotes) {
|
||||||
return b.toString();
|
return b.toString();
|
||||||
else if (escaped)
|
} else if (escaped) {
|
||||||
return "E'$b'";
|
return "E'$b'";
|
||||||
else
|
} else {
|
||||||
return "'$b'";
|
return "'$b'";
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return obj.toString();
|
return obj.toString();
|
||||||
}
|
}
|
||||||
|
@ -140,10 +141,10 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
|
||||||
return n == 0 ? name : '${name}$n';
|
return n == 0 ? name : '${name}$n';
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Makes a new [Where] clause.
|
/// Makes a [Where] clause.
|
||||||
Where newWhereClause() {
|
Where newWhereClause() {
|
||||||
throw new UnsupportedError(
|
throw UnsupportedError(
|
||||||
'This instance does not support creating new WHERE clauses.');
|
'This instance does not support creating WHERE clauses.');
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Determines whether this query can be compiled.
|
/// 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.
|
/// Used to prevent ambiguities in joins.
|
||||||
bool canCompile(Set<String> trampoline) => true;
|
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) {
|
void andWhere(void Function(Where) f) {
|
||||||
var w = newWhereClause();
|
var w = newWhereClause();
|
||||||
f(w);
|
f(w);
|
||||||
where.and(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) {
|
void notWhere(void Function(Where) f) {
|
||||||
var w = newWhereClause();
|
var w = newWhereClause();
|
||||||
f(w);
|
f(w);
|
||||||
where.not(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) {
|
void orWhere(void Function(Where) f) {
|
||||||
var w = newWhereClause();
|
var w = newWhereClause();
|
||||||
f(w);
|
f(w);
|
||||||
|
@ -189,7 +190,7 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
|
||||||
|
|
||||||
/// Sorts the results by a key.
|
/// Sorts the results by a key.
|
||||||
void orderBy(String key, {bool descending = false}) {
|
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.
|
/// 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';
|
var a = 'a$i';
|
||||||
if (trampoline.add(a)) {
|
if (trampoline.add(a)) {
|
||||||
return a;
|
return a;
|
||||||
} else
|
} else {
|
||||||
i++;
|
i++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String _compileJoin(tableName, Set<String> trampoline) {
|
String _compileJoin(tableName, Set<String> trampoline) {
|
||||||
if (tableName is String)
|
if (tableName is String) {
|
||||||
return tableName;
|
return tableName;
|
||||||
else if (tableName is Query) {
|
} else if (tableName is Query) {
|
||||||
var c = tableName.compile(trampoline);
|
var c = tableName.compile(trampoline);
|
||||||
if (c == null) return c;
|
if (c == null) return c;
|
||||||
return '($c)';
|
return '($c)';
|
||||||
|
@ -241,7 +243,7 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
|
||||||
|
|
||||||
var to = _compileJoin(tableName, trampoline);
|
var to = _compileJoin(tableName, trampoline);
|
||||||
if (to != null) {
|
if (to != null) {
|
||||||
_joins.add(new JoinBuilder(type, this, to, localKey, foreignKey,
|
_joins.add(JoinBuilder(type, this, to, localKey, foreignKey,
|
||||||
op: op,
|
op: op,
|
||||||
alias: _joinAlias(trampoline),
|
alias: _joinAlias(trampoline),
|
||||||
additionalFields: additionalFields));
|
additionalFields: additionalFields));
|
||||||
|
@ -305,14 +307,14 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
includeTableName = includeTableName || _joins.isNotEmpty;
|
includeTableName = includeTableName || _joins.isNotEmpty;
|
||||||
var b = new StringBuffer(preamble ?? 'SELECT');
|
var b = StringBuffer(preamble ?? 'SELECT');
|
||||||
b.write(' ');
|
b.write(' ');
|
||||||
List<String> f;
|
List<String> f;
|
||||||
|
|
||||||
if (fields == null) {
|
if (fields == null) {
|
||||||
f = ['*'];
|
f = ['*'];
|
||||||
} else {
|
} else {
|
||||||
f = new List<String>.from(fields.map((s) {
|
f = List<String>.from(fields.map((s) {
|
||||||
var ss = includeTableName ? '$tableName.$s' : s;
|
var ss = includeTableName ? '$tableName.$s' : s;
|
||||||
var cast = casts[s];
|
var cast = casts[s];
|
||||||
if (cast != null) ss = 'CAST ($ss AS $cast)';
|
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 (_limit != null) b.write(' LIMIT $_limit');
|
||||||
if (_offset != null) b.write(' OFFSET $_offset');
|
if (_offset != null) b.write(' OFFSET $_offset');
|
||||||
if (_groupBy != null) b.write(' GROUP BY $_groupBy');
|
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();
|
return b.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,7 +386,7 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
|
||||||
var insertion = values.compileInsert(this, tableName);
|
var insertion = values.compileInsert(this, tableName);
|
||||||
|
|
||||||
if (insertion == null) {
|
if (insertion == null) {
|
||||||
throw new StateError('No values have been specified for update.');
|
throw StateError('No values have been specified for update.');
|
||||||
} else {
|
} else {
|
||||||
// TODO: How to do this in a non-Postgres DB?
|
// TODO: How to do this in a non-Postgres DB?
|
||||||
var returning = fields.map(adornWithTableName).join(', ');
|
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 {
|
Future<List<T>> update(QueryExecutor executor) async {
|
||||||
var updateSql = new StringBuffer('UPDATE $tableName ');
|
var updateSql = StringBuffer('UPDATE $tableName ');
|
||||||
var valuesClause = values.compileForUpdate(this);
|
var valuesClause = values.compileForUpdate(this);
|
||||||
|
|
||||||
if (valuesClause == null) {
|
if (valuesClause == null) {
|
||||||
throw new StateError('No values have been specified for update.');
|
throw StateError('No values have been specified for update.');
|
||||||
} else {
|
} else {
|
||||||
updateSql.write(' $valuesClause');
|
updateSql.write(' $valuesClause');
|
||||||
var whereClause = where.compile();
|
var whereClause = where.compile();
|
||||||
|
@ -442,7 +446,7 @@ abstract class QueryValues {
|
||||||
if (data.isEmpty) return null;
|
if (data.isEmpty) return null;
|
||||||
|
|
||||||
var fieldSet = data.keys.join(', ');
|
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;
|
int i = 0;
|
||||||
|
|
||||||
for (var entry in data.entries) {
|
for (var entry in data.entries) {
|
||||||
|
@ -461,7 +465,7 @@ abstract class QueryValues {
|
||||||
String compileForUpdate(Query query) {
|
String compileForUpdate(Query query) {
|
||||||
var data = toMap();
|
var data = toMap();
|
||||||
if (data.isEmpty) return null;
|
if (data.isEmpty) return null;
|
||||||
var b = new StringBuffer('SET');
|
var b = StringBuffer('SET');
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
for (var entry in data.entries) {
|
for (var entry in data.entries) {
|
||||||
|
@ -489,9 +493,9 @@ class MapQueryValues extends QueryValues {
|
||||||
|
|
||||||
/// Builds a SQL `WHERE` clause.
|
/// Builds a SQL `WHERE` clause.
|
||||||
abstract class QueryWhere {
|
abstract class QueryWhere {
|
||||||
final Set<QueryWhere> _and = new Set();
|
final Set<QueryWhere> _and = Set();
|
||||||
final Set<QueryWhere> _not = new Set();
|
final Set<QueryWhere> _not = Set();
|
||||||
final Set<QueryWhere> _or = new Set();
|
final Set<QueryWhere> _or = Set();
|
||||||
|
|
||||||
Iterable<SqlExpressionBuilder> get expressionBuilders;
|
Iterable<SqlExpressionBuilder> get expressionBuilders;
|
||||||
|
|
||||||
|
@ -508,7 +512,7 @@ abstract class QueryWhere {
|
||||||
}
|
}
|
||||||
|
|
||||||
String compile({String tableName}) {
|
String compile({String tableName}) {
|
||||||
var b = new StringBuffer();
|
var b = StringBuffer();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
for (var builder in expressionBuilders) {
|
for (var builder in expressionBuilders) {
|
||||||
|
@ -608,7 +612,7 @@ class JoinBuilder {
|
||||||
|
|
||||||
String compile(Set<String> trampoline) {
|
String compile(Set<String> trampoline) {
|
||||||
if (to == null) return null;
|
if (to == null) return null;
|
||||||
var b = new StringBuffer();
|
var b = StringBuffer();
|
||||||
var left = '${from.tableName}.$key';
|
var left = '${from.tableName}.$key';
|
||||||
var right = fieldName;
|
var right = fieldName;
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ class HasMany extends Relationship {
|
||||||
cascadeOnDelete: cascadeOnDelete == true);
|
cascadeOnDelete: cascadeOnDelete == true);
|
||||||
}
|
}
|
||||||
|
|
||||||
const HasMany hasMany = const HasMany();
|
const HasMany hasMany = HasMany();
|
||||||
|
|
||||||
class HasOne extends Relationship {
|
class HasOne extends Relationship {
|
||||||
const HasOne(
|
const HasOne(
|
||||||
|
@ -47,7 +47,7 @@ class HasOne extends Relationship {
|
||||||
cascadeOnDelete: cascadeOnDelete == true);
|
cascadeOnDelete: cascadeOnDelete == true);
|
||||||
}
|
}
|
||||||
|
|
||||||
const HasOne hasOne = const HasOne();
|
const HasOne hasOne = HasOne();
|
||||||
|
|
||||||
class BelongsTo extends Relationship {
|
class BelongsTo extends Relationship {
|
||||||
const BelongsTo({String localKey, String foreignKey, String foreignTable})
|
const BelongsTo({String localKey, String foreignKey, String foreignTable})
|
||||||
|
@ -57,7 +57,7 @@ class BelongsTo extends Relationship {
|
||||||
foreignTable: foreignTable);
|
foreignTable: foreignTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
const BelongsTo belongsTo = const BelongsTo();
|
const BelongsTo belongsTo = BelongsTo();
|
||||||
|
|
||||||
class ManyToMany extends Relationship {
|
class ManyToMany extends Relationship {
|
||||||
final Type through;
|
final Type through;
|
||||||
|
|
Loading…
Reference in a new issue