🗃️ Add expired to cache

 Add sticker cache
This commit is contained in:
LittleSheep 2025-03-04 22:56:43 +08:00
parent b835c8edea
commit 97ddc18b8e
10 changed files with 1798 additions and 59 deletions

File diff suppressed because one or more lines are too long

View File

@ -37,4 +37,6 @@ class SnLocalAccount extends Table {
TextColumn get content => text().map(const SnAccountConverter())(); TextColumn get content => text().map(const SnAccountConverter())();
DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)(); DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)();
DateTimeColumn get cacheExpiredAt => dateTime()();
} }

View File

@ -42,4 +42,6 @@ class SnLocalAttachment extends Table {
IntColumn get accountId => integer()(); IntColumn get accountId => integer()();
DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)(); DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)();
DateTimeColumn get cacheExpiredAt => dateTime()();
} }

View File

@ -112,4 +112,6 @@ class SnLocalChannelMember extends Table {
TextColumn get content => text().map(SnChannelMemberConverter())(); TextColumn get content => text().map(SnChannelMemberConverter())();
DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)(); DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)();
DateTimeColumn get cacheExpiredAt => dateTime()();
} }

View File

@ -6,6 +6,7 @@ import 'package:surface/database/attachment.dart';
import 'package:surface/database/chat.dart'; import 'package:surface/database/chat.dart';
import 'package:surface/database/database.steps.dart'; import 'package:surface/database/database.steps.dart';
import 'package:surface/database/keypair.dart'; import 'package:surface/database/keypair.dart';
import 'package:surface/database/sticker.dart';
import 'package:surface/types/chat.dart'; import 'package:surface/types/chat.dart';
import 'package:surface/types/attachment.dart'; import 'package:surface/types/attachment.dart';
import 'package:surface/types/account.dart'; import 'package:surface/types/account.dart';
@ -19,6 +20,8 @@ part 'database.g.dart';
SnLocalKeyPair, SnLocalKeyPair,
SnLocalAccount, SnLocalAccount,
SnLocalAttachment, SnLocalAttachment,
SnLocalSticker,
SnLocalStickerPack,
]) ])
class AppDatabase extends _$AppDatabase { class AppDatabase extends _$AppDatabase {
AppDatabase([QueryExecutor? e]) : super(e ?? _openConnection()); AppDatabase([QueryExecutor? e]) : super(e ?? _openConnection());

File diff suppressed because it is too large Load Diff

View File

@ -151,6 +151,8 @@ final class Schema3 extends i0.VersionedSchema {
snLocalKeyPair, snLocalKeyPair,
snLocalAccount, snLocalAccount,
snLocalAttachment, snLocalAttachment,
snLocalSticker,
snLocalStickerPack,
idxChannelAlias, idxChannelAlias,
idxChatChannel, idxChatChannel,
idxAccountName, idxAccountName,
@ -200,6 +202,7 @@ final class Schema3 extends i0.VersionedSchema {
_column_6, _column_6,
_column_2, _column_2,
_column_3, _column_3,
_column_11,
], ],
attachedDatabase: database, attachedDatabase: database,
), ),
@ -230,9 +233,10 @@ final class Schema3 extends i0.VersionedSchema {
tableConstraints: [], tableConstraints: [],
columns: [ columns: [
_column_0, _column_0,
_column_11, _column_12,
_column_2, _column_2,
_column_3, _column_3,
_column_11,
], ],
attachedDatabase: database, attachedDatabase: database,
), ),
@ -245,11 +249,42 @@ final class Schema3 extends i0.VersionedSchema {
tableConstraints: [], tableConstraints: [],
columns: [ columns: [
_column_0, _column_0,
_column_12,
_column_13, _column_13,
_column_14,
_column_2, _column_2,
_column_6, _column_6,
_column_3, _column_3,
_column_11,
],
attachedDatabase: database,
),
alias: null);
late final Shape7 snLocalSticker = Shape7(
source: i0.VersionedTable(
entityName: 'sn_local_sticker',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_1,
_column_15,
_column_2,
_column_3,
],
attachedDatabase: database,
),
alias: null);
late final Shape8 snLocalStickerPack = Shape8(
source: i0.VersionedTable(
entityName: 'sn_local_sticker_pack',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_2,
_column_3,
], ],
attachedDatabase: database, attachedDatabase: database,
), ),
@ -296,8 +331,14 @@ class Shape4 extends i0.VersionedTable {
columnsByName['content']! as i1.GeneratedColumn<String>; columnsByName['content']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<DateTime> get createdAt => i1.GeneratedColumn<DateTime> get createdAt =>
columnsByName['created_at']! as i1.GeneratedColumn<DateTime>; columnsByName['created_at']! as i1.GeneratedColumn<DateTime>;
i1.GeneratedColumn<DateTime> get cacheExpiredAt =>
columnsByName['cache_expired_at']! as i1.GeneratedColumn<DateTime>;
} }
i1.GeneratedColumn<DateTime> _column_11(String aliasedName) =>
i1.GeneratedColumn<DateTime>('cache_expired_at', aliasedName, false,
type: i1.DriftSqlType.dateTime);
class Shape5 extends i0.VersionedTable { class Shape5 extends i0.VersionedTable {
Shape5({required super.source, required super.alias}) : super.aliased(); Shape5({required super.source, required super.alias}) : super.aliased();
i1.GeneratedColumn<int> get id => i1.GeneratedColumn<int> get id =>
@ -308,9 +349,11 @@ class Shape5 extends i0.VersionedTable {
columnsByName['content']! as i1.GeneratedColumn<String>; columnsByName['content']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<DateTime> get createdAt => i1.GeneratedColumn<DateTime> get createdAt =>
columnsByName['created_at']! as i1.GeneratedColumn<DateTime>; columnsByName['created_at']! as i1.GeneratedColumn<DateTime>;
i1.GeneratedColumn<DateTime> get cacheExpiredAt =>
columnsByName['cache_expired_at']! as i1.GeneratedColumn<DateTime>;
} }
i1.GeneratedColumn<String> _column_11(String aliasedName) => i1.GeneratedColumn<String> _column_12(String aliasedName) =>
i1.GeneratedColumn<String>('name', aliasedName, false, i1.GeneratedColumn<String>('name', aliasedName, false,
type: i1.DriftSqlType.string); type: i1.DriftSqlType.string);
@ -328,16 +371,47 @@ class Shape6 extends i0.VersionedTable {
columnsByName['account_id']! as i1.GeneratedColumn<int>; columnsByName['account_id']! as i1.GeneratedColumn<int>;
i1.GeneratedColumn<DateTime> get createdAt => i1.GeneratedColumn<DateTime> get createdAt =>
columnsByName['created_at']! as i1.GeneratedColumn<DateTime>; columnsByName['created_at']! as i1.GeneratedColumn<DateTime>;
i1.GeneratedColumn<DateTime> get cacheExpiredAt =>
columnsByName['cache_expired_at']! as i1.GeneratedColumn<DateTime>;
} }
i1.GeneratedColumn<String> _column_12(String aliasedName) => i1.GeneratedColumn<String> _column_13(String aliasedName) =>
i1.GeneratedColumn<String>('rid', aliasedName, false, i1.GeneratedColumn<String>('rid', aliasedName, false,
type: i1.DriftSqlType.string, type: i1.DriftSqlType.string,
defaultConstraints: i1.GeneratedColumn.constraintIsAlways('UNIQUE')); defaultConstraints: i1.GeneratedColumn.constraintIsAlways('UNIQUE'));
i1.GeneratedColumn<String> _column_13(String aliasedName) => i1.GeneratedColumn<String> _column_14(String aliasedName) =>
i1.GeneratedColumn<String>('uuid', aliasedName, false, i1.GeneratedColumn<String>('uuid', aliasedName, false,
type: i1.DriftSqlType.string, type: i1.DriftSqlType.string,
defaultConstraints: i1.GeneratedColumn.constraintIsAlways('UNIQUE')); defaultConstraints: i1.GeneratedColumn.constraintIsAlways('UNIQUE'));
class Shape7 extends i0.VersionedTable {
Shape7({required super.source, required super.alias}) : super.aliased();
i1.GeneratedColumn<int> get id =>
columnsByName['id']! as i1.GeneratedColumn<int>;
i1.GeneratedColumn<String> get alias =>
columnsByName['alias']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get fullAlias =>
columnsByName['full_alias']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get content =>
columnsByName['content']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<DateTime> get createdAt =>
columnsByName['created_at']! as i1.GeneratedColumn<DateTime>;
}
i1.GeneratedColumn<String> _column_15(String aliasedName) =>
i1.GeneratedColumn<String>('full_alias', aliasedName, false,
type: i1.DriftSqlType.string);
class Shape8 extends i0.VersionedTable {
Shape8({required super.source, required super.alias}) : super.aliased();
i1.GeneratedColumn<int> get id =>
columnsByName['id']! as i1.GeneratedColumn<int>;
i1.GeneratedColumn<String> get content =>
columnsByName['content']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<DateTime> get createdAt =>
columnsByName['created_at']! as i1.GeneratedColumn<DateTime>;
}
i0.MigrationStepWithVersion migrationSteps({ i0.MigrationStepWithVersion migrationSteps({
required Future<void> Function(i1.Migrator m, Schema2 schema) from1To2, 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, Schema3 schema) from2To3,

74
lib/database/sticker.dart Normal file
View File

@ -0,0 +1,74 @@
import 'dart:convert';
import 'package:drift/drift.dart';
import 'package:surface/types/attachment.dart';
class SnStickerConverter extends TypeConverter<SnSticker, String>
with JsonTypeConverter2<SnSticker, String, Map<String, Object?>> {
const SnStickerConverter();
@override
SnSticker fromSql(String fromDb) {
return fromJson(jsonDecode(fromDb) as Map<String, dynamic>);
}
@override
String toSql(SnSticker value) {
return jsonEncode(toJson(value));
}
@override
SnSticker fromJson(Map<String, Object?> json) {
return SnSticker.fromJson(json);
}
@override
Map<String, Object?> toJson(SnSticker value) {
return value.toJson();
}
}
class SnLocalSticker extends Table {
IntColumn get id => integer().autoIncrement()();
TextColumn get alias => text()();
TextColumn get fullAlias => text()();
TextColumn get content => text().map(const SnStickerConverter())();
DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)();
}
class SnStickerPackConverter extends TypeConverter<SnStickerPack, String>
with JsonTypeConverter2<SnStickerPack, String, Map<String, Object?>> {
const SnStickerPackConverter();
@override
SnStickerPack fromSql(String fromDb) {
return fromJson(jsonDecode(fromDb) as Map<String, dynamic>);
}
@override
String toSql(SnStickerPack value) {
return jsonEncode(toJson(value));
}
@override
SnStickerPack fromJson(Map<String, Object?> json) {
return SnStickerPack.fromJson(json);
}
@override
Map<String, Object?> toJson(SnStickerPack value) {
return value.toJson();
}
}
class SnLocalStickerPack extends Table {
IntColumn get id => integer().autoIncrement()();
TextColumn get content => text().map(const SnStickerPackConverter())();
DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)();
}

View File

@ -48,6 +48,7 @@ class UserDirectoryProvider {
if (plannedQuery.isEmpty) return out; if (plannedQuery.isEmpty) return out;
final dbResp = await (_dt.db.snLocalAccount.select() final dbResp = await (_dt.db.snLocalAccount.select()
..where((e) => e.id.isIn(plannedQuery)) ..where((e) => e.id.isIn(plannedQuery))
..where((e) => e.cacheExpiredAt.isBiggerThanValue(DateTime.now()))
..limit(plannedQuery.length)) ..limit(plannedQuery.length))
.get(); .get();
for (var idx = 0; idx < out.length; idx++) { for (var idx = 0; idx < out.length; idx++) {
@ -91,7 +92,8 @@ class UserDirectoryProvider {
} }
// On-disk cache // On-disk cache
final dbResp = await (_dt.db.snLocalAccount.select() final dbResp = await (_dt.db.snLocalAccount.select()
..where((e) => e.id.equals(id))) ..where((e) => e.id.equals(id))
..where((e) => e.cacheExpiredAt.isBiggerThanValue(DateTime.now())))
.getSingleOrNull(); .getSingleOrNull();
if (dbResp != null) { if (dbResp != null) {
_cache[dbResp.id] = dbResp.content; _cache[dbResp.id] = dbResp.content;
@ -130,6 +132,7 @@ class UserDirectoryProvider {
id: Value(ele.id), id: Value(ele.id),
name: ele.name, name: ele.name,
content: ele, content: ele,
cacheExpiredAt: DateTime.now().add(const Duration(hours: 1)),
), ),
onConflict: DoUpdate( onConflict: DoUpdate(
(_) => SnLocalAccountCompanion.custom( (_) => SnLocalAccountCompanion.custom(

File diff suppressed because it is too large Load Diff