Optionally use data class name for companions

Closes #185
This commit is contained in:
Simon Binder 2019-10-16 21:33:13 +02:00
parent 4c090af98c
commit 95f37575f8
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
9 changed files with 72 additions and 26 deletions

View File

@ -6,7 +6,7 @@ description: >-
The `moor_generator` package has some options that control how the The `moor_generator` package has some options that control how the
code is generated. Note that, in most cases, the default settings code is generated. Note that, in most cases, the default settings
should be sufficient. should be sufficient. See the section on recommended settings below.
To use the options, create a `build.yaml` file in the root of your project (e.g. next To use the options, create a `build.yaml` file in the root of your project (e.g. next
to your `pubspec.yaml`): to your `pubspec.yaml`):
@ -39,3 +39,16 @@ At the moment, moor supports these options:
of inserted data and report detailed errors when the integrity is violated. If you're only using of inserted data and report detailed errors when the integrity is violated. If you're only using
inserts with SQL, or don't need this functionality, enabling this flag can help to reduce the amount inserts with SQL, or don't need this functionality, enabling this flag can help to reduce the amount
generated code. generated code.
* `use_data_class_name_for_companions`: By default, the name for [companion classes]({{< relref "../Getting started/writing_queries.md#updates-and-deletes" >}})
is based on the table name (e.g. a `@DataClassName('Users') class UsersTable extends Table` would generate
a `UsersTableCompanion`). With this option, the name is based on the data class (so `UsersCompanion` in
this case).
## Recommended options
In general, we recommend not enabling these options unless you need to. There are two exceptions though:
- `compact_query_methods`: We recommend enabling this flag because it generates less code and it will
be the only option in the next breaking upgrade.
- `skip_verification_code`: You can remove a significant portion of generated code with this option. The
downside is that error messages when inserting invalid data will be less specific.

View File

@ -2,6 +2,8 @@
- Accept inheritance in table definitions (e.g. if an abstract class declared as `IntColumn get foo => integer()()`, - Accept inheritance in table definitions (e.g. if an abstract class declared as `IntColumn get foo => integer()()`,
tables inheriting from that class will also have a `foo` column) tables inheriting from that class will also have a `foo` column)
- New `use_data_class_name_for_companions` option that will make the name of the companion
based on the data class name (uses table name by default).
## 2.0.1 ## 2.0.1

View File

@ -5,12 +5,14 @@ class MoorOptions {
final bool overrideHashAndEqualsInResultSets; final bool overrideHashAndEqualsInResultSets;
final bool compactQueryMethods; final bool compactQueryMethods;
final bool skipVerificationCode; final bool skipVerificationCode;
final bool useDataClassNameForCompanions;
MoorOptions( const MoorOptions(
this.generateFromJsonStringConstructor, {this.generateFromJsonStringConstructor = false,
this.overrideHashAndEqualsInResultSets, this.overrideHashAndEqualsInResultSets = false,
this.compactQueryMethods, this.compactQueryMethods = false,
this.skipVerificationCode); this.skipVerificationCode = false,
this.useDataClassNameForCompanions = false});
factory MoorOptions.fromBuilder(Map<String, dynamic> config) { factory MoorOptions.fromBuilder(Map<String, dynamic> config) {
final writeFromString = final writeFromString =
@ -25,13 +27,15 @@ class MoorOptions {
final skipVerificationCode = final skipVerificationCode =
config['skip_verification_code'] as bool ?? false; config['skip_verification_code'] as bool ?? false;
return MoorOptions(writeFromString, overrideInResultSets, final dataClassNamesForCompanions =
compactQueryMethods, skipVerificationCode); config['use_data_class_name_for_companions'] as bool ?? false;
}
const MoorOptions.defaults() return MoorOptions(
: generateFromJsonStringConstructor = false, generateFromJsonStringConstructor: writeFromString,
overrideHashAndEqualsInResultSets = false, overrideHashAndEqualsInResultSets: overrideInResultSets,
compactQueryMethods = false, compactQueryMethods: compactQueryMethods,
skipVerificationCode = false; skipVerificationCode: skipVerificationCode,
useDataClassNameForCompanions: dataClassNamesForCompanions,
);
}
} }

View File

