Last active
March 17, 2024 17:56
-
-
Save paulschuetz/a1f0d63d01a5435b2118941c35838f3d to your computer and use it in GitHub Desktop.
Exposed 0.30.2 CrudRepository Proposal
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
abstract class CrudRepository <ID, DOMAIN, TABLE : Table> { | |
abstract val table: TABLE | |
abstract fun toDomain(row: ResultRow): DOMAIN | |
abstract fun toRow(domain: DOMAIN): TABLE.(InsertStatement<Number>) -> Unit | |
abstract fun match(id: ID): SqlExpressionBuilder.() -> Op<Boolean> | |
abstract fun extractId(domain: DOMAIN): ID | |
abstract fun updateRow(domain: DOMAIN): TABLE.(UpdateStatement) -> Unit | |
/** | |
* Get a particular record by its ID. | |
* | |
* @param id The ID of the record to retrieve. | |
* @return The domain object which corresponds to the specified ID if operation was successful or null otherwise. | |
*/ | |
fun get(id: ID): DOMAIN? = transaction { | |
table.select(where = match(id)).singleOrNull()?.let { toDomain(it) } | |
} | |
/** | |
* Simply retrieves all records. | |
*/ | |
fun getAll(): List<DOMAIN> = transaction { | |
table.selectAll().map { toDomain(it) } | |
} | |
/** | |
* Creates a new record. | |
* | |
* @param domain The object to be created in its domain form. | |
* @return The newly created record if operation was successful or null otherwise. | |
*/ | |
fun create(domain: DOMAIN): DOMAIN? = transaction { | |
table.insert(toRow(domain)).let { | |
it.resultedValues?.singleOrNull()?.let { toDomain(it) } | |
} | |
} | |
/** | |
* Updates an existing record. | |
* | |
* @param domain The domain object which will be updated. | |
* @return The freshly updated domain object if operation was successful or null otherwise. | |
*/ | |
fun update(domain: DOMAIN): DOMAIN? = transaction { | |
table.update(where = match(extractId(domain)), body = updateRow(domain)) | |
.let { | |
if(it == 0) null else get(extractId(domain)) | |
} | |
} | |
/** | |
* Deletes the single record which corresponds to the specified ID. | |
* | |
* @param id The ID of the record to be deleted. | |
* @return The ID of the deleted record if operation was successful or null otherwise. | |
*/ | |
fun delete(id: ID): ID? = transaction { | |
table.deleteWhere(op = match(id)).let { | |
if(it == 0) null else id | |
} | |
} | |
} | |
// Our Domain Object | |
data class Person( | |
val identityId: UUID, | |
val userName: String, | |
val givenName: String, | |
val familyName: String, | |
val email: String | |
) | |
// Our Table Definition | |
object Persons : Table("persons") { | |
val identityId = varchar("identityId", 36) | |
val userName = varchar("userName", 64) | |
val givenName = varchar("givenName", 64) | |
val familyName = varchar("familyName", 64) | |
val email = varchar("email", 64) | |
override val primaryKey = PrimaryKey(identityId) | |
} | |
// Exemplaratory CrudRepositry for managing Persons :-) | |
object PersonRepository : CrudRepository<UUID, Person, Persons>() { | |
override val table = Persons | |
override fun toDomain(row: ResultRow): Person { | |
return Person( | |
identityId = UUID.fromString(row[Persons.identityId]), | |
userName = row[Persons.userName], | |
givenName = row[Persons.givenName], | |
familyName = row[Persons.familyName], | |
email = row[Persons.email] | |
) | |
} | |
override fun toRow(domain: Person): Persons.(InsertStatement<Number>) -> Unit = { | |
it[identityId] = domain.identityId.toString() | |
it[userName] = domain.userName | |
it[givenName] = domain.givenName | |
it[familyName] = domain.familyName | |
it[email] = domain.email | |
} | |
override fun updateRow(domain: Person): Persons.(UpdateStatement) -> Unit = { | |
it[userName] = domain.userName | |
it[givenName] = domain.givenName | |
it[familyName] = domain.familyName | |
it[email] = domain.email | |
} | |
override fun match(id: UUID): SqlExpressionBuilder.() -> Op<Boolean> = { | |
Persons.identityId eq id.toString() | |
} | |
override fun extractId(domain: Person): UUID = domain.identityId | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
really helpful, thank you