Begin with simple ast and parser

This commit is contained in:
Simon Binder 2019-06-02 22:30:23 +02:00
parent cb8cb6b1a0
commit 69f0b9b393
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
17 changed files with 1199 additions and 8 deletions

View File

@ -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});
}

View File

@ -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);
}

View File

@ -0,0 +1,3 @@
abstract class Expression {
const Expression();
}

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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');
}

View File

@ -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;
}
}

View File

@ -0,0 +1,3 @@
export 'package:petitparser/petitparser.dart';
export 'grammar/grammar.dart';
export 'parser/parser.dart';

View File

@ -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'));
}
}

View File

View File

@ -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);
});
}

View File

@ -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'));
});
}