Persistance: Note can now be put in the trash

This commit is contained in:
2020-08-17 18:51:33 +02:00
parent 4e2fe463e0
commit 15de81394c
8 changed files with 120 additions and 34 deletions
@@ -4,8 +4,7 @@ import be.simplenotes.domain.model.Note
import be.simplenotes.domain.model.PersistedNote
import be.simplenotes.domain.model.PersistedNoteMetadata
import be.simplenotes.domain.usecases.repositories.NoteRepository
import be.simplenotes.persistance.extensions.uuidBinary
import me.liuwj.ktorm.database.*
import me.liuwj.ktorm.database.Database
import me.liuwj.ktorm.dsl.*
import me.liuwj.ktorm.entity.*
import java.time.LocalDateTime
@@ -15,7 +14,13 @@ import kotlin.collections.HashMap
internal class NoteRepositoryImpl(private val db: Database) : NoteRepository {
@Throws(IllegalArgumentException::class)
override fun findAll(userId: Int, limit: Int, offset: Int, tag: String?): List<PersistedNoteMetadata> {
override fun findAll(
userId: Int,
limit: Int,
offset: Int,
tag: String?,
deleted: Boolean
): List<PersistedNoteMetadata> {
require(limit > 0) { "limit should be positive" }
require(offset >= 0) { "offset should not be negative" }
@@ -23,13 +28,13 @@ internal class NoteRepositoryImpl(private val db: Database) : NoteRepository {
db.from(Tags)
.leftJoin(Notes, on = Notes.uuid eq Tags.noteUuid)
.select(Notes.uuid)
.where { (Notes.userId eq userId) and (Tags.name eq tag) }
.where { (Notes.userId eq userId) and (Tags.name eq tag) and (Notes.deleted eq deleted) }
.map { it[Notes.uuid]!! }
} else null
var query = db.notes
.filterColumns { listOf(it.uuid, it.title, it.updatedAt) }
.filter { it.userId eq userId }
.filter { (it.userId eq userId) and (it.deleted eq deleted) }
if (uuids1 != null) query = query.filter { it.uuid inList uuids1 }
@@ -55,7 +60,7 @@ internal class NoteRepositoryImpl(private val db: Database) : NoteRepository {
}
override fun exists(userId: Int, uuid: UUID): Boolean {
return db.notes.any { (it.userId eq userId) and (it.uuid eq uuid) }
return db.notes.any { (it.userId eq userId) and (it.uuid eq uuid) and (it.deleted eq false) }
}
override fun create(userId: Int, note: Note): PersistedNote {
@@ -78,17 +83,17 @@ internal class NoteRepositoryImpl(private val db: Database) : NoteRepository {
return entity.toPersistedNote(note.meta.tags)
}
@Suppress("UNCHECKED_CAST")
override fun find(userId: Int, uuid: UUID): PersistedNote? {
val note = db.notes
.filterColumns { it.columns - it.userId }
.filter { it.uuid eq uuid }
.find { it.userId eq userId }
.find { (it.userId eq userId) and (it.deleted eq false) }
?: return null
val tags = db.tags
.filter { it.noteUuid eq uuid }
.mapColumns { it.name } as List<String>
val tags = db.from(Tags)
.select(Tags.name)
.where { Tags.noteUuid eq uuid }
.map { it[Tags.name]!! }
return note.toPersistedNote(tags)
}
@@ -96,7 +101,7 @@ internal class NoteRepositoryImpl(private val db: Database) : NoteRepository {
override fun update(userId: Int, uuid: UUID, note: Note): PersistedNote? {
db.useTransaction {
val currentNote = db.notes
.find { it.uuid eq uuid and (it.userId eq userId) }
.find { (it.uuid eq uuid) and (it.userId eq userId) and (it.deleted eq false) }
?: return null
currentNote.title = note.meta.title
@@ -121,20 +126,45 @@ internal class NoteRepositoryImpl(private val db: Database) : NoteRepository {
}
}
override fun delete(userId: Int, uuid: UUID): Boolean = db.useTransaction {
db.delete(Notes) { it.uuid eq uuid and (it.userId eq userId) } == 1
override fun delete(userId: Int, uuid: UUID, permanent: Boolean): Boolean {
if (!permanent) {
return db.useTransaction {
db.update(Notes) {
it.deleted to true
it.updatedAt to LocalDateTime.now()
where { it.userId eq userId and (it.uuid eq uuid) }
}
} == 1
}
return db.useTransaction {
db.delete(Notes) { it.uuid eq uuid and (it.userId eq userId) } == 1
}
}
@Suppress("UNCHECKED_CAST")
override fun getTags(userId: Int): List<String> {
return db.sequenceOf(Tags)
.filter { it.note.userId eq userId }
.mapColumns(isDistinct = true) { it.name } as List<String>
override fun restore(userId: Int, uuid: UUID): Boolean {
return db.useTransaction {
db.update(Notes) {
it.deleted to false
where {
(it.userId eq userId) and (it.uuid eq uuid)
}
} == 1
}
}
override fun count(userId: Int, tag: String?): Int {
if (tag == null) return db.notes.count { it.userId eq userId }
return db.sequenceOf(Tags)
.count { it.name eq tag and (it.note.userId eq userId) }
override fun getTags(userId: Int): List<String> =
db.from(Tags)
.leftJoin(Notes, on = Notes.uuid eq Tags.noteUuid)
.selectDistinct(Tags.name)
.where { (Notes.userId eq userId) and (Notes.deleted eq false) }
.map { it[Tags.name]!! }
override fun count(userId: Int, tag: String?, deleted: Boolean): Int {
if (tag == null) return db.notes.count { (it.userId eq userId) and (Notes.deleted eq deleted) }
return db.sequenceOf(Tags).count {
(it.name eq tag) and (it.note.userId eq userId) and (Notes.deleted eq deleted)
}
}
}
@@ -24,6 +24,7 @@ internal open class Notes(alias: String?) : Table<NoteEntity>("Notes", alias) {
val html = text("html").bindTo { it.html }
val userId = int("user_id").references(Users) { it.user }
val updatedAt = datetime("updated_at").bindTo { it.updatedAt }
val deleted = boolean("deleted").bindTo { it.deleted }
val user get() = userId.referenceTable as Users
}
@@ -37,6 +38,7 @@ internal interface NoteEntity : Entity<NoteEntity> {
var markdown: String
var html: String
var updatedAt: LocalDateTime
var deleted: Boolean
var user: UserEntity
}
@@ -52,6 +54,7 @@ internal fun Note.toEntity(uuid: UUID, userId: Int): NoteEntity {
this.markdown = note.markdown
this.html = note.html
this.uuid = uuid
this.deleted = false
this.user["id"] = userId
}
}
@@ -0,0 +1,2 @@
alter table Notes
add column deleted bool not null default false
@@ -0,0 +1,2 @@
alter table Notes
add column deleted bool not null default false