simolus3 / drift

Drift is an easy to use, reactive, typesafe persistence library for Dart & Flutter.
https://drift.simonbinder.eu/
MIT License
2.59k stars 366 forks source link

Migrations 2.7 => 2.19, unlogic errors #3149

Open CharlotteJu opened 1 month ago

CharlotteJu commented 1 month ago

Hello,

I just updated Drift (I went from 2.7.0 to 2.19.1), and it created 2 incomprehensible errors for me. I specify that everything worked well in 2.7

1 - I can not have the word "Menus" in the name of a Table (I had the case with 2 tables having this word in their name)

Example:

class Menus extends Table {
  IntColumn get id => integer()();
  @override
  Set<Column> get primaryKey => {id};

  @override
  String get tableName => "Menus";
}

Error message in console when building the generated files: [SEVERE] drift_dev on lib/core/data/tables/menus.dart (cached): type 'Null' is not a subtype of type 'InterfaceElement' in type cast

Errors in my generated database file:

Capture d’écran 2024-08-14 à 11 21 18

$MainMenusTable extends ... : Missing concrete implementations of 'Table.blob', 'Table.boolean', 'Table.customType', 'Table.dateTime', and 11 more. TableInfo : 'TableInfo<$MainMenusTable, MainMenus>' can't be mixed onto 'MainMenus' because 'MainMenus' doesn't implement 'Table'. $MainMenusTable(...) : The implicitly invoked unnamed constructor from 'MainMenus' has required parameters. id : '$MainMenusTable.id' ('GeneratedColumn<int> Function()') isn't a valid override of 'MainMenus.id' ('int Function()').

If I just remove the 'u', I no longer have any errors.

class Mens extends Table {
  IntColumn get id => integer()();
  @override
  Set<Column> get primaryKey => {id};

  @override
  String get tableName => "Menus";
}
Capture d’écran 2024-08-14 à 11 26 33

2 - I have a warning on a reference that uses @UseRowClass, but I really do not understand why. I need to have custom classes, here I have hidden the methods because they are not useful in this problem.

Warning message in console :

Warning : 
line 9, column 28 of package:[].dart: The referenced element, CompleteEntityFilterDataClass, is not understood by drift.
  ╷
9 │       integer().references(CompleteEntityFilterDataClass, #id,
  │                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  ╵

Code :

@UseRowClass(CompleteEntityFilter)
class CompleteEntityFilterDataClass extends Table {
  IntColumn get id => integer().autoIncrement().nullable()();
  TextColumn get label => text().nullable()();
  IntColumn get typeListToFilterId => integer()();
}

class CompleteEntityFilter {
  CompleteEntityFilter({
    this.id,
    this.label,
    required this.typeListToFilterId,
  });

  CompleteEntityFilter.withFilters({
    this.id,
    required this.typeListToFilterId,
    this.filters,
  });

  int? id;
  String? label;
  int typeListToFilterId;
  List<Filter>? filters;

[...]

}

@UseRowClass(Filter)
FilterDataClass extends Table {
  IntColumn get id => integer().autoIncrement()();
  IntColumn get completeFilterId =>
      integer().references(CompleteEntityFilterDataClass, #id,
          onUpdate: KeyAction.cascade, onDelete: KeyAction.cascade)();
  IntColumn get typeFilterSortId => integer()();
}

class Filter {
  Filter({
    this.id,
    this.completeFilterId,
    required this.typeFilterSortId,
  });

  int? id;
  int? completeFilterId;
  int typeFilterSortId;

[...]

}

Do you know why these errors occur?

BR,

MatheusPatricioo commented 1 month ago

:)

simolus3 commented 1 month ago

1 - I can not have the word "Menus" in the name of a Table (I had the case with 2 tables having this word in their name)

This was a regression from a while ago and will be fixed in the next drift version. You can also use a @DataClassName annotation on the table as a workaround.

2 - I have a warning on a reference that uses @UseRowClass, but I really do not understand why. I need to have custom classes, here I have hidden the methods because they are not useful in this problem.

Note that the snippet you've posted has a syntax error:

@UseRowClass(Filter)
-FilterDataClass extends Table {
+class FilterDataClass extends Table {

I can't reproduce the issue with the fix applied.

CharlotteJu commented 1 month ago

Ok thanks @simolus3, noted for the 1st point !

For the 2nd point, it's just a copy-paste error in the example :) This warning does'nt prevent the generation of the file, the Filter class is well written.

class $FilterDataClassTable extends FilterDataClass
    with TableInfo<$FilterDataClassTable, Filter> {
  @override
  final GeneratedDatabase attachedDatabase;
  final String? _alias;
  $FilterDataClassTable(this.attachedDatabase, [this._alias]);
  static const VerificationMeta _idMeta = const VerificationMeta('id');
  @override
  late final GeneratedColumn<int> id = GeneratedColumn<int>(
      'Id', aliasedName, false,
      hasAutoIncrement: true,
      type: DriftSqlType.int,
      requiredDuringInsert: false,
      defaultConstraints:
          GeneratedColumn.constraintIsAlways('PRIMARY KEY AUTOINCREMENT'));
  static const VerificationMeta _completeFilterIdMeta =
      const VerificationMeta('completeFilterId');
  @override
  late final GeneratedColumn<int> completeFilterId = GeneratedColumn<int>(
      'CompleteFilterId', aliasedName, false,
      type: DriftSqlType.int,
      requiredDuringInsert: true,
      defaultConstraints: GeneratedColumn.constraintIsAlways(
          'REFERENCES CompleteEntityFilterDataClass (Id) ON UPDATE CASCADE ON DELETE CASCADE'));
  static const VerificationMeta _typeFilterSortIdMeta =
      const VerificationMeta('typeFilterSortId');
  @override
  late final GeneratedColumn<int> typeFilterSortId = GeneratedColumn<int>(
      'TypeFilterSortId', aliasedName, false,
      type: DriftSqlType.int, requiredDuringInsert: true);

      ...

  }

It's strange but not blocking ...

simolus3 commented 1 month ago

So you only get the "is not understood by drift" warning now? Is there anything you're doing differently to me here? I can't reproduce the issue with this file:

import 'package:drift/drift.dart';

part 'repro.g.dart';

@UseRowClass(CompleteEntityFilter)
class CompleteEntityFilterDataClass extends Table {
  IntColumn get id => integer().autoIncrement().nullable()();
  TextColumn get label => text().nullable()();
  IntColumn get typeListToFilterId => integer()();
}

class CompleteEntityFilter {
  CompleteEntityFilter({
    this.id,
    this.label,
    required this.typeListToFilterId,
  });

  CompleteEntityFilter.withFilters({
    this.id,
    required this.typeListToFilterId,
    this.filters,
  });

  int? id;
  String? label;
  int typeListToFilterId;
  List<Filter>? filters;
}

@UseRowClass(Filter)
class FilterDataClass extends Table {
  IntColumn get id => integer().autoIncrement()();
  IntColumn get completeFilterId =>
      integer().references(CompleteEntityFilterDataClass, #id,
          onUpdate: KeyAction.cascade, onDelete: KeyAction.cascade)();
  IntColumn get typeFilterSortId => integer()();
}

class Filter {
  Filter({
    this.id,
    this.completeFilterId,
    required this.typeFilterSortId,
  });

  int? id;
  int? completeFilterId;
  int typeFilterSortId;
}

@DriftDatabase(tables: [FilterDataClass, CompleteEntityFilterDataClass])
class Database extends _$Database {
  Database(super.e);

  @override
  int get schemaVersion => 1;
}