Floor2Drift is dart library to help you migrate from the Floor orm library to Drift.
The library generates the equivalent drift code for your floor database. For a (not complete) list of supported features see Features
Warning
This project is WORK IN PROGRESS.
Not all floor features are supported at the moment and expect to make some adjustments to the generated code to work properly.
Add the floor2Drift as a dev dependencies and floor2Drift_annotation as a regular dependencies to your pubspec.yaml.
If you want to convert only part of your database you also need to add glob.
dependencies:
floor2drift_annotation: 1.0.0
dev_dependencies:
floor2drift: 0.1.0
flutter pub add dev:floor2drift floor2drift_annotationIf your entities/daos inherit fields or queries from a super class you need to annotated these super classes.
Base entities with @convertBaseEntitiy and base daos with @convertBaseDao.
If the super classes are not annotated the generator will not convert these and the fields/queries will be missing from the output.
To generate the drift classes you need to write a script and place it under tool/floor2drift.dart.
The Script is used to configure the builder and start the generation process.
The dbPath should point to the location of your with @Database annotated Floor database class.
The rootPath should point to the root directory of your flutter project. (Directory in which the /lib is).
The classNameFilter option can be used to generate dart file for a subset of all files.
If set only Entity/Dao/TypeConverter Classnames which pass the glob will be converted.
This is perfect for initial testing with only one or a few entities.
Use can use the outputFileSuffix argument to add a suffix to all generated files. The default value is "_drift".
For all configuration options see: Configuration
Note
In the default configuration the generator uses the drift @UseRowClass annotation. This is needed if you have any kind of logic in your entity classes.
See UseRowClass for instruction on how to use this option.
import 'package:floor2drift/floor2drift.dart';
import 'package:glob/glob.dart';
void main(List<String> arguments) async {
final generator = Floor2DriftGenerator(
dbPath: "../test_databases/floor_test_database.dart",
rootPath: "../",
classNameFilter: Glob("*task*", caseSensitive: false),
);
generator.start();
}case_from_dart_to_sql: camelCase is needed for the column names from drift and floor to be the same.
targets:
$default:
builders:
drift_dev:
options:
case_from_dart_to_sql: camelCaseMost of the result of methods annotated with @Insert @Update @delete will be different than the floor equivalent at the moment.
List insert/delete could have a performance impact from floor. It uses a transaction to delete/insert every entity after another to return the same result as floor. Could probably be faster if the result is not needed, but didn't check if there is an actual impact.
@Update will return nothing or always -1
TODO maybe add an option in the future to use the "more efficient" version or the result correct version
Check your usage of the return values for these kinds of methods.
Methods in dao classes with the @transaction annotation will be wrapped in a drift transaction() block. Make sure all queries in the transaction are awaited.
Transaction in other classes are not converted at the moment. Converting them yourself is not complex.
Maybe this feature will be added in the future, but it's hard to find out which transactions to convert.
see TODO.md
At the moment DB migrations have to be converted manually to drift migrations.
The example consists of 2 flutter projects
The initial_project directory contains a very simple todo app with a login in floor. The converted_project directory contains the same simple todo app but converted to drift using this library.
To run the converted_project the drift files need to be generated and the build_runner has to run Generating the drift files
cd floor2drift/example/converted_project/tool && dart floor2drift.dartRunning the build_runner
cd floor2drift/example/converted_project && dart run build_runner buildGenerate the test drift files
cd floor2drift/test/tool && dart test_generator.dartRun the build_runner
cd floor2drift && dart run build_runner buildRun all flutter tests
cd floor2drift && flutter test test/flutter_testRun all dart tests
cd floor2drift && dart test test/dart_testOverview over some of the feature, which are already supported.
This ist not an exhaustive list. If a feature that you need is not listed here. Try out if it already works or feel free to create an issue.
- type converters
- Including the same priority system, that the closes type converter is used
- default values in the default constructor are added as drift client default
- inheritance with
@convertBaseEntity - enums save the value fo
.indexin the column - renaming
- table with
@Entity(tableName: "tableName") - column with
@ColumnInfo(name: "columnName")
- table with
@Query: see expression_converter.dart and token_converter for all supported sql expressions and tokens- custom SELECT, DELETE, and UPDATE statements
@delete,@insert, and@deletesupported, but most return values are wrong- type converters of the columns are applied for return values and arguments
- Inheritance requires a specific structure at the moment, but is possible with
@convertBaseDao
The easiest way to configure this library is to use the Floor2DriftGenerator default constructor.
factory Floor2DriftGenerator({
required String dbPath,
String rootPath = "../",
Glob? classNameFilter,
String outputFileSuffix = "_drift",
bool dryRun = false,
bool convertDao = true,
bool convertEntity = true,
bool convertTypeConverter = true,
bool useRowClass = true,
ETableNameOption tableRenaming = ETableNameOption.floorScheme,
bool useDriftModularCodeGeneration = false,
})The path to the file containing the floor database.
The path to the root of the project to be converted (parent directory of lib directory)
The default should work for you if the scripts working dir is /tool/floor2drift.dart
A glob to filter the class name that should be converted.
This is used for @dao, @entity and, @typeConverter classes. Found base dao and base entity classes, with the correct annotation, are always converted.
If you want to use have the floor and drift files side by side, you can use this option to specify a suffix that will be added to the file name of all generated file for drift classes.
If the suffix is set to an empty string, the generated files will overwrite the existing floor files.
This option will work with imports in the generated files. If the generated database file imports a generated dao file, the suffix will be added to the import to ensure that the correct file is imported.
If set to true it will print the paths of files that would be generated instead of writing the files.
If set to false, dao classes will not be converted.
If set to false, entity classes will not be converted.
If set to false, type converter classes will not be converted.
If set to true all table/entity classes will be annotated with @UseRowClass from Drift.
The Drift builder will not generate an own entity class and will use the old Floor entity in the database.
All entities used for this need to implement the Insertable interface by implementing Map<String, Expression> toColumns(bool nullToAbsent);
To help with this in the generated (base-)entity classes a static toColumns method will be generated. You only need to add the interface to your entity class and call the generated method. If you have base entities the base entity implementation needs to be called also. Every generated toColumn method only includes field directly in the class.
If your entity classes are not only data classes and contain any kind of logic, this option should be set to true.
TODO setting the option to false will produce error at the moment.
You can specify which table naming convention should be used. If you want to migrate existing floor databases to drift you should stick with the default floorScheme.
Then drift can open the old floor db and migrate it to drift directly.
floorScheme(default)- the table name is the same as the class name.
- overrides with
@Table(name: "NewName")annotation, will be taken into account.
driftScheme- the table name is snake_case version of the class name
driftSchemeWithOverride- the same as driftScheme, but the table name can be overridden by the
@Table(name: "NewName")annotation.
- the same as driftScheme, but the table name can be overridden by the
when set the generated code is changed to work with drift modular code generation This is recommended for larger projects.
You can also create a more custom configuration by using the Floor2DriftGenerator.custom constructor.
Override the default option objects or implement them yourself.
Beware that some checks to guarantee that the configuration is valid are not done with the custom constructor.