I started using Room database and went through several docs to create room entities. These are my relations. A Chat Channel can have Many Conversations. So this goes as one-to-many relationship. Hence i created entities as below.
Channel Entity
@Entity(primaryKeys = ["channelId"])
@TypeConverters(TypeConverters::class)
data class Channel(
@field:SerializedName("channelId")
val channelId: String,
@field:SerializedName("channelName")
val channelName: String,
@field:SerializedName("createdBy")
val creationTs: String,
@field:SerializedName("creationTs")
val createdBy: String,
@field:SerializedName("members")
val members: List<String>,
@field:SerializedName("favMembers")
val favMembers: List<String>
) {
// Does not show up in the response but set in post processing.
var isOneToOneChat: Boolean = false
var isChatBot: Boolean = false
}
Conversation Entity
@Entity(primaryKeys = ["msgId"],
foreignKeys = [
ForeignKey(entity = Channel::class,
parentColumns = arrayOf("channelId"),
childColumns = arrayOf("msgId"),
onUpdate = CASCADE,
onDelete = CASCADE
)
])
@TypeConverters(TypeConverters::class)
data class Conversation(
@field:SerializedName("msgId")
val msgId: String,
@field:SerializedName("employeeID")
val employeeID: String,
@field:SerializedName("channelId")
val channelId: String,
@field:SerializedName("channelName")
val channelName: String,
@field:SerializedName("sender")
val sender: String,
@field:SerializedName("sentAt")
val sentAt: String,
@field:SerializedName("senderName")
val senderName: String,
@field:SerializedName("status")
val status: String,
@field:SerializedName("msgType")
val msgType: String,
@field:SerializedName("type")
val panicType: String?,
@field:SerializedName("message")
val message: List<Message>,
@field:SerializedName("deliveredTo")
val delivered: List<Delivered>?,
@field:SerializedName("readBy")
val read: List<Read>?
) {
data class Message(
@field:SerializedName("txt")
val txt: String,
@field:SerializedName("lang")
val lang: String,
@field:SerializedName("trans")
val trans: String
)
data class Delivered(
@field:SerializedName("employeeID")
val employeeID: String,
@field:SerializedName("date")
val date: String
)
data class Read(
@field:SerializedName("employeeID")
val employeeID: String,
@field:SerializedName("date")
val date: String
)
// Does not show up in the response but set in post processing.
var isHeaderView: Boolean = false
}
Now as you can see Conversation belongs to a Channel. When user sees a list of channels, i need to display several attributes of last Conversation in the list item. My question is, is it enough if i just declare relation like above or should i contain Converstion object in Channel class? What are the other ways in which i can handle it? Because UI needs to get most recent conversation that happened along with time, status etc. in each item of the channel list when user scrolls. So there should not be any lag in UI because of this when i query.
And how can i have recent Converstaion object in Channel object?
I suggest create another class (not in DB, just for show in UI) like this:
data class LastConversationInChannel(
val channelId: String,
val channelName: String,
val creationTs: String,
val createdBy: String,
val msgId: String,
val employeeID: String,
val sender: String,
val sentAt: String,
val senderName: String
.
.
.
)
Get last Conversation in each Channel by this query:
SELECT Channel.*
,IFNULL(LastConversation.msgId,'') msgId
,IFNULL(LastConversation.sender,'') sender
,IFNULL(LastConversation.employeeID,'') employeeID
,IFNULL(LastConversation.sentAt,'') sentAt
,IFNULL(LastConversation.senderName,'') senderName
from Channel left join
(SELECT * from Conversation a
WHERE a.msgId IN ( SELECT b.msgId FROM Conversation AS b
WHERE a.channelId = b.channelId
ORDER BY b.sentAt DESC LIMIT 1 )) as LastConversation
on Channel.channelId = LastConversation.channelId
then use it in your dao like this:
@Query(" SELECT Channel.*\n" +
" ,IFNULL(LastConversation.msgId,'') msgId\n" +
" ,IFNULL(LastConversation.sender,'') sender\n" +
" ,IFNULL(LastConversation.employeeID,'') employeeID\n" +
" ,IFNULL(LastConversation.sentAt,'') sentAt\n" +
" ,IFNULL(LastConversation.senderName,'') senderName\n" +
" from Channel left join \n" +
" (SELECT * from Conversation a \n" +
" WHERE a.msgId IN ( SELECT b.msgId FROM Conversation AS b \n" +
" WHERE a.channelId = b.channelId \n" +
" ORDER BY b.sentAt DESC LIMIT 1 )) as LastConversation\n" +
" on Channel.channelId = LastConversation.channelId")
fun getLastConversationInChannel(): LiveData<List<LastConversationInChannel>>
is it enough if i just declare relation like above or should i contain Converstion object in Channel class?
You should not contain Conversation in Channel class, because Room will create some columns for it in Conversation table.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With