diff --git a/lib/data_layer/db/object_box_ndk/db_object_box.dart b/lib/data_layer/db/object_box_ndk/db_object_box.dart index 0eb326b..bf1bd9f 100644 --- a/lib/data_layer/db/object_box_ndk/db_object_box.dart +++ b/lib/data_layer/db/object_box_ndk/db_object_box.dart @@ -10,6 +10,7 @@ import 'schema/db_contact_list.dart'; import 'schema/db_metadata.dart'; import 'schema/db_nip_01_event.dart'; import 'schema/db_nip_05.dart'; +import 'schema/db_user_relay_list.dart'; class DbObjectBox implements CacheManager { final Completer _initCompleter = Completer(); @@ -256,9 +257,18 @@ class DbObjectBox implements CacheManager { } @override - Future loadUserRelayList(String pubKey) { - // TODO: implement loadUserRelayList - throw UnimplementedError(); + Future loadUserRelayList(String pubKey) async { + await _dbRdy; + final userRelayListBox = _objectBox.store.box(); + final existingUserRelayList = userRelayListBox + .query(DbUserRelayList_.pubKey.equals(pubKey)) + .order(DbUserRelayList_.createdAt, flags: Order.descending) + .build() + .findFirst(); + if (existingUserRelayList == null) { + return null; + } + return existingUserRelayList.toNdk(); } @override @@ -345,15 +355,27 @@ class DbObjectBox implements CacheManager { } @override - Future saveUserRelayList(UserRelayList userRelayList) { - // TODO: implement saveUserRelayList - throw UnimplementedError(); + Future saveUserRelayList(UserRelayList userRelayList) async { + await _dbRdy; + final userRelayListBox = _objectBox.store.box(); + final existingUserRelayList = userRelayListBox + .query(DbUserRelayList_.pubKey.equals(userRelayList.pubKey)) + .order(DbUserRelayList_.createdAt, flags: Order.descending) + .build() + .findFirst(); + if (existingUserRelayList != null) { + userRelayListBox.remove(existingUserRelayList.dbId); + } + userRelayListBox.put(DbUserRelayList.fromNdk(userRelayList)); } @override - Future saveUserRelayLists(List userRelayLists) { - // TODO: implement saveUserRelayLists - throw UnimplementedError(); + Future saveUserRelayLists(List userRelayLists) async { + final wait = []; + for (final userRelayList in userRelayLists) { + wait.add(saveUserRelayList(userRelayList)); + } + await Future.wait(wait); } @override diff --git a/lib/data_layer/db/object_box_ndk/schema/db_user_relay_list.dart b/lib/data_layer/db/object_box_ndk/schema/db_user_relay_list.dart new file mode 100644 index 0000000..d24a48a --- /dev/null +++ b/lib/data_layer/db/object_box_ndk/schema/db_user_relay_list.dart @@ -0,0 +1,63 @@ +import 'dart:convert'; + +import 'package:ndk/entities.dart'; +import 'package:objectbox/objectbox.dart'; +import 'package:ndk/entities.dart' as ndk_entities; + +@Entity() +class DbUserRelayList { + @Id() + int dbId = 0; + + @Property() + String pubKey; + + @Property() + int createdAt; + + @Property() + int refreshedTimestamp; + + @Property() + String relaysJson; + + DbUserRelayList({ + required this.pubKey, + required this.relaysJson, + required this.createdAt, + required this.refreshedTimestamp, + }); + + // Convert from UserRelayList to DbUserRelayList + static DbUserRelayList fromNdk(ndk_entities.UserRelayList userRelayList) { + return DbUserRelayList( + pubKey: userRelayList.pubKey, + relaysJson: _encodeRelays(userRelayList.relays), + createdAt: userRelayList.createdAt, + refreshedTimestamp: userRelayList.refreshedTimestamp, + ); + } + + // Convert to NDK model + ndk_entities.UserRelayList toNdk() { + return UserRelayList( + pubKey: pubKey, + relays: _decodeRelays(relaysJson), + createdAt: createdAt, + refreshedTimestamp: refreshedTimestamp, + ); + } + + // Helper method to encode relays map to JSON string + static String _encodeRelays(Map relays) { + return json + .encode(relays.map((key, value) => MapEntry(key, value.toString()))); + } + + // Helper method to decode JSON string to relays map + static Map _decodeRelays(String relaysJson) { + Map decodedMap = json.decode(relaysJson); + return decodedMap.map((key, value) => MapEntry( + key, ReadWriteMarker.values.firstWhere((e) => e.toString() == value))); + } +} diff --git a/lib/objectbox-model.json b/lib/objectbox-model.json index 2ff3d5d..36f365e 100644 --- a/lib/objectbox-model.json +++ b/lib/objectbox-model.json @@ -293,9 +293,43 @@ } ], "relations": [] + }, + { + "id": "7:7121738077069950407", + "lastPropertyId": "6:3769539562209329664", + "name": "DbUserRelayList", + "properties": [ + { + "id": "2:1626955690315208675", + "name": "pubKey", + "type": 9 + }, + { + "id": "3:2279200721602944096", + "name": "createdAt", + "type": 6 + }, + { + "id": "4:7429007344040003737", + "name": "refreshedTimestamp", + "type": 6 + }, + { + "id": "5:1857705759697671386", + "name": "relaysJson", + "type": 9 + }, + { + "id": "6:3769539562209329664", + "name": "dbId", + "type": 6, + "flags": 1 + } + ], + "relations": [] } ], - "lastEntityId": "6:5273186663970464575", + "lastEntityId": "7:7121738077069950407", "lastIndexId": "1:6758634951668169698", "lastRelationId": "0:0", "lastSequenceId": "0:0", @@ -303,7 +337,9 @@ "modelVersionParserMinimum": 5, "retiredEntityUids": [], "retiredIndexUids": [], - "retiredPropertyUids": [], + "retiredPropertyUids": [ + 4498920375281389613 + ], "retiredRelationUids": [], "version": 1 } \ No newline at end of file diff --git a/lib/objectbox.g.dart b/lib/objectbox.g.dart index a786b3c..8631b58 100644 --- a/lib/objectbox.g.dart +++ b/lib/objectbox.g.dart @@ -19,6 +19,7 @@ import 'data_layer/db/object_box_ndk/schema/db_contact_list.dart'; import 'data_layer/db/object_box_ndk/schema/db_metadata.dart'; import 'data_layer/db/object_box_ndk/schema/db_nip_01_event.dart'; import 'data_layer/db/object_box_ndk/schema/db_nip_05.dart'; +import 'data_layer/db/object_box_ndk/schema/db_user_relay_list.dart'; export 'package:objectbox/objectbox.dart'; // so that callers only have to import this file @@ -312,6 +313,40 @@ final _entities = [ flags: 0) ], relations: [], + backlinks: []), + obx_int.ModelEntity( + id: const obx_int.IdUid(7, 7121738077069950407), + name: 'DbUserRelayList', + lastPropertyId: const obx_int.IdUid(6, 3769539562209329664), + flags: 0, + properties: [ + obx_int.ModelProperty( + id: const obx_int.IdUid(2, 1626955690315208675), + name: 'pubKey', + type: 9, + flags: 0), + obx_int.ModelProperty( + id: const obx_int.IdUid(3, 2279200721602944096), + name: 'createdAt', + type: 6, + flags: 0), + obx_int.ModelProperty( + id: const obx_int.IdUid(4, 7429007344040003737), + name: 'refreshedTimestamp', + type: 6, + flags: 0), + obx_int.ModelProperty( + id: const obx_int.IdUid(5, 1857705759697671386), + name: 'relaysJson', + type: 9, + flags: 0), + obx_int.ModelProperty( + id: const obx_int.IdUid(6, 3769539562209329664), + name: 'dbId', + type: 6, + flags: 1) + ], + relations: [], backlinks: []) ]; @@ -350,13 +385,13 @@ Future openStore( obx_int.ModelDefinition getObjectBoxModel() { final model = obx_int.ModelInfo( entities: _entities, - lastEntityId: const obx_int.IdUid(6, 5273186663970464575), + lastEntityId: const obx_int.IdUid(7, 7121738077069950407), lastIndexId: const obx_int.IdUid(1, 6758634951668169698), lastRelationId: const obx_int.IdUid(0, 0), lastSequenceId: const obx_int.IdUid(0, 0), retiredEntityUids: const [], retiredIndexUids: const [], - retiredPropertyUids: const [], + retiredPropertyUids: const [4498920375281389613], retiredRelationUids: const [], modelVersion: 5, modelVersionParserMinimum: 5, @@ -718,6 +753,47 @@ obx_int.ModelDefinition getObjectBoxModel() { relays: relaysParam) ..dbId = const fb.Int64Reader().vTableGet(buffer, rootOffset, 4, 0); + return object; + }), + DbUserRelayList: obx_int.EntityDefinition( + model: _entities[6], + toOneRelations: (DbUserRelayList object) => [], + toManyRelations: (DbUserRelayList object) => {}, + getId: (DbUserRelayList object) => object.dbId, + setId: (DbUserRelayList object, int id) { + object.dbId = id; + }, + objectToFB: (DbUserRelayList object, fb.Builder fbb) { + final pubKeyOffset = fbb.writeString(object.pubKey); + final relaysJsonOffset = fbb.writeString(object.relaysJson); + fbb.startTable(7); + fbb.addOffset(1, pubKeyOffset); + fbb.addInt64(2, object.createdAt); + fbb.addInt64(3, object.refreshedTimestamp); + fbb.addOffset(4, relaysJsonOffset); + fbb.addInt64(5, object.dbId); + fbb.finish(fbb.endTable()); + return object.dbId; + }, + objectFromFB: (obx.Store store, ByteData fbData) { + final buffer = fb.BufferContext(fbData); + final rootOffset = buffer.derefObject(0); + final pubKeyParam = const fb.StringReader(asciiOptimization: true) + .vTableGet(buffer, rootOffset, 6, ''); + final relaysJsonParam = const fb.StringReader(asciiOptimization: true) + .vTableGet(buffer, rootOffset, 12, ''); + final createdAtParam = + const fb.Int64Reader().vTableGet(buffer, rootOffset, 8, 0); + final refreshedTimestampParam = + const fb.Int64Reader().vTableGet(buffer, rootOffset, 10, 0); + final object = DbUserRelayList( + pubKey: pubKeyParam, + relaysJson: relaysJsonParam, + createdAt: createdAtParam, + refreshedTimestamp: refreshedTimestampParam) + ..dbId = + const fb.Int64Reader().vTableGet(buffer, rootOffset, 14, 0); + return object; }) }; @@ -928,3 +1004,26 @@ class DbNip05_ { static final relays = obx.QueryStringVectorProperty(_entities[5].properties[5]); } + +/// [DbUserRelayList] entity fields to define ObjectBox queries. +class DbUserRelayList_ { + /// See [DbUserRelayList.pubKey]. + static final pubKey = + obx.QueryStringProperty(_entities[6].properties[0]); + + /// See [DbUserRelayList.createdAt]. + static final createdAt = + obx.QueryIntegerProperty(_entities[6].properties[1]); + + /// See [DbUserRelayList.refreshedTimestamp]. + static final refreshedTimestamp = + obx.QueryIntegerProperty(_entities[6].properties[2]); + + /// See [DbUserRelayList.relaysJson]. + static final relaysJson = + obx.QueryStringProperty(_entities[6].properties[3]); + + /// See [DbUserRelayList.dbId]. + static final dbId = + obx.QueryIntegerProperty(_entities[6].properties[4]); +}