Skip to content

Commit

Permalink
#14 Room 작업
Browse files Browse the repository at this point in the history
- Room 추가
- Database 작업
- DI 모듈 작성
  • Loading branch information
kimny927 committed Dec 7, 2024
1 parent 293598f commit e2deb5c
Show file tree
Hide file tree
Showing 16 changed files with 390 additions and 157 deletions.
2 changes: 1 addition & 1 deletion .idea/kotlinc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ plugins {
alias(libs.plugins.kotlin.kapt)
alias(libs.plugins.hilt.android)
alias(libs.plugins.secrets.gradle.plugin)
alias(libs.plugins.compose.compiler)
}

val keystorePropertiesFile = rootProject.file("keystore.properties")
Expand Down
2 changes: 2 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ plugins {
alias(libs.plugins.kotlin.kapt) apply false
alias(libs.plugins.hilt.android) apply false
alias(libs.plugins.jetbrains.kotlin.jvm) apply false
alias(libs.plugins.ksp) apply false
alias(libs.plugins.compose.compiler) apply false
}

buildscript {
Expand Down
11 changes: 8 additions & 3 deletions data/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ plugins {
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.kapt)
alias(libs.plugins.hilt.android)
alias(libs.plugins.ksp)
}

android {
Expand All @@ -26,11 +27,11 @@ android {
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
sourceCompatibility = JavaVersion.VERSION_19
targetCompatibility = JavaVersion.VERSION_19
}
kotlinOptions {
jvmTarget = "11"
jvmTarget = "19"
}
testOptions {
unitTests {
Expand All @@ -51,6 +52,10 @@ dependencies {
implementation(libs.hilt.android)
kapt(libs.hilt.android.compiler)
kapt(libs.hilt.compiler)
implementation(libs.room.runtime)
ksp(libs.room.compiler)
implementation(libs.room.ktx)
testImplementation(libs.room.testing)
testImplementation(libs.junit)
testImplementation(libs.mockito.kotlin)
testImplementation(libs.robolectric)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package ny.photomap.data.datasource

import ny.photomap.data.db.PhotoLocationEntity
import ny.photomap.data.model.PhotoLocationData

interface PhotoDataSource {
Expand All @@ -16,23 +17,23 @@ interface PhotoDataSource {
latitude: Double,
longitude: Double,
range: Double,
): Result<List<PhotoLocationData>>
): Result<List<PhotoLocationEntity>>

suspend fun getPhotoLocationWithOffset(
latitude: Double,
longitude: Double,
range: Double,
offset: Int,
limit: Int,
): Result<List<PhotoLocationData>>
): Result<List<PhotoLocationEntity>>

suspend fun getPhotoLocation(
latitude: Double,
longitude: Double,
range: Double,
startTime: Long,
endTime: Long,
): Result<List<PhotoLocationData>>
): Result<List<PhotoLocationEntity>>

suspend fun getPhotoLocationWithOffset(
latitude: Double,
Expand All @@ -42,7 +43,7 @@ interface PhotoDataSource {
endTime: Long,
offset: Int,
limit: Int,
): Result<List<PhotoLocationData>>
): Result<List<PhotoLocationEntity>>


}
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,15 @@ import androidx.core.os.bundleOf
import androidx.exifinterface.media.ExifInterface
import androidx.exifinterface.media.ExifInterface.TAG_DATETIME
import androidx.exifinterface.media.ExifInterface.TAG_DATETIME_ORIGINAL
import ny.photomap.data.db.PhotoLocationDao
import ny.photomap.data.db.PhotoLocationEntity
import ny.photomap.data.model.PhotoLocationData
import javax.inject.Inject

class PhotoDataSourceImpl @Inject constructor(private val contentResolver: ContentResolver) :
PhotoDataSource {
class PhotoDataSourceImpl @Inject constructor(
private val contentResolver: ContentResolver,
private val photoLocationDao: PhotoLocationDao,
) : PhotoDataSource {

private val projection = arrayOf(
MediaStore.Images.Media._ID,
Expand Down Expand Up @@ -107,27 +111,39 @@ class PhotoDataSourceImpl @Inject constructor(private val contentResolver: Conte
latitude: Double,
longitude: Double,
range: Double,
): Result<List<PhotoLocationData>> {
TODO("Not yet implemented")
): Result<List<PhotoLocationEntity>> = runCatching {
photoLocationDao.getLocationOf(
latitude = latitude,
longitude = longitude,
range = range
)
}


override suspend fun getPhotoLocation(
latitude: Double,
longitude: Double,
range: Double,
startTime: Long,
endTime: Long,
): Result<List<PhotoLocationData>> {
TODO("Not yet implemented")
): Result<List<PhotoLocationEntity>> = runCatching {
photoLocationDao.getLocationAndDateOf(
latitude = latitude,
longitude = longitude,
range = range,
fromTime = startTime,
toTime = endTime
)
}


override suspend fun getPhotoLocationWithOffset(
latitude: Double,
longitude: Double,
range: Double,
offset: Int,
limit: Int,
): Result<List<PhotoLocationData>> {
): Result<List<PhotoLocationEntity>> {
TODO("Not yet implemented")
}

Expand All @@ -139,7 +155,7 @@ class PhotoDataSourceImpl @Inject constructor(private val contentResolver: Conte
endTime: Long,
offset: Int,
limit: Int,
): Result<List<PhotoLocationData>> {
): Result<List<PhotoLocationEntity>> {
TODO("Not yet implemented")
}

Expand Down
66 changes: 66 additions & 0 deletions data/src/main/java/ny/photomap/data/db/PhotoLocationDao.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package ny.photomap.data.db

import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update

@Dao
interface PhotoLocationDao {

@Query("SELECT * FROM photo_location_table")
suspend fun getAll(): List<PhotoLocationEntity>

@Query(
"SELECT * FROM photo_location_table WHERE (latitude BETWEEN :latitude - :range AND :latitude + :range) " +
"AND (longitude BETWEEN :longitude - :range AND :longitude + :range)"
)
suspend fun getLocationOf(
latitude: Double,
longitude: Double,
range: Double,
): List<PhotoLocationEntity>

@Query(
"SELECT * FROM photo_location_table WHERE (latitude BETWEEN :latitude - :range AND :latitude + :range) " +
"AND (longitude BETWEEN :longitude - :range AND :longitude + :range) " +
"AND (generatedTime BETWEEN :fromTime AND :toTime)"
)
suspend fun getLocationAndDateOf(
latitude: Double,
longitude: Double,
range: Double,
fromTime: Long,
toTime: Long,
): List<PhotoLocationEntity>

@Query(
"SELECT COUNT(*) FROM photo_location_table WHERE (latitude BETWEEN :latitude - :range AND :latitude + :range) " +
"AND (longitude BETWEEN :longitude - :range AND :longitude + :range) " +
"AND (generatedTime BETWEEN :fromTime AND :toTime)"
)
suspend fun getCountOfLocationAndDate(
latitude: Double,
longitude: Double,
range: Double,
fromTime: Long,
toTime: Long,
): Int

@Insert
suspend fun insert(entity: PhotoLocationEntity)

@Insert
suspend fun insertAll(entityList: List<PhotoLocationEntity>)

@Update
suspend fun update(entity: PhotoLocationEntity)

@Delete
suspend fun delete(entity: PhotoLocationEntity)

@Delete
suspend fun deleteAll(entityList: List<PhotoLocationEntity>)

}
20 changes: 20 additions & 0 deletions data/src/main/java/ny/photomap/data/db/PhotoLocationDatabase.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package ny.photomap.data.db

import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase

@Database(entities = [PhotoLocationEntity::class], version = 1)
abstract class PhotoLocationDatabase : RoomDatabase() {
abstract fun photoLocationDao(): PhotoLocationDao

companion object {
fun getInstance(context: Context): PhotoLocationDatabase = Room.databaseBuilder(
context,
PhotoLocationDatabase::class.java,
"photo_location.db"
)
.build()
}
}
20 changes: 20 additions & 0 deletions data/src/main/java/ny/photomap/data/db/PhotoLocationEntity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package ny.photomap.data.db

import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey

@Entity(tableName = "photo_location_table")
data class PhotoLocationEntity(
val uri: String,
val name: String?,
val latitude: Double,
val longitude: Double,
val generatedTime: String?,
val addedTime: String?,
@ColumnInfo(typeAffinity = ColumnInfo.BLOB)
val thumbNail: ByteArray?,
) {
@PrimaryKey(autoGenerate = true)
var id: Long = 0
}
22 changes: 22 additions & 0 deletions data/src/main/java/ny/photomap/data/di/DatabaseModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package ny.photomap.data.di

import android.content.Context
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import ny.photomap.data.db.PhotoLocationDao
import ny.photomap.data.db.PhotoLocationDatabase

@InstallIn(SingletonComponent::class)
@Module
object DatabaseModule {
@Provides
fun providePhotoLocationDatabase(@ApplicationContext context: Context): PhotoLocationDatabase =
PhotoLocationDatabase.getInstance(context)

@Provides
fun providePhotoLocationDao(photoLocationDatabase: PhotoLocationDatabase): PhotoLocationDao =
photoLocationDatabase.photoLocationDao()
}
20 changes: 10 additions & 10 deletions data/src/test/java/ny/photomap/data/PhotoRepositoryTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ class PhotoRepositoryTest {
private lateinit var dataSource: PhotoDataSourceImpl
private lateinit var repository: PhotoRepositoryImpl

@Before
fun setUp() {
contentResolver = mock()
dataSource = Mockito.spy<PhotoDataSourceImpl>(PhotoDataSourceImpl(contentResolver))
repository = Mockito.spy<PhotoRepositoryImpl>(
PhotoRepositoryImpl(
dataSource = dataSource
)
)
}
// @Before
// fun setUp() {
// contentResolver = mock()
// dataSource = Mockito.spy<PhotoDataSourceImpl>(PhotoDataSourceImpl(contentResolver))
// repository = Mockito.spy<PhotoRepositoryImpl>(
// PhotoRepositoryImpl(
// dataSource = dataSource
// )
// )
// }

// todo : PhotoRepositoryImpl 완성 후 작업
/*@Test
Expand Down
15 changes: 11 additions & 4 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[versions]
agp = "8.7.3"
kotlin = "1.9.25"
kotlin = "2.1.0"
coreKtx = "1.15.0"
junit = "4.13.2"
junitVersion = "1.2.1"
Expand All @@ -20,6 +20,8 @@ mockito-kotlin = "5.4.0"
robolectric = "4.14"
hilt = "2.53"
jetbrainsKotlinJvm = "1.9.25"
room = "2.6.1"
ksp = "2.1.0-1.0.29"


[libraries]
Expand Down Expand Up @@ -52,14 +54,19 @@ robolectric = { group = "org.robolectric", name = "robolectric", version.ref = "
hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "hilt" }
hilt-android-compiler = { group = "com.google.dagger", name = "hilt-android-compiler", version.ref = "hilt" }
hilt-compiler = { group = "com.google.dagger", name = "hilt-compiler", version.ref = "hilt" }
hilt-android-gradle-plugin = { group="com.google.dagger", name="hilt-android-gradle-plugin", version.ref = "hilt" }
hilt-android-gradle-plugin = { group = "com.google.dagger", name = "hilt-android-gradle-plugin", version.ref = "hilt" }
room-runtime = { group = "androidx.room", name = "room-runtime", version.ref = "room" }
room-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "room" }
room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "room" }
room-testing = { group = "androidx.room", name = "room-testing", version.ref = "room" }

[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
secrets-gradle-plugin = { id = "com.google.android.libraries.mapsplatform.secrets-gradle-plugin" }
android-library = { id = "com.android.library", version.ref = "agp" }
kotlin-kapt = { id = "org.jetbrains.kotlin.kapt", version.ref = "kotlin" }
hilt-android = { id = "com.google.dagger.hilt.android", version.ref = "hilt"}
hilt-android = { id = "com.google.dagger.hilt.android", version.ref = "hilt" }
jetbrains-kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "jetbrainsKotlinJvm" }

ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
5 changes: 3 additions & 2 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#Mon Nov 04 20:49:31 KST 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Loading

0 comments on commit e2deb5c

Please sign in to comment.