@ -1,4 +1,5 @@
import 'package:moor_generator/src/analyzer/sql_queries/meta/declarations.dart'; import 'package:moor_generator/src/analyzer/sql_queries/meta/declarations.dart';
import 'package:moor_generator/src/backends/build/moor_builder.dart';
import 'package:moor_generator/src/model/specified_column.dart'; import 'package:moor_generator/src/model/specified_column.dart';
import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/element.dart';
import 'package:moor_generator/src/model/used_type_converter.dart'; import 'package:moor_generator/src/model/used_type_converter.dart';
@ -48,7 +49,11 @@ class SpecifiedTable {
return name; return name;
} }
String get updateCompanionName => _updateCompanionName(_baseName); String getNameForCompanionClass(MoorOptions options) {
final baseName =
options.useDataClassNameForCompanions ? dartTypeName : _baseName;
return '${baseName}Companion';
}
/// The set of primary keys, if they have been explicitly defined by /// The set of primary keys, if they have been explicitly defined by
/// overriding `primaryKey` in the table class. `null` if the primary key has /// overriding `primaryKey` in the table class. `null` if the primary key has
@ -104,5 +109,3 @@ class SpecifiedTable {
String _dbFieldName(String className) => ReCase(className).camelCase; String _dbFieldName(String className) => ReCase(className).camelCase;
String tableInfoNameForTableClass(String className) => '\$${className}Table'; String tableInfoNameForTableClass(String className) => '\$${className}Table';
String _updateCompanionName(String className) => '${className}Companion';

View File

@ -219,7 +219,7 @@ class DataClassWriter {
void _writeCompanionOverride() { void _writeCompanionOverride() {
// TableCompanion createCompanion(bool nullToAbsent) // TableCompanion createCompanion(bool nullToAbsent)
final companionClass = table.updateCompanionName; final companionClass = table.getNameForCompanionClass(scope.options);
_buffer.write('@override\n' _buffer.write('@override\n'
'$companionClass createCompanion(bool nullToAbsent) {\n' '$companionClass createCompanion(bool nullToAbsent) {\n'
'return $companionClass('); 'return $companionClass(');

View File

@ -98,7 +98,7 @@ class TableWriter {
// Map<String, Variable> entityToSql(covariant UpdateCompanion<D> instance) // Map<String, Variable> entityToSql(covariant UpdateCompanion<D> instance)
_buffer _buffer
..write('@override\nMap<String, Variable> entityToSql(' ..write('@override\nMap<String, Variable> entityToSql('
'${table.updateCompanionName} d) {\n') '${table.getNameForCompanionClass(scope.options)} d) {\n')
..write('final map = <String, Variable> {};'); ..write('final map = <String, Variable> {};');
for (var column in table.columns) { for (var column in table.columns) {
@ -204,7 +204,8 @@ class TableWriter {
_buffer _buffer
..write('@override\nVerificationContext validateIntegrity' ..write('@override\nVerificationContext validateIntegrity'
'(${table.updateCompanionName} d, {bool isInserting = false}) {\n') '(${table.getNameForCompanionClass(scope.options)} d, '
'{bool isInserting = false}) {\n')
..write('final context = VerificationContext();\n'); ..write('final context = VerificationContext();\n');
for (var column in table.columns) { for (var column in table.columns) {

View File

@ -13,7 +13,7 @@ class UpdateCompanionWriter {
} }
void write() { void write() {
_buffer.write('class ${table.updateCompanionName} ' _buffer.write('class ${table.getNameForCompanionClass(scope.options)} '
'extends UpdateCompanion<${table.dartTypeName}> {\n'); 'extends UpdateCompanion<${table.dartTypeName}> {\n');
_writeFields(); _writeFields();
_writeConstructor(); _writeConstructor();
@ -31,7 +31,7 @@ class UpdateCompanionWriter {
} }
void _writeConstructor() { void _writeConstructor() {
_buffer.write('const ${table.updateCompanionName}({'); _buffer.write('const ${table.getNameForCompanionClass(scope.options)}({');
for (var column in table.columns) { for (var column in table.columns) {
_buffer.write('this.${column.dartGetterName} = const Value.absent(),'); _buffer.write('this.${column.dartGetterName} = const Value.absent(),');
@ -48,7 +48,7 @@ class UpdateCompanionWriter {
// can't be constant because we use initializers (this.a = Value(a)). // can't be constant because we use initializers (this.a = Value(a)).
// for a parameter a which is only potentially constant. // for a parameter a which is only potentially constant.
_buffer.write('${table.updateCompanionName}.insert({'); _buffer.write('${table.getNameForCompanionClass(scope.options)}.insert({');
// Say we had two required columns a and c, and an optional column b. // Say we had two required columns a and c, and an optional column b.
// .insert({ // .insert({
@ -87,7 +87,9 @@ class UpdateCompanionWriter {
} }
void _writeCopyWith() { void _writeCopyWith() {
_buffer.write('${table.updateCompanionName} copyWith({'); _buffer
..write(table.getNameForCompanionClass(scope.options))
..write(' copyWith({');
var first = true; var first = true;
for (var column in table.columns) { for (var column in table.columns) {
if (!first) { if (!first) {
@ -99,7 +101,7 @@ class UpdateCompanionWriter {
_buffer _buffer
..write('}) {\n') // ..write('}) {\n') //
..write('return ${table.updateCompanionName}('); ..write('return ${table.getNameForCompanionClass(scope.options)}(');
for (var column in table.columns) { for (var column in table.columns) {
final name = column.dartGetterName; final name = column.dartGetterName;
_buffer.write('$name: $name ?? this.$name,'); _buffer.write('$name: $name ?? this.$name,');

View File

@ -50,6 +50,8 @@ class Scope extends _Node {
final DartScope scope; final DartScope scope;
final Writer writer; final Writer writer;
MoorOptions get options => writer.options;
Scope({@required Scope parent, Writer writer}) Scope({@required Scope parent, Writer writer})
: scope = parent?.scope?.nextLevel ?? DartScope.library, : scope = parent?.scope?.nextLevel ?? DartScope.library,
writer = writer ?? parent?.writer, writer = writer ?? parent?.writer,

View File

@ -0,0 +1,19 @@
import 'package:moor_generator/src/backends/build/moor_builder.dart';
import 'package:moor_generator/src/model/specified_table.dart';
import 'package:test/test.dart';
void main() {
test('companion names', () {
final table =
SpecifiedTable(overriddenName: 'GoogleUser', dartTypeName: 'User');
expect(table.getNameForCompanionClass(const MoorOptions()),
'GoogleUserCompanion');
expect(
table.getNameForCompanionClass(
const MoorOptions(useDataClassNameForCompanions: true)),
'UserCompanion',
);
});
}