Skip to content

[WIP] Implementing Drift backend #181

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"yaml.schemas": {
"https://json.schemastore.org/dart-build": [
"build.yaml",
"*.build.yaml",
"build.*.yaml"
]
}
}
13 changes: 13 additions & 0 deletions build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
targets:
$default:
builders:
drift_dev:
enabled: false
drift_dev:analyzer:
enabled: true
options: &options
named_parameters: true
store_date_time_values_as_text: true
drift_dev:modular:
enabled: true
options: *options
1 change: 1 addition & 0 deletions example/android/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ android {
targetSdk = flutter.targetSdkVersion
versionCode = flutter.versionCode
versionName = flutter.versionName
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86_64'
}

buildTypes {
Expand Down
4 changes: 2 additions & 2 deletions lib/src/backend/export_external.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
// A full license can be found at .\LICENSE

export 'errors/errors.dart';
export 'impls/web_noop/backend.dart'
if (dart.library.ffi) 'impls/objectbox/backend/backend.dart';
export 'impls/objectbox/web_noop/backend.dart'
if (dart.library.ffi) 'impls/objectbox/native/backend/backend.dart';
export 'interfaces/backend/backend.dart';
export 'interfaces/backend/internal.dart';
export 'interfaces/backend/internal_thread_safe.dart';
90 changes: 90 additions & 0 deletions lib/src/backend/impls/drift/native/backend/backend.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Copyright © Luka S (JaffaKetchup) under GPL-v3
// A full license can be found at .\LICENSE

import 'dart:async';
import 'dart:collection';
import 'dart:convert';
import 'dart:io';
import 'dart:isolate';
import 'dart:math';

import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:meta/meta.dart';
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart';

import '../../../../../../flutter_map_tile_caching.dart';
import '../../../../../misc/int_extremes.dart';
import '../../../../export_internal.dart';
import '../models/generated/objectbox.g.dart';
import '../models/src/recovery.dart';
import '../models/src/recovery_region.dart';
import '../models/src/root.dart';
import '../database/models/store.dart';
import '../models/src/tile.dart';

export 'package:objectbox/objectbox.dart' show StorageException;

part 'internal_workers/standard/cmd_type.dart';
part 'internal_workers/standard/worker.dart';
part 'internal_workers/shared.dart';
part 'internal_workers/thread_safe.dart';
part 'internal.dart';

/// Implementation of [FMTCBackend] that uses ObjectBox as the storage database
///
/// On web, this redirects to a no-op implementation that throws
/// [UnsupportedError]s when attempting to use [initialise] or [uninitialise],
/// and [RootUnavailable] when trying to use any other method.
final class FMTCObjectBoxBackend implements FMTCBackend {
/// {@macro fmtc.backend.initialise}
///
/// ---
///
/// [maxDatabaseSize] is the maximum size the database file can grow
/// to, in KB. Exceeding it throws [DbFullException] (from
/// 'package:objectbox') on write operations. Defaults to 10 GB (10000000 KB).
///
/// [macosApplicationGroup] should be set when creating a sandboxed macOS app,
/// specify the application group (of less than 20 chars). See
/// [the ObjectBox docs](https://docs.objectbox.io/getting-started) for
/// details.
///
/// [rootIsolateToken] should only be used in exceptional circumstances where
/// this backend is being initialised in a seperate isolate (or background)
/// thread.
///
/// Avoid using [useInMemoryDatabase] outside of testing purposes.
@override
Future<void> initialise({
String? rootDirectory,
int maxDatabaseSize = 10000000,
String? macosApplicationGroup,
RootIsolateToken? rootIsolateToken,
@visibleForTesting bool useInMemoryDatabase = false,
}) =>
FMTCObjectBoxBackendInternal._instance.initialise(
rootDirectory: rootDirectory,
maxDatabaseSize: maxDatabaseSize,
macosApplicationGroup: macosApplicationGroup,
useInMemoryDatabase: useInMemoryDatabase,
rootIsolateToken: rootIsolateToken,
);

/// {@macro fmtc.backend.uninitialise}
///
/// If [immediate] is `true`, any operations currently underway will be lost,
/// as the worker will be killed as quickly as possible (not necessarily
/// instantly).
/// If `false`, all operations currently underway will be allowed to complete,
/// but any operations started after this method call will be lost.
@override
Future<void> uninitialise({
bool deleteRoot = false,
bool immediate = false,
}) =>
FMTCObjectBoxBackendInternal._instance
.uninitialise(deleteRoot: deleteRoot, immediate: immediate);
}
33 changes: 33 additions & 0 deletions lib/src/backend/impls/drift/native/database/database.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import 'package:drift/drift.dart';

import 'database.drift.dart';
import 'models/recovery.dart';
import 'models/recovery_region.dart';
import 'models/root.dart';
import 'models/store.dart';
import 'models/store_tile.dart';
import 'models/tile.dart';

@DriftDatabase(
tables: [
DriftTile,
DriftStore,
DriftStoreTile,
DriftRoot,
DriftRecovery,
DriftRecoveryRegion,
],
)
class DriftFMTCDatabase extends $DriftFMTCDatabase {
DriftFMTCDatabase(QueryExecutor connection) : super(connection);

@override
int get schemaVersion => 1;

@override
MigrationStrategy get migration => MigrationStrategy(
beforeOpen: (details) async {
await customStatement('PRAGMA foreign_keys = ON');
},
);
}
62 changes: 62 additions & 0 deletions lib/src/backend/impls/drift/native/database/database.drift.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// dart format width=80
// ignore_for_file: type=lint
import 'package:drift/drift.dart' as i0;
import 'package:flutter_map_tile_caching/src/backend/impls/drift/native/database/models/tile.drift.dart'
as i1;
import 'package:flutter_map_tile_caching/src/backend/impls/drift/native/database/models/store.drift.dart'
as i2;
import 'package:flutter_map_tile_caching/src/backend/impls/drift/native/database/models/store_tile.drift.dart'
as i3;
import 'package:flutter_map_tile_caching/src/backend/impls/drift/native/database/models/root.drift.dart'
as i4;
import 'package:flutter_map_tile_caching/src/backend/impls/drift/native/database/models/recovery.drift.dart'
as i5;
import 'package:flutter_map_tile_caching/src/backend/impls/drift/native/database/models/recovery_region.drift.dart'
as i6;

abstract class $DriftFMTCDatabase extends i0.GeneratedDatabase {
$DriftFMTCDatabase(i0.QueryExecutor e) : super(e);
$DriftFMTCDatabaseManager get managers => $DriftFMTCDatabaseManager(this);
late final i1.$DriftTileTable driftTile = i1.$DriftTileTable(this);
late final i2.$DriftStoreTable driftStore = i2.$DriftStoreTable(this);
late final i3.$DriftStoreTileTable driftStoreTile =
i3.$DriftStoreTileTable(this);
late final i4.$DriftRootTable driftRoot = i4.$DriftRootTable(this);
late final i5.$DriftRecoveryTable driftRecovery =
i5.$DriftRecoveryTable(this);
late final i6.$DriftRecoveryRegionTable driftRecoveryRegion =
i6.$DriftRecoveryRegionTable(this);
@override
Iterable<i0.TableInfo<i0.Table, Object?>> get allTables =>
allSchemaEntities.whereType<i0.TableInfo<i0.Table, Object?>>();
@override
List<i0.DatabaseSchemaEntity> get allSchemaEntities => [
driftTile,
driftStore,
driftStoreTile,
driftRoot,
driftRecovery,
driftRecoveryRegion,
i1.lastModified
];
@override
i0.DriftDatabaseOptions get options =>
const i0.DriftDatabaseOptions(storeDateTimeAsText: true);
}

class $DriftFMTCDatabaseManager {
final $DriftFMTCDatabase _db;
$DriftFMTCDatabaseManager(this._db);
i1.$$DriftTileTableTableManager get driftTile =>
i1.$$DriftTileTableTableManager(_db, _db.driftTile);
i2.$$DriftStoreTableTableManager get driftStore =>
i2.$$DriftStoreTableTableManager(_db, _db.driftStore);
i3.$$DriftStoreTileTableTableManager get driftStoreTile =>
i3.$$DriftStoreTileTableTableManager(_db, _db.driftStoreTile);
i4.$$DriftRootTableTableManager get driftRoot =>
i4.$$DriftRootTableTableManager(_db, _db.driftRoot);
i5.$$DriftRecoveryTableTableManager get driftRecovery =>
i5.$$DriftRecoveryTableTableManager(_db, _db.driftRecovery);
i6.$$DriftRecoveryRegionTableTableManager get driftRecoveryRegion =>
i6.$$DriftRecoveryRegionTableTableManager(_db, _db.driftRecoveryRegion);
}
21 changes: 21 additions & 0 deletions lib/src/backend/impls/drift/native/database/models/recovery.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import 'package:drift/drift.dart';

import 'store.dart';

class DriftRecovery extends Table {
late final id = integer()();
late final store = text().references(DriftStore, #name)();

late final creationTime = dateTime().withDefault(currentDateAndTime)();

late final minZoom = integer()();
late final maxZoom = integer()();
late final startTile = integer()();
late final endTile = integer()();

@override
Set<Column<Object>> get primaryKey => {id};

@override
bool get isStrict => true;
}
Loading
Loading