Write companions with new analyzer

This commit is contained in:
Simon Binder 2022-10-03 17:37:10 +02:00
parent 1a39c5eb8d
commit 470fb49592
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
6 changed files with 495 additions and 3055 deletions

View File

@ -2,183 +2,6 @@
part of 'main.dart';
// **************************************************************************
// DriftDatabaseGenerator
// **************************************************************************
// ignore_for_file: type=lint
class TodoCategory extends DataClass implements Insertable<TodoCategory> {
final int id;
final String name;
const TodoCategory({required this.id, required this.name});
@override
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
map['id'] = Variable<int>(id);
map['name'] = Variable<String>(name);
return map;
}
TodoCategoriesCompanion toCompanion(bool nullToAbsent) {
return TodoCategoriesCompanion(
id: Value(id),
name: Value(name),
);
}
factory TodoCategory.fromJson(Map<String, dynamic> json,
{ValueSerializer? serializer}) {
serializer ??= driftRuntimeOptions.defaultSerializer;
return TodoCategory(
id: serializer.fromJson<int>(json['id']),
name: serializer.fromJson<String>(json['name']),
);
}
factory TodoCategory.fromJsonString(String encodedJson,
{ValueSerializer? serializer}) =>
TodoCategory.fromJson(
DataClass.parseJson(encodedJson) as Map<String, dynamic>,
serializer: serializer);
@override
Map<String, dynamic> toJson({ValueSerializer? serializer}) {
serializer ??= driftRuntimeOptions.defaultSerializer;
return <String, dynamic>{
'id': serializer.toJson<int>(id),
'name': serializer.toJson<String>(name),
};
}
TodoCategory copyWith({int? id, String? name}) => TodoCategory(
id: id ?? this.id,
name: name ?? this.name,
);
@override
String toString() {
return (StringBuffer('TodoCategory(')
..write('id: $id, ')
..write('name: $name')
..write(')'))
.toString();
}
@override
int get hashCode => Object.hash(id, name);
@override
bool operator ==(Object other) =>
identical(this, other) ||
(other is TodoCategory && other.id == this.id && other.name == this.name);
}
class TodoCategoriesCompanion extends UpdateCompanion<TodoCategory> {
final Value<int> id;
final Value<String> name;
const TodoCategoriesCompanion({
this.id = const Value.absent(),
this.name = const Value.absent(),
});
TodoCategoriesCompanion.insert({
this.id = const Value.absent(),
required String name,
}) : name = Value(name);
static Insertable<TodoCategory> custom({
Expression<int>? id,
Expression<String>? name,
}) {
return RawValuesInsertable({
if (id != null) 'id': id,
if (name != null) 'name': name,
});
}
TodoCategoriesCompanion copyWith({Value<int>? id, Value<String>? name}) {
return TodoCategoriesCompanion(
id: id ?? this.id,
name: name ?? this.name,
);
}
@override
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
if (id.present) {
map['id'] = Variable<int>(id.value);
}
if (name.present) {
map['name'] = Variable<String>(name.value);
}
return map;
}
@override
String toString() {
return (StringBuffer('TodoCategoriesCompanion(')
..write('id: $id, ')
..write('name: $name')
..write(')'))
.toString();
}
}
class $TodoCategoriesTable extends TodoCategories
with TableInfo<$TodoCategoriesTable, TodoCategory> {
@override
final GeneratedDatabase attachedDatabase;
final String? _alias;
$TodoCategoriesTable(this.attachedDatabase, [this._alias]);
final VerificationMeta _idMeta = const VerificationMeta('id');
@override
late final GeneratedColumn<int> id = GeneratedColumn<int>(
'id', aliasedName, false,
type: DriftSqlType.int,
requiredDuringInsert: false,
defaultConstraints: 'PRIMARY KEY AUTOINCREMENT');
final VerificationMeta _nameMeta = const VerificationMeta('name');
@override
late final GeneratedColumn<String> name = GeneratedColumn<String>(
'name', aliasedName, false,
type: DriftSqlType.string, requiredDuringInsert: true);
@override
List<GeneratedColumn> get $columns => [id, name];
@override
String get aliasedName => _alias ?? 'todo_categories';
@override
String get actualTableName => 'todo_categories';
@override
VerificationContext validateIntegrity(Insertable<TodoCategory> instance,
{bool isInserting = false}) {
final context = VerificationContext();
final data = instance.toColumns(true);
if (data.containsKey('id')) {
context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta));
}
if (data.containsKey('name')) {
context.handle(
_nameMeta, name.isAcceptableOrUnknown(data['name']!, _nameMeta));
} else if (isInserting) {
context.missing(_nameMeta);
}
return context;
}
@override
Set<GeneratedColumn> get $primaryKey => {id};
@override
TodoCategory map(Map<String, dynamic> data, {String? tablePrefix}) {
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
return TodoCategory(
id: attachedDatabase.options.types
.read(DriftSqlType.int, data['${effectivePrefix}id'])!,
name: attachedDatabase.options.types
.read(DriftSqlType.string, data['${effectivePrefix}name'])!,
);
}
@override
$TodoCategoriesTable createAlias(String alias) {
return $TodoCategoriesTable(attachedDatabase, alias);
}
}
class TodoItem extends DataClass implements Insertable<TodoItem> {
final int id;
final String title;
@ -392,10 +215,10 @@ class $TodoItemsTable extends TodoItems
@override
late final GeneratedColumn<String> generatedText = GeneratedColumn<String>(
'generated_text', aliasedName, true,
type: DriftSqlType.string,
requiredDuringInsert: false,
generatedAs: GeneratedAs(
title + const Constant(' (') + content + const Constant(')'), false));
title + const Constant(' (') + content + const Constant(')'), false),
type: DriftSqlType.string,
requiredDuringInsert: false);
@override
List<GeneratedColumn> get $columns =>
[id, title, content, categoryId, generatedText];
@ -463,126 +286,36 @@ class $TodoItemsTable extends TodoItems
}
}
class TodoCategoryItemCountData extends DataClass {
final String name;
final int? itemCount;
const TodoCategoryItemCountData({required this.name, this.itemCount});
factory TodoCategoryItemCountData.fromJson(Map<String, dynamic> json,
{ValueSerializer? serializer}) {
serializer ??= driftRuntimeOptions.defaultSerializer;
return TodoCategoryItemCountData(
name: serializer.fromJson<String>(json['name']),
itemCount: serializer.fromJson<int?>(json['itemCount']),
);
}
factory TodoCategoryItemCountData.fromJsonString(String encodedJson,
{ValueSerializer? serializer}) =>
TodoCategoryItemCountData.fromJson(
DataClass.parseJson(encodedJson) as Map<String, dynamic>,
serializer: serializer);
@override
Map<String, dynamic> toJson({ValueSerializer? serializer}) {
serializer ??= driftRuntimeOptions.defaultSerializer;
return <String, dynamic>{
'name': serializer.toJson<String>(name),
'itemCount': serializer.toJson<int?>(itemCount),
};
}
TodoCategoryItemCountData copyWith(
{String? name, Value<int?> itemCount = const Value.absent()}) =>
TodoCategoryItemCountData(
name: name ?? this.name,
itemCount: itemCount.present ? itemCount.value : this.itemCount,
);
@override
String toString() {
return (StringBuffer('TodoCategoryItemCountData(')
..write('name: $name, ')
..write('itemCount: $itemCount')
..write(')'))
.toString();
}
@override
int get hashCode => Object.hash(name, itemCount);
@override
bool operator ==(Object other) =>
identical(this, other) ||
(other is TodoCategoryItemCountData &&
other.name == this.name &&
other.itemCount == this.itemCount);
}
class $TodoCategoryItemCountView
extends ViewInfo<$TodoCategoryItemCountView, TodoCategoryItemCountData>
implements HasResultSet {
final String? _alias;
@override
final _$Database attachedDatabase;
$TodoCategoryItemCountView(this.attachedDatabase, [this._alias]);
$TodoItemsTable get todoItems => attachedDatabase.todoItems.createAlias('t0');
$TodoCategoriesTable get todoCategories =>
attachedDatabase.todoCategories.createAlias('t1');
@override
List<GeneratedColumn> get $columns => [name, itemCount];
@override
String get aliasedName => _alias ?? entityName;
@override
String get entityName => 'todo_category_item_count';
@override
String? get createViewStmt => null;
@override
$TodoCategoryItemCountView get asDslTable => this;
@override
TodoCategoryItemCountData map(Map<String, dynamic> data,
{String? tablePrefix}) {
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
return TodoCategoryItemCountData(
name: attachedDatabase.options.types
.read(DriftSqlType.string, data['${effectivePrefix}name'])!,
itemCount: attachedDatabase.options.types
.read(DriftSqlType.int, data['${effectivePrefix}item_count']),
);
}
late final GeneratedColumn<String> name = GeneratedColumn<String>(
'name', aliasedName, false,
type: DriftSqlType.string,
generatedAs: GeneratedAs(todoCategories.name, false));
late final GeneratedColumn<int> itemCount = GeneratedColumn<int>(
'item_count', aliasedName, true,
type: DriftSqlType.int,
generatedAs: GeneratedAs(todoItems.id.count(), false));
@override
$TodoCategoryItemCountView createAlias(String alias) {
return $TodoCategoryItemCountView(attachedDatabase, alias);
}
@override
Query? get query =>
(attachedDatabase.selectOnly(todoCategories)..addColumns($columns)).join([
innerJoin(todoItems, todoItems.categoryId.equalsExp(todoCategories.id))
]);
@override
Set<String> get readTables => const {'todo_items', 'todo_categories'};
}
class TodoItemWithCategoryNameViewData extends DataClass {
class TodoCategory extends DataClass implements Insertable<TodoCategory> {
final int id;
final String? title;
const TodoItemWithCategoryNameViewData({required this.id, this.title});
factory TodoItemWithCategoryNameViewData.fromJson(Map<String, dynamic> json,
{ValueSerializer? serializer}) {
serializer ??= driftRuntimeOptions.defaultSerializer;
return TodoItemWithCategoryNameViewData(
id: serializer.fromJson<int>(json['id']),
title: serializer.fromJson<String?>(json['title']),
final String name;
const TodoCategory({required this.id, required this.name});
@override
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
map['id'] = Variable<int>(id);
map['name'] = Variable<String>(name);
return map;
}
TodoCategoriesCompanion toCompanion(bool nullToAbsent) {
return TodoCategoriesCompanion(
id: Value(id),
name: Value(name),
);
}
factory TodoItemWithCategoryNameViewData.fromJsonString(String encodedJson,
factory TodoCategory.fromJson(Map<String, dynamic> json,
{ValueSerializer? serializer}) {
serializer ??= driftRuntimeOptions.defaultSerializer;
return TodoCategory(
id: serializer.fromJson<int>(json['id']),
name: serializer.fromJson<String>(json['name']),
);
}
factory TodoCategory.fromJsonString(String encodedJson,
{ValueSerializer? serializer}) =>
TodoItemWithCategoryNameViewData.fromJson(
TodoCategory.fromJson(
DataClass.parseJson(encodedJson) as Map<String, dynamic>,
serializer: serializer);
@override
@ -590,107 +323,146 @@ class TodoItemWithCategoryNameViewData extends DataClass {
serializer ??= driftRuntimeOptions.defaultSerializer;
return <String, dynamic>{
'id': serializer.toJson<int>(id),
'title': serializer.toJson<String?>(title),
'name': serializer.toJson<String>(name),
};
}
TodoItemWithCategoryNameViewData copyWith(
{int? id, Value<String?> title = const Value.absent()}) =>
TodoItemWithCategoryNameViewData(
TodoCategory copyWith({int? id, String? name}) => TodoCategory(
id: id ?? this.id,
title: title.present ? title.value : this.title,
name: name ?? this.name,
);
@override
String toString() {
return (StringBuffer('TodoItemWithCategoryNameViewData(')
return (StringBuffer('TodoCategory(')
..write('id: $id, ')
..write('title: $title')
..write('name: $name')
..write(')'))
.toString();
}
@override
int get hashCode => Object.hash(id, title);
int get hashCode => Object.hash(id, name);
@override
bool operator ==(Object other) =>
identical(this, other) ||
(other is TodoItemWithCategoryNameViewData &&
other.id == this.id &&
other.title == this.title);
(other is TodoCategory && other.id == this.id && other.name == this.name);
}
class $TodoItemWithCategoryNameViewView extends ViewInfo<
$TodoItemWithCategoryNameViewView,
TodoItemWithCategoryNameViewData> implements HasResultSet {
final String? _alias;
@override
final _$Database attachedDatabase;
$TodoItemWithCategoryNameViewView(this.attachedDatabase, [this._alias]);
$TodoItemsTable get todoItems => attachedDatabase.todoItems.createAlias('t0');
$TodoCategoriesTable get todoCategories =>
attachedDatabase.todoCategories.createAlias('t1');
@override
List<GeneratedColumn> get $columns => [id, title];
@override
String get aliasedName => _alias ?? entityName;
@override
String get entityName => 'customViewName';
@override
String? get createViewStmt => null;
@override
$TodoItemWithCategoryNameViewView get asDslTable => this;
@override
TodoItemWithCategoryNameViewData map(Map<String, dynamic> data,
{String? tablePrefix}) {
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
return TodoItemWithCategoryNameViewData(
id: attachedDatabase.options.types
.read(DriftSqlType.int, data['${effectivePrefix}id'])!,
title: attachedDatabase.options.types
.read(DriftSqlType.string, data['${effectivePrefix}title']),
class TodoCategoriesCompanion extends UpdateCompanion<TodoCategory> {
final Value<int> id;
final Value<String> name;
const TodoCategoriesCompanion({
this.id = const Value.absent(),
this.name = const Value.absent(),
});
TodoCategoriesCompanion.insert({
this.id = const Value.absent(),
required String name,
}) : name = Value(name);
static Insertable<TodoCategory> custom({
Expression<int>? id,
Expression<String>? name,
}) {
return RawValuesInsertable({
if (id != null) 'id': id,
if (name != null) 'name': name,
});
}
TodoCategoriesCompanion copyWith({Value<int>? id, Value<String>? name}) {
return TodoCategoriesCompanion(
id: id ?? this.id,
name: name ?? this.name,
);
}
late final GeneratedColumn<int> id = GeneratedColumn<int>(
'id', aliasedName, false,
type: DriftSqlType.int, generatedAs: GeneratedAs(todoItems.id, false));
late final GeneratedColumn<String> title = GeneratedColumn<String>(
'title', aliasedName, true,
type: DriftSqlType.string,
generatedAs: GeneratedAs(
todoItems.title +
const Constant('(') +
todoCategories.name +
const Constant(')'),
false));
@override
$TodoItemWithCategoryNameViewView createAlias(String alias) {
return $TodoItemWithCategoryNameViewView(attachedDatabase, alias);
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
if (id.present) {
map['id'] = Variable<int>(id.value);
}
if (name.present) {
map['name'] = Variable<String>(name.value);
}
return map;
}
@override
Query? get query =>
(attachedDatabase.selectOnly(todoItems)..addColumns($columns)).join([
innerJoin(
todoCategories, todoCategories.id.equalsExp(todoItems.categoryId))
]);
String toString() {
return (StringBuffer('TodoCategoriesCompanion(')
..write('id: $id, ')
..write('name: $name')
..write(')'))
.toString();
}
}
class $TodoCategoriesTable extends TodoCategories
with TableInfo<$TodoCategoriesTable, TodoCategory> {
@override
Set<String> get readTables => const {'todo_items', 'todo_categories'};
final GeneratedDatabase attachedDatabase;
final String? _alias;
$TodoCategoriesTable(this.attachedDatabase, [this._alias]);
final VerificationMeta _idMeta = const VerificationMeta('id');
@override
late final GeneratedColumn<int> id = GeneratedColumn<int>(
'id', aliasedName, false,
type: DriftSqlType.int,
requiredDuringInsert: false,
defaultConstraints: 'PRIMARY KEY AUTOINCREMENT');
final VerificationMeta _nameMeta = const VerificationMeta('name');
@override
late final GeneratedColumn<String> name = GeneratedColumn<String>(
'name', aliasedName, false,
type: DriftSqlType.string, requiredDuringInsert: true);
@override
List<GeneratedColumn> get $columns => [id, name];
@override
String get aliasedName => _alias ?? 'todo_categories';
@override
String get actualTableName => 'todo_categories';
@override
VerificationContext validateIntegrity(Insertable<TodoCategory> instance,
{bool isInserting = false}) {
final context = VerificationContext();
final data = instance.toColumns(true);
if (data.containsKey('id')) {
context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta));
}
if (data.containsKey('name')) {
context.handle(
_nameMeta, name.isAcceptableOrUnknown(data['name']!, _nameMeta));
} else if (isInserting) {
context.missing(_nameMeta);
}
return context;
}
@override
Set<GeneratedColumn> get $primaryKey => {id};
@override
TodoCategory map(Map<String, dynamic> data, {String? tablePrefix}) {
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
return TodoCategory(
id: attachedDatabase.options.types
.read(DriftSqlType.int, data['${effectivePrefix}id'])!,
name: attachedDatabase.options.types
.read(DriftSqlType.string, data['${effectivePrefix}name'])!,
);
}
@override
$TodoCategoriesTable createAlias(String alias) {
return $TodoCategoriesTable(attachedDatabase, alias);
}
}
abstract class _$Database extends GeneratedDatabase {
_$Database(QueryExecutor e) : super(e);
_$Database.connect(DatabaseConnection c) : super.connect(c);
late final $TodoCategoriesTable todoCategories = $TodoCategoriesTable(this);
late final $TodoItemsTable todoItems = $TodoItemsTable(this);
late final $TodoCategoryItemCountView todoCategoryItemCount =
$TodoCategoryItemCountView(this);
late final $TodoItemWithCategoryNameViewView customViewName =
$TodoItemWithCategoryNameViewView(this);
@override
Iterable<TableInfo<Table, dynamic>> get allTables =>
allSchemaEntities.whereType<TableInfo<Table, Object?>>();
@override
List<DatabaseSchemaEntity> get allSchemaEntities =>
[todoCategories, todoItems, todoCategoryItemCount, customViewName];
late final $TodoCategoriesTable todoCategories = $TodoCategoriesTable(this);
}
// DriftElementId(asset:drift/example/main.dart, todo_items)
// DriftElementId(asset:drift/example/main.dart, todo_categories)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,7 @@ import '../utils/column_constraints.dart';
import '../utils/memoized_getter.dart';
import '../writer.dart';
import 'data_class_writer.dart';
import 'update_companion_writer.dart';
/// Common writer for tables or views.
///
@ -240,7 +241,7 @@ class TableWriter extends TableOrViewWriter {
}
if (scope.generationOptions.writeCompanions) {
//UpdateCompanionWriter(table, scope.child()).write();
UpdateCompanionWriter(table, scope.child()).write();
}
}

View File

@ -1,28 +1,34 @@
import 'package:collection/collection.dart';
import 'package:drift_dev/moor_generator.dart';
import 'package:drift_dev/src/utils/string_escaper.dart';
import 'package:drift_dev/src/writer/utils/override_toString.dart';
import 'package:drift_dev/writer.dart';
import '../../analysis/results/results.dart';
import '../../utils/string_escaper.dart';
import '../utils/override_toString.dart';
import '../writer.dart';
class UpdateCompanionWriter {
final DriftTable table;
final Scope scope;
late StringBuffer _buffer;
final TextEmitter _emitter;
StringBuffer get _buffer => _emitter.buffer;
late final List<DriftColumn> columns = [
for (final column in table.columns)
if (!column.isGenerated) column,
];
UpdateCompanionWriter(this.table, this.scope) {
_buffer = scope.leaf();
}
UpdateCompanionWriter(this.table, this.scope) : _emitter = scope.leaf();
String get _companionClass =>
_emitter.dartCode(_emitter.companionType(table));
void write() {
_buffer.write('class ${table.getNameForCompanionClass(scope.options)} '
final rowClass = _emitter.dartCode(_emitter.rowType(table));
_buffer.write('class $_companionClass '
'extends '
'UpdateCompanion<${table.dartTypeCode(scope.generationOptions)}> {\n');
'UpdateCompanion<$rowClass> {\n');
_writeFields();
_writeConstructor();
@ -43,8 +49,8 @@ class UpdateCompanionWriter {
void _writeFields() {
for (final column in columns) {
final modifier = scope.options.fieldModifier;
final type = column.dartTypeCode();
_buffer.write('$modifier Value<$type> ${column.dartGetterName};\n');
final type = _emitter.dartCode(scope.writer.dartType(column));
_buffer.write('$modifier Value<$type> ${column.nameInDart};\n');
}
}
@ -52,10 +58,10 @@ class UpdateCompanionWriter {
if (!scope.options.generateMutableClasses) {
_buffer.write('const ');
}
_buffer.write('${table.getNameForCompanionClass(scope.options)}({');
_buffer.write('$_companionClass({');
for (final column in columns) {
_buffer.write('this.${column.dartGetterName} = const Value.absent(),');
_buffer.write('this.${column.nameInDart} = const Value.absent(),');
}
_buffer.write('});\n');
@ -69,7 +75,7 @@ class UpdateCompanionWriter {
// can't be constant because we use initializers (this.a = Value(a)).
// for a parameter a which is only potentially constant.
_buffer.write('${table.getNameForCompanionClass(scope.options)}.insert({');
_buffer.write('$_companionClass.insert({');
// Say we had two required columns a and c, and an optional column b.
// .insert({
@ -79,11 +85,11 @@ class UpdateCompanionWriter {
// We don't need to use this. for the initializers, Dart figures that out.
for (final column in columns) {
final param = column.dartGetterName;
final param = column.nameInDart;
if (table.isColumnRequiredForInsert(column)) {
requiredColumns.add(column);
final typeName = column.dartTypeCode();
final typeName = _emitter.dartCode(_emitter.dartType(column));
_buffer.write('required $typeName $param,');
} else {
@ -101,7 +107,7 @@ class UpdateCompanionWriter {
_buffer.write(', ');
}
final param = required.dartGetterName;
final param = required.nameInDart;
_buffer.write('$param = Value($param)');
}
@ -112,18 +118,18 @@ class UpdateCompanionWriter {
// Prefer a .custom constructor, unless there already is a field called
// "custom", in which case we'll use createCustom
final constructorName =
columns.map((e) => e.dartGetterName).any((name) => name == 'custom')
columns.map((e) => e.nameInDart).any((name) => name == 'custom')
? 'createCustom'
: 'custom';
final dartTypeName = table.dartTypeCode(scope.generationOptions);
final rowType = _emitter.dartCode(_emitter.rowType(table));
_buffer
..write('static Insertable<$dartTypeName> $constructorName')
..write('static Insertable<$rowType> $constructorName')
..write('({');
for (final column in columns) {
final typeName = column.innerColumnType();
_buffer.write('Expression<$typeName>? ${column.dartGetterName}, \n');
_buffer.write('Expression<$typeName>? ${column.nameInDart}, \n');
}
_buffer
@ -132,9 +138,9 @@ class UpdateCompanionWriter {
for (final column in columns) {
_buffer
..write('if (${column.dartGetterName} != null)')
..write(asDartLiteral(column.name.name))
..write(': ${column.dartGetterName},');
..write('if (${column.nameInDart} != null)')
..write(asDartLiteral(column.nameInSql))
..write(': ${column.nameInDart},');
}
_buffer.write('});\n}');
@ -142,7 +148,7 @@ class UpdateCompanionWriter {
void _writeCopyWith() {
_buffer
..write(table.getNameForCompanionClass(scope.options))
..write(_companionClass)
..write(' copyWith({');
var first = true;
for (final column in columns) {
@ -151,15 +157,15 @@ class UpdateCompanionWriter {
}
first = false;
final typeName = column.dartTypeCode();
_buffer.write('Value<$typeName>? ${column.dartGetterName}');
final typeName = _emitter.dartCode(_emitter.dartType(column));
_buffer.write('Value<$typeName>? ${column.nameInDart}');
}
_buffer
..write('}) {\n') //
..write('return ${table.getNameForCompanionClass(scope.options)}(');
..writeln('}) {')
..write('return $_companionClass(');
for (final column in columns) {
final name = column.dartGetterName;
final name = column.nameInDart;
_buffer.write('$name: $name ?? this.$name,');
}
_buffer.write(');\n}\n');
@ -175,18 +181,18 @@ class UpdateCompanionWriter {
const locals = {'map', 'nullToAbsent', 'converter'};
for (final column in columns) {
final getterName = column.thisIfNeeded(locals);
final getterName = thisIfNeeded(column.nameInDart, locals);
_buffer.write('if ($getterName.present) {');
final typeName = column.variableTypeCode(nullable: false);
final mapSetter = 'map[${asDartLiteral(column.name.name)}] = '
final mapSetter = 'map[${asDartLiteral(column.nameInSql)}] = '
'Variable<$typeName>';
final converter = column.typeConverter;
if (converter != null) {
// apply type converter before writing the variable
final fieldName =
converter.tableAndField(forNullableColumn: column.nullable);
final fieldName = _emitter.dartCode(
_emitter.readConverter(converter, forNullable: column.nullable));
_buffer
..write('final converter = $fieldName;\n')
..write(mapSetter)
@ -209,44 +215,47 @@ class UpdateCompanionWriter {
void _writeToString() {
overrideToString(
table.getNameForCompanionClass(scope.options),
[for (final column in columns) column.dartGetterName],
_emitter.dartCode(_emitter.companionType(table)),
[for (final column in columns) column.nameInDart],
_buffer,
);
}
/// Writes an extension on an existing row class to map an instance of that
/// class to a suitable companion.
void _writeToCompanionExtension() {
final info = table.existingRowClass;
if (info == null) return;
final companionName = table.getNameForCompanionClass(scope.options);
final className = table.dartTypeName;
final insertableClass = '_\$${className}Insertable';
final rowClass = _emitter.rowClass(table).toString();
final rowType = _emitter.dartCode(_emitter.rowType(table));
final insertableClass = '_\$${rowClass}Insertable';
_buffer.write('class $insertableClass implements '
'Insertable<$className> {\n'
'$className _object;\n\n'
'Insertable<$rowType> {\n'
'$rowType _object;\n\n'
'$insertableClass(this._object);\n\n'
'@override\n'
'Map<String, Expression> toColumns(bool nullToAbsent) {\n'
'return $companionName(\n');
'return $_companionClass(\n');
for (final field in info.mapping.values) {
final fields = info.positionalColumns.followedBy(info.namedColumns.keys);
for (final field in fields) {
final column =
table.columns.firstWhereOrNull((e) => e.dartGetterName == field.name);
table.columns.firstWhereOrNull((e) => e.nameInDart == field);
if (column != null && !column.isGenerated) {
final dartName = column.dartGetterName;
final dartName = column.nameInDart;
_buffer.write('$dartName: Value (_object.$dartName),\n');
}
}
_buffer
..write(').toColumns(false);\n}\n}\n\n')
..write('extension ${table.dartTypeName}ToInsertable '
'on ${table.dartTypeName} {')
..write('extension ${rowClass}ToInsertable '
'on $rowType {')
..write('$insertableClass toInsertable() {\n')
..write('return _\$${className}Insertable(this);\n')
..write('return $insertableClass(this);\n')
..write('}\n}\n');
}
}

View File

@ -12,7 +12,7 @@ Uri _driftImport = Uri.parse('package:drift/drift.dart');
/// realize we need to introduce another top-level class! When passing a single
/// [StringBuffer] to the generators that will get ugly to manage, but when
/// passing a [Scope] we will always be able to write code in a parent scope.
class Writer {
class Writer extends _NodeOrWriter {
late final Scope _root;
late final TextEmitter _header;
late final TextEmitter _imports;
@ -23,6 +23,9 @@ class Writer {
TextEmitter get header => _header;
TextEmitter get imports => _imports;
@override
Writer get writer => this;
Writer(this.options, {required this.generationOptions}) {
_root = Scope(parent: null, writer: this);
_header = leaf();
@ -42,8 +45,15 @@ class Writer {
}
}
Scope child() => _root.child();
TextEmitter leaf() => _root.leaf();
}
abstract class _NodeOrWriter {
Writer get writer;
AnnotatedDartCode companionType(DriftTable table) {
final baseName = options.useDataClassNameForCompanions
final baseName = writer.options.useDataClassNameForCompanions
? table.nameOfRowClass
: table.baseDartName;
@ -121,7 +131,8 @@ class Writer {
}
String refUri(Uri definition, String element) {
final prefix = generationOptions.imports.prefixFor(definition, element);
final prefix =
writer.generationOptions.imports.prefixFor(definition, element);
if (prefix == null) {
return element;
@ -149,12 +160,9 @@ class Writer {
return buffer.toString();
}
Scope child() => _root.child();
TextEmitter leaf() => _root.leaf();
}
abstract class _Node {
abstract class _Node extends _NodeOrWriter {
final Scope? parent;
_Node(this.parent);
@ -168,6 +176,7 @@ abstract class _Node {
/// we just pass a single [StringBuffer] around, this is annoying to manage.
class Scope extends _Node {
final List<_Node> _children = [];
@override
final Writer writer;
/// An arbitrary counter.
@ -206,6 +215,7 @@ class Scope extends _Node {
class TextEmitter extends _Node {
final StringBuffer buffer = StringBuffer();
@override
final Writer writer;
TextEmitter(Scope super.parent) : writer = parent.writer;
@ -219,15 +229,9 @@ class TextEmitter extends _Node {
void writeDriftRef(String element) => write(refDrift(element));
String refUri(Uri definition, String element) {
return writer.refUri(definition, element);
}
String refDrift(String element) => refUri(_driftImport, element);
void writeDart(AnnotatedDartCode code) => write(dartCode(code));
String dartCode(AnnotatedDartCode code) => writer.dartCode(code);
}
/// Options that are specific to code-generation.