Add Supa account and search changes

This commit is contained in:
Fabian Freund
2026-05-22 18:10:22 +02:00
parent 3a19865b2e
commit 51289f1266
374 changed files with 54061 additions and 5013 deletions
@@ -19,6 +19,7 @@
*/
import 'package:drift/drift.dart';
import 'package:weblibre/data/database/extensions/database_table_size.dart';
import 'package:weblibre/features/user/data/icon_cache_marker.dart';
import 'package:weblibre/features/user/data/database/daos/cache.drift.dart';
import 'package:weblibre/features/user/data/database/database.dart';
import 'package:weblibre/features/user/data/database/definitions.drift.dart';
@@ -43,6 +44,14 @@ class CacheDao extends DatabaseAccessor<UserDatabase> with $CacheDaoMixin {
return query.map((row) => row.read(db.iconCache.iconData));
}
SingleOrNullSelectable<DateTime?> getCachedIconFetchDate(String origin) {
final query = selectOnly(db.iconCache)
..addColumns([db.iconCache.fetchDate])
..where(db.iconCache.origin.equals(origin));
return query.map((row) => row.read(db.iconCache.fetchDate));
}
Future<int> cacheIcon(String origin, Uint8List bytes) {
return db.iconCache.insertOne(
IconCacheCompanion.insert(
@@ -58,4 +67,15 @@ class CacheDao extends DatabaseAccessor<UserDatabase> with $CacheDaoMixin {
),
);
}
Future<void> cacheIconIfAbsent(String origin, Uint8List bytes) async {
final existing = await getCachedIcon(origin).getSingleOrNull();
if (existing == null || isMissingIconMarker(existing)) {
await cacheIcon(origin, bytes);
}
}
Future<int> cacheMissingIcon(String origin) {
return cacheIcon(origin, missingIconMarkerBytes);
}
}
@@ -0,0 +1,100 @@
import 'package:drift/drift.dart';
import 'package:weblibre/features/user/data/database/database.dart';
import 'package:weblibre/features/user/data/database/definitions.drift.dart';
class ReservedToken {
final int id;
final Uint8List token;
const ReservedToken({required this.id, required this.token});
}
@DriftAccessor()
class SearchTokensDao extends DatabaseAccessor<UserDatabase> {
SearchTokensDao(super.attachedDatabase);
Future<void> addTokens(
List<Uint8List> tokens, {
required String issuerKeyVersion,
}) {
return batch((b) {
b.insertAll(
db.searchTokens,
tokens
.map(
(t) => SearchTokensCompanion.insert(
token: t,
issuerKeyVersion: issuerKeyVersion,
insertedAt: DateTime.now(),
),
)
.toList(),
);
});
}
/// Reserve the oldest unreserved token. Stamps `reserved_at` so the same
/// row won't be handed out twice. Caller MUST follow with either
/// [commitReserved] (server consumed it) or [releaseReserved] (we know the
/// server didn't see it).
Future<ReservedToken?> reserveOne() {
return transaction(() async {
final row =
await (select(db.searchTokens)
..where((t) => t.reservedAt.isNull())
..orderBy([(t) => OrderingTerm.asc(t.id)])
..limit(1))
.getSingleOrNull();
if (row == null) return null;
await (update(db.searchTokens)..where((t) => t.id.equals(row.id))).write(
SearchTokensCompanion(reservedAt: Value(DateTime.now())),
);
return ReservedToken(id: row.id, token: row.token);
});
}
/// Permanently delete a reserved token after a successful redemption.
Future<void> commitReserved(int id) async {
await (delete(db.searchTokens)..where((t) => t.id.equals(id))).go();
}
/// Clear the reservation so the token is handed out again. Use only when
/// the server is known not to have consumed it.
Future<void> releaseReserved(int id) async {
await (update(db.searchTokens)..where((t) => t.id.equals(id))).write(
const SearchTokensCompanion(reservedAt: Value(null)),
);
}
/// Release any reservation older than [maxAge] — covers crashes mid-flight.
/// Returns the number of rows released.
Future<int> releaseStaleReservations(Duration maxAge) async {
final cutoff = DateTime.now().subtract(maxAge);
return (update(db.searchTokens)..where(
(t) =>
t.reservedAt.isNotNull() &
t.reservedAt.isSmallerThanValue(cutoff),
))
.write(const SearchTokensCompanion(reservedAt: Value(null)));
}
Future<int> count() async {
final c = db.searchTokens.id.count();
final query = selectOnly(db.searchTokens)
..addColumns([c])
..where(db.searchTokens.reservedAt.isNull());
final row = await query.getSingle();
return row.read(c) ?? 0;
}
Stream<int> watchCount() {
final c = db.searchTokens.id.count();
final query = selectOnly(db.searchTokens)
..addColumns([c])
..where(db.searchTokens.reservedAt.isNull());
return query.map((row) => row.read(c) ?? 0).watchSingle();
}
Future<int> clear() {
return delete(db.searchTokens).go();
}
}
@@ -0,0 +1,13 @@
// dart format width=80
// ignore_for_file: type=lint
import 'package:drift/drift.dart' as i0;
import 'package:weblibre/features/user/data/database/database.dart' as i1;
mixin $SearchTokensDaoMixin on i0.DatabaseAccessor<i1.UserDatabase> {
SearchTokensDaoManager get managers => SearchTokensDaoManager(this);
}
class SearchTokensDaoManager {
final $SearchTokensDaoMixin _db;
SearchTokensDaoManager(this._db);
}
@@ -23,6 +23,7 @@ import 'package:drift_dev/api/migrations_native.dart';
import 'package:flutter/foundation.dart';
import 'package:weblibre/features/user/data/database/daos/cache.dart';
import 'package:weblibre/features/user/data/database/daos/onboarding.dart';
import 'package:weblibre/features/user/data/database/daos/search_tokens.dart';
import 'package:weblibre/features/user/data/database/daos/setting.dart';
import 'package:weblibre/features/user/data/database/daos/toolbar_button_config.dart';
import 'package:weblibre/features/user/data/database/database.drift.dart';
@@ -30,11 +31,17 @@ import 'package:weblibre/features/user/data/database/database.steps.dart';
@DriftDatabase(
include: {'definitions.drift'},
daos: [SettingDao, CacheDao, OnboardingDao, ToolbarButtonConfigDao],
daos: [
SettingDao,
CacheDao,
OnboardingDao,
ToolbarButtonConfigDao,
SearchTokensDao,
],
)
class UserDatabase extends $UserDatabase {
@override
final int schemaVersion = 3;
final int schemaVersion = 5;
@override
MigrationStrategy get migration => MigrationStrategy(
@@ -88,5 +95,13 @@ class UserDatabase extends $UserDatabase {
await m.createTable(schema.toolbarButtonConfigs);
await m.createIndex(schema.idxToolbarOrderKey);
},
from3To4: (m, schema) async {
await m.createTable(schema.searchTokens);
await m.createIndex(schema.idxSearchTokensInsertedAt);
},
from4To5: (m, schema) async {
await m.addColumn(schema.searchTokens, schema.searchTokens.reservedAt);
await m.createIndex(schema.idxSearchTokensReservedAt);
},
);
}
@@ -10,8 +10,10 @@ import 'package:weblibre/features/user/data/database/daos/onboarding.dart'
as i5;
import 'package:weblibre/features/user/data/database/daos/toolbar_button_config.dart'
as i6;
import 'package:drift/internal/modular.dart' as i7;
import 'package:sqlite3/common.dart' as i8;
import 'package:weblibre/features/user/data/database/daos/search_tokens.dart'
as i7;
import 'package:drift/internal/modular.dart' as i8;
import 'package:sqlite3/common.dart' as i9;
abstract class $UserDatabase extends i0.GeneratedDatabase {
$UserDatabase(i0.QueryExecutor e) : super(e);
@@ -22,6 +24,7 @@ abstract class $UserDatabase extends i0.GeneratedDatabase {
late final i1.Riverpod riverpod = i1.Riverpod(this);
late final i1.ToolbarButtonConfigs toolbarButtonConfigs =
i1.ToolbarButtonConfigs(this);
late final i1.SearchTokens searchTokens = i1.SearchTokens(this);
late final i2.SettingDao settingDao = i2.SettingDao(this as i3.UserDatabase);
late final i4.CacheDao cacheDao = i4.CacheDao(this as i3.UserDatabase);
late final i5.OnboardingDao onboardingDao = i5.OnboardingDao(
@@ -29,7 +32,10 @@ abstract class $UserDatabase extends i0.GeneratedDatabase {
);
late final i6.ToolbarButtonConfigDao toolbarButtonConfigDao =
i6.ToolbarButtonConfigDao(this as i3.UserDatabase);
i1.DefinitionsDrift get definitionsDrift => i7.ReadDatabaseContainer(
late final i7.SearchTokensDao searchTokensDao = i7.SearchTokensDao(
this as i3.UserDatabase,
);
i1.DefinitionsDrift get definitionsDrift => i8.ReadDatabaseContainer(
this,
).accessor<i1.DefinitionsDrift>(i1.DefinitionsDrift.new);
@override
@@ -43,6 +49,9 @@ abstract class $UserDatabase extends i0.GeneratedDatabase {
riverpod,
toolbarButtonConfigs,
i1.idxToolbarOrderKey,
searchTokens,
i1.idxSearchTokensInsertedAt,
i1.idxSearchTokensReservedAt,
];
}
@@ -59,18 +68,25 @@ class $UserDatabaseManager {
i1.$RiverpodTableManager(_db, _db.riverpod);
i1.$ToolbarButtonConfigsTableManager get toolbarButtonConfigs =>
i1.$ToolbarButtonConfigsTableManager(_db, _db.toolbarButtonConfigs);
i1.$SearchTokensTableManager get searchTokens =>
i1.$SearchTokensTableManager(_db, _db.searchTokens);
}
extension DefineFunctions on i8.CommonDatabase {
extension DefineFunctions on i9.CommonDatabase {
void defineFunctions({
required String Function(int, String?) lexoRankNext,
required String Function(int, String?) lexoRankPrevious,
required String Function(String?, String?) lexoRankReorderAfter,
required String Function(String?, String?) lexoRankReorderBefore,
required int Function() generateContentHash,
required bool Function(String?) urlIndexable,
required String Function(String?) urlCanonical,
required String Function(String?) urlHost,
required String Function(String?) urlPath,
}) {
createFunction(
functionName: 'lexo_rank_next',
argumentCount: const i8.AllowedArgumentCount(2),
argumentCount: const i9.AllowedArgumentCount(2),
function: (args) {
final arg0 = args[0] as int;
final arg1 = args[1] as String?;
@@ -79,7 +95,7 @@ extension DefineFunctions on i8.CommonDatabase {
);
createFunction(
functionName: 'lexo_rank_previous',
argumentCount: const i8.AllowedArgumentCount(2),
argumentCount: const i9.AllowedArgumentCount(2),
function: (args) {
final arg0 = args[0] as int;
final arg1 = args[1] as String?;
@@ -88,7 +104,7 @@ extension DefineFunctions on i8.CommonDatabase {
);
createFunction(
functionName: 'lexo_rank_reorder_after',
argumentCount: const i8.AllowedArgumentCount(2),
argumentCount: const i9.AllowedArgumentCount(2),
function: (args) {
final arg0 = args[0] as String?;
final arg1 = args[1] as String?;
@@ -97,12 +113,51 @@ extension DefineFunctions on i8.CommonDatabase {
);
createFunction(
functionName: 'lexo_rank_reorder_before',
argumentCount: const i8.AllowedArgumentCount(2),
argumentCount: const i9.AllowedArgumentCount(2),
function: (args) {
final arg0 = args[0] as String?;
final arg1 = args[1] as String?;
return lexoRankReorderBefore(arg0, arg1);
},
);
createFunction(
functionName: 'generate_content_hash',
argumentCount: const i9.AllowedArgumentCount(0),
function: (args) {
return generateContentHash();
},
);
createFunction(
functionName: 'url_indexable',
argumentCount: const i9.AllowedArgumentCount(1),
function: (args) {
final arg0 = args[0] as String?;
return urlIndexable(arg0);
},
);
createFunction(
functionName: 'url_canonical',
argumentCount: const i9.AllowedArgumentCount(1),
function: (args) {
final arg0 = args[0] as String?;
return urlCanonical(arg0);
},
);
createFunction(
functionName: 'url_host',
argumentCount: const i9.AllowedArgumentCount(1),
function: (args) {
final arg0 = args[0] as String?;
return urlHost(arg0);
},
);
createFunction(
functionName: 'url_path',
argumentCount: const i9.AllowedArgumentCount(1),
function: (args) {
final arg0 = args[0] as String?;
return urlPath(arg0);
},
);
}
}
@@ -311,9 +311,263 @@ i1.GeneratedColumn<String> _column_14(String aliasedName) =>
$customConstraints:
'REFERENCES toolbar_button_configs(button_id)ON DELETE SET NULL',
);
final class Schema4 extends i0.VersionedSchema {
Schema4({required super.database}) : super(version: 4);
@override
late final List<i1.DatabaseSchemaEntity> entities = [
setting,
iconCache,
onboarding,
riverpod,
toolbarButtonConfigs,
idxToolbarOrderKey,
searchTokens,
idxSearchTokensInsertedAt,
];
late final Shape0 setting = Shape0(
source: i0.VersionedTable(
entityName: 'setting',
withoutRowId: false,
isStrict: true,
tableConstraints: [],
columns: [_column_0, _column_1, _column_2],
attachedDatabase: database,
),
alias: null,
);
late final Shape1 iconCache = Shape1(
source: i0.VersionedTable(
entityName: 'icon_cache',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [_column_3, _column_4, _column_5],
attachedDatabase: database,
),
alias: null,
);
late final Shape2 onboarding = Shape2(
source: i0.VersionedTable(
entityName: 'onboarding',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [_column_6, _column_7],
attachedDatabase: database,
),
alias: null,
);
late final Shape3 riverpod = Shape3(
source: i0.VersionedTable(
entityName: 'riverpod',
withoutRowId: true,
isStrict: false,
tableConstraints: [],
columns: [_column_0, _column_8, _column_9, _column_10],
attachedDatabase: database,
),
alias: null,
);
late final Shape4 toolbarButtonConfigs = Shape4(
source: i0.VersionedTable(
entityName: 'toolbar_button_configs',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [_column_11, _column_12, _column_13, _column_14],
attachedDatabase: database,
),
alias: null,
);
final i1.Index idxToolbarOrderKey = i1.Index(
'idx_toolbar_order_key',
'CREATE INDEX idx_toolbar_order_key ON toolbar_button_configs (order_key)',
);
late final Shape5 searchTokens = Shape5(
source: i0.VersionedTable(
entityName: 'search_tokens',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [_column_15, _column_16, _column_17, _column_18],
attachedDatabase: database,
),
alias: null,
);
final i1.Index idxSearchTokensInsertedAt = i1.Index(
'idx_search_tokens_inserted_at',
'CREATE INDEX idx_search_tokens_inserted_at ON search_tokens (inserted_at)',
);
}
class Shape5 extends i0.VersionedTable {
Shape5({required super.source, required super.alias}) : super.aliased();
i1.GeneratedColumn<int> get id =>
columnsByName['id']! as i1.GeneratedColumn<int>;
i1.GeneratedColumn<i2.Uint8List> get token =>
columnsByName['token']! as i1.GeneratedColumn<i2.Uint8List>;
i1.GeneratedColumn<int> get insertedAt =>
columnsByName['inserted_at']! as i1.GeneratedColumn<int>;
i1.GeneratedColumn<String> get issuerKeyVersion =>
columnsByName['issuer_key_version']! as i1.GeneratedColumn<String>;
}
i1.GeneratedColumn<int> _column_15(String aliasedName) =>
i1.GeneratedColumn<int>(
'id',
aliasedName,
false,
hasAutoIncrement: true,
type: i1.DriftSqlType.int,
$customConstraints: 'PRIMARY KEY AUTOINCREMENT',
);
i1.GeneratedColumn<i2.Uint8List> _column_16(String aliasedName) =>
i1.GeneratedColumn<i2.Uint8List>(
'token',
aliasedName,
false,
type: i1.DriftSqlType.blob,
$customConstraints: 'NOT NULL',
);
i1.GeneratedColumn<int> _column_17(String aliasedName) =>
i1.GeneratedColumn<int>(
'inserted_at',
aliasedName,
false,
type: i1.DriftSqlType.int,
$customConstraints: 'NOT NULL',
);
i1.GeneratedColumn<String> _column_18(String aliasedName) =>
i1.GeneratedColumn<String>(
'issuer_key_version',
aliasedName,
false,
type: i1.DriftSqlType.string,
$customConstraints: 'NOT NULL',
);
final class Schema5 extends i0.VersionedSchema {
Schema5({required super.database}) : super(version: 5);
@override
late final List<i1.DatabaseSchemaEntity> entities = [
setting,
iconCache,
onboarding,
riverpod,
toolbarButtonConfigs,
idxToolbarOrderKey,
searchTokens,
idxSearchTokensInsertedAt,
idxSearchTokensReservedAt,
];
late final Shape0 setting = Shape0(
source: i0.VersionedTable(
entityName: 'setting',
withoutRowId: false,
isStrict: true,
tableConstraints: [],
columns: [_column_0, _column_1, _column_2],
attachedDatabase: database,
),
alias: null,
);
late final Shape1 iconCache = Shape1(
source: i0.VersionedTable(
entityName: 'icon_cache',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [_column_3, _column_4, _column_5],
attachedDatabase: database,
),
alias: null,
);
late final Shape2 onboarding = Shape2(
source: i0.VersionedTable(
entityName: 'onboarding',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [_column_6, _column_7],
attachedDatabase: database,
),
alias: null,
);
late final Shape3 riverpod = Shape3(
source: i0.VersionedTable(
entityName: 'riverpod',
withoutRowId: true,
isStrict: false,
tableConstraints: [],
columns: [_column_0, _column_8, _column_9, _column_10],
attachedDatabase: database,
),
alias: null,
);
late final Shape4 toolbarButtonConfigs = Shape4(
source: i0.VersionedTable(
entityName: 'toolbar_button_configs',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [_column_11, _column_12, _column_13, _column_14],
attachedDatabase: database,
),
alias: null,
);
final i1.Index idxToolbarOrderKey = i1.Index(
'idx_toolbar_order_key',
'CREATE INDEX idx_toolbar_order_key ON toolbar_button_configs (order_key)',
);
late final Shape6 searchTokens = Shape6(
source: i0.VersionedTable(
entityName: 'search_tokens',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [_column_15, _column_16, _column_17, _column_18, _column_19],
attachedDatabase: database,
),
alias: null,
);
final i1.Index idxSearchTokensInsertedAt = i1.Index(
'idx_search_tokens_inserted_at',
'CREATE INDEX idx_search_tokens_inserted_at ON search_tokens (inserted_at)',
);
final i1.Index idxSearchTokensReservedAt = i1.Index(
'idx_search_tokens_reserved_at',
'CREATE INDEX idx_search_tokens_reserved_at ON search_tokens (reserved_at)',
);
}
class Shape6 extends i0.VersionedTable {
Shape6({required super.source, required super.alias}) : super.aliased();
i1.GeneratedColumn<int> get id =>
columnsByName['id']! as i1.GeneratedColumn<int>;
i1.GeneratedColumn<i2.Uint8List> get token =>
columnsByName['token']! as i1.GeneratedColumn<i2.Uint8List>;
i1.GeneratedColumn<int> get insertedAt =>
columnsByName['inserted_at']! as i1.GeneratedColumn<int>;
i1.GeneratedColumn<String> get issuerKeyVersion =>
columnsByName['issuer_key_version']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<int> get reservedAt =>
columnsByName['reserved_at']! as i1.GeneratedColumn<int>;
}
i1.GeneratedColumn<int> _column_19(String aliasedName) =>
i1.GeneratedColumn<int>(
'reserved_at',
aliasedName,
true,
type: i1.DriftSqlType.int,
$customConstraints: '',
);
i0.MigrationStepWithVersion migrationSteps({
required Future<void> Function(i1.Migrator m, Schema2 schema) from1To2,
required Future<void> Function(i1.Migrator m, Schema3 schema) from2To3,
required Future<void> Function(i1.Migrator m, Schema4 schema) from3To4,
required Future<void> Function(i1.Migrator m, Schema5 schema) from4To5,
}) {
return (currentVersion, database) async {
switch (currentVersion) {
@@ -327,6 +581,16 @@ i0.MigrationStepWithVersion migrationSteps({
final migrator = i1.Migrator(database, schema);
await from2To3(migrator, schema);
return 3;
case 3:
final schema = Schema4(database: database);
final migrator = i1.Migrator(database, schema);
await from3To4(migrator, schema);
return 4;
case 4:
final schema = Schema5(database: database);
final migrator = i1.Migrator(database, schema);
await from4To5(migrator, schema);
return 5;
default:
throw ArgumentError.value('Unknown migration from $currentVersion');
}
@@ -336,6 +600,13 @@ i0.MigrationStepWithVersion migrationSteps({
i1.OnUpgrade stepByStep({
required Future<void> Function(i1.Migrator m, Schema2 schema) from1To2,
required Future<void> Function(i1.Migrator m, Schema3 schema) from2To3,
required Future<void> Function(i1.Migrator m, Schema4 schema) from3To4,
required Future<void> Function(i1.Migrator m, Schema5 schema) from4To5,
}) => i0.VersionedSchema.stepByStepHelper(
step: migrationSteps(from1To2: from1To2, from2To3: from2To3),
step: migrationSteps(
from1To2: from1To2,
from2To3: from2To3,
from3To4: from3To4,
from4To5: from4To5,
),
);
@@ -31,6 +31,17 @@ CREATE TABLE toolbar_button_configs (
CREATE INDEX idx_toolbar_order_key ON toolbar_button_configs(order_key);
CREATE TABLE search_tokens (
id INTEGER PRIMARY KEY AUTOINCREMENT,
token BLOB NOT NULL,
inserted_at DATETIME NOT NULL,
issuer_key_version TEXT NOT NULL,
reserved_at DATETIME
);
CREATE INDEX idx_search_tokens_inserted_at ON search_tokens(inserted_at);
CREATE INDEX idx_search_tokens_reserved_at ON search_tokens(reserved_at);
-- All four queries are scoped to a visibility partition (`is_visible`) so the
-- generated key falls strictly within the targeted section. The Customize
-- Toolbar UI renders Enabled and Disabled as two independent reorderable
@@ -863,6 +863,214 @@ typedef $ToolbarButtonConfigsProcessedTableManager =
i1.ToolbarButtonConfig,
i0.PrefetchHooks Function()
>;
typedef $SearchTokensCreateCompanionBuilder =
i1.SearchTokensCompanion Function({
i0.Value<int> id,
required i2.Uint8List token,
required DateTime insertedAt,
required String issuerKeyVersion,
i0.Value<DateTime?> reservedAt,
});
typedef $SearchTokensUpdateCompanionBuilder =
i1.SearchTokensCompanion Function({
i0.Value<int> id,
i0.Value<i2.Uint8List> token,
i0.Value<DateTime> insertedAt,
i0.Value<String> issuerKeyVersion,
i0.Value<DateTime?> reservedAt,
});
class $SearchTokensFilterComposer
extends i0.Composer<i0.GeneratedDatabase, i1.SearchTokens> {
$SearchTokensFilterComposer({
required super.$db,
required super.$table,
super.joinBuilder,
super.$addJoinBuilderToRootComposer,
super.$removeJoinBuilderFromRootComposer,
});
i0.ColumnFilters<int> get id => $composableBuilder(
column: $table.id,
builder: (column) => i0.ColumnFilters(column),
);
i0.ColumnFilters<i2.Uint8List> get token => $composableBuilder(
column: $table.token,
builder: (column) => i0.ColumnFilters(column),
);
i0.ColumnFilters<DateTime> get insertedAt => $composableBuilder(
column: $table.insertedAt,
builder: (column) => i0.ColumnFilters(column),
);
i0.ColumnFilters<String> get issuerKeyVersion => $composableBuilder(
column: $table.issuerKeyVersion,
builder: (column) => i0.ColumnFilters(column),
);
i0.ColumnFilters<DateTime> get reservedAt => $composableBuilder(
column: $table.reservedAt,
builder: (column) => i0.ColumnFilters(column),
);
}
class $SearchTokensOrderingComposer
extends i0.Composer<i0.GeneratedDatabase, i1.SearchTokens> {
$SearchTokensOrderingComposer({
required super.$db,
required super.$table,
super.joinBuilder,
super.$addJoinBuilderToRootComposer,
super.$removeJoinBuilderFromRootComposer,
});
i0.ColumnOrderings<int> get id => $composableBuilder(
column: $table.id,
builder: (column) => i0.ColumnOrderings(column),
);
i0.ColumnOrderings<i2.Uint8List> get token => $composableBuilder(
column: $table.token,
builder: (column) => i0.ColumnOrderings(column),
);
i0.ColumnOrderings<DateTime> get insertedAt => $composableBuilder(
column: $table.insertedAt,
builder: (column) => i0.ColumnOrderings(column),
);
i0.ColumnOrderings<String> get issuerKeyVersion => $composableBuilder(
column: $table.issuerKeyVersion,
builder: (column) => i0.ColumnOrderings(column),
);
i0.ColumnOrderings<DateTime> get reservedAt => $composableBuilder(
column: $table.reservedAt,
builder: (column) => i0.ColumnOrderings(column),
);
}
class $SearchTokensAnnotationComposer
extends i0.Composer<i0.GeneratedDatabase, i1.SearchTokens> {
$SearchTokensAnnotationComposer({
required super.$db,
required super.$table,
super.joinBuilder,
super.$addJoinBuilderToRootComposer,
super.$removeJoinBuilderFromRootComposer,
});
i0.GeneratedColumn<int> get id =>
$composableBuilder(column: $table.id, builder: (column) => column);
i0.GeneratedColumn<i2.Uint8List> get token =>
$composableBuilder(column: $table.token, builder: (column) => column);
i0.GeneratedColumn<DateTime> get insertedAt => $composableBuilder(
column: $table.insertedAt,
builder: (column) => column,
);
i0.GeneratedColumn<String> get issuerKeyVersion => $composableBuilder(
column: $table.issuerKeyVersion,
builder: (column) => column,
);
i0.GeneratedColumn<DateTime> get reservedAt => $composableBuilder(
column: $table.reservedAt,
builder: (column) => column,
);
}
class $SearchTokensTableManager
extends
i0.RootTableManager<
i0.GeneratedDatabase,
i1.SearchTokens,
i1.SearchToken,
i1.$SearchTokensFilterComposer,
i1.$SearchTokensOrderingComposer,
i1.$SearchTokensAnnotationComposer,
$SearchTokensCreateCompanionBuilder,
$SearchTokensUpdateCompanionBuilder,
(
i1.SearchToken,
i0.BaseReferences<
i0.GeneratedDatabase,
i1.SearchTokens,
i1.SearchToken
>,
),
i1.SearchToken,
i0.PrefetchHooks Function()
> {
$SearchTokensTableManager(i0.GeneratedDatabase db, i1.SearchTokens table)
: super(
i0.TableManagerState(
db: db,
table: table,
createFilteringComposer: () =>
i1.$SearchTokensFilterComposer($db: db, $table: table),
createOrderingComposer: () =>
i1.$SearchTokensOrderingComposer($db: db, $table: table),
createComputedFieldComposer: () =>
i1.$SearchTokensAnnotationComposer($db: db, $table: table),
updateCompanionCallback:
({
i0.Value<int> id = const i0.Value.absent(),
i0.Value<i2.Uint8List> token = const i0.Value.absent(),
i0.Value<DateTime> insertedAt = const i0.Value.absent(),
i0.Value<String> issuerKeyVersion = const i0.Value.absent(),
i0.Value<DateTime?> reservedAt = const i0.Value.absent(),
}) => i1.SearchTokensCompanion(
id: id,
token: token,
insertedAt: insertedAt,
issuerKeyVersion: issuerKeyVersion,
reservedAt: reservedAt,
),
createCompanionCallback:
({
i0.Value<int> id = const i0.Value.absent(),
required i2.Uint8List token,
required DateTime insertedAt,
required String issuerKeyVersion,
i0.Value<DateTime?> reservedAt = const i0.Value.absent(),
}) => i1.SearchTokensCompanion.insert(
id: id,
token: token,
insertedAt: insertedAt,
issuerKeyVersion: issuerKeyVersion,
reservedAt: reservedAt,
),
withReferenceMapper: (p0) => p0
.map((e) => (e.readTable(table), i0.BaseReferences(db, table, e)))
.toList(),
prefetchHooksCallback: null,
),
);
}
typedef $SearchTokensProcessedTableManager =
i0.ProcessedTableManager<
i0.GeneratedDatabase,
i1.SearchTokens,
i1.SearchToken,
i1.$SearchTokensFilterComposer,
i1.$SearchTokensOrderingComposer,
i1.$SearchTokensAnnotationComposer,
$SearchTokensCreateCompanionBuilder,
$SearchTokensUpdateCompanionBuilder,
(
i1.SearchToken,
i0.BaseReferences<
i0.GeneratedDatabase,
i1.SearchTokens,
i1.SearchToken
>,
),
i1.SearchToken,
i0.PrefetchHooks Function()
>;
class Setting extends i0.Table with i0.TableInfo<Setting, i1.SettingData> {
@override
@@ -2022,6 +2230,317 @@ i0.Index get idxToolbarOrderKey => i0.Index(
'CREATE INDEX idx_toolbar_order_key ON toolbar_button_configs (order_key)',
);
class SearchTokens extends i0.Table
with i0.TableInfo<SearchTokens, i1.SearchToken> {
@override
final i0.GeneratedDatabase attachedDatabase;
final String? _alias;
SearchTokens(this.attachedDatabase, [this._alias]);
late final i0.GeneratedColumn<int> id = i0.GeneratedColumn<int>(
'id',
aliasedName,
false,
hasAutoIncrement: true,
type: i0.DriftSqlType.int,
requiredDuringInsert: false,
$customConstraints: 'PRIMARY KEY AUTOINCREMENT',
);
late final i0.GeneratedColumn<i2.Uint8List> token =
i0.GeneratedColumn<i2.Uint8List>(
'token',
aliasedName,
false,
type: i0.DriftSqlType.blob,
requiredDuringInsert: true,
$customConstraints: 'NOT NULL',
);
late final i0.GeneratedColumn<DateTime> insertedAt =
i0.GeneratedColumn<DateTime>(
'inserted_at',
aliasedName,
false,
type: i0.DriftSqlType.dateTime,
requiredDuringInsert: true,
$customConstraints: 'NOT NULL',
);
late final i0.GeneratedColumn<String> issuerKeyVersion =
i0.GeneratedColumn<String>(
'issuer_key_version',
aliasedName,
false,
type: i0.DriftSqlType.string,
requiredDuringInsert: true,
$customConstraints: 'NOT NULL',
);
late final i0.GeneratedColumn<DateTime> reservedAt =
i0.GeneratedColumn<DateTime>(
'reserved_at',
aliasedName,
true,
type: i0.DriftSqlType.dateTime,
requiredDuringInsert: false,
$customConstraints: '',
);
@override
List<i0.GeneratedColumn> get $columns => [
id,
token,
insertedAt,
issuerKeyVersion,
reservedAt,
];
@override
String get aliasedName => _alias ?? actualTableName;
@override
String get actualTableName => $name;
static const String $name = 'search_tokens';
@override
Set<i0.GeneratedColumn> get $primaryKey => {id};
@override
i1.SearchToken map(Map<String, dynamic> data, {String? tablePrefix}) {
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
return i1.SearchToken(
id: attachedDatabase.typeMapping.read(
i0.DriftSqlType.int,
data['${effectivePrefix}id'],
)!,
token: attachedDatabase.typeMapping.read(
i0.DriftSqlType.blob,
data['${effectivePrefix}token'],
)!,
insertedAt: attachedDatabase.typeMapping.read(
i0.DriftSqlType.dateTime,
data['${effectivePrefix}inserted_at'],
)!,
issuerKeyVersion: attachedDatabase.typeMapping.read(
i0.DriftSqlType.string,
data['${effectivePrefix}issuer_key_version'],
)!,
reservedAt: attachedDatabase.typeMapping.read(
i0.DriftSqlType.dateTime,
data['${effectivePrefix}reserved_at'],
),
);
}
@override
SearchTokens createAlias(String alias) {
return SearchTokens(attachedDatabase, alias);
}
@override
bool get dontWriteConstraints => true;
}
class SearchToken extends i0.DataClass
implements i0.Insertable<i1.SearchToken> {
final int id;
final i2.Uint8List token;
final DateTime insertedAt;
final String issuerKeyVersion;
final DateTime? reservedAt;
const SearchToken({
required this.id,
required this.token,
required this.insertedAt,
required this.issuerKeyVersion,
this.reservedAt,
});
@override
Map<String, i0.Expression> toColumns(bool nullToAbsent) {
final map = <String, i0.Expression>{};
map['id'] = i0.Variable<int>(id);
map['token'] = i0.Variable<i2.Uint8List>(token);
map['inserted_at'] = i0.Variable<DateTime>(insertedAt);
map['issuer_key_version'] = i0.Variable<String>(issuerKeyVersion);
if (!nullToAbsent || reservedAt != null) {
map['reserved_at'] = i0.Variable<DateTime>(reservedAt);
}
return map;
}
factory SearchToken.fromJson(
Map<String, dynamic> json, {
i0.ValueSerializer? serializer,
}) {
serializer ??= i0.driftRuntimeOptions.defaultSerializer;
return SearchToken(
id: serializer.fromJson<int>(json['id']),
token: serializer.fromJson<i2.Uint8List>(json['token']),
insertedAt: serializer.fromJson<DateTime>(json['inserted_at']),
issuerKeyVersion: serializer.fromJson<String>(json['issuer_key_version']),
reservedAt: serializer.fromJson<DateTime?>(json['reserved_at']),
);
}
@override
Map<String, dynamic> toJson({i0.ValueSerializer? serializer}) {
serializer ??= i0.driftRuntimeOptions.defaultSerializer;
return <String, dynamic>{
'id': serializer.toJson<int>(id),
'token': serializer.toJson<i2.Uint8List>(token),
'inserted_at': serializer.toJson<DateTime>(insertedAt),
'issuer_key_version': serializer.toJson<String>(issuerKeyVersion),
'reserved_at': serializer.toJson<DateTime?>(reservedAt),
};
}
i1.SearchToken copyWith({
int? id,
i2.Uint8List? token,
DateTime? insertedAt,
String? issuerKeyVersion,
i0.Value<DateTime?> reservedAt = const i0.Value.absent(),
}) => i1.SearchToken(
id: id ?? this.id,
token: token ?? this.token,
insertedAt: insertedAt ?? this.insertedAt,
issuerKeyVersion: issuerKeyVersion ?? this.issuerKeyVersion,
reservedAt: reservedAt.present ? reservedAt.value : this.reservedAt,
);
SearchToken copyWithCompanion(i1.SearchTokensCompanion data) {
return SearchToken(
id: data.id.present ? data.id.value : this.id,
token: data.token.present ? data.token.value : this.token,
insertedAt: data.insertedAt.present
? data.insertedAt.value
: this.insertedAt,
issuerKeyVersion: data.issuerKeyVersion.present
? data.issuerKeyVersion.value
: this.issuerKeyVersion,
reservedAt: data.reservedAt.present
? data.reservedAt.value
: this.reservedAt,
);
}
@override
String toString() {
return (StringBuffer('SearchToken(')
..write('id: $id, ')
..write('token: $token, ')
..write('insertedAt: $insertedAt, ')
..write('issuerKeyVersion: $issuerKeyVersion, ')
..write('reservedAt: $reservedAt')
..write(')'))
.toString();
}
@override
int get hashCode => Object.hash(
id,
i0.$driftBlobEquality.hash(token),
insertedAt,
issuerKeyVersion,
reservedAt,
);
@override
bool operator ==(Object other) =>
identical(this, other) ||
(other is i1.SearchToken &&
other.id == this.id &&
i0.$driftBlobEquality.equals(other.token, this.token) &&
other.insertedAt == this.insertedAt &&
other.issuerKeyVersion == this.issuerKeyVersion &&
other.reservedAt == this.reservedAt);
}
class SearchTokensCompanion extends i0.UpdateCompanion<i1.SearchToken> {
final i0.Value<int> id;
final i0.Value<i2.Uint8List> token;
final i0.Value<DateTime> insertedAt;
final i0.Value<String> issuerKeyVersion;
final i0.Value<DateTime?> reservedAt;
const SearchTokensCompanion({
this.id = const i0.Value.absent(),
this.token = const i0.Value.absent(),
this.insertedAt = const i0.Value.absent(),
this.issuerKeyVersion = const i0.Value.absent(),
this.reservedAt = const i0.Value.absent(),
});
SearchTokensCompanion.insert({
this.id = const i0.Value.absent(),
required i2.Uint8List token,
required DateTime insertedAt,
required String issuerKeyVersion,
this.reservedAt = const i0.Value.absent(),
}) : token = i0.Value(token),
insertedAt = i0.Value(insertedAt),
issuerKeyVersion = i0.Value(issuerKeyVersion);
static i0.Insertable<i1.SearchToken> custom({
i0.Expression<int>? id,
i0.Expression<i2.Uint8List>? token,
i0.Expression<DateTime>? insertedAt,
i0.Expression<String>? issuerKeyVersion,
i0.Expression<DateTime>? reservedAt,
}) {
return i0.RawValuesInsertable({
if (id != null) 'id': id,
if (token != null) 'token': token,
if (insertedAt != null) 'inserted_at': insertedAt,
if (issuerKeyVersion != null) 'issuer_key_version': issuerKeyVersion,
if (reservedAt != null) 'reserved_at': reservedAt,
});
}
i1.SearchTokensCompanion copyWith({
i0.Value<int>? id,
i0.Value<i2.Uint8List>? token,
i0.Value<DateTime>? insertedAt,
i0.Value<String>? issuerKeyVersion,
i0.Value<DateTime?>? reservedAt,
}) {
return i1.SearchTokensCompanion(
id: id ?? this.id,
token: token ?? this.token,
insertedAt: insertedAt ?? this.insertedAt,
issuerKeyVersion: issuerKeyVersion ?? this.issuerKeyVersion,
reservedAt: reservedAt ?? this.reservedAt,
);
}
@override
Map<String, i0.Expression> toColumns(bool nullToAbsent) {
final map = <String, i0.Expression>{};
if (id.present) {
map['id'] = i0.Variable<int>(id.value);
}
if (token.present) {
map['token'] = i0.Variable<i2.Uint8List>(token.value);
}
if (insertedAt.present) {
map['inserted_at'] = i0.Variable<DateTime>(insertedAt.value);
}
if (issuerKeyVersion.present) {
map['issuer_key_version'] = i0.Variable<String>(issuerKeyVersion.value);
}
if (reservedAt.present) {
map['reserved_at'] = i0.Variable<DateTime>(reservedAt.value);
}
return map;
}
@override
String toString() {
return (StringBuffer('SearchTokensCompanion(')
..write('id: $id, ')
..write('token: $token, ')
..write('insertedAt: $insertedAt, ')
..write('issuerKeyVersion: $issuerKeyVersion, ')
..write('reservedAt: $reservedAt')
..write(')'))
.toString();
}
}
i0.Index get idxSearchTokensInsertedAt => i0.Index(
'idx_search_tokens_inserted_at',
'CREATE INDEX idx_search_tokens_inserted_at ON search_tokens (inserted_at)',
);
i0.Index get idxSearchTokensReservedAt => i0.Index(
'idx_search_tokens_reserved_at',
'CREATE INDEX idx_search_tokens_reserved_at ON search_tokens (reserved_at)',
);
class DefinitionsDrift extends i3.ModularAccessor {
DefinitionsDrift(i0.GeneratedDatabase db) : super(db);
i0.Selectable<String> toolbarLeadingOrderKey({