mirror of https://github.com/AMT-Cheif/drift.git
Add NamedResultSet type, adress review issues
This commit is contained in:
parent
0bc2a7548d
commit
df6f6fafa2
|
@ -16,6 +16,7 @@ part 'error.dart';
|
||||||
part 'schema/column.dart';
|
part 'schema/column.dart';
|
||||||
part 'schema/from_create_table.dart';
|
part 'schema/from_create_table.dart';
|
||||||
part 'schema/references.dart';
|
part 'schema/references.dart';
|
||||||
|
part 'schema/resultset.dart';
|
||||||
part 'schema/table.dart';
|
part 'schema/table.dart';
|
||||||
part 'schema/view.dart';
|
part 'schema/view.dart';
|
||||||
part 'steps/column_resolver.dart';
|
part 'steps/column_resolver.dart';
|
||||||
|
|
|
@ -114,8 +114,8 @@ class ViewColumn extends Column with DelegatedColumn {
|
||||||
/// The view this column belongs to.
|
/// The view this column belongs to.
|
||||||
View view;
|
View view;
|
||||||
|
|
||||||
/// Creates a view column wrapping a [Column] from the select statement used to
|
/// Creates a view column wrapping a [Column] from the select statement used
|
||||||
/// create the view.
|
/// to create the view.
|
||||||
///
|
///
|
||||||
/// The optional name parameter can be used to override the name for this column.
|
/// The optional name parameter can be used to override the name for this column.
|
||||||
/// By default, the name of the [innerColumn] will be used.
|
/// By default, the name of the [innerColumn] will be used.
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
part of '../analysis.dart';
|
||||||
|
|
||||||
|
/// Something that will resolve to an [ResultSet] when referred to via
|
||||||
|
/// the [ReferenceScope].
|
||||||
|
abstract class ResolvesToResultSet with Referencable {
|
||||||
|
ResultSet get resultSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Something that returns a set of columns when evaluated.
|
||||||
|
abstract class ResultSet implements ResolvesToResultSet {
|
||||||
|
/// The columns that will be returned when evaluating this query.
|
||||||
|
List<Column> get resolvedColumns;
|
||||||
|
|
||||||
|
@override
|
||||||
|
ResultSet get resultSet => this;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get visibleToChildren => false;
|
||||||
|
|
||||||
|
Column findColumn(String name) {
|
||||||
|
return resolvedColumns.firstWhere((c) => c.name == name,
|
||||||
|
orElse: () => null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A custom result set that has columns but isn't a table.
|
||||||
|
class CustomResultSet with ResultSet {
|
||||||
|
@override
|
||||||
|
final List<Column> resolvedColumns;
|
||||||
|
|
||||||
|
CustomResultSet(this.resolvedColumns);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Something that returns a set of Columns and can be referenced by a name,
|
||||||
|
/// such as a table or a view.
|
||||||
|
abstract class NamedResultSet extends ResultSet{
|
||||||
|
/// The name of this result set, as it appears in sql statements. This should
|
||||||
|
/// be the raw name, not an escaped version.
|
||||||
|
///
|
||||||
|
/// To obtain an escaped name, use [escapedName].
|
||||||
|
String get name;
|
||||||
|
|
||||||
|
/// If [name] is a reserved sql keyword, wraps it in double ticks. Otherwise
|
||||||
|
/// just returns the [name] directly.
|
||||||
|
String get escapedName {
|
||||||
|
return isKeywordLexeme(name) ? '"$name"' : name;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -4,52 +4,16 @@ part of '../analysis.dart';
|
||||||
/// https://www.sqlite.org/lang_createtable.html#rowid
|
/// https://www.sqlite.org/lang_createtable.html#rowid
|
||||||
const aliasesForRowId = ['rowid', 'oid', '_rowid_'];
|
const aliasesForRowId = ['rowid', 'oid', '_rowid_'];
|
||||||
|
|
||||||
/// Something that will resolve to an [ResultSet] when referred to via
|
|
||||||
/// the [ReferenceScope].
|
|
||||||
abstract class ResolvesToResultSet with Referencable {
|
|
||||||
ResultSet get resultSet;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Something that returns a set of columns when evaluated.
|
|
||||||
abstract class ResultSet implements ResolvesToResultSet {
|
|
||||||
/// The columns that will be returned when evaluating this query.
|
|
||||||
List<Column> get resolvedColumns;
|
|
||||||
|
|
||||||
@override
|
|
||||||
ResultSet get resultSet => this;
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool get visibleToChildren => false;
|
|
||||||
|
|
||||||
Column findColumn(String name) {
|
|
||||||
return resolvedColumns.firstWhere((c) => c.name == name,
|
|
||||||
orElse: () => null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A custom result set that has columns but isn't a table.
|
|
||||||
class CustomResultSet with ResultSet {
|
|
||||||
@override
|
|
||||||
final List<Column> resolvedColumns;
|
|
||||||
|
|
||||||
CustomResultSet(this.resolvedColumns);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A database table. The information stored here will be used to resolve
|
/// A database table. The information stored here will be used to resolve
|
||||||
/// references and for type inference.
|
/// references and for type inference.
|
||||||
class Table with ResultSet, HasMetaMixin implements HumanReadable {
|
class Table extends NamedResultSet with HasMetaMixin implements HumanReadable {
|
||||||
/// The name of this table, as it appears in sql statements. This should be
|
/// The name of this table, as it appears in sql statements. This should be
|
||||||
/// the raw name, not an escaped version.
|
/// the raw name, not an escaped version.
|
||||||
///
|
///
|
||||||
/// To obtain an escaped name, use [escapedName].
|
/// To obtain an escaped name, use [escapedName].
|
||||||
|
@override
|
||||||
final String name;
|
final String name;
|
||||||
|
|
||||||
/// If [name] is a reserved sql keyword, wraps it in double ticks. Otherwise
|
|
||||||
/// just returns the [name] directly.
|
|
||||||
String get escapedName {
|
|
||||||
return isKeywordLexeme(name) ? '"$name"' : name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final List<TableColumn> resolvedColumns;
|
final List<TableColumn> resolvedColumns;
|
||||||
|
|
||||||
|
|
|
@ -2,28 +2,16 @@ part of '../analysis.dart';
|
||||||
|
|
||||||
/// A database view. The information stored here will be used to resolve
|
/// A database view. The information stored here will be used to resolve
|
||||||
/// references and for type inference.
|
/// references and for type inference.
|
||||||
class View with HasMetaMixin, ResultSet implements HumanReadable {
|
class View extends NamedResultSet with HasMetaMixin implements HumanReadable {
|
||||||
/// The name of this view, as it appears in sql statements. This should be
|
@override
|
||||||
/// the raw name, not an escaped version.
|
|
||||||
///
|
|
||||||
/// To obtain an escaped name, use [escapedName].
|
|
||||||
final String name;
|
final String name;
|
||||||
|
|
||||||
/// If [name] is a reserved sql keyword, wraps it in double ticks. Otherwise
|
|
||||||
/// just returns the [name] directly.
|
|
||||||
String get escapedName {
|
|
||||||
return isKeywordLexeme(name) ? '"$name"' : name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final List<ViewColumn> resolvedColumns;
|
final List<ViewColumn> resolvedColumns;
|
||||||
|
|
||||||
/// The ast node that created this table
|
/// The ast node that created this table
|
||||||
final CreateViewStatement definition;
|
final CreateViewStatement definition;
|
||||||
|
|
||||||
@override
|
|
||||||
bool get visibleToChildren => true;
|
|
||||||
|
|
||||||
/// Constructs a view from the known [name] and [selectColumns].
|
/// Constructs a view from the known [name] and [selectColumns].
|
||||||
View({
|
View({
|
||||||
@required this.name,
|
@required this.name,
|
||||||
|
@ -42,13 +30,13 @@ class View with HasMetaMixin, ResultSet implements HumanReadable {
|
||||||
String humanReadableDescription() {
|
String humanReadableDescription() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
List<ViewColumn> _createColumns(
|
static List<ViewColumn> _createColumns(
|
||||||
List<Column> resolvedColumns, List<String> columnNames) {
|
List<Column> resolvedColumns, List<String> columnNames) {
|
||||||
final columns = List<ViewColumn>(resolvedColumns.length);
|
final columns = List<ViewColumn>(resolvedColumns.length);
|
||||||
for (var i = 0; i < resolvedColumns.length; ++i) {
|
for (var i = 0; i < resolvedColumns.length; ++i) {
|
||||||
columns[i] = ViewColumn(resolvedColumns[i], columnNames?.elementAt(i));
|
columns[i] = ViewColumn(resolvedColumns[i], columnNames?.elementAt(i));
|
||||||
|
}
|
||||||
|
return columns;
|
||||||
}
|
}
|
||||||
return columns;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ class TableNameDescription extends HintDescription {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Iterable<Suggestion> suggest(CalculationRequest request) {
|
Iterable<Suggestion> suggest(CalculationRequest request) {
|
||||||
final tableNames = request.engine.knownTables.map((t) => t.escapedName);
|
final tableNames = request.engine.knownResultSets.map((t) => t.escapedName);
|
||||||
|
|
||||||
return tableNames.map((t) {
|
return tableNames.map((t) {
|
||||||
return Suggestion(t, 1);
|
return Suggestion(t, 1);
|
||||||
|
|
|
@ -12,7 +12,7 @@ import 'builtin_tables.dart';
|
||||||
|
|
||||||
class SqlEngine {
|
class SqlEngine {
|
||||||
/// All tables registered with [registerTable].
|
/// All tables registered with [registerTable].
|
||||||
final List<Table> knownTables = [];
|
final List<NamedResultSet> knownResultSets = [];
|
||||||
final List<Module> _knownModules = [];
|
final List<Module> _knownModules = [];
|
||||||
|
|
||||||
/// Internal options for this sql engine.
|
/// Internal options for this sql engine.
|
||||||
|
@ -43,7 +43,19 @@ class SqlEngine {
|
||||||
/// Registers the [table], which means that it can later be used in sql
|
/// Registers the [table], which means that it can later be used in sql
|
||||||
/// statements.
|
/// statements.
|
||||||
void registerTable(Table table) {
|
void registerTable(Table table) {
|
||||||
knownTables.add(table);
|
registerResultSet(table);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Registers the [view], which means that it can later be used in sql
|
||||||
|
/// statements.
|
||||||
|
void registerView(View view) {
|
||||||
|
registerResultSet(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Registers an arbitrary [namedResultSet], which means that it can later
|
||||||
|
/// be used in sql statements.
|
||||||
|
void registerResultSet(NamedResultSet namedResultSet) {
|
||||||
|
knownResultSets.add(namedResultSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Registers the [module], which means that it can be used as a function in
|
/// Registers the [module], which means that it can be used as a function in
|
||||||
|
@ -67,8 +79,8 @@ class SqlEngine {
|
||||||
|
|
||||||
ReferenceScope _constructRootScope({ReferenceScope parent}) {
|
ReferenceScope _constructRootScope({ReferenceScope parent}) {
|
||||||
final scope = parent == null ? ReferenceScope(null) : parent.createChild();
|
final scope = parent == null ? ReferenceScope(null) : parent.createChild();
|
||||||
for (final table in knownTables) {
|
for (final resultSet in knownResultSets) {
|
||||||
scope.register(table.name, table);
|
scope.register(resultSet.name, resultSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final module in _knownModules) {
|
for (final module in _knownModules) {
|
||||||
|
|
Loading…
Reference in New Issue