mirror of https://github.com/AMT-Cheif/drift.git
Parse MAPPED BY constraints for moor files
This commit is contained in:
parent
aa13aad276
commit
5d2149d727
|
@ -40,6 +40,7 @@ abstract class ColumnConstraint extends AstNode {
|
|||
T Function(Default) isDefault,
|
||||
T Function(CollateConstraint) collate,
|
||||
T Function(ForeignKeyColumnConstraint) foreignKey,
|
||||
T Function(MappedBy) mappedBy,
|
||||
}) {
|
||||
if (this is NotNull) {
|
||||
return notNull?.call(this as NotNull);
|
||||
|
@ -55,6 +56,8 @@ abstract class ColumnConstraint extends AstNode {
|
|||
return collate?.call(this as CollateConstraint);
|
||||
} else if (this is ForeignKeyColumnConstraint) {
|
||||
return foreignKey?.call(this as ForeignKeyColumnConstraint);
|
||||
} else if (this is MappedBy) {
|
||||
return mappedBy?.call(this as MappedBy);
|
||||
} else {
|
||||
throw Exception('Did not expect $runtimeType as a ColumnConstraint');
|
||||
}
|
||||
|
@ -164,3 +167,20 @@ class ForeignKeyColumnConstraint extends ColumnConstraint {
|
|||
@override
|
||||
Iterable<AstNode> get childNodes => [clause];
|
||||
}
|
||||
|
||||
/// A `MAPPED BY` constraint, which is only parsed for moor files. It can be
|
||||
/// used to declare a type converter for this column.
|
||||
class MappedBy extends ColumnConstraint {
|
||||
/// The Dart expression creating the type converter we use to map this token.
|
||||
final InlineDartToken mapper;
|
||||
|
||||
MappedBy(String name, this.mapper) : super(name);
|
||||
|
||||
@override
|
||||
bool _equalToConstraint(MappedBy other) {
|
||||
return other.mapper.dartCode == mapper.dartCode;
|
||||
}
|
||||
|
||||
@override
|
||||
final Iterable<AstNode> childNodes = const [];
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ class SqlEngine {
|
|||
/// Parses the [sql] statement into an AST-representation.
|
||||
ParseResult parse(String sql) {
|
||||
final tokens = tokenize(sql);
|
||||
final parser = Parser(tokens);
|
||||
final parser = Parser(tokens, useMoor: useMoorExtensions);
|
||||
|
||||
final stmt = parser.statement();
|
||||
return ParseResult._(stmt, parser.errors, sql);
|
||||
|
|
|
@ -43,9 +43,13 @@ class ParsingError implements Exception {
|
|||
abstract class ParserBase {
|
||||
final List<Token> tokens;
|
||||
final List<ParsingError> errors = [];
|
||||
|
||||
/// Whether to enable the extensions moor makes to the sql grammar.
|
||||
final bool enableMoorExtensions;
|
||||
|
||||
int _current = 0;
|
||||
|
||||
ParserBase(this.tokens);
|
||||
ParserBase(this.tokens, this.enableMoorExtensions);
|
||||
|
||||
bool get _isAtEnd => _peek.type == TokenType.eof;
|
||||
Token get _peek => tokens[_current];
|
||||
|
@ -145,7 +149,7 @@ abstract class ParserBase {
|
|||
|
||||
class Parser extends ParserBase
|
||||
with ExpressionParser, SchemaParser, CrudParser {
|
||||
Parser(List<Token> tokens) : super(tokens);
|
||||
Parser(List<Token> tokens, {bool useMoor = false}) : super(tokens, useMoor);
|
||||
|
||||
Statement statement({bool expectEnd = true}) {
|
||||
final first = _peek;
|
||||
|
|
|
@ -153,6 +153,15 @@ mixin SchemaParser on ParserBase {
|
|||
return ForeignKeyColumnConstraint(resolvedName, clause)
|
||||
..setSpan(first, _previous);
|
||||
}
|
||||
if (enableMoorExtensions && _matchOne(TokenType.mapped)) {
|
||||
_consume(TokenType.by, 'Expected a MAPPED BY constraint');
|
||||
|
||||
final dartExpr = _consume(
|
||||
TokenType.inlineDart, 'Expected Dart expression in backticks');
|
||||
|
||||
return MappedBy(resolvedName, dartExpr as InlineDartToken)
|
||||
..setSpan(first, _previous);
|
||||
}
|
||||
|
||||
// no known column constraint matched. If orNull is set and we're not
|
||||
// guaranteed to be in a constraint clause (started with CONSTRAINT), we
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:sqlparser/sqlparser.dart';
|
||||
import 'package:sqlparser/src/ast/ast.dart';
|
||||
import 'package:sqlparser/src/utils/ast_equality.dart';
|
||||
import 'package:test_core/test_core.dart';
|
||||
|
||||
import '../common_data.dart';
|
||||
|
@ -115,4 +116,24 @@ void main() {
|
|||
),
|
||||
);
|
||||
});
|
||||
|
||||
test('parses MAPPED BY expressions when in moor mode', () {
|
||||
const stmt = 'CREATE TABLE a (b NOT NULL MAPPED BY `Mapper()` PRIMARY KEY)';
|
||||
final parsed = SqlEngine(useMoorExtensions: true).parse(stmt).rootNode;
|
||||
|
||||
enforceEqual(
|
||||
parsed,
|
||||
CreateTableStatement(tableName: 'a', columns: [
|
||||
ColumnDefinition(
|
||||
columnName: 'b',
|
||||
typeName: null,
|
||||
constraints: [
|
||||
NotNull(null),
|
||||
MappedBy(null, inlineDart('Mapper()')),
|
||||
PrimaryKeyColumn(null),
|
||||
],
|
||||
),
|
||||
]),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -10,6 +10,11 @@ Token token(TokenType type) {
|
|||
return Token(type, null);
|
||||
}
|
||||
|
||||
InlineDartToken inlineDart(String dartCode) {
|
||||
final fakeFile = SourceFile.fromString('`$dartCode`');
|
||||
return InlineDartToken(fakeFile.span(0));
|
||||
}
|
||||
|
||||
IdentifierToken identifier(String content) {
|
||||
final fakeFile = SourceFile.fromString(content);
|
||||
return IdentifierToken(false, fakeFile.span(0));
|
||||
|
|
Loading…
Reference in New Issue