mirror of https://github.com/AMT-Cheif/drift.git
Begin with simple ast and parser
This commit is contained in:
parent
cb8cb6b1a0
commit
69f0b9b393
|
@ -25,9 +25,21 @@ class UseMoor {
|
|||
/// For instructions on how to write a dao, see the documentation of [UseDao]
|
||||
final List<Type> daos;
|
||||
|
||||
/// Optionally, a list of queries. Moor will generate matching methods for the
|
||||
/// variables and return types.
|
||||
// todo better documentation
|
||||
final List<Sql> queries;
|
||||
|
||||
/// Use this class as an annotation to inform moor_generator that a database
|
||||
/// class should be generated using the specified [UseMoor.tables].
|
||||
const UseMoor({@required this.tables, this.daos = const []});
|
||||
const UseMoor({@required this.tables, this.daos = const [], this.queries});
|
||||
}
|
||||
|
||||
class Sql {
|
||||
final String name;
|
||||
final String query;
|
||||
|
||||
const Sql(this.name, this.query);
|
||||
}
|
||||
|
||||
/// Annotation to use on classes that implement [DatabaseAccessor]. It specifies
|
||||
|
@ -51,6 +63,8 @@ class UseMoor {
|
|||
class UseDao {
|
||||
/// The tables accessed by this DAO.
|
||||
final List<Type> tables;
|
||||
// todo better documentation
|
||||
final List<Sql> queries;
|
||||
|
||||
const UseDao({@required this.tables});
|
||||
const UseDao({@required this.tables, this.queries});
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ class _$ColumnName extends ColumnName {
|
|||
@override
|
||||
final String name;
|
||||
|
||||
factory _$ColumnName([void updates(ColumnNameBuilder b)]) =>
|
||||
factory _$ColumnName([void Function(ColumnNameBuilder) updates]) =>
|
||||
(new ColumnNameBuilder()..update(updates)).build();
|
||||
|
||||
_$ColumnName._({this.implicit, this.name}) : super._() {
|
||||
|
@ -25,7 +25,7 @@ class _$ColumnName extends ColumnName {
|
|||
}
|
||||
|
||||
@override
|
||||
ColumnName rebuild(void updates(ColumnNameBuilder b)) =>
|
||||
ColumnName rebuild(void Function(ColumnNameBuilder) updates) =>
|
||||
(toBuilder()..update(updates)).build();
|
||||
|
||||
@override
|
||||
|
@ -84,7 +84,7 @@ class ColumnNameBuilder implements Builder<ColumnName, ColumnNameBuilder> {
|
|||
}
|
||||
|
||||
@override
|
||||
void update(void updates(ColumnNameBuilder b)) {
|
||||
void update(void Function(ColumnNameBuilder) updates) {
|
||||
if (updates != null) updates(this);
|
||||
}
|
||||
|
||||
|
@ -102,13 +102,15 @@ class _$LimitingTextLength extends LimitingTextLength {
|
|||
@override
|
||||
final int maxLength;
|
||||
|
||||
factory _$LimitingTextLength([void updates(LimitingTextLengthBuilder b)]) =>
|
||||
factory _$LimitingTextLength(
|
||||
[void Function(LimitingTextLengthBuilder) updates]) =>
|
||||
(new LimitingTextLengthBuilder()..update(updates)).build();
|
||||
|
||||
_$LimitingTextLength._({this.minLength, this.maxLength}) : super._();
|
||||
|
||||
@override
|
||||
LimitingTextLength rebuild(void updates(LimitingTextLengthBuilder b)) =>
|
||||
LimitingTextLength rebuild(
|
||||
void Function(LimitingTextLengthBuilder) updates) =>
|
||||
(toBuilder()..update(updates)).build();
|
||||
|
||||
@override
|
||||
|
@ -169,7 +171,7 @@ class LimitingTextLengthBuilder
|
|||
}
|
||||
|
||||
@override
|
||||
void update(void updates(LimitingTextLengthBuilder b)) {
|
||||
void update(void Function(LimitingTextLengthBuilder) updates) {
|
||||
if (updates != null) updates(this);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
abstract class Expression {
|
||||
const Expression();
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
import 'package:built_value/built_value.dart';
|
||||
|
||||
import 'expressions.dart';
|
||||
|
||||
part 'literals.g.dart';
|
||||
|
||||
// https://www.sqlite.org/syntax/literal-value.html
|
||||
|
||||
class NullLiteral extends Expression {
|
||||
const NullLiteral();
|
||||
|
||||
@override
|
||||
String toString() => 'NULL';
|
||||
|
||||
@override
|
||||
int get hashCode => runtimeType.hashCode;
|
||||
|
||||
@override
|
||||
bool operator ==(other) => identical(this, other) || other is NullLiteral;
|
||||
}
|
||||
|
||||
abstract class BooleanLiteral extends Expression
|
||||
implements Built<BooleanLiteral, BooleanLiteralBuilder> {
|
||||
bool get value;
|
||||
|
||||
BooleanLiteral._();
|
||||
factory BooleanLiteral.from(bool value) =>
|
||||
BooleanLiteral((b) => b.value = value);
|
||||
|
||||
factory BooleanLiteral(Function(BooleanLiteralBuilder) updates) =
|
||||
_$BooleanLiteral;
|
||||
}
|
||||
|
||||
enum CurrentTimeAccessor { currentTime, currentDate, currentTimestamp }
|
||||
|
||||
/// Represents the CURRENT_TIME, CURRENT_DATE or CURRENT_TIMESTAMP mode.
|
||||
abstract class CurrentTimeResolver extends Expression
|
||||
implements Built<CurrentTimeResolver, CurrentTimeResolverBuilder> {
|
||||
CurrentTimeAccessor get mode;
|
||||
|
||||
CurrentTimeResolver._();
|
||||
factory CurrentTimeResolver.mode(CurrentTimeAccessor mode) {
|
||||
return CurrentTimeResolver((b) => b.mode = mode);
|
||||
}
|
||||
factory CurrentTimeResolver(Function(CurrentTimeResolverBuilder) updates) =
|
||||
_$CurrentTimeResolver;
|
||||
}
|
||||
|
||||
abstract class NumericLiteral extends Expression
|
||||
implements Built<NumericLiteral, NumericLiteralBuilder> {
|
||||
num get value;
|
||||
NumericLiteral._();
|
||||
factory NumericLiteral(Function(NumericLiteralBuilder) updates) =
|
||||
_$NumericLiteral;
|
||||
}
|
||||
|
||||
abstract class StringLiteral extends Expression
|
||||
implements Built<StringLiteral, StringLiteralBuilder> {
|
||||
bool get isBlob;
|
||||
String get content;
|
||||
|
||||
StringLiteral._();
|
||||
factory StringLiteral(Function(StringLiteralBuilder) updates) =
|
||||
_$StringLiteral;
|
||||
}
|
|
@ -0,0 +1,338 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'literals.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// BuiltValueGenerator
|
||||
// **************************************************************************
|
||||
|
||||
class _$BooleanLiteral extends BooleanLiteral {
|
||||
@override
|
||||
final bool value;
|
||||
|
||||
factory _$BooleanLiteral([void Function(BooleanLiteralBuilder) updates]) =>
|
||||
(new BooleanLiteralBuilder()..update(updates)).build();
|
||||
|
||||
_$BooleanLiteral._({this.value}) : super._() {
|
||||
if (value == null) {
|
||||
throw new BuiltValueNullFieldError('BooleanLiteral', 'value');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
BooleanLiteral rebuild(void Function(BooleanLiteralBuilder) updates) =>
|
||||
(toBuilder()..update(updates)).build();
|
||||
|
||||
@override
|
||||
BooleanLiteralBuilder toBuilder() =>
|
||||
new BooleanLiteralBuilder()..replace(this);
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(other, this)) return true;
|
||||
return other is BooleanLiteral && value == other.value;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return $jf($jc(0, value.hashCode));
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return (newBuiltValueToStringHelper('BooleanLiteral')..add('value', value))
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
||||
class BooleanLiteralBuilder
|
||||
implements Builder<BooleanLiteral, BooleanLiteralBuilder> {
|
||||
_$BooleanLiteral _$v;
|
||||
|
||||
bool _value;
|
||||
bool get value => _$this._value;
|
||||
set value(bool value) => _$this._value = value;
|
||||
|
||||
BooleanLiteralBuilder();
|
||||
|
||||
BooleanLiteralBuilder get _$this {
|
||||
if (_$v != null) {
|
||||
_value = _$v.value;
|
||||
_$v = null;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@override
|
||||
void replace(BooleanLiteral other) {
|
||||
if (other == null) {
|
||||
throw new ArgumentError.notNull('other');
|
||||
}
|
||||
_$v = other as _$BooleanLiteral;
|
||||
}
|
||||
|
||||
@override
|
||||
void update(void Function(BooleanLiteralBuilder) updates) {
|
||||
if (updates != null) updates(this);
|
||||
}
|
||||
|
||||
@override
|
||||
_$BooleanLiteral build() {
|
||||
final _$result = _$v ?? new _$BooleanLiteral._(value: value);
|
||||
replace(_$result);
|
||||
return _$result;
|
||||
}
|
||||
}
|
||||
|
||||
class _$CurrentTimeResolver extends CurrentTimeResolver {
|
||||
@override
|
||||
final CurrentTimeAccessor mode;
|
||||
|
||||
factory _$CurrentTimeResolver(
|
||||
[void Function(CurrentTimeResolverBuilder) updates]) =>
|
||||
(new CurrentTimeResolverBuilder()..update(updates)).build();
|
||||
|
||||
_$CurrentTimeResolver._({this.mode}) : super._() {
|
||||
if (mode == null) {
|
||||
throw new BuiltValueNullFieldError('CurrentTimeResolver', 'mode');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
CurrentTimeResolver rebuild(
|
||||
void Function(CurrentTimeResolverBuilder) updates) =>
|
||||
(toBuilder()..update(updates)).build();
|
||||
|
||||
@override
|
||||
CurrentTimeResolverBuilder toBuilder() =>
|
||||
new CurrentTimeResolverBuilder()..replace(this);
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(other, this)) return true;
|
||||
return other is CurrentTimeResolver && mode == other.mode;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return $jf($jc(0, mode.hashCode));
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return (newBuiltValueToStringHelper('CurrentTimeResolver')
|
||||
..add('mode', mode))
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
||||
class CurrentTimeResolverBuilder
|
||||
implements Builder<CurrentTimeResolver, CurrentTimeResolverBuilder> {
|
||||
_$CurrentTimeResolver _$v;
|
||||
|
||||
CurrentTimeAccessor _mode;
|
||||
CurrentTimeAccessor get mode => _$this._mode;
|
||||
set mode(CurrentTimeAccessor mode) => _$this._mode = mode;
|
||||
|
||||
CurrentTimeResolverBuilder();
|
||||
|
||||
CurrentTimeResolverBuilder get _$this {
|
||||
if (_$v != null) {
|
||||
_mode = _$v.mode;
|
||||
_$v = null;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@override
|
||||
void replace(CurrentTimeResolver other) {
|
||||
if (other == null) {
|
||||
throw new ArgumentError.notNull('other');
|
||||
}
|
||||
_$v = other as _$CurrentTimeResolver;
|
||||
}
|
||||
|
||||
@override
|
||||
void update(void Function(CurrentTimeResolverBuilder) updates) {
|
||||
if (updates != null) updates(this);
|
||||
}
|
||||
|
||||
@override
|
||||
_$CurrentTimeResolver build() {
|
||||
final _$result = _$v ?? new _$CurrentTimeResolver._(mode: mode);
|
||||
replace(_$result);
|
||||
return _$result;
|
||||
}
|
||||
}
|
||||
|
||||
class _$NumericLiteral extends NumericLiteral {
|
||||
@override
|
||||
final num value;
|
||||
|
||||
factory _$NumericLiteral([void Function(NumericLiteralBuilder) updates]) =>
|
||||
(new NumericLiteralBuilder()..update(updates)).build();
|
||||
|
||||
_$NumericLiteral._({this.value}) : super._() {
|
||||
if (value == null) {
|
||||
throw new BuiltValueNullFieldError('NumericLiteral', 'value');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
NumericLiteral rebuild(void Function(NumericLiteralBuilder) updates) =>
|
||||
(toBuilder()..update(updates)).build();
|
||||
|
||||
@override
|
||||
NumericLiteralBuilder toBuilder() =>
|
||||
new NumericLiteralBuilder()..replace(this);
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(other, this)) return true;
|
||||
return other is NumericLiteral && value == other.value;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return $jf($jc(0, value.hashCode));
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return (newBuiltValueToStringHelper('NumericLiteral')..add('value', value))
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
||||
class NumericLiteralBuilder
|
||||
implements Builder<NumericLiteral, NumericLiteralBuilder> {
|
||||
_$NumericLiteral _$v;
|
||||
|
||||
num _value;
|
||||
num get value => _$this._value;
|
||||
set value(num value) => _$this._value = value;
|
||||
|
||||
NumericLiteralBuilder();
|
||||
|
||||
NumericLiteralBuilder get _$this {
|
||||
if (_$v != null) {
|
||||
_value = _$v.value;
|
||||
_$v = null;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@override
|
||||
void replace(NumericLiteral other) {
|
||||
if (other == null) {
|
||||
throw new ArgumentError.notNull('other');
|
||||
}
|
||||
_$v = other as _$NumericLiteral;
|
||||
}
|
||||
|
||||
@override
|
||||
void update(void Function(NumericLiteralBuilder) updates) {
|
||||
if (updates != null) updates(this);
|
||||
}
|
||||
|
||||
@override
|
||||
_$NumericLiteral build() {
|
||||
final _$result = _$v ?? new _$NumericLiteral._(value: value);
|
||||
replace(_$result);
|
||||
return _$result;
|
||||
}
|
||||
}
|
||||
|
||||
class _$StringLiteral extends StringLiteral {
|
||||
@override
|
||||
final bool isBlob;
|
||||
@override
|
||||
final String content;
|
||||
|
||||
factory _$StringLiteral([void Function(StringLiteralBuilder) updates]) =>
|
||||
(new StringLiteralBuilder()..update(updates)).build();
|
||||
|
||||
_$StringLiteral._({this.isBlob, this.content}) : super._() {
|
||||
if (isBlob == null) {
|
||||
throw new BuiltValueNullFieldError('StringLiteral', 'isBlob');
|
||||
}
|
||||
if (content == null) {
|
||||
throw new BuiltValueNullFieldError('StringLiteral', 'content');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
StringLiteral rebuild(void Function(StringLiteralBuilder) updates) =>
|
||||
(toBuilder()..update(updates)).build();
|
||||
|
||||
@override
|
||||
StringLiteralBuilder toBuilder() => new StringLiteralBuilder()..replace(this);
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(other, this)) return true;
|
||||
return other is StringLiteral &&
|
||||
isBlob == other.isBlob &&
|
||||
content == other.content;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return $jf($jc($jc(0, isBlob.hashCode), content.hashCode));
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return (newBuiltValueToStringHelper('StringLiteral')
|
||||
..add('isBlob', isBlob)
|
||||
..add('content', content))
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
||||
class StringLiteralBuilder
|
||||
implements Builder<StringLiteral, StringLiteralBuilder> {
|
||||
_$StringLiteral _$v;
|
||||
|
||||
bool _isBlob;
|
||||
bool get isBlob => _$this._isBlob;
|
||||
set isBlob(bool isBlob) => _$this._isBlob = isBlob;
|
||||
|
||||
String _content;
|
||||
String get content => _$this._content;
|
||||
set content(String content) => _$this._content = content;
|
||||
|
||||
StringLiteralBuilder();
|
||||
|
||||
StringLiteralBuilder get _$this {
|
||||
if (_$v != null) {
|
||||
_isBlob = _$v.isBlob;
|
||||
_content = _$v.content;
|
||||
_$v = null;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@override
|
||||
void replace(StringLiteral other) {
|
||||
if (other == null) {
|
||||
throw new ArgumentError.notNull('other');
|
||||
}
|
||||
_$v = other as _$StringLiteral;
|
||||
}
|
||||
|
||||
@override
|
||||
void update(void Function(StringLiteralBuilder) updates) {
|
||||
if (updates != null) updates(this);
|
||||
}
|
||||
|
||||
@override
|
||||
_$StringLiteral build() {
|
||||
final _$result =
|
||||
_$v ?? new _$StringLiteral._(isBlob: isBlob, content: content);
|
||||
replace(_$result);
|
||||
return _$result;
|
||||
}
|
||||
}
|
||||
|
||||
// ignore_for_file: always_put_control_body_on_new_line,always_specify_types,annotate_overrides,avoid_annotating_with_dynamic,avoid_as,avoid_catches_without_on_clauses,avoid_returning_this,lines_longer_than_80_chars,omit_local_variable_types,prefer_expression_function_bodies,sort_constructors_first,test_types_in_equals,unnecessary_const,unnecessary_new
|
|
@ -0,0 +1,34 @@
|
|||
import 'package:built_value/built_value.dart';
|
||||
|
||||
import 'package:moor_generator/src/sql/ast/expressions/expressions.dart';
|
||||
|
||||
part 'columns.g.dart';
|
||||
|
||||
/// https://www.sqlite.org/syntax/result-column.html
|
||||
abstract class ResultColumn {}
|
||||
|
||||
abstract class ExprResultColumn extends ResultColumn
|
||||
implements Built<ExprResultColumn, ExprResultColumnBuilder> {
|
||||
Expression get expr;
|
||||
@nullable
|
||||
String get alias;
|
||||
|
||||
ExprResultColumn._();
|
||||
factory ExprResultColumn(Function(ExprResultColumnBuilder builder) updates) =
|
||||
_$ExprResultColumn;
|
||||
}
|
||||
|
||||
abstract class StarResultColumn extends ResultColumn
|
||||
implements Built<StarResultColumn, StarResultColumnBuilder> {
|
||||
/// When non-null, refers to the "table.*" select expression. Otherwise,
|
||||
/// refers to all tables in the query (just *).
|
||||
@nullable
|
||||
String get table;
|
||||
|
||||
StarResultColumn._();
|
||||
factory StarResultColumn.from({String table}) =>
|
||||
StarResultColumn((b) => b.table = table);
|
||||
|
||||
factory StarResultColumn(Function(StarResultColumnBuilder builder) updates) =
|
||||
_$StarResultColumn;
|
||||
}
|
|
@ -0,0 +1,175 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'columns.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// BuiltValueGenerator
|
||||
// **************************************************************************
|
||||
|
||||
class _$ExprResultColumn extends ExprResultColumn {
|
||||
@override
|
||||
final Expression expr;
|
||||
@override
|
||||
final String alias;
|
||||
|
||||
factory _$ExprResultColumn(
|
||||
[void Function(ExprResultColumnBuilder) updates]) =>
|
||||
(new ExprResultColumnBuilder()..update(updates)).build();
|
||||
|
||||
_$ExprResultColumn._({this.expr, this.alias}) : super._() {
|
||||
if (expr == null) {
|
||||
throw new BuiltValueNullFieldError('ExprResultColumn', 'expr');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
ExprResultColumn rebuild(void Function(ExprResultColumnBuilder) updates) =>
|
||||
(toBuilder()..update(updates)).build();
|
||||
|
||||
@override
|
||||
ExprResultColumnBuilder toBuilder() =>
|
||||
new ExprResultColumnBuilder()..replace(this);
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(other, this)) return true;
|
||||
return other is ExprResultColumn &&
|
||||
expr == other.expr &&
|
||||
alias == other.alias;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return $jf($jc($jc(0, expr.hashCode), alias.hashCode));
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return (newBuiltValueToStringHelper('ExprResultColumn')
|
||||
..add('expr', expr)
|
||||
..add('alias', alias))
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
||||
class ExprResultColumnBuilder
|
||||
implements Builder<ExprResultColumn, ExprResultColumnBuilder> {
|
||||
_$ExprResultColumn _$v;
|
||||
|
||||
Expression _expr;
|
||||
Expression get expr => _$this._expr;
|
||||
set expr(Expression expr) => _$this._expr = expr;
|
||||
|
||||
String _alias;
|
||||
String get alias => _$this._alias;
|
||||
set alias(String alias) => _$this._alias = alias;
|
||||
|
||||
ExprResultColumnBuilder();
|
||||
|
||||
ExprResultColumnBuilder get _$this {
|
||||
if (_$v != null) {
|
||||
_expr = _$v.expr;
|
||||
_alias = _$v.alias;
|
||||
_$v = null;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@override
|
||||
void replace(ExprResultColumn other) {
|
||||
if (other == null) {
|
||||
throw new ArgumentError.notNull('other');
|
||||
}
|
||||
_$v = other as _$ExprResultColumn;
|
||||
}
|
||||
|
||||
@override
|
||||
void update(void Function(ExprResultColumnBuilder) updates) {
|
||||
if (updates != null) updates(this);
|
||||
}
|
||||
|
||||
@override
|
||||
_$ExprResultColumn build() {
|
||||
final _$result = _$v ?? new _$ExprResultColumn._(expr: expr, alias: alias);
|
||||
replace(_$result);
|
||||
return _$result;
|
||||
}
|
||||
}
|
||||
|
||||
class _$StarResultColumn extends StarResultColumn {
|
||||
@override
|
||||
final String table;
|
||||
|
||||
factory _$StarResultColumn(
|
||||
[void Function(StarResultColumnBuilder) updates]) =>
|
||||
(new StarResultColumnBuilder()..update(updates)).build();
|
||||
|
||||
_$StarResultColumn._({this.table}) : super._();
|
||||
|
||||
@override
|
||||
StarResultColumn rebuild(void Function(StarResultColumnBuilder) updates) =>
|
||||
(toBuilder()..update(updates)).build();
|
||||
|
||||
@override
|
||||
StarResultColumnBuilder toBuilder() =>
|
||||
new StarResultColumnBuilder()..replace(this);
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(other, this)) return true;
|
||||
return other is StarResultColumn && table == other.table;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return $jf($jc(0, table.hashCode));
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return (newBuiltValueToStringHelper('StarResultColumn')
|
||||
..add('table', table))
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
||||
class StarResultColumnBuilder
|
||||
implements Builder<StarResultColumn, StarResultColumnBuilder> {
|
||||
_$StarResultColumn _$v;
|
||||
|
||||
String _table;
|
||||
String get table => _$this._table;
|
||||
set table(String table) => _$this._table = table;
|
||||
|
||||
StarResultColumnBuilder();
|
||||
|
||||
StarResultColumnBuilder get _$this {
|
||||
if (_$v != null) {
|
||||
_table = _$v.table;
|
||||
_$v = null;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@override
|
||||
void replace(StarResultColumn other) {
|
||||
if (other == null) {
|
||||
throw new ArgumentError.notNull('other');
|
||||
}
|
||||
_$v = other as _$StarResultColumn;
|
||||
}
|
||||
|
||||
@override
|
||||
void update(void Function(StarResultColumnBuilder) updates) {
|
||||
if (updates != null) updates(this);
|
||||
}
|
||||
|
||||
@override
|
||||
_$StarResultColumn build() {
|
||||
final _$result = _$v ?? new _$StarResultColumn._(table: table);
|
||||
replace(_$result);
|
||||
return _$result;
|
||||
}
|
||||
}
|
||||
|
||||
// ignore_for_file: always_put_control_body_on_new_line,always_specify_types,annotate_overrides,avoid_annotating_with_dynamic,avoid_as,avoid_catches_without_on_clauses,avoid_returning_this,lines_longer_than_80_chars,omit_local_variable_types,prefer_expression_function_bodies,sort_constructors_first,test_types_in_equals,unnecessary_const,unnecessary_new
|
|
@ -0,0 +1,40 @@
|
|||
import 'package:built_value/built_value.dart';
|
||||
import 'package:built_collection/built_collection.dart';
|
||||
import 'package:moor_generator/src/sql/ast/expressions/expressions.dart';
|
||||
import 'columns.dart';
|
||||
|
||||
part 'select.g.dart';
|
||||
|
||||
abstract class SelectStatement
|
||||
implements Built<SelectStatement, SelectStatementBuilder> {
|
||||
BuiltList<ResultColumn> get columns;
|
||||
BuiltList<SelectTarget> get from;
|
||||
@nullable
|
||||
Expression get where;
|
||||
@nullable
|
||||
Limit get limit;
|
||||
|
||||
SelectStatement._();
|
||||
factory SelectStatement(void Function(SelectStatementBuilder) builder) =
|
||||
_$SelectStatement;
|
||||
}
|
||||
|
||||
/// Anything that can appear behind a "FROM" clause in a select statement.
|
||||
abstract class SelectTarget {}
|
||||
|
||||
abstract class TableTarget implements Built<TableTarget, TableTargetBuilder> {
|
||||
String get table;
|
||||
|
||||
TableTarget._();
|
||||
factory TableTarget(void Function(TableTargetBuilder) builder) =
|
||||
_$TableTarget;
|
||||
}
|
||||
|
||||
abstract class Limit implements Built<Limit, LimitBuilder> {
|
||||
Expression get amount;
|
||||
@nullable
|
||||
Expression get offset;
|
||||
|
||||
Limit._();
|
||||
factory Limit(void Function(LimitBuilder) builder) = _$Limit;
|
||||
}
|
|
@ -0,0 +1,308 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'select.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// BuiltValueGenerator
|
||||
// **************************************************************************
|
||||
|
||||
class _$SelectStatement extends SelectStatement {
|
||||
@override
|
||||
final BuiltList<ResultColumn> columns;
|
||||
@override
|
||||
final BuiltList<SelectTarget> from;
|
||||
@override
|
||||
final Expression where;
|
||||
@override
|
||||
final Limit limit;
|
||||
|
||||
factory _$SelectStatement([void Function(SelectStatementBuilder) updates]) =>
|
||||
(new SelectStatementBuilder()..update(updates)).build();
|
||||
|
||||
_$SelectStatement._({this.columns, this.from, this.where, this.limit})
|
||||
: super._() {
|
||||
if (columns == null) {
|
||||
throw new BuiltValueNullFieldError('SelectStatement', 'columns');
|
||||
}
|
||||
if (from == null) {
|
||||
throw new BuiltValueNullFieldError('SelectStatement', 'from');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
SelectStatement rebuild(void Function(SelectStatementBuilder) updates) =>
|
||||
(toBuilder()..update(updates)).build();
|
||||
|
||||
@override
|
||||
SelectStatementBuilder toBuilder() =>
|
||||
new SelectStatementBuilder()..replace(this);
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(other, this)) return true;
|
||||
return other is SelectStatement &&
|
||||
columns == other.columns &&
|
||||
from == other.from &&
|
||||
where == other.where &&
|
||||
limit == other.limit;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return $jf($jc(
|
||||
$jc($jc($jc(0, columns.hashCode), from.hashCode), where.hashCode),
|
||||
limit.hashCode));
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return (newBuiltValueToStringHelper('SelectStatement')
|
||||
..add('columns', columns)
|
||||
..add('from', from)
|
||||
..add('where', where)
|
||||
..add('limit', limit))
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
||||
class SelectStatementBuilder
|
||||
implements Builder<SelectStatement, SelectStatementBuilder> {
|
||||
_$SelectStatement _$v;
|
||||
|
||||
ListBuilder<ResultColumn> _columns;
|
||||
ListBuilder<ResultColumn> get columns =>
|
||||
_$this._columns ??= new ListBuilder<ResultColumn>();
|
||||
set columns(ListBuilder<ResultColumn> columns) => _$this._columns = columns;
|
||||
|
||||
ListBuilder<SelectTarget> _from;
|
||||
ListBuilder<SelectTarget> get from =>
|
||||
_$this._from ??= new ListBuilder<SelectTarget>();
|
||||
set from(ListBuilder<SelectTarget> from) => _$this._from = from;
|
||||
|
||||
Expression _where;
|
||||
Expression get where => _$this._where;
|
||||
set where(Expression where) => _$this._where = where;
|
||||
|
||||
LimitBuilder _limit;
|
||||
LimitBuilder get limit => _$this._limit ??= new LimitBuilder();
|
||||
set limit(LimitBuilder limit) => _$this._limit = limit;
|
||||
|
||||
SelectStatementBuilder();
|
||||
|
||||
SelectStatementBuilder get _$this {
|
||||
if (_$v != null) {
|
||||
_columns = _$v.columns?.toBuilder();
|
||||
_from = _$v.from?.toBuilder();
|
||||
_where = _$v.where;
|
||||
_limit = _$v.limit?.toBuilder();
|
||||
_$v = null;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@override
|
||||
void replace(SelectStatement other) {
|
||||
if (other == null) {
|
||||
throw new ArgumentError.notNull('other');
|
||||
}
|
||||
_$v = other as _$SelectStatement;
|
||||
}
|
||||
|
||||
@override
|
||||
void update(void Function(SelectStatementBuilder) updates) {
|
||||
if (updates != null) updates(this);
|
||||
}
|
||||
|
||||
@override
|
||||
_$SelectStatement build() {
|
||||
_$SelectStatement _$result;
|
||||
try {
|
||||
_$result = _$v ??
|
||||
new _$SelectStatement._(
|
||||
columns: columns.build(),
|
||||
from: from.build(),
|
||||
where: where,
|
||||
limit: _limit?.build());
|
||||
} catch (_) {
|
||||
String _$failedField;
|
||||
try {
|
||||
_$failedField = 'columns';
|
||||
columns.build();
|
||||
_$failedField = 'from';
|
||||
from.build();
|
||||
|
||||
_$failedField = 'limit';
|
||||
_limit?.build();
|
||||
} catch (e) {
|
||||
throw new BuiltValueNestedFieldError(
|
||||
'SelectStatement', _$failedField, e.toString());
|
||||
}
|
||||
rethrow;
|
||||
}
|
||||
replace(_$result);
|
||||
return _$result;
|
||||
}
|
||||
}
|
||||
|
||||
class _$TableTarget extends TableTarget {
|
||||
@override
|
||||
final String table;
|
||||
|
||||
factory _$TableTarget([void Function(TableTargetBuilder) updates]) =>
|
||||
(new TableTargetBuilder()..update(updates)).build();
|
||||
|
||||
_$TableTarget._({this.table}) : super._() {
|
||||
if (table == null) {
|
||||
throw new BuiltValueNullFieldError('TableTarget', 'table');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
TableTarget rebuild(void Function(TableTargetBuilder) updates) =>
|
||||
(toBuilder()..update(updates)).build();
|
||||
|
||||
@override
|
||||
TableTargetBuilder toBuilder() => new TableTargetBuilder()..replace(this);
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(other, this)) return true;
|
||||
return other is TableTarget && table == other.table;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return $jf($jc(0, table.hashCode));
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return (newBuiltValueToStringHelper('TableTarget')..add('table', table))
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
||||
class TableTargetBuilder implements Builder<TableTarget, TableTargetBuilder> {
|
||||
_$TableTarget _$v;
|
||||
|
||||
String _table;
|
||||
String get table => _$this._table;
|
||||
set table(String table) => _$this._table = table;
|
||||
|
||||
TableTargetBuilder();
|
||||
|
||||
TableTargetBuilder get _$this {
|
||||
if (_$v != null) {
|
||||
_table = _$v.table;
|
||||
_$v = null;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@override
|
||||
void replace(TableTarget other) {
|
||||
if (other == null) {
|
||||
throw new ArgumentError.notNull('other');
|
||||
}
|
||||
_$v = other as _$TableTarget;
|
||||
}
|
||||
|
||||
@override
|
||||
void update(void Function(TableTargetBuilder) updates) {
|
||||
if (updates != null) updates(this);
|
||||
}
|
||||
|
||||
@override
|
||||
_$TableTarget build() {
|
||||
final _$result = _$v ?? new _$TableTarget._(table: table);
|
||||
replace(_$result);
|
||||
return _$result;
|
||||
}
|
||||
}
|
||||
|
||||
class _$Limit extends Limit {
|
||||
@override
|
||||
final Expression amount;
|
||||
@override
|
||||
final Expression offset;
|
||||
|
||||
factory _$Limit([void Function(LimitBuilder) updates]) =>
|
||||
(new LimitBuilder()..update(updates)).build();
|
||||
|
||||
_$Limit._({this.amount, this.offset}) : super._() {
|
||||
if (amount == null) {
|
||||
throw new BuiltValueNullFieldError('Limit', 'amount');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Limit rebuild(void Function(LimitBuilder) updates) =>
|
||||
(toBuilder()..update(updates)).build();
|
||||
|
||||
@override
|
||||
LimitBuilder toBuilder() => new LimitBuilder()..replace(this);
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(other, this)) return true;
|
||||
return other is Limit && amount == other.amount && offset == other.offset;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return $jf($jc($jc(0, amount.hashCode), offset.hashCode));
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return (newBuiltValueToStringHelper('Limit')
|
||||
..add('amount', amount)
|
||||
..add('offset', offset))
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
||||
class LimitBuilder implements Builder<Limit, LimitBuilder> {
|
||||
_$Limit _$v;
|
||||
|
||||
Expression _amount;
|
||||
Expression get amount => _$this._amount;
|
||||
set amount(Expression amount) => _$this._amount = amount;
|
||||
|
||||
Expression _offset;
|
||||
Expression get offset => _$this._offset;
|
||||
set offset(Expression offset) => _$this._offset = offset;
|
||||
|
||||
LimitBuilder();
|
||||
|
||||
LimitBuilder get _$this {
|
||||
if (_$v != null) {
|
||||
_amount = _$v.amount;
|
||||
_offset = _$v.offset;
|
||||
_$v = null;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@override
|
||||
void replace(Limit other) {
|
||||
if (other == null) {
|
||||
throw new ArgumentError.notNull('other');
|
||||
}
|
||||
_$v = other as _$Limit;
|
||||
}
|
||||
|
||||
@override
|
||||
void update(void Function(LimitBuilder) updates) {
|
||||
if (updates != null) updates(this);
|
||||
}
|
||||
|
||||
@override
|
||||
_$Limit build() {
|
||||
final _$result = _$v ?? new _$Limit._(amount: amount, offset: offset);
|
||||
replace(_$result);
|
||||
return _$result;
|
||||
}
|
||||
}
|
||||
|
||||
// ignore_for_file: always_put_control_body_on_new_line,always_specify_types,annotate_overrides,avoid_annotating_with_dynamic,avoid_as,avoid_catches_without_on_clauses,avoid_returning_this,lines_longer_than_80_chars,omit_local_variable_types,prefer_expression_function_bodies,sort_constructors_first,test_types_in_equals,unnecessary_const,unnecessary_new
|
|
@ -0,0 +1,67 @@
|
|||
import '../parser.dart';
|
||||
|
||||
class SqlGrammar extends GrammarParser {
|
||||
SqlGrammar() : super(const SqlGrammarDefinition());
|
||||
}
|
||||
|
||||
class SqlGrammarDefinition extends GrammarDefinition {
|
||||
const SqlGrammarDefinition();
|
||||
@override
|
||||
Parser start() => ref(select).end();
|
||||
|
||||
Parser select() => string('SELECT') & ref(resultColumns).trim();
|
||||
|
||||
Parser resultColumns() => ref(resultColumn)
|
||||
.separatedBy(ref(comma).trim().flatten(), includeSeparators: false);
|
||||
Parser resultColumn() => ref(exprColumn).or(ref(starColumn));
|
||||
Parser exprColumn() =>
|
||||
ref(expression) &
|
||||
(string('AS').trim() & ref(identifier).trim()).optional();
|
||||
Parser starColumn() => (tableName() & ref(dot)).optional() & ref(star);
|
||||
|
||||
// todo these
|
||||
Parser<String> tableName() => string('tableName');
|
||||
Parser<String> identifier() => string('id');
|
||||
|
||||
Parser comma() => char(',');
|
||||
Parser dot() => char('.');
|
||||
Parser star() => char('*');
|
||||
Parser hexDigit() => anyOf('0123456789abcdefABCDEF');
|
||||
|
||||
// expressions
|
||||
Parser expression() => ref(literal);
|
||||
|
||||
Parser literal() =>
|
||||
ref(stringLiteral) |
|
||||
ref(numericLiteral) |
|
||||
ref(nullLiteral) |
|
||||
ref(trueLiteral) |
|
||||
ref(falseLiteral) |
|
||||
ref(currentTimeLiteral) |
|
||||
ref(currentDateLiteral) |
|
||||
ref(currentTimestampLiteral);
|
||||
Parser stringLiteral() =>
|
||||
(anyOf('xX').optional() & char("'") & noneOf("'").star() & char("'"))
|
||||
.flatten(); // todo support '' for escaping
|
||||
Parser numericLiteral() {
|
||||
final hex = stringIgnoreCase('0x') & ref(hexDigit).plus();
|
||||
final exponent =
|
||||
(anyOf('eE') & (char('+') | char('-')).optional('+') & digit().plus())
|
||||
.flatten();
|
||||
|
||||
final numberWithTrailingDecimalPoint = ref(dot) & digit().plus();
|
||||
final regularNumber =
|
||||
digit().plus() & (ref(dot) & digit().star()).optional();
|
||||
|
||||
final numeric = (numberWithTrailingDecimalPoint | regularNumber).flatten();
|
||||
|
||||
return hex | (numeric & exponent.optional());
|
||||
}
|
||||
|
||||
Parser nullLiteral() => stringIgnoreCase('NULL');
|
||||
Parser trueLiteral() => stringIgnoreCase('TRUE');
|
||||
Parser falseLiteral() => stringIgnoreCase('FALSE');
|
||||
Parser currentTimeLiteral() => stringIgnoreCase('CURRENT_TIME');
|
||||
Parser currentDateLiteral() => stringIgnoreCase('CURRENT_DATE');
|
||||
Parser currentTimestampLiteral() => stringIgnoreCase('CURRENT_TIMESTAMP');
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
import 'package:moor/sqlite_keywords.dart';
|
||||
import 'package:petitparser/petitparser.dart';
|
||||
|
||||
/// A parser that accepts any word as long as it's not a sql keyword.
|
||||
class NotAKeywordParser extends Parser<String> {
|
||||
final Parser<String> _inner = word().star().flatten();
|
||||
|
||||
@override
|
||||
Parser<String> copy() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@override
|
||||
Result<String> parseOn(Context context) {
|
||||
final innerResult = _inner.parseOn(context);
|
||||
|
||||
if (innerResult.isFailure) {
|
||||
return innerResult;
|
||||
}
|
||||
|
||||
if (sqliteKeywords.contains(innerResult.value.toUpperCase())) {
|
||||
return innerResult.failure('did not expect a sqlite keyword');
|
||||
}
|
||||
|
||||
return innerResult;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
export 'package:petitparser/petitparser.dart';
|
||||
export 'grammar/grammar.dart';
|
||||
export 'parser/parser.dart';
|
|
@ -0,0 +1,85 @@
|
|||
import 'package:moor_generator/src/sql/ast/expressions/expressions.dart';
|
||||
import 'package:moor_generator/src/sql/ast/expressions/literals.dart';
|
||||
import 'package:moor_generator/src/sql/ast/select/columns.dart';
|
||||
import 'package:moor_generator/src/sql/parser/parser.dart';
|
||||
|
||||
class SemanticSqlParser extends GrammarParser {
|
||||
SemanticSqlParser() : super(SemanticSqlParserDefinition());
|
||||
}
|
||||
|
||||
class SemanticSqlParserDefinition extends SqlGrammarDefinition {
|
||||
@override
|
||||
Parser starColumn() {
|
||||
return super.starColumn().map((each) {
|
||||
final typedEach = each as List;
|
||||
if (typedEach.first == null) {
|
||||
// just a simple star column
|
||||
return StarResultColumn.from();
|
||||
} else {
|
||||
return StarResultColumn.from(
|
||||
table: (typedEach.first as List).first as String);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Parser exprColumn() {
|
||||
return super.exprColumn().map((each) {
|
||||
// [expression, [AS, "column_name"]] or just [expression, null]
|
||||
final typedEach = each as List;
|
||||
final expression = typedEach.first as Expression;
|
||||
final alias = typedEach[1] != null ? typedEach[1][1] as String : null;
|
||||
|
||||
return ExprResultColumn((b) => b
|
||||
..expr = expression
|
||||
..alias = alias);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Parser currentTimestampLiteral() {
|
||||
return super.currentTimestampLiteral().map(
|
||||
(e) => CurrentTimeResolver.mode(CurrentTimeAccessor.currentTimestamp));
|
||||
}
|
||||
|
||||
@override
|
||||
Parser currentDateLiteral() {
|
||||
return super
|
||||
.currentDateLiteral()
|
||||
.map((_) => CurrentTimeResolver.mode(CurrentTimeAccessor.currentDate));
|
||||
}
|
||||
|
||||
@override
|
||||
Parser currentTimeLiteral() {
|
||||
return super
|
||||
.currentTimeLiteral()
|
||||
.map((_) => CurrentTimeResolver.mode(CurrentTimeAccessor.currentTime));
|
||||
}
|
||||
|
||||
@override
|
||||
Parser falseLiteral() =>
|
||||
super.falseLiteral().map((_) => BooleanLiteral.from(false));
|
||||
|
||||
@override
|
||||
Parser trueLiteral() =>
|
||||
super.falseLiteral().map((_) => BooleanLiteral.from(true));
|
||||
|
||||
@override
|
||||
Parser nullLiteral() => super.nullLiteral().map((_) => const NullLiteral());
|
||||
|
||||
@override
|
||||
Parser numericLiteral() {
|
||||
// we don't really care about the value, we just need to know the type
|
||||
return super
|
||||
.numericLiteral()
|
||||
.map((_) => NumericLiteral((b) => b.value = 0));
|
||||
}
|
||||
|
||||
@override
|
||||
Parser stringLiteral() {
|
||||
// same here, only the type is relevant, the actual content doesn't matter.
|
||||
return super
|
||||
.stringLiteral()
|
||||
.map((_) => StringLiteral((b) => b.content = 'hi'));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
import 'package:moor_generator/src/sql/parser/grammar/not_a_keyword.dart';
|
||||
import 'package:test_api/test_api.dart';
|
||||
|
||||
final parser = NotAKeywordParser();
|
||||
final withTrim = parser.trim();
|
||||
|
||||
void main() {
|
||||
test('does not accept sqlite keywords', () {
|
||||
expect(parser.parse('SELECT').isSuccess, isFalse);
|
||||
expect(parser.parse('USING').isSuccess, isFalse);
|
||||
expect(withTrim.parse(' PRAGMA ').isSuccess, isFalse);
|
||||
});
|
||||
|
||||
test('does accept words that are not sqlite keywords', () {
|
||||
expect(parser.parse('users').isSuccess, isTrue);
|
||||
expect(parser.parse('is_awesome').isSuccess, isTrue);
|
||||
});
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
import 'package:moor_generator/src/sql/parser/parser.dart';
|
||||
import 'package:test_api/test_api.dart';
|
||||
|
||||
void main() {
|
||||
test('test', () {
|
||||
final grammar = SqlGrammar();
|
||||
final semantics = SemanticSqlParser();
|
||||
|
||||
print(grammar.parse("SELECT 'lol' AS test"));
|
||||
print(semantics.parse('SELECT *, tableName.*, NULL AS id'));
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue