-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
다대다 구조 Relation을 이용해서 구현 / Fix: Foreign Key Constraint Fail… #53
Changes from 2 commits
f9ef015
727c6ae
3c23d6f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,27 +5,32 @@ import androidx.room.Dao | |
import androidx.room.Insert | ||
import androidx.room.OnConflictStrategy | ||
import androidx.room.Query | ||
import androidx.room.Transaction | ||
import com.wakeup.data.database.entity.GlobeEntity | ||
import com.wakeup.data.database.entity.MomentEntity | ||
import com.wakeup.data.database.entity.MomentGlobeEntity | ||
import com.wakeup.data.database.entity.MomentPictureEntity | ||
import com.wakeup.data.database.entity.MomentWithGlobesAndPictures | ||
import com.wakeup.data.database.entity.PictureEntity | ||
|
||
@Dao | ||
interface MomentDao { | ||
|
||
@Transaction | ||
@Query( | ||
""" | ||
SELECT * FROM moment | ||
WHERE mainAddress LIKE '%' || :query || '%' | ||
WHERE mainAddress LIKE '%' || :query || '%' | ||
OR detailAddress LIKE '%' || :query || '%' | ||
OR content LIKE '%' || :query || '%' | ||
ORDER BY | ||
CASE WHEN :sortType = 0 THEN date END DESC, | ||
CASE WHEN :sortType = 1 THEN date END ASC | ||
""" | ||
) | ||
fun getMoments(sortType: Int = 0, query: String): PagingSource<Int, MomentEntity> | ||
fun getMoments(sortType: Int = 0, query: String): PagingSource<Int, MomentWithGlobesAndPictures> | ||
|
||
@Transaction | ||
@Query( | ||
""" | ||
SELECT *, | ||
|
@@ -38,26 +43,30 @@ interface MomentDao { | |
ORDER BY distance | ||
""" | ||
) | ||
fun getMomentsByNearestDistance(query: String, lat: Double?, lng: Double?): PagingSource<Int, MomentEntity> | ||
fun getMomentsByNearestDistance( | ||
query: String, | ||
lat: Double?, | ||
lng: Double?, | ||
): PagingSource<Int, MomentWithGlobesAndPictures> | ||
|
||
@Query( | ||
"SELECT * FROM picture WHERE id IN" + | ||
"(SELECT picture_id FROM moment_picture WHERE moment_id = :momentId)" | ||
) | ||
suspend fun getPictures(momentId: Long): List<PictureEntity> | ||
@Query("SELECT globe_entity_id FROM globe WHERE name = :globeName") | ||
suspend fun getGlobeIdByName(globeName: String): Long | ||
|
||
@Query( | ||
"SELECT * FROM globe WHERE id IN " + | ||
"(SELECT globe_id FROM moment_globe WHERE moment_id = :momentId)" | ||
) | ||
suspend fun getGlobes(momentId: Long): List<GlobeEntity> | ||
@Query("SELECT picture_entity_id FROM picture WHERE bitmap = :bitmap") | ||
suspend fun getPictureIdByByteArray(bitmap: ByteArray): Long | ||
|
||
@Insert(onConflict = OnConflictStrategy.REPLACE) | ||
suspend fun saveMoment(moment: MomentEntity): Long | ||
|
||
@Insert(onConflict = OnConflictStrategy.REPLACE) | ||
@Insert(onConflict = OnConflictStrategy.IGNORE) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IGNORE 가 존재했군요!! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 넵 들어가는 걸 |
||
suspend fun savePicture(picture: List<PictureEntity>): List<Long> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 헷갈리지 않도록 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 넵 좋습니다! |
||
|
||
@Insert(onConflict = OnConflictStrategy.REPLACE) | ||
suspend fun saveMomentPicture(momentPictures: List<MomentPictureEntity>) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 여기도 같은 맥락으로 뭔가
공식 문서에도 사용하는 네이밍 방식입니다. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 최대한 폴더 이름과 같게 하려고 했어요 함수 네이밍 suspend fun saveMomentPictures(momentPictures: List<MomentPictureXRef>)
->
suspend fun saveMomentPictureXRefs(momentPictures: List<MomentPictureXRef>) suspend fun saveMomentGlobe(momentGlobe: MomentGlobeXRef)
->
suspend fun saveMomentGlobeXRef(momentGlobe: MomentGlobeXRef) |
||
|
||
@Insert(onConflict = OnConflictStrategy.IGNORE) | ||
suspend fun saveGlobes(globes: List<GlobeEntity>): List<Long> | ||
|
||
@Insert(onConflict = OnConflictStrategy.REPLACE) | ||
suspend fun saveMomentGlobe(momentGlobe: MomentGlobeEntity) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,6 @@ import androidx.room.PrimaryKey | |
indices = [Index(value = ["name"], unique = true)] | ||
) | ||
data class GlobeEntity( | ||
@PrimaryKey(autoGenerate = true) val id: Long = 0L, | ||
@PrimaryKey(autoGenerate = true) @ColumnInfo(name = "globe_entity_id") val id: Long = 0L, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 모든 entity 의 id 를 동일하게 한다면, 중간에 entity 를 빼고 동일하게 해도 좋을 것 같습니다!🙂 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 넵 아까 이야기한 것처럼 |
||
@ColumnInfo(name = "name") val name: String, | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package com.wakeup.data.database.entity | ||
|
||
import androidx.room.Embedded | ||
import androidx.room.Junction | ||
import androidx.room.Relation | ||
|
||
data class MomentWithGlobesAndPictures( | ||
@Embedded val moment: MomentEntity, | ||
@Relation( | ||
parentColumn = "moment_entity_id", | ||
entity = GlobeEntity::class, | ||
entityColumn = "globe_entity_id", | ||
associateBy = Junction(MomentGlobeEntity::class) | ||
) | ||
val globeList: List<GlobeEntity>, | ||
@Relation( | ||
parentColumn = "moment_entity_id", | ||
entity = PictureEntity::class, | ||
entityColumn = "picture_entity_id", | ||
associateBy = Junction(MomentPictureEntity::class) | ||
) | ||
val pictureList: List<PictureEntity>, | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,32 +2,47 @@ package com.wakeup.data.repository | |
|
||
import androidx.paging.PagingData | ||
import androidx.paging.map | ||
import com.wakeup.data.database.entity.GlobeEntity | ||
import com.wakeup.data.database.entity.MomentGlobeEntity | ||
import com.wakeup.data.database.entity.MomentPictureEntity | ||
import com.wakeup.data.database.mapper.toDomain | ||
import com.wakeup.data.database.mapper.toEntity | ||
import com.wakeup.data.source.local.moment.MomentLocalDataSource | ||
import com.wakeup.domain.model.Location | ||
import com.wakeup.domain.model.Moment | ||
import com.wakeup.domain.model.Place | ||
import com.wakeup.domain.model.SortType | ||
import com.wakeup.domain.model.Picture | ||
import com.wakeup.domain.repository.MomentRepository | ||
import kotlinx.coroutines.CoroutineScope | ||
import kotlinx.coroutines.Dispatchers | ||
import kotlinx.coroutines.flow.Flow | ||
import kotlinx.coroutines.flow.map | ||
import timber.log.Timber | ||
import kotlinx.coroutines.launch | ||
import javax.inject.Inject | ||
|
||
class MomentRepositoryImpl @Inject constructor( | ||
private val localDataSource: MomentLocalDataSource, | ||
) : MomentRepository { | ||
|
||
override fun getMoments(sort: SortType, query: String, myLocation: Location?): Flow<PagingData<Moment>> = | ||
init { | ||
// todo: globe_test_code (must remove to release) | ||
CoroutineScope(Dispatchers.IO).launch { | ||
localDataSource.saveGlobes(listOf( | ||
GlobeEntity(name = "default"), | ||
GlobeEntity(name = "globe 1"), | ||
GlobeEntity(name = "globe 2"), | ||
GlobeEntity(name = "globe 3")) | ||
) | ||
} | ||
} | ||
|
||
override fun getMoments( | ||
sort: SortType, | ||
query: String, | ||
myLocation: Location?, | ||
): Flow<PagingData<Moment>> = | ||
localDataSource.getMoments(sort, query, myLocation?.toEntity()).map { pagingData -> | ||
pagingData.map { momentEntity -> | ||
momentEntity.toDomain( | ||
localDataSource.getPictures(momentEntity.id), | ||
localDataSource.getGlobes(momentEntity.id) | ||
) | ||
pagingData.map { momentInfo -> | ||
momentInfo.toDomain(momentInfo.pictureList, momentInfo.globeList) | ||
} | ||
} | ||
|
||
|
@@ -37,15 +52,20 @@ class MomentRepositoryImpl @Inject constructor( | |
return | ||
} else { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 부분에 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 맞네요 early return |
||
val pictureIndexes = | ||
localDataSource.savePicture(moment.pictures.map { it.toEntity() }) | ||
localDataSource.savePictures(moment.pictures.map { it.toEntity() }) | ||
// 정책: moment 추가할 때 항상 globe 하나 선택해서 추가(default 도 하나 선택해서 추가 임). | ||
val globeIndex = localDataSource.getGlobeId(moment.globes[0].name) | ||
val momentIndex = | ||
localDataSource.saveMoment(moment.toEntity(moment.place, pictureIndexes[0])) | ||
|
||
localDataSource.saveMomentPicture( | ||
localDataSource.saveMomentPictures( | ||
pictureIndexes.map { pictureId -> | ||
MomentPictureEntity(momentId = momentIndex, pictureId = pictureId) | ||
} | ||
) | ||
localDataSource.saveMomentGlobe( | ||
MomentGlobeEntity(momentId = momentIndex, globeId = globeIndex) | ||
) | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
검색 기능이 이미 구현된건가요? 제 담당이긴 한데 😅
query
없이 모먼트를 가져오려면,query = ""
를 파라미터 값으로 넘겨줘야 할까요?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
검색 기능이 재민님이 구현하신 내용인데 검색 없이는
""
맞습니다!There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
엇 검색 쿼리는 원래 있었는데 저는 정렬만 추가했습니다!