Универсальный сервис для CRUD-запросов в KtorAndroid

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Универсальный сервис для CRUD-запросов в Ktor

Сообщение Anonymous »

Я создал новый проект Ktor, в котором можно найти файл UsersSchema.kt.

Код: Выделить всё

@Serializable
data class ExposedUser(val name: String, val age: Int)

class UserService(database: Database) {
object Users : Table() {
val id = integer("id").autoIncrement()
val name = varchar("name", length = 50)
val age = integer("age")

override val primaryKey = PrimaryKey(id)
}

init {
transaction(database) {
SchemaUtils.create(Users)
}
}

suspend fun create(user: ExposedUser): Int = dbQuery {
Users.insert {
it[name] = user.name
it[age] = user.age
}[Users.id]
}

suspend fun read(id: Int): ExposedUser? {
return dbQuery {
Users.selectAll()
.where { Users.id eq id }
.map { ExposedUser(it[Users.name], it[Users.age]) }
.singleOrNull()
}
}

suspend fun update(id: Int, user: ExposedUser) {
dbQuery {
Users.update({ Users.id eq id }) {
it[name] = user.name
it[age] = user.age
}
}
}

suspend fun delete(id: Int) {
dbQuery {
Users.deleteWhere { Users.id.eq(id) }
}
}

private suspend fun  dbQuery(block: suspend () -> T): T =
newSuspendedTransaction(Dispatchers.IO) { block() }
}
На основе этого примера я создал файл CategorySchema.kt.

Код: Выделить всё

@Serializable
data class Category(
val id: String,
val name: String,
val image: String?,
val slug: String,
)

class CategoryService(database: Database) {
object CategoryTable: Table("\"Category\"") {
val id = varchar("id", 36).uniqueIndex()
val name = varchar("name", 50).uniqueIndex()
val image = text("image").nullable()
val slug = varchar("slug", 50).uniqueIndex()
val createdAt = datetime("createdAt")
val updatedAt = datetime("updatedAt")

override val primaryKey = PrimaryKey(id)
}

init {
transaction(database) {
SchemaUtils.create(CategoryTable)
addLogger(StdOutSqlLogger)
}
}

suspend fun getAll(): List {
try {
return dbQuery {
CategoryTable.selectAll().map {
Category(
it[CategoryTable.id],
it[CategoryTable.name],
it[CategoryTable.image],
it[CategoryTable.slug]
)
}
}
} catch (e: Exception) {
exposedLogger.error("Aucune catégorie existante")
return emptyList()
}
}

suspend fun getOne(id: String): Category? {
try {
return dbQuery {
CategoryTable
.selectAll()
.where { CategoryTable.id eq id }
.map {
Category(
it[CategoryTable.id],
it[CategoryTable.name],
it[CategoryTable.image],
it[CategoryTable.slug]
)
}
.singleOrNull()
}
} catch (e: Exception) {
exposedLogger.error("La catégorie recherchée n'existe pas")
return null
}
}

private suspend fun  dbQuery(block: suspend () -> T): T =
newSuspendedTransaction(Dispatchers.IO) { block() }
}
Затем я понял, что многие из моих таблиц имеют схожие методы, и, поскольку не хотелось повторяться, я решил создать класс BaseService.

Код: Выделить всё

abstract class BaseService(
private val table: ExposedTable,
private val mapper: (ResultRow) -> Entity
) {
suspend fun getAll(): List  {
try {
return dbQuery {
table.selectAll().map(mapper)
}
} catch (e: Exception) {
exposedLogger.error("Erreur lors de la récupération des éléments issus de ${table.tableName}")
return emptyList()
}
}

private suspend fun  dbQuery(block: suspend () -> T): T =
newSuspendedTransaction(Dispatchers.IO) { block() }
}
Однако я не знаю, как мне написать метод getOne().
Что я сделал пробовал:

Код: Выделить всё

suspend fun getOne(id: String): Entity? {
try {
return dbQuery {
table
.selectAll()
.where { table.primaryKey eq id }
.map(mapper)
.singleOrNull()
}
} catch (e: Exception) {
exposedLogger.error("Erreur lors de la récupération de l'élément issu de ${table.tableName}")
return null
}
}
Ошибка:

Несоответствие типов. Требуется: Операция Найдено: Единица

Что я хочу сделать:
Я хотел бы создать API только с методами GET и POST. Я должен иметь возможность получать данные из всех моих таблиц и обновлять некоторые из них. Поскольку методы GET всегда работают одинаково, я хотел создать универсальный сервис с двумя методами getAll() и getOne(). Благодаря этому я мог передавать им параметры и использовать их во всех своих сервисах.

Подробнее здесь: https://stackoverflow.com/questions/792 ... ts-in-ktor
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»