Skip to content
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

✨ Dao を追加 #147

Merged
merged 5 commits into from
Dec 12, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package club.nito.core.database

import app.cash.sqldelight.EnumColumnAdapter
import app.cash.sqldelight.db.SqlDriver
import club.nito.core.database.adapter.InstantLongColumnAdapter

internal expect class DriverFactory {
fun createDriver(): SqlDriver
Expand All @@ -16,6 +17,10 @@ internal fun createDatabase(driverFactory: DriverFactory): Database {
participantsAdapter = Participants.Adapter(
statusAdapter = EnumColumnAdapter(),
),
schedulesAdapter = Schedules.Adapter(
scheduled_atAdapter = InstantLongColumnAdapter,
met_atAdapter = InstantLongColumnAdapter,
),
)

// Do more work with the database (see below).
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package club.nito.core.database.adapter

import app.cash.sqldelight.ColumnAdapter
import kotlinx.datetime.Instant

internal object InstantLongColumnAdapter : ColumnAdapter<Instant, Long> {
override fun decode(databaseValue: Long): Instant = Instant.fromEpochMilliseconds(databaseValue)
override fun encode(value: Instant): Long = value.toEpochMilliseconds()
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,18 @@ package club.nito.core.database.di

import club.nito.core.database.DriverFactory
import club.nito.core.database.createDatabase
import club.nito.core.database.participant.ParticipantDao
import club.nito.core.database.participant.SqlDelightParticipantDao
import club.nito.core.database.place.PlaceDao
import club.nito.core.database.place.SqlDelightPlaceDao
import club.nito.core.database.profile.ProfileDao
import club.nito.core.database.profile.SqlDelightProfileDao
import club.nito.core.database.schedule.ScheduleDao
import club.nito.core.database.schedule.SqlDelightScheduleDao
import org.koin.core.module.Module
import org.koin.core.module.dsl.singleOf
import org.koin.core.scope.Scope
import org.koin.dsl.bind
import org.koin.dsl.module

public val databaseModule: Module = module {
Expand All @@ -12,6 +22,11 @@ public val databaseModule: Module = module {
driverFactory = createDriverFactory(),
)
}

singleOf(::SqlDelightParticipantDao) bind ParticipantDao::class
singleOf(::SqlDelightPlaceDao) bind PlaceDao::class
singleOf(::SqlDelightProfileDao) bind ProfileDao::class
singleOf(::SqlDelightScheduleDao) bind ScheduleDao::class
}

internal expect fun Scope.createDriverFactory(): DriverFactory
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package club.nito.core.database.participant

import club.nito.core.model.participant.Participant
import club.nito.core.model.participant.ParticipantStatus
import club.nito.core.model.participant.ParticipantUser
import kotlinx.coroutines.flow.Flow

public interface ParticipantDao {
/**
* 該当の予定の参加情報のストリームを取得する
*
* @param scheduleId 参加情報を取得するスケジュールID
*/
public fun participantUsersStream(scheduleId: String): Flow<List<ParticipantUser>>

/**
* 該当の予定の参加情報のストリームを取得する
*
* @param scheduleId 参加情報を取得するスケジュールID
*/
public fun participantStatusStream(scheduleId: String, userId: String): Flow<ParticipantStatus>
Comment on lines +16 to +21
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

メソッド participantUsersStreamparticipantStatusStream のコメントが同じですが、これらのメソッドが異なる機能を提供していることを考慮すると、コメントを区別することをお勧めします。例えば、participantStatusStream のコメントにはユーザーIDに関する情報を追加することができます。


/**
* 参加者を登録 / 更新する
*/
public fun upsert(entities: List<Participant>)

/**
* 参加者を登録 / 更新する
*/
public fun upsert(entity: Participant)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package club.nito.core.database.participant

import app.cash.sqldelight.coroutines.asFlow
import app.cash.sqldelight.coroutines.mapToList
import app.cash.sqldelight.coroutines.mapToOneOrNull
import club.nito.core.common.NitoCoroutineDispatchers
import club.nito.core.database.Database
import club.nito.core.database.ParticipantUsersByScheduleId
import club.nito.core.database.participant.model.toModel
import club.nito.core.model.participant.Participant
import club.nito.core.model.participant.ParticipantStatus
import club.nito.core.model.participant.ParticipantUser
import club.nito.core.model.schedule.ScheduleId
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map

internal class SqlDelightParticipantDao(
private val database: Database,
private val dispatchers: NitoCoroutineDispatchers,
) : ParticipantDao {
override fun participantUsersStream(scheduleId: ScheduleId): Flow<List<ParticipantUser>> {
return database.participantsQueries.participantUsersByScheduleId(scheduleId)
.asFlow()
.mapToList(dispatchers.io)
.map {
it.map(ParticipantUsersByScheduleId::toModel)
}
}

override fun participantStatusStream(scheduleId: String, userId: String): Flow<ParticipantStatus> = database
.participantsQueries
.participantStatusByUserId(
schedule_id = scheduleId,
user_id = userId,
)
.asFlow()
.mapToOneOrNull(dispatchers.io)
.map {
it ?: ParticipantStatus.NONE
}

override fun upsert(entities: List<Participant>) {
database.transaction {
for (entity in entities) {
upsertParticipant(entity)
}
}
}

override fun upsert(entity: Participant) {
database.transaction {
upsertParticipant(entity)
}
}

private fun upsertParticipant(entity: Participant) {
database.participantsQueries.upsert(
schedule_id = entity.scheduleId,
user_id = entity.userId,
status = entity.status,
)
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package club.nito.core.database.adapter
package club.nito.core.database.participant.adapter

import app.cash.sqldelight.ColumnAdapter
import club.nito.core.model.participant.ParticipantStatus
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package club.nito.core.database.participant.model

import club.nito.core.model.UserProfile
import club.nito.core.model.participant.Participant
import club.nito.core.model.participant.ParticipantUser
import club.nito.core.database.ParticipantUsersByScheduleId as LocalParticipantUser
import club.nito.core.database.Participants as LocalParticipant

internal fun LocalParticipant.toModel(): Participant = Participant(
scheduleId = schedule_id,
userId = user_id,
status = status,
)

internal fun LocalParticipantUser.toModel(): ParticipantUser = ParticipantUser(
profile = UserProfile(
id = id,
username = username,
displayName = display_name,
avatarUrl = avatar_url,
website = website,
),
status = status,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package club.nito.core.database.place

import club.nito.core.model.place.Place
import kotlinx.coroutines.flow.Flow

public interface PlaceDao {
/**
* 場所一覧のストリームを取得する
*/
public val placesStream: Flow<List<Place>>

/**
* 場所のストリームを取得する
*
* @param placeId 取得する場所の ID
*/
public fun placeStream(placeId: String): Flow<Place?>

/**
* 場所一覧のストリームを取得する
*
* @param placeIds 取得する場所の ID 配列
*/
public fun placesStream(placeIds: List<String>): Flow<List<Place>>

/**
* スケジュール一覧を登録 / 更新する
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

upsert メソッドのコメントに「スケジュール」と記載されていますが、これは「場所」の操作を行うメソッドであるため、「場所」に修正する必要があります。これはドキュメントの誤りであり、混乱を招く可能性があります。

-     * スケジュール一覧を登録 / 更新する
+     * 場所一覧を登録 / 更新する
-     * スケジュールを登録 / 更新する
+     * 場所を登録 / 更新する

Also applies to: 32-32

*/
public fun upsert(entities: List<Place>)

/**
* スケジュールを登録 / 更新する
*/
public fun upsert(entity: Place)
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

インターフェース PlaceDao の実装は、場所に関連するデータアクセスのためのメソッドを提供しています。これには、場所のストリームを取得するメソッドや、場所を登録/更新するメソッドが含まれています。コードは明確で、ドキュメントコメントも適切に提供されています。ただし、upsert メソッドのコメントには「スケジュール」という言葉が使われていますが、これは「場所」の間違いではないでしょうか。これは、コードの意図とドキュメントの整合性を保つために重要です。

Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package club.nito.core.database.place

import app.cash.sqldelight.coroutines.asFlow
import app.cash.sqldelight.coroutines.mapToList
import app.cash.sqldelight.coroutines.mapToOneOrNull
import club.nito.core.common.NitoCoroutineDispatchers
import club.nito.core.database.Database
import club.nito.core.database.Places
import club.nito.core.database.place.model.toModel
import club.nito.core.model.place.Place
import club.nito.core.model.schedule.ScheduleId
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map

internal class SqlDelightPlaceDao(
private val database: Database,
private val dispatchers: NitoCoroutineDispatchers,
) : PlaceDao {
override val placesStream: Flow<List<Place>>
get() = database.placesQueries.places()
.asFlow()
.mapToList(dispatchers.io)
.map {
it.map(Places::toModel)
}

override fun placeStream(placeId: ScheduleId): Flow<Place?> {
return database.placesQueries.placeById(placeId)
.asFlow()
.mapToOneOrNull(dispatchers.io)
.map {
it?.toModel()
}
}

override fun placesStream(placeIds: List<String>): Flow<List<Place>> {
return database.placesQueries.placesByIds(placeIds)
.asFlow()
.mapToList(dispatchers.io)
.map {
it.map(Places::toModel)
}
}

override fun upsert(entities: List<Place>) {
database.transaction {
for (entity in entities) {
upsertUserProfile(entity)
}
}
}

override fun upsert(entity: Place) {
database.transaction {
upsertUserProfile(entity)
}
}

private fun upsertUserProfile(entity: Place) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

メソッド名 upsertUserProfilePlace エンティティを扱っているにも関わらず、UserProfile という名前になっています。これはおそらくコピペのミスか見落としでしょう。エンティティに合わせて名前を変更することをお勧めします。

- private fun upsertUserProfile(entity: Place) {
+ private fun upsertPlace(entity: Place) {

Committable suggestion

IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
private fun upsertUserProfile(entity: Place) {
private fun upsertPlace(entity: Place) {

database.placesQueries.upsert(
id = entity.id,
name = entity.name,
url = entity.url,
description = entity.description,
map_url = entity.mapUrl,
image_url = entity.imageUrl,
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package club.nito.core.database.place.model

import club.nito.core.model.place.Place
import club.nito.core.database.Places as LocalPlace

internal fun LocalPlace.toModel(): Place = Place(
id = id,
name = name,
url = url,
description = description,
mapUrl = map_url,
imageUrl = image_url,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package club.nito.core.database.profile

import club.nito.core.model.UserProfile
import kotlinx.coroutines.flow.Flow

public interface ProfileDao {
/**
* ユーザー情報のストリームを取得する
*
* @param userId 取得するユーザーの ID
*/
public fun profileStream(userId: String): Flow<UserProfile?>

/**
* ユーザー情報のストリームを取得する
*
* @param userIds 取得するユーザーの ID 配列
*/
public fun profilesStream(userIds: List<String>): Flow<List<UserProfile>>

/**
* ユーザー一覧を登録 / 更新する
*/
public fun upsert(entities: List<UserProfile>)

/**
* ユーザーを登録 / 更新する
*/
public fun upsert(entity: UserProfile)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package club.nito.core.database.profile

import app.cash.sqldelight.coroutines.asFlow
import app.cash.sqldelight.coroutines.mapToList
import app.cash.sqldelight.coroutines.mapToOneOrNull
import club.nito.core.common.NitoCoroutineDispatchers
import club.nito.core.database.Database
import club.nito.core.database.Profiles
import club.nito.core.database.profile.model.toModel
import club.nito.core.model.UserProfile
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map

internal class SqlDelightProfileDao(
private val database: Database,
private val dispatchers: NitoCoroutineDispatchers,
) : ProfileDao {
override fun profileStream(userId: String): Flow<UserProfile?> {
return database.profilesQueries.profileById(userId)
.asFlow()
.mapToOneOrNull(dispatchers.io)
.map {
it?.toModel()
}
}

override fun profilesStream(userIds: List<String>): Flow<List<UserProfile>> {
return database.profilesQueries.profileByIds(userIds)
.asFlow()
.mapToList(dispatchers.io)
.map {
it.map(Profiles::toModel)
}
}

override fun upsert(entities: List<UserProfile>) {
database.transaction {
for (entity in entities) {
upsertUserProfile(entity)
}
}
}

override fun upsert(entity: UserProfile) {
database.transaction {
upsertUserProfile(entity)
}
}

private fun upsertUserProfile(entity: UserProfile) {
database.profilesQueries.upsert(
id = entity.id,
username = entity.username,
display_name = entity.displayName,
avatar_url = entity.avatarUrl,
website = entity.website,
)
}
}
Loading