Add connection/following/followers db model.
This commit is contained in:
@@ -3,6 +3,7 @@ package ac.cord.auxiliary.compose.database
|
||||
import ac.cord.auxiliary.compose.database.converters.AuxConverters
|
||||
import ac.cord.auxiliary.compose.database.dao.BroadcastNostrEventReceiptDao
|
||||
import ac.cord.auxiliary.compose.database.dao.BroadcastNostrEventRequestDao
|
||||
import ac.cord.auxiliary.compose.database.dao.ConnectionDao
|
||||
import ac.cord.auxiliary.compose.database.dao.NostrDao
|
||||
import ac.cord.auxiliary.compose.database.dao.NostrEventDao
|
||||
import ac.cord.auxiliary.compose.database.dao.PostDao
|
||||
@@ -17,6 +18,7 @@ import ac.cord.auxiliary.compose.database.dao.UnsignedNostrEventDao
|
||||
import ac.cord.auxiliary.compose.database.dao.ZapDao
|
||||
import ac.cord.auxiliary.compose.database.model.BroadcastNostrEventReceipt
|
||||
import ac.cord.auxiliary.compose.database.model.BroadcastNostrEventRequest
|
||||
import ac.cord.auxiliary.compose.database.model.Connection
|
||||
import ac.cord.auxiliary.compose.database.model.NostrEvent
|
||||
import ac.cord.auxiliary.compose.database.model.Post
|
||||
import ac.cord.auxiliary.compose.database.model.Profile
|
||||
@@ -41,6 +43,7 @@ val GENESIS_AT = Instant.fromEpochMilliseconds(1231006505000L)
|
||||
entities = [
|
||||
BroadcastNostrEventReceipt::class,
|
||||
BroadcastNostrEventRequest::class,
|
||||
Connection::class,
|
||||
NostrEvent::class,
|
||||
Post::class,
|
||||
Profile::class,
|
||||
@@ -59,6 +62,8 @@ val GENESIS_AT = Instant.fromEpochMilliseconds(1231006505000L)
|
||||
abstract class AuxDatabase: RoomDatabase() {
|
||||
abstract fun broadcastNostrEventReceiptDao(): BroadcastNostrEventReceiptDao
|
||||
abstract fun broadcastNostrEventRequestDao(): BroadcastNostrEventRequestDao
|
||||
abstract fun connectionDao(): ConnectionDao
|
||||
|
||||
abstract fun nostrDao(): NostrDao
|
||||
|
||||
abstract fun nostrEventDao(): NostrEventDao
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package ac.cord.auxiliary.compose.database.dao
|
||||
|
||||
import ac.cord.auxiliary.compose.database.model.Connection
|
||||
import ac.cord.auxiliary.compose.database.model.Profile
|
||||
import ac.cord.auxiliary.compose.database.model.intermdiate.LocalFollowers
|
||||
import ac.cord.auxiliary.compose.database.model.intermdiate.LocalFollowing
|
||||
import ac.cord.auxiliary.compose.database.model.intermdiate.LocalProfile
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.Query
|
||||
import androidx.room.Upsert
|
||||
import fr.acinq.bitcoin.PublicKey
|
||||
|
||||
@Dao
|
||||
interface ConnectionDao {
|
||||
@Query("SELECT * FROM Connection LIMIT :limit")
|
||||
fun getAllConnections(limit: Int = 21): List<Connection>
|
||||
|
||||
@Query("SELECT * FROM Connection WHERE sourcePublicKey = :sourcePublicKey")
|
||||
fun getPublicKeyFollowing(sourcePublicKey: String): LocalFollowing?
|
||||
|
||||
@Query("SELECT * FROM Connection WHERE destinationPublicKey = :destinationPublicKey")
|
||||
fun getPublicKeyFollowers(destinationPublicKey: String): LocalFollowers?
|
||||
|
||||
@Insert
|
||||
suspend fun insertPlaceholderProfile(connection: Connection)
|
||||
|
||||
@Upsert
|
||||
suspend fun upsert(connection: Connection)
|
||||
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package ac.cord.auxiliary.compose.database.dao
|
||||
import ac.cord.auxiliary.compose.database.AuxDatabase
|
||||
import ac.cord.auxiliary.compose.database.GENESIS_AT
|
||||
import ac.cord.auxiliary.compose.database.model.BroadcastNostrEventRequest
|
||||
import ac.cord.auxiliary.compose.database.model.Connection
|
||||
import ac.cord.auxiliary.compose.database.model.NostrEvent
|
||||
import ac.cord.auxiliary.compose.database.model.Post
|
||||
import ac.cord.auxiliary.compose.database.model.Profile
|
||||
@@ -359,5 +360,66 @@ abstract class NostrDao(
|
||||
|
||||
database.zapDao().upsert(zap)
|
||||
}
|
||||
|
||||
if (nostrEvent.kind == ContactListEvent.KIND) {
|
||||
val contactListEvent = ContactListEvent(
|
||||
id = nostrEvent.id,
|
||||
tags = nostrEvent.tags,
|
||||
pubKey = nostrEvent.pubKey,
|
||||
createdAt = nostrEvent.createdAt.epochSeconds,
|
||||
content = nostrEvent.content,
|
||||
sig = nostrEvent.sig
|
||||
)
|
||||
logger.i("Store contact list: $contactListEvent")
|
||||
|
||||
contactListEvent.verifiedFollowKeySet().forEach { followedHexKEys ->
|
||||
|
||||
// Find or create profile with the pubKey... if not found submit a sync request...
|
||||
val profile = database.profileDao().getProfileByPublicKey(followedHexKEys)
|
||||
|
||||
if (profile == null) {
|
||||
val placeHolderProfile = Profile(
|
||||
publicKey = nostrEvent.pubKey,
|
||||
createdAt = GENESIS_AT,
|
||||
nostrEventId = nostrEvent.id, // Will get overwriting by sync,
|
||||
)
|
||||
database.profileDao().insertPlaceholderProfile(placeHolderProfile)
|
||||
|
||||
database.synchronizeNostrEventRequestDao().insert(
|
||||
synchronizationRelayURLs.map { synchronizationRelayURL ->
|
||||
SynchronizeNostrEventRequest(
|
||||
purpose = "synchronization",
|
||||
synchronizationFilters = arrayOf(
|
||||
SynchronizationFilter(
|
||||
authors = arrayOf(nostrEvent.pubKey),
|
||||
kinds = arrayOf(
|
||||
MetadataEvent.KIND,
|
||||
ContactListEvent.KIND,
|
||||
AdvertisedRelayListEvent.KIND,
|
||||
ChatMessageRelayListEvent.KIND,
|
||||
SearchRelayListEvent.KIND,
|
||||
IndexerRelayListEvent.KIND,
|
||||
ChannelListEvent.KIND,
|
||||
RelayFeedsListEvent.KIND
|
||||
)
|
||||
)
|
||||
),
|
||||
relayURL = synchronizationRelayURL
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// Save profile connections...
|
||||
database.connectionDao().upsert(
|
||||
Connection(
|
||||
sourcePublicKey = nostrEvent.pubKey,
|
||||
destinationPublicKey = followedHexKEys,
|
||||
nostrEventId = nostrEvent.id
|
||||
)
|
||||
)
|
||||
}
|
||||
// TODO: Delete connections where sourcePublicKey == nostr.pubKey but destinationPublickKey !in verifiedFollowKeySet
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package ac.cord.auxiliary.compose.database.model
|
||||
|
||||
import ac.cord.auxiliary.compose.database.model.traits.BroadcastableEntity
|
||||
import ac.cord.auxiliary.compose.database.model.traits.LocalStoreEntity
|
||||
import ac.cord.auxiliary.compose.database.model.traits.NostrEventEntity
|
||||
import ac.cord.auxiliary.compose.database.model.traits.SoftDeletableEntity
|
||||
import ac.cord.auxiliary.compose.database.model.traits.TimestampedEntity
|
||||
import androidx.room.Entity
|
||||
import androidx.room.ForeignKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import kotlin.time.Clock
|
||||
import kotlin.time.Instant
|
||||
|
||||
@Entity(
|
||||
foreignKeys = [
|
||||
ForeignKey(
|
||||
entity = Profile::class,
|
||||
parentColumns = ["publicKey"],
|
||||
childColumns = ["sourcePublicKey"],
|
||||
onDelete = ForeignKey.CASCADE,
|
||||
),
|
||||
ForeignKey(
|
||||
entity = Profile::class,
|
||||
parentColumns = ["publicKey"],
|
||||
childColumns = ["destinationPublicKey"],
|
||||
onDelete = ForeignKey.CASCADE,
|
||||
),
|
||||
],
|
||||
primaryKeys = ["sourcePublicKey", "destinationPublicKey"]
|
||||
)
|
||||
data class Connection(
|
||||
val sourcePublicKey: HexKey,
|
||||
val destinationPublicKey: HexKey,
|
||||
|
||||
override val nostrEventId: HexKey, // This is the contactListEvent with this following...
|
||||
|
||||
override val createdAt: Instant = Clock.System.now(),
|
||||
override val updatedAt: Instant = Clock.System.now(),
|
||||
override val savedAt: Instant = Clock.System.now(),
|
||||
override val deletedAt: Instant? = null,
|
||||
override val broadcastedAt: Instant? = null,
|
||||
): NostrEventEntity, TimestampedEntity, LocalStoreEntity, BroadcastableEntity, SoftDeletableEntity
|
||||
@@ -0,0 +1,17 @@
|
||||
package ac.cord.auxiliary.compose.database.model.intermdiate
|
||||
|
||||
import ac.cord.auxiliary.compose.database.model.Profile
|
||||
import ac.cord.auxiliary.compose.database.model.Connection
|
||||
import androidx.room.Embedded
|
||||
import androidx.room.Junction
|
||||
import androidx.room.Relation
|
||||
|
||||
data class LocalFollowers(
|
||||
@Embedded val connection: Connection,
|
||||
|
||||
@Relation(
|
||||
parentColumn = "destinationPublicKey",
|
||||
entityColumn = "publicKey",
|
||||
)
|
||||
val followers: List<Profile>
|
||||
)
|
||||
@@ -0,0 +1,17 @@
|
||||
package ac.cord.auxiliary.compose.database.model.intermdiate
|
||||
|
||||
import ac.cord.auxiliary.compose.database.model.Profile
|
||||
import ac.cord.auxiliary.compose.database.model.Connection
|
||||
import androidx.room.Embedded
|
||||
import androidx.room.Junction
|
||||
import androidx.room.Relation
|
||||
|
||||
data class LocalFollowing(
|
||||
@Embedded val connection: Connection,
|
||||
|
||||
@Relation(
|
||||
parentColumn = "sourcePublicKey",
|
||||
entityColumn = "publicKey",
|
||||
)
|
||||
val following: List<Profile>
|
||||
)
|
||||
Reference in New Issue
Block a user