Skip to content

Commit 94800e8

Browse files
jpicklykclaude
andcommitted
refactor: extract shared repository transaction wrapper
Add DatabaseManager.suspendedTransaction() extension function that wraps newSuspendedTransaction + try/catch into a single call. Apply across all 33 suspend repository methods in SQLiteNoteRepository (7), SQLiteRoleTransitionRepository (5), and SQLiteWorkItemRepository (21). Net reduction of ~80 lines of boilerplate. Consolidates the deprecated newSuspendedTransaction call to a single site for future Exposed migration. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent d094da5 commit 94800e8

File tree

4 files changed

+138
-217
lines changed

4 files changed

+138
-217
lines changed

current/src/main/kotlin/io/github/jpicklyk/mcptask/current/infrastructure/repository/SQLiteNoteRepository.kt

Lines changed: 18 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import org.jetbrains.exposed.v1.jdbc.deleteWhere
1414
import org.jetbrains.exposed.v1.jdbc.insert
1515
import org.jetbrains.exposed.v1.jdbc.selectAll
1616
import org.jetbrains.exposed.v1.jdbc.update
17-
import org.jetbrains.exposed.v1.jdbc.transactions.experimental.newSuspendedTransaction
1817
import java.time.Instant
1918
import java.util.UUID
2019

