Migration done for the backend
This commit is contained in:
parent
52aae6773f
commit
69ede50a59
@ -5,9 +5,9 @@ drop table if exists Notes;
|
|||||||
|
|
||||||
CREATE TABLE `Notes`
|
CREATE TABLE `Notes`
|
||||||
(
|
(
|
||||||
`uuid` binary(16) PRIMARY KEY,
|
`uuid` binary(16) PRIMARY KEY,
|
||||||
`title` varchar(50) NOT NULL,
|
`title` varchar(50) NOT NULL,
|
||||||
`user_id` int NOT NULL,
|
`user_id` int NOT NULL,
|
||||||
`updated_at` datetime
|
`updated_at` datetime
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -27,9 +27,10 @@ ALTER TABLE `Tags`
|
|||||||
CREATE TABLE `Chapters`
|
CREATE TABLE `Chapters`
|
||||||
(
|
(
|
||||||
`id` int PRIMARY KEY AUTO_INCREMENT,
|
`id` int PRIMARY KEY AUTO_INCREMENT,
|
||||||
`number` int NOT NULL,
|
`number` int NOT NULL,
|
||||||
`content` text NOT NULL,
|
`title` varchar(50) NOT NULL,
|
||||||
`note_uuid` binary(16) NOT NULL
|
`content` text NOT NULL,
|
||||||
|
`note_uuid` binary(16) NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
ALTER TABLE `Chapters`
|
ALTER TABLE `Chapters`
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
<pattern>%d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
<pattern>%d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||||
</encoder>
|
</encoder>
|
||||||
</appender>
|
</appender>
|
||||||
<root level="INFO">
|
<root level="TRACE">
|
||||||
<appender-ref ref="STDOUT"/>
|
<appender-ref ref="STDOUT"/>
|
||||||
</root>
|
</root>
|
||||||
<logger name="org.eclipse.jetty" level="INFO"/>
|
<logger name="org.eclipse.jetty" level="INFO"/>
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
package be.vandewalleh.extensions
|
package be.vandewalleh.extensions
|
||||||
|
|
||||||
import be.vandewalleh.kodein
|
import be.vandewalleh.kodein
|
||||||
import be.vandewalleh.services.FullNoteDTOPatch
|
import be.vandewalleh.services.FullNoteCreateDTO
|
||||||
|
import be.vandewalleh.services.FullNotePatchDTO
|
||||||
import be.vandewalleh.services.UserService
|
import be.vandewalleh.services.UserService
|
||||||
import io.ktor.application.*
|
import io.ktor.application.*
|
||||||
import io.ktor.auth.*
|
import io.ktor.auth.*
|
||||||
@ -26,6 +27,6 @@ fun ApplicationCall.userId(): Int {
|
|||||||
|
|
||||||
class NoteCreate(val title: String, val tags: List<String>)
|
class NoteCreate(val title: String, val tags: List<String>)
|
||||||
|
|
||||||
suspend fun ApplicationCall.receiveNoteCreate(): NoteCreate = receive()
|
suspend fun ApplicationCall.receiveNoteCreate(): FullNoteCreateDTO = receive()
|
||||||
|
|
||||||
suspend fun ApplicationCall.receiveNotePatch() : FullNoteDTOPatch = receive()
|
suspend fun ApplicationCall.receiveNotePatch() : FullNotePatchDTO = receive()
|
||||||
@ -1,8 +1,6 @@
|
|||||||
package be.vandewalleh.routing
|
package be.vandewalleh.routing
|
||||||
|
|
||||||
import be.vandewalleh.extensions.noteTitle
|
|
||||||
import be.vandewalleh.extensions.receiveNoteCreate
|
import be.vandewalleh.extensions.receiveNoteCreate
|
||||||
import be.vandewalleh.extensions.respondStatus
|
|
||||||
import be.vandewalleh.extensions.userId
|
import be.vandewalleh.extensions.userId
|
||||||
import be.vandewalleh.services.NotesService
|
import be.vandewalleh.services.NotesService
|
||||||
import io.ktor.application.*
|
import io.ktor.application.*
|
||||||
@ -25,16 +23,9 @@ fun Routing.notes(kodein: Kodein) {
|
|||||||
|
|
||||||
post("/notes") {
|
post("/notes") {
|
||||||
val userId = call.userId()
|
val userId = call.userId()
|
||||||
val noteUuid = call.parameters.noteTitle()
|
|
||||||
val note = call.receiveNoteCreate()
|
val note = call.receiveNoteCreate()
|
||||||
val exists = notesService.noteExistsWithTitle(userId, note.title)
|
val uuid = notesService.createNote(userId, note)
|
||||||
|
call.respond(HttpStatusCode.Created, mapOf("uuid" to uuid))
|
||||||
if (exists) {
|
|
||||||
return@post call.respondStatus(HttpStatusCode.Conflict)
|
|
||||||
}
|
|
||||||
|
|
||||||
notesService.createNote(userId, note.title, note.tags)
|
|
||||||
call.respondStatus(HttpStatusCode.Created)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,7 +23,7 @@ fun Routing.title(kodein: Kodein) {
|
|||||||
val noteUuid = call.parameters.noteUuid()
|
val noteUuid = call.parameters.noteUuid()
|
||||||
|
|
||||||
val exists = notesService.noteExists(userId, noteUuid)
|
val exists = notesService.noteExists(userId, noteUuid)
|
||||||
if (exists) return@get call.respondStatus(HttpStatusCode.NotFound)
|
if (!exists) return@get call.respondStatus(HttpStatusCode.NotFound)
|
||||||
|
|
||||||
val response = notesService.getNote(noteUuid)
|
val response = notesService.getNote(noteUuid)
|
||||||
call.respond(response)
|
call.respond(response)
|
||||||
|
|||||||
@ -29,7 +29,7 @@ class NotesService(override val kodein: Kodein) : KodeinAware {
|
|||||||
.sortedByDescending { it.updatedAt }
|
.sortedByDescending { it.updatedAt }
|
||||||
.toList()
|
.toList()
|
||||||
|
|
||||||
if(notes.isEmpty()) return emptyList()
|
if (notes.isEmpty()) return emptyList()
|
||||||
|
|
||||||
val tags = db.sequenceOf(Tags)
|
val tags = db.sequenceOf(Tags)
|
||||||
.filterColumns { listOf(it.noteUuid, it.name) }
|
.filterColumns { listOf(it.noteUuid, it.name) }
|
||||||
@ -46,37 +46,54 @@ class NotesService(override val kodein: Kodein) : KodeinAware {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun noteExistsWithTitle(userId: Int, title: String): Boolean {
|
|
||||||
TODO()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun noteExists(userId: Int, uuid: UUID): Boolean {
|
fun noteExists(userId: Int, uuid: UUID): Boolean {
|
||||||
TODO()
|
return db.from(Notes)
|
||||||
|
.select(Notes.uuid)
|
||||||
|
.where { Notes.userId eq userId }
|
||||||
|
.where { Notes.uuid eq uuid }
|
||||||
|
.limit(0, 1)
|
||||||
|
.toList().size == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createNote(userId: Int, title: String, tags: List<String>) {
|
fun createNote(userId: Int, note: FullNoteCreateDTO): UUID {
|
||||||
|
val uuid = UUID.randomUUID()
|
||||||
db.useTransaction {
|
db.useTransaction {
|
||||||
val uuid = UUID.randomUUID()
|
|
||||||
db.insert(Notes) {
|
db.insert(Notes) {
|
||||||
it.uuid to uuid
|
it.uuid to uuid
|
||||||
it.title to title
|
it.title to note.title
|
||||||
it.userId to userId
|
it.userId to userId
|
||||||
it.updatedAt to LocalDateTime.now()
|
it.updatedAt to LocalDateTime.now()
|
||||||
}
|
}
|
||||||
|
|
||||||
db.batchInsert(Tags) {
|
db.batchInsert(Tags) {
|
||||||
tags.forEach { tagName ->
|
note.tags.forEach { tagName ->
|
||||||
item {
|
item {
|
||||||
it.noteUuid to uuid
|
it.noteUuid to uuid
|
||||||
it.name to tagName
|
it.name to tagName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
db.batchInsert(Chapters) {
|
||||||
|
note.chapters.forEachIndexed { index, chapter ->
|
||||||
|
item {
|
||||||
|
it.noteUuid to uuid
|
||||||
|
it.title to chapter.title
|
||||||
|
it.number to index
|
||||||
|
it.content to chapter.content
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
return uuid
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getNote(noteUuid: UUID): FullNoteDTO {
|
fun getNote(noteUuid: UUID): FullNoteDTO {
|
||||||
TODO()
|
val note = db.sequenceOf(Notes)
|
||||||
|
.filterColumns { listOf(it.title, it.updatedAt) }
|
||||||
|
.find { it.uuid eq noteUuid } ?: error("Note not found")
|
||||||
|
|
||||||
val tags = db.from(Tags)
|
val tags = db.from(Tags)
|
||||||
.select(Tags.name)
|
.select(Tags.name)
|
||||||
.where { Tags.noteUuid eq noteUuid }
|
.where { Tags.noteUuid eq noteUuid }
|
||||||
@ -90,10 +107,18 @@ class NotesService(override val kodein: Kodein) : KodeinAware {
|
|||||||
.map { ChapterDTO(it[Chapters.title]!!, it[Chapters.content]!!) }
|
.map { ChapterDTO(it[Chapters.title]!!, it[Chapters.content]!!) }
|
||||||
.toList()
|
.toList()
|
||||||
|
|
||||||
|
val updatedAtFormatted = DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(note.updatedAt)
|
||||||
|
return FullNoteDTO(
|
||||||
|
uuid = noteUuid,
|
||||||
|
title = note.title,
|
||||||
|
updatedAt = updatedAtFormatted,
|
||||||
|
tags = tags,
|
||||||
|
chapters = chapters
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateNote(patch: FullNoteDTOPatch) {
|
fun updateNote(patch: FullNotePatchDTO) {
|
||||||
if(patch.uuid == null) return
|
if (patch.uuid == null) return
|
||||||
db.useTransaction {
|
db.useTransaction {
|
||||||
if (patch.title != null) {
|
if (patch.title != null) {
|
||||||
db.update(Notes) {
|
db.update(Notes) {
|
||||||
@ -134,7 +159,11 @@ class NotesService(override val kodein: Kodein) : KodeinAware {
|
|||||||
.map { it[Tags.name]!! }
|
.map { it[Tags.name]!! }
|
||||||
}
|
}
|
||||||
|
|
||||||
data class ChapterDTO(val title: String, val content: String)
|
data class ChapterDTO(
|
||||||
|
val title: String,
|
||||||
|
val content: String
|
||||||
|
)
|
||||||
|
|
||||||
data class FullNoteDTO(
|
data class FullNoteDTO(
|
||||||
val uuid: UUID,
|
val uuid: UUID,
|
||||||
val title: String,
|
val title: String,
|
||||||
@ -143,7 +172,13 @@ data class FullNoteDTO(
|
|||||||
val chapters: List<ChapterDTO>
|
val chapters: List<ChapterDTO>
|
||||||
)
|
)
|
||||||
|
|
||||||
data class FullNoteDTOPatch(
|
data class FullNoteCreateDTO(
|
||||||
|
val title: String,
|
||||||
|
val tags: List<String>,
|
||||||
|
val chapters: List<ChapterDTO>
|
||||||
|
)
|
||||||
|
|
||||||
|
data class FullNotePatchDTO(
|
||||||
val uuid: UUID? = null,
|
val uuid: UUID? = null,
|
||||||
val title: String? = null,
|
val title: String? = null,
|
||||||
val updatedAt: String? = null,
|
val updatedAt: String? = null,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user