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]
|
/// For instructions on how to write a dao, see the documentation of [UseDao]
|
||||||
final List<Type> daos;
|
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
|
/// Use this class as an annotation to inform moor_generator that a database
|
||||||
/// class should be generated using the specified [UseMoor.tables].
|
/// 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
|
/// Annotation to use on classes that implement [DatabaseAccessor]. It specifies
|
||||||
|
@ -51,6 +63,8 @@ class UseMoor {
|
||||||
class UseDao {
|
class UseDao {
|
||||||
/// The tables accessed by this DAO.
|
/// The tables accessed by this DAO.
|
||||||
final List<Type> tables;
|
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
|
@override
|
||||||
final String name;
|
final String name;
|
||||||
|
|
||||||
factory _$ColumnName([void updates(ColumnNameBuilder b)]) =>
|
factory _$ColumnName([void Function(ColumnNameBuilder) updates]) =>
|
||||||
(new ColumnNameBuilder()..update(updates)).build();
|
(new ColumnNameBuilder()..update(updates)).build();
|
||||||
|
|
||||||
_$ColumnName._({this.implicit, this.name}) : super._() {
|
_$ColumnName._({this.implicit, this.name}) : super._() {
|
||||||
|
@ -25,7 +25,7 @@ class _$ColumnName extends ColumnName {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ColumnName rebuild(void updates(ColumnNameBuilder b)) =>
|
ColumnName rebuild(void Function(ColumnNameBuilder) updates) =>
|
||||||
(toBuilder()..update(updates)).build();
|
(toBuilder()..update(updates)).build();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -84,7 +84,7 @@ class ColumnNameBuilder implements Builder<ColumnName, ColumnNameBuilder> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void update(void updates(ColumnNameBuilder b)) {
|
void update(void Function(ColumnNameBuilder) updates) {
|
||||||
if (updates != null) updates(this);
|
if (updates != null) updates(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,13 +102,15 @@ class _$LimitingTextLength extends LimitingTextLength {
|
||||||
@override
|
@override
|
||||||
final int maxLength;
|
final int maxLength;
|
||||||
|
|
||||||
factory _$LimitingTextLength([void updates(LimitingTextLengthBuilder b)]) =>
|
factory _$LimitingTextLength(
|
||||||
|
[void Function(LimitingTextLengthBuilder) updates]) =>
|
||||||
(new LimitingTextLengthBuilder()..update(updates)).build();
|
(new LimitingTextLengthBuilder()..update(updates)).build();
|
||||||
|
|
||||||
_$LimitingTextLength._({this.minLength, this.maxLength}) : super._();
|
_$LimitingTextLength._({this.minLength, this.maxLength}) : super._();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
LimitingTextLength rebuild(void updates(LimitingTextLengthBuilder b)) =>
|
LimitingTextLength rebuild(
|
||||||
|
void Function(LimitingTextLengthBuilder) updates) =>
|
||||||
(toBuilder()..update(updates)).build();
|
(toBuilder()..update(updates)).build();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -169,7 +171,7 @@ class LimitingTextLengthBuilder
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void update(void updates(LimitingTextLengthBuilder b)) {
|
void update(void Function(LimitingTextLengthBuilder) updates) {
|
||||||
if (updates != null) updates(this);
|
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