@@ -23,22 +22,19 @@ import java.util.UUID
2322
*/
2423
class SQLiteNoteRepository(private val databaseManager: DatabaseManager) : NoteRepository {
2524

26-
override suspend fun getById(id: UUID): Result<Note> = try {
27-
newSuspendedTransaction(db = databaseManager.getDatabase()) {
25+
override suspend fun getById(id: UUID): Result<Note> =
26+
databaseManager.suspendedTransaction("Failed to get Note by id") {
2827
val row = NotesTable.selectAll().where { NotesTable.id eq id }.singleOrNull()
2928
if (row != null) {
3029
Result.Success(mapRowToNote(row))
3130
} else {
3231
Result.Error(RepositoryError.NotFound(id, "Note not found with id: $id"))
3332
}
3433
}
35-
} catch (e: Exception) {
36-
Result.Error(RepositoryError.DatabaseError("Failed to get Note by id: ${e.message}", e))
37-
}
3834

39-
override suspend fun upsert(note: Note): Result<Note> = try {
40-
note.validate()
41-
newSuspendedTransaction(db = databaseManager.getDatabase()) {
35+
override suspend fun upsert(note: Note): Result<Note> =
36+
databaseManager.suspendedTransaction("Failed to upsert Note") {
37+
note.validate()
4238
// Check if a note with the same (itemId, key) already exists
4339
val existing = NotesTable.selectAll()
4440
.where { (NotesTable.itemId eq note.itemId) and (NotesTable.key eq note.key) }
@@ -69,30 +65,21 @@ class SQLiteNoteRepository(private val databaseManager: DatabaseManager) : NoteR
6965
Result.Success(note)
7066
}
7167
}
72-
} catch (e: Exception) {
73-
Result.Error(RepositoryError.DatabaseError("Failed to upsert Note: ${e.message}", e))
74-
}
7568

76-
override suspend fun delete(id: UUID): Result<Boolean> = try {
77-
newSuspendedTransaction(db = databaseManager.getDatabase()) {
69+
override suspend fun delete(id: UUID): Result<Boolean> =
70+
databaseManager.suspendedTransaction("Failed to delete Note") {
7871
val deletedCount = NotesTable.deleteWhere { NotesTable.id eq id }
7972
Result.Success(deletedCount > 0)
8073
}
81-
} catch (e: Exception) {
82-
Result.Error(RepositoryError.DatabaseError("Failed to delete Note: ${e.message}", e))
83-
}
8474

85-
override suspend fun deleteByItemId(itemId: UUID): Result<Int> = try {
86-
newSuspendedTransaction(db = databaseManager.getDatabase()) {
75+
override suspend fun deleteByItemId(itemId: UUID): Result<Int> =
76+
databaseManager.suspendedTransaction("Failed to delete Notes by itemId") {
8777
val deletedCount = NotesTable.deleteWhere { NotesTable.itemId eq itemId }
8878
Result.Success(deletedCount)
8979
}
90-
} catch (e: Exception) {
91-
Result.Error(RepositoryError.DatabaseError("Failed to delete Notes by itemId: ${e.message}", e))
92-
}
9380

94-
override suspend fun findByItemId(itemId: UUID, role: String?): Result<List<Note>> = try {
95-
newSuspendedTransaction(db = databaseManager.getDatabase()) {
81+
override suspend fun findByItemId(itemId: UUID, role: String?): Result<List<Note>> =
82+
databaseManager.suspendedTransaction("Failed to find Notes by itemId") {
9683
val notes = if (role != null) {
9784
NotesTable.selectAll()
9885
.where { (NotesTable.itemId eq itemId) and (NotesTable.role eq role) }
@@ -102,34 +89,24 @@ class SQLiteNoteRepository(private val databaseManager: DatabaseManager) : NoteR
10289
}.map { mapRowToNote(it) }
10390
Result.Success(notes)
10491
}
105-
} catch (e: Exception) {
106-
Result.Error(RepositoryError.DatabaseError("Failed to find Notes by itemId: ${e.message}", e))
107-
}
10892

10993
override suspend fun findByItemIds(itemIds: Set<UUID>): Result<Map<UUID, List<Note>>> {
11094
if (itemIds.isEmpty()) return Result.Success(emptyMap())
111-
return try {
112-
newSuspendedTransaction(db = databaseManager.getDatabase()) {
113-
val notes = NotesTable.selectAll()
114-
.where { NotesTable.itemId inList itemIds }
115-
.map { mapRowToNote(it) }
116-
Result.Success(notes.groupBy { it.itemId })
117-
}
118-
} catch (e: Exception) {
119-
Result.Error(RepositoryError.DatabaseError("Failed to find Notes by itemIds: ${e.message}", e))
95+
return databaseManager.suspendedTransaction("Failed to find Notes by itemIds") {
96+
val notes = NotesTable.selectAll()
97+
.where { NotesTable.itemId inList itemIds }
98+
.map { mapRowToNote(it) }
99+
Result.Success(notes.groupBy { it.itemId })
120100
}
121101
}
122102

123-
override suspend fun findByItemIdAndKey(itemId: UUID, key: String): Result<Note?> = try {
124-
newSuspendedTransaction(db = databaseManager.getDatabase()) {
103+
override suspend fun findByItemIdAndKey(itemId: UUID, key: String): Result<Note?> =
104+
databaseManager.suspendedTransaction("Failed to find Note by itemId and key") {
125105
val row = NotesTable.selectAll()
126106
.where { (NotesTable.itemId eq itemId) and (NotesTable.key eq key) }
127107
.singleOrNull()
128108
Result.Success(row?.let { mapRowToNote(it) })
129109
}
130-
} catch (e: Exception) {
131-
Result.Error(RepositoryError.DatabaseError("Failed to find Note by itemId and key: ${e.message}", e))
132-
}
133110

134111
private fun mapRowToNote(row: ResultRow): Note {
135112
return Note(

current/src/main/kotlin/io/github/jpicklyk/mcptask/current/infrastructure/repository/SQLiteRoleTransitionRepository.kt

Lines changed: 10 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package io.github.jpicklyk.mcptask.current.infrastructure.repository
22

33
import io.github.jpicklyk.mcptask.current.domain.model.RoleTransition
4-
import io.github.jpicklyk.mcptask.current.domain.repository.RepositoryError
54
import io.github.jpicklyk.mcptask.current.domain.repository.Result
65
import io.github.jpicklyk.mcptask.current.domain.repository.RoleTransitionRepository
76
import io.github.jpicklyk.mcptask.current.infrastructure.database.DatabaseManager
@@ -15,7 +14,6 @@ import org.jetbrains.exposed.v1.jdbc.andWhere
1514
import org.jetbrains.exposed.v1.jdbc.deleteWhere
1615
import org.jetbrains.exposed.v1.jdbc.insert
1716
import org.jetbrains.exposed.v1.jdbc.selectAll
18-
import org.jetbrains.exposed.v1.jdbc.transactions.experimental.newSuspendedTransaction
1917
import java.time.Instant
2018
import java.util.UUID
2119

@@ -24,8 +22,8 @@ import java.util.UUID
2422
*/
2523
class SQLiteRoleTransitionRepository(private val databaseManager: DatabaseManager) : RoleTransitionRepository {
2624

27-
override suspend fun create(transition: RoleTransition): Result<RoleTransition> = try {
28-
newSuspendedTransaction(db = databaseManager.getDatabase()) {
25+
override suspend fun create(transition: RoleTransition): Result<RoleTransition> =
26+
databaseManager.suspendedTransaction("Failed to create RoleTransition") {
2927
RoleTransitionsTable.insert {
3028
it[id] = transition.id
3129
it[itemId] = transition.itemId
@@ -39,30 +37,24 @@ class SQLiteRoleTransitionRepository(private val databaseManager: DatabaseManage
3937
}
4038
Result.Success(transition)
4139
}
42-
} catch (e: Exception) {
43-
Result.Error(RepositoryError.DatabaseError("Failed to create RoleTransition: ${e.message}", e))
44-
}
4540

46-
override suspend fun findByItemId(itemId: UUID, limit: Int): Result<List<RoleTransition>> = try {
47-
newSuspendedTransaction(db = databaseManager.getDatabase()) {
41+
override suspend fun findByItemId(itemId: UUID, limit: Int): Result<List<RoleTransition>> =
42+
databaseManager.suspendedTransaction("Failed to find RoleTransitions by itemId") {
4843
val transitions = RoleTransitionsTable.selectAll()
4944
.where { RoleTransitionsTable.itemId eq itemId }
5045
.orderBy(RoleTransitionsTable.transitionedAt, SortOrder.DESC)
5146
.limit(limit)
5247
.map { mapRowToRoleTransition(it) }
5348
Result.Success(transitions)
5449
}
55-
} catch (e: Exception) {
56-
Result.Error(RepositoryError.DatabaseError("Failed to find RoleTransitions by itemId: ${e.message}", e))
57-
}
5850

5951
override suspend fun findByTimeRange(
6052
startTime: Instant,
6153
endTime: Instant,
6254
role: String?,
6355
limit: Int
64-
): Result<List<RoleTransition>> = try {
65-
newSuspendedTransaction(db = databaseManager.getDatabase()) {
56+
): Result<List<RoleTransition>> =
57+
databaseManager.suspendedTransaction("Failed to find RoleTransitions by time range") {
6658
var query = RoleTransitionsTable.selectAll().where {
6759
(RoleTransitionsTable.transitionedAt greaterEq startTime) and
6860
(RoleTransitionsTable.transitionedAt lessEq endTime)
@@ -80,31 +72,22 @@ class SQLiteRoleTransitionRepository(private val databaseManager: DatabaseManage
8072
.map { mapRowToRoleTransition(it) }
8173
Result.Success(transitions)
8274
}
83-
} catch (e: Exception) {
84-
Result.Error(RepositoryError.DatabaseError("Failed to find RoleTransitions by time range: ${e.message}", e))
85-
}
8675

87-
override suspend fun findSince(since: Instant, limit: Int): Result<List<RoleTransition>> = try {
88-
newSuspendedTransaction(db = databaseManager.getDatabase()) {
76+
override suspend fun findSince(since: Instant, limit: Int): Result<List<RoleTransition>> =
77+
databaseManager.suspendedTransaction("Failed to find transitions since $since") {
8978
val results = RoleTransitionsTable.selectAll()
9079
.where { RoleTransitionsTable.transitionedAt greaterEq since }
9180
.orderBy(RoleTransitionsTable.transitionedAt, SortOrder.DESC)
9281
.limit(limit)
9382
.map { mapRowToRoleTransition(it) }
9483
Result.Success(results)
9584
}
96-
} catch (e: Exception) {
97-
Result.Error(RepositoryError.DatabaseError("Failed to find transitions since $since: ${e.message}", e))
98-
}
9985

100-
override suspend fun deleteByItemId(itemId: UUID): Result<Int> = try {
101-
newSuspendedTransaction(db = databaseManager.getDatabase()) {
86+
override suspend fun deleteByItemId(itemId: UUID): Result<Int> =
87+
databaseManager.suspendedTransaction("Failed to delete RoleTransitions by itemId") {
10288
val deletedCount = RoleTransitionsTable.deleteWhere { RoleTransitionsTable.itemId eq itemId }
10389
Result.Success(deletedCount)
10490
}
105-
} catch (e: Exception) {
106-
Result.Error(RepositoryError.DatabaseError("Failed to delete RoleTransitions by itemId: ${e.message}", e))
107-
}
10891

10992
private fun mapRowToRoleTransition(row: ResultRow): RoleTransition {
11093
return RoleTransition(

0 commit comments

Comments
 (0)