“This is the 28th day of my participation in the November Gwen Challenge. See details of the event: The Last Gwen Challenge 2021”.
Native Drift (Desktop Support) (Simonbinder.eu)
Meat turn more deficiencies, generous advice.
Important notice: MOOR has been renamed drift. More information [英 文].
Native Drift (Desktop support)
Run Drift on both the mobile and desktop sides.
Supported Platforms
The Drift /native.dart library uses the sqlite3 package to send queries. As of now, the package is available for iOS, Mac, and Android (out of the box). Most Linux distributions come with SQLite as a shared library, and these distributions are supported.
If you want to load applications on Windows and Linux, it is recommended to bundle sqlite3.so and sqlite3.dll. Drift can be installed by moving the following code before opening the database:
import 'dart:ffi';
import 'dart:io';
import 'package:sqlite3/sqlite3.dart';
import 'package:sqlite3/open.dart';
void main() {
open.overrideFor(OperatingSystem.linux, _openOnLinux);
final db = sqlite3.openInMemory();
db.dispose();
}
DynamicLibrary _openOnLinux() {
final script = File(Platform.script.toFilePath());
final libraryNextToScript = File('${script.path}/sqlite3.so');
return DynamicLibrary.open(libraryNextToScript.path);
}
// _openOnWindows works as well as opening 'sqlite3.dll'.
Copy the code
Migrate from moor_FLUTTER todrift/navitve
Yaml can remove moor_FLUTTER dependencies and instead add drFIT and SQLITe3_flutter_libs dependencies:
Dependencies: drift: ^1.0.1 sqlite3_flutter_libs: sqflite: ^1.1.7Copy the code
Modify import:
- When creating a
FlutterQueryExecutor
In the file, withpackage:drift/native.dart
replacemoor_flutter
The import. - All other imports
moor_flutter
File, only need to importpackage:drift/drift.dart
.
Replace the actuator. The code is as follows:
FlutterQueryExecutor.inDatabaseFolder(path: 'db.sqlite')
Copy the code
Now the code could look like this:
import 'package:sqflite/sqflite.dart' show getDatabasesPath;
import 'package:path/path.dart' as p;
LazyDatabase(() async {
final dbFolder = await getDatabasesPath();
final file = File(p.join(dbFolder, 'db.sqlite'));
return NativeDatabase(file);
})
Copy the code
Note: If a version of Moor_FLUTTER is not loaded for the user, you can remove the dependency of SQflite. You can use the path_provider used on the desktop. Note on Android, FlutterQueryExecutor inDatabaseFolder may generate a and path_provider different directory. This may cause data loss if a version of moor_FLUTTER has been loaded. In this case, the recommended solution is to use SQflite’s getDatabasePath.
Use Drift with an existing database
If an existing SQLite database is saved as a file, use NativeDatabase(thatFile) without further modification.
If you want to load a database from assets or another source, you can use LazyDatabase. This allows some asynchronous processing before opening the database:
// (above) the previous content
NativeDatabase(File('... '));
// (above)
LazyDatabase(() async {
final file = File('... ');
if (!await file.exists()) {
Copy files from asset, network, or other sources.
}
return NativeDatabase(file);
});
Copy the code
Compilation options used on Android
On Android, iOS, and macOs, relying on SQlite3_Flutter_libs involves a custom build rather than a system build. The selected option helps reduce the size of binary packages by removing features not used by Drift. Important options are highlighted in bold:
-
Use the -03 performance option
-
* * SQLITE_DQS = 0:
This causes SQLite to reject double-quoted strings (treating them as identifiers). This matches the behavior of Drift and compiled queries.
-
* * SQLITE_THREADSAFE = 0:
Because most Flutter applications use only one ISOLATE, thread safety is turned off. Note that you can still use the ISOLATE API for background operations. Just as database access happens on the same thread, there’s nothing wrong with doing so.
-
SQLITE_DEFAULT_MEMSTATUS = 0:
The sqlite3_status() interface is not exposed by drift, so there is no need to use these here.
-
SQLITE_OMIT_AUTHORIZATION, SQLITE_OMIT_DECLTYPE, SQLITE_OMIT_DEPRECATED, SQLITE_OMIT_GET_TABLE, SQLITE_OMIT_LOAD_EXTENSION, SQLITE_OMIT_PROGRESS_CALLBACK, SQLITE_OMIT_SHARED_CACHE, SQLITE_OMIT_TCL_VARIABLE, SQLITE_OMIT_TRACE:
Disable features not supported by Drift.
-
SQLITE_USE_ALLOCA:
Allocate temporary memory on the stack.
-
SQLITE_UNTESTABLE:
Remove all functions that are only used in testing SQlite3.
-
SQLITE_HAVE_ISNAN:
Use the system’s isnan function instead of using this function loaded in SQlite3.
-
SQLITE_ENABLE_FTS5:
Make the FTS5 engine available for full-text retrieval.
-
SQLITE_ENABLE_JSON1:
Make the JSON1 extension available to support JSON in SQL queries.
For more details on SQLite compilation options, refer to sqLite’s documentation.
Used only as a function of drift
NativeDatabase contains additional SQL functions that are not available in standard SQLite:
-
Pow (base, Exponent) and power(base, Exponent) :
This function takes two numeric arguments and returns base exponent. If base or exponent is not a number or null, this function returns NULL. This function is identical to the POW behavior in DART: Math.
-
SQRT, sin, cos, tan, ASIN, ACOS, ATAN:
These functions take one argument. If the argument is null or not a number, NULL is returned. Otherwise, the result of the matching function in DART: Math is returned.
-
Regexp:
A wrapper around the RegExp API in Dart, so foo RegExp bar equals RegExp(bar).hasmatch (foo). Note that a new regEXP needs to be created for each call to the regEXP SQL, which can affect performance for large-scale queries.
-
Current_time_millis:
Returns the current UNIX timestamp in milliseconds. Is the same as datetime.now ().zipgedssinceepoch in Dart.
Note that NaN, -infinity, or +infinity are NULL in SQL.
Want to use these methods in the Dart, you need to import the package: drift/extensions/native Dart. These additional functions can be used as follows:
import 'package:drift/drift.dart';
// These methods are hidden behind other imports because they are only available in NativeDatabase '.
import 'package:drift/extensions/native.dart';
class Coordinates extends Table {
RealColumn get x => real()();
RealColumn get y => real()();
}
// Can now be used as follows:
Future<List<Coordinate>> findNearby(Coordinate center, int radius) {
return(select(coordinates).. where((other) {SQRT ((center-x)² + (center-y)²) < RADIUS
// SQRT: square root radius: radius
final distanceSquared = sqlPow(center.x - row.x, 2) + sqlPow(center.y - row.y, 2);
return sqlSqrt(distanceSquared).isLessThanValue(radius);
})).get(a); }Copy the code
All other functions have similar names available (sqlSin, sqlCos, sqlAtan, etc.). They all have SQL prefixes to avoid conflicts with DART: Math.