import 'package:drift/drift.dart'; import 'package:twonly/globals.dart'; import 'package:twonly/src/database/tables/signal_contact_prekey_table.dart'; import 'package:twonly/src/database/tables/signal_contact_signed_prekey_table.dart'; import 'package:twonly/src/database/twonly_database.dart'; import 'package:twonly/src/utils/log.dart'; part 'signal_dao.g.dart'; @DriftAccessor( tables: [ SignalContactPreKeys, SignalContactSignedPreKeys, ], ) class SignalDao extends DatabaseAccessor with _$SignalDaoMixin { // this constructor is required so that the main database can create an instance // of this object. // ignore: matching_super_parameters SignalDao(super.db); Future deleteAllByContactId(int contactId) async { await (delete(signalContactPreKeys) ..where((t) => t.contactId.equals(contactId))) .go(); await (delete(signalContactSignedPreKeys) ..where((t) => t.contactId.equals(contactId))) .go(); } Future deleteAllPreKeysByContactId(int contactId) async { await (delete(signalContactPreKeys) ..where((t) => t.contactId.equals(contactId))) .go(); } // 1: Count the number of pre-keys by contact ID Future countPreKeysByContactId(int contactId) { return (select(signalContactPreKeys) ..where((tbl) => tbl.contactId.equals(contactId))) .get() .then((rows) => rows.length); } // 2: Pop a pre-key by contact ID Future popPreKeyByContactId(int contactId) async { final preKey = await ((select(signalContactPreKeys)..where((tbl) => tbl.contactId.equals(contactId))) ..limit(1)) .getSingleOrNull(); if (preKey != null) { // remove the pre key... await (delete(signalContactPreKeys) ..where( (tbl) => tbl.contactId.equals(contactId) & tbl.preKeyId.equals(preKey.preKeyId), )) .go(); return preKey; } return null; } // 3: Insert multiple pre-keys Future insertPreKeys( List preKeys, ) async { for (final preKey in preKeys) { try { await into(signalContactPreKeys).insert(preKey); } catch (e) { Log.error('$e'); } } } // 4: Get signed pre-key by contact ID Future getSignedPreKeyByContactId(int contactId) { return (select(signalContactSignedPreKeys) ..where((tbl) => tbl.contactId.equals(contactId))) .getSingleOrNull(); } // 5: Insert or update signed pre-key by contact ID Future insertOrUpdateSignedPreKeyByContactId( SignalContactSignedPreKeysCompanion signedPreKey, ) async { await (delete(signalContactSignedPreKeys) ..where((t) => t.contactId.equals(signedPreKey.contactId.value))) .go(); await into(signalContactSignedPreKeys).insert(signedPreKey); } Future purgeOutDatedPreKeys() async { // other pre keys are valid 25 days await (delete(signalContactSignedPreKeys) ..where( (t) => (t.createdAt.isSmallerThanValue( DateTime.now().subtract( const Duration(days: 25), ), )), )) .go(); // own pre keys are valid for 40 days await (delete(twonlyDB.signalPreKeyStores) ..where( (t) => (t.createdAt.isSmallerThanValue( DateTime.now().subtract( const Duration(days: 40), ), )), )) .go(); } }