From 00b2956b359525a0b83e4812636304cedaac19de Mon Sep 17 00:00:00 2001 From: Simon Binder Date: Tue, 17 Sep 2019 15:23:24 +0200 Subject: [PATCH] Allow data class names to be overridden in sql Closes #147 --- moor/test/data/tables/custom_tables.g.dart | 56 +++++++++---------- moor/test/data/tables/tables.moor | 2 +- .../moor_files_integration_test.dart | 2 +- .../analyzer/moor/create_table_reader.dart | 6 +- .../lib/src/model/specified_table.dart | 10 +++- .../lib/src/ast/statements/create_table.dart | 11 +++- sqlparser/lib/src/reader/parser/schema.dart | 9 +++ sqlparser/test/parser/moor_file_test.dart | 3 +- 8 files changed, 61 insertions(+), 38 deletions(-) diff --git a/moor/test/data/tables/custom_tables.g.dart b/moor/test/data/tables/custom_tables.g.dart index 5dca3282..b9a41720 100644 --- a/moor/test/data/tables/custom_tables.g.dart +++ b/moor/test/data/tables/custom_tables.g.dart @@ -474,24 +474,24 @@ class WithConstraints extends Table final bool dontWriteConstraints = true; } -class ConfigData extends DataClass implements Insertable { +class Config extends DataClass implements Insertable { final String configKey; final String configValue; - ConfigData({@required this.configKey, this.configValue}); - factory ConfigData.fromData(Map data, GeneratedDatabase db, + Config({@required this.configKey, this.configValue}); + factory Config.fromData(Map data, GeneratedDatabase db, {String prefix}) { final effectivePrefix = prefix ?? ''; final stringType = db.typeSystem.forDartType(); - return ConfigData( + return Config( configKey: stringType .mapFromDatabaseResponse(data['${effectivePrefix}config_key']), configValue: stringType .mapFromDatabaseResponse(data['${effectivePrefix}config_value']), ); } - factory ConfigData.fromJson(Map json, + factory Config.fromJson(Map json, {ValueSerializer serializer = const ValueSerializer.defaults()}) { - return ConfigData( + return Config( configKey: serializer.fromJson(json['configKey']), configValue: serializer.fromJson(json['configValue']), ); @@ -506,7 +506,7 @@ class ConfigData extends DataClass implements Insertable { } @override - T createCompanion>(bool nullToAbsent) { + T createCompanion>(bool nullToAbsent) { return ConfigCompanion( configKey: configKey == null && nullToAbsent ? const Value.absent() @@ -517,13 +517,13 @@ class ConfigData extends DataClass implements Insertable { ) as T; } - ConfigData copyWith({String configKey, String configValue}) => ConfigData( + Config copyWith({String configKey, String configValue}) => Config( configKey: configKey ?? this.configKey, configValue: configValue ?? this.configValue, ); @override String toString() { - return (StringBuffer('ConfigData(') + return (StringBuffer('Config(') ..write('configKey: $configKey, ') ..write('configValue: $configValue') ..write(')')) @@ -535,12 +535,12 @@ class ConfigData extends DataClass implements Insertable { @override bool operator ==(other) => identical(this, other) || - (other is ConfigData && + (other is Config && other.configKey == configKey && other.configValue == configValue); } -class ConfigCompanion extends UpdateCompanion { +class ConfigCompanion extends UpdateCompanion { final Value configKey; final Value configValue; const ConfigCompanion({ @@ -560,10 +560,10 @@ class ConfigCompanion extends UpdateCompanion { } } -class Config extends Table with TableInfo { +class ConfigTable extends Table with TableInfo { final GeneratedDatabase _db; final String _alias; - Config(this._db, [this._alias]); + ConfigTable(this._db, [this._alias]); final VerificationMeta _configKeyMeta = const VerificationMeta('configKey'); GeneratedTextColumn _configKey; GeneratedTextColumn get configKey => _configKey ??= _constructConfigKey(); @@ -585,7 +585,7 @@ class Config extends Table with TableInfo { @override List get $columns => [configKey, configValue]; @override - Config get asDslTable => this; + ConfigTable get asDslTable => this; @override String get $tableName => _alias ?? 'config'; @override @@ -612,9 +612,9 @@ class Config extends Table with TableInfo { @override Set get $primaryKey => {configKey}; @override - ConfigData map(Map data, {String tablePrefix}) { + Config map(Map data, {String tablePrefix}) { final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : null; - return ConfigData.fromData(data, _db, prefix: effectivePrefix); + return Config.fromData(data, _db, prefix: effectivePrefix); } @override @@ -630,8 +630,8 @@ class Config extends Table with TableInfo { } @override - Config createAlias(String alias) { - return Config(_db, alias); + ConfigTable createAlias(String alias) { + return ConfigTable(_db, alias); } @override @@ -808,24 +808,24 @@ abstract class _$CustomTablesDb extends GeneratedDatabase { WithConstraints _withConstraints; WithConstraints get withConstraints => _withConstraints ??= WithConstraints(this); - Config _config; - Config get config => _config ??= Config(this); + ConfigTable _config; + ConfigTable get config => _config ??= ConfigTable(this); Mytable _mytable; Mytable get mytable => _mytable ??= Mytable(this); - ConfigData _rowToConfigData(QueryRow row) { - return ConfigData( + Config _rowToConfig(QueryRow row) { + return Config( configKey: row.readString('config_key'), configValue: row.readString('config_value'), ); } - Selectable readConfig(String var1) { + Selectable readConfig(String var1) { return customSelectQuery('SELECT * FROM config WHERE config_key = ?', variables: [Variable.withString(var1)], - readsFrom: {config}).map(_rowToConfigData); + readsFrom: {config}).map(_rowToConfig); } - Selectable readMultiple(List var1, OrderBy clause) { + Selectable readMultiple(List var1, OrderBy clause) { var $arrayStartIndex = 1; final expandedvar1 = $expandVar($arrayStartIndex, var1.length); $arrayStartIndex += var1.length; @@ -839,15 +839,15 @@ abstract class _$CustomTablesDb extends GeneratedDatabase { ], readsFrom: { config - }).map(_rowToConfigData); + }).map(_rowToConfig); } - Selectable readDynamic(Expression predicate) { + Selectable readDynamic(Expression predicate) { final generatedpredicate = $write(predicate); return customSelectQuery( 'SELECT * FROM config WHERE ${generatedpredicate.sql}', variables: [...generatedpredicate.introducedVariables], - readsFrom: {config}).map(_rowToConfigData); + readsFrom: {config}).map(_rowToConfig); } Future writeConfig(String key, String value) { diff --git a/moor/test/data/tables/tables.moor b/moor/test/data/tables/tables.moor index e4676550..b75c016d 100644 --- a/moor/test/data/tables/tables.moor +++ b/moor/test/data/tables/tables.moor @@ -18,7 +18,7 @@ CREATE TABLE with_constraints ( create table config ( config_key TEXT not null primary key, config_value TEXT -); +) AS "Config"; CREATE TABLE mytable ( someid INTEGER NOT NULL PRIMARY KEY, diff --git a/moor/test/parsed_sql/moor_files_integration_test.dart b/moor/test/parsed_sql/moor_files_integration_test.dart index 730b1963..d933925b 100644 --- a/moor/test/parsed_sql/moor_files_integration_test.dart +++ b/moor/test/parsed_sql/moor_files_integration_test.dart @@ -81,6 +81,6 @@ void main() { verify( mock.runSelect('SELECT * FROM config WHERE config_key = ?', ['key'])); - expect(parsed, ConfigData(configKey: 'key', configValue: 'value')); + expect(parsed, Config(configKey: 'key', configValue: 'value')); }); } diff --git a/moor_generator/lib/src/analyzer/moor/create_table_reader.dart b/moor_generator/lib/src/analyzer/moor/create_table_reader.dart index e9381760..2ee9bef7 100644 --- a/moor_generator/lib/src/analyzer/moor/create_table_reader.dart +++ b/moor_generator/lib/src/analyzer/moor/create_table_reader.dart @@ -76,6 +76,8 @@ class CreateTableReader { final tableName = table.name; final dartTableName = ReCase(tableName).pascalCase; + final dataClassName = stmt.overriddenDataClassName ?? + dataClassNameForClassName(dartTableName); final constraints = table.tableConstraints.map((c) => c.span.text).toList(); @@ -91,8 +93,8 @@ class CreateTableReader { fromClass: null, columns: foundColumns.values.toList(), sqlName: table.name, - dartTypeName: dataClassNameForClassName(dartTableName), - overriddenName: ReCase(tableName).pascalCase, + dartTypeName: dataClassName, + overriddenName: dartTableName, primaryKey: primaryKey, overrideWithoutRowId: table.withoutRowId ? true : null, overrideTableConstraints: constraints.isNotEmpty ? constraints : null, diff --git a/moor_generator/lib/src/model/specified_table.dart b/moor_generator/lib/src/model/specified_table.dart index 2c249171..67ce70da 100644 --- a/moor_generator/lib/src/model/specified_table.dart +++ b/moor_generator/lib/src/model/specified_table.dart @@ -35,10 +35,14 @@ class SpecifiedTable { // directly because there is no user defined parent class. // So, turn CREATE TABLE users into something called "Users" instead of // "$UsersTable". - if (_overriddenName != null) { - return _overriddenName; + final name = _overriddenName ?? tableInfoNameForTableClass(_baseName); + if (name == dartTypeName) { + // resolve clashes if the table info class has the same name as the data + // class. This can happen because the data class name can be specified by + // the user. + return '${name}Table'; } - return tableInfoNameForTableClass(_baseName); + return name; } String get updateCompanionName => _updateCompanionName(_baseName); diff --git a/sqlparser/lib/src/ast/statements/create_table.dart b/sqlparser/lib/src/ast/statements/create_table.dart index cf7b900f..55f67038 100644 --- a/sqlparser/lib/src/ast/statements/create_table.dart +++ b/sqlparser/lib/src/ast/statements/create_table.dart @@ -11,6 +11,11 @@ class CreateTableStatement extends Statement final List tableConstraints; final bool withoutRowId; + /// Specific to moor. Overrides the name of the data class used to hold a + /// result for of this table. Will be null when the moor extensions are not + /// enabled or if no name has been set. + final String overriddenDataClassName; + Token openingBracket; Token closingBracket; @@ -19,7 +24,8 @@ class CreateTableStatement extends Statement @required this.tableName, this.columns = const [], this.tableConstraints = const [], - this.withoutRowId = false}); + this.withoutRowId = false, + this.overriddenDataClassName}); @override T accept(AstVisitor visitor) => visitor.visitCreateTableStatement(this); @@ -31,6 +37,7 @@ class CreateTableStatement extends Statement bool contentEquals(CreateTableStatement other) { return other.ifNotExists == ifNotExists && other.tableName == tableName && - other.withoutRowId == withoutRowId; + other.withoutRowId == withoutRowId && + other.overriddenDataClassName == overriddenDataClassName; } } diff --git a/sqlparser/lib/src/reader/parser/schema.dart b/sqlparser/lib/src/reader/parser/schema.dart index a0aa9363..bd362987 100644 --- a/sqlparser/lib/src/reader/parser/schema.dart +++ b/sqlparser/lib/src/reader/parser/schema.dart @@ -55,12 +55,21 @@ mixin SchemaParser on ParserBase { withoutRowId = true; } + String overriddenName; + if (enableMoorExtensions && _matchOne(TokenType.as)) { + overriddenName = _consumeIdentifier( + 'Expected the name for the data class', + lenient: true) + .identifier; + } + return CreateTableStatement( ifNotExists: ifNotExists, tableName: tableIdentifier.identifier, withoutRowId: withoutRowId, columns: columns, tableConstraints: tableConstraints, + overriddenDataClassName: overriddenName, ) ..setSpan(first, _previous) ..openingBracket = leftParen diff --git a/sqlparser/test/parser/moor_file_test.dart b/sqlparser/test/parser/moor_file_test.dart index 1a6e5c36..e457cb08 100644 --- a/sqlparser/test/parser/moor_file_test.dart +++ b/sqlparser/test/parser/moor_file_test.dart @@ -10,7 +10,7 @@ CREATE TABLE tbl ( id INT NOT NULL PRIMARY KEY AUTOINCREMENT, -- this is a single-line comment place VARCHAR REFERENCES other(location) -) +) AS RowName all: SELECT /* COUNT(*), */ * FROM tbl WHERE $predicate; '''; @@ -52,6 +52,7 @@ void main() { ], ), ], + overriddenDataClassName: 'RowName', ), DeclaredStatement( 'all',