diff --git a/api/resources/db/migration/V8__Notes_uuid.sql b/api/resources/db/migration/V8__Notes_uuid.sql
index ef36e39..f944b38 100644
--- a/api/resources/db/migration/V8__Notes_uuid.sql
+++ b/api/resources/db/migration/V8__Notes_uuid.sql
@@ -5,9 +5,9 @@ drop table if exists Notes;
CREATE TABLE `Notes`
(
- `uuid` binary(16) PRIMARY KEY,
- `title` varchar(50) NOT NULL,
- `user_id` int NOT NULL,
+ `uuid` binary(16) PRIMARY KEY,
+ `title` varchar(50) NOT NULL,
+ `user_id` int NOT NULL,
`updated_at` datetime
);
@@ -27,9 +27,10 @@ ALTER TABLE `Tags`
CREATE TABLE `Chapters`
(
`id` int PRIMARY KEY AUTO_INCREMENT,
- `number` int NOT NULL,
- `content` text NOT NULL,
- `note_uuid` binary(16) NOT NULL
+ `number` int NOT NULL,
+ `title` varchar(50) NOT NULL,
+ `content` text NOT NULL,
+ `note_uuid` binary(16) NOT NULL
);
ALTER TABLE `Chapters`
diff --git a/api/resources/logback.xml b/api/resources/logback.xml
index e573f7d..c19e387 100644
--- a/api/resources/logback.xml
+++ b/api/resources/logback.xml
@@ -4,7 +4,7 @@
%d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
-
+
diff --git a/api/src/extensions/ApplicationCallExtensions.kt b/api/src/extensions/ApplicationCallExtensions.kt
index a09a900..a8a3f3b 100644
--- a/api/src/extensions/ApplicationCallExtensions.kt
+++ b/api/src/extensions/ApplicationCallExtensions.kt
@@ -1,7 +1,8 @@
package be.vandewalleh.extensions
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 io.ktor.application.*
import io.ktor.auth.*
@@ -26,6 +27,6 @@ fun ApplicationCall.userId(): Int {
class NoteCreate(val title: String, val tags: List)
-suspend fun ApplicationCall.receiveNoteCreate(): NoteCreate = receive()
+suspend fun ApplicationCall.receiveNoteCreate(): FullNoteCreateDTO = receive()
-suspend fun ApplicationCall.receiveNotePatch() : FullNoteDTOPatch = receive()
\ No newline at end of file
+suspend fun ApplicationCall.receiveNotePatch() : FullNotePatchDTO = receive()
\ No newline at end of file
diff --git a/api/src/routing/NotesController.kt b/api/src/routing/NotesController.kt
index e5fc693..00ec6a5 100644
--- a/api/src/routing/NotesController.kt
+++ b/api/src/routing/NotesController.kt
@@ -1,8 +1,6 @@
package be.vandewalleh.routing
-import be.vandewalleh.extensions.noteTitle
import be.vandewalleh.extensions.receiveNoteCreate
-import be.vandewalleh.extensions.respondStatus
import be.vandewalleh.extensions.userId
import be.vandewalleh.services.NotesService
import io.ktor.application.*
@@ -25,16 +23,9 @@ fun Routing.notes(kodein: Kodein) {
post("/notes") {
val userId = call.userId()
- val noteUuid = call.parameters.noteTitle()
val note = call.receiveNoteCreate()
- val exists = notesService.noteExistsWithTitle(userId, note.title)
-
- if (exists) {
- return@post call.respondStatus(HttpStatusCode.Conflict)
- }
-
- notesService.createNote(userId, note.title, note.tags)
- call.respondStatus(HttpStatusCode.Created)
+ val uuid = notesService.createNote(userId, note)
+ call.respond(HttpStatusCode.Created, mapOf("uuid" to uuid))
}
}
}
diff --git a/api/src/routing/TitleController.kt b/api/src/routing/TitleController.kt
index fda2058..af8e476 100644
--- a/api/src/routing/TitleController.kt
+++ b/api/src/routing/TitleController.kt
@@ -23,7 +23,7 @@ fun Routing.title(kodein: Kodein) {
val noteUuid = call.parameters.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)
call.respond(response)
diff --git a/api/src/services/NotesService.kt b/api/src/services/NotesService.kt
index 9feeda5..38f6d6e 100644
--- a/api/src/services/NotesService.kt
+++ b/api/src/services/NotesService.kt
@@ -29,7 +29,7 @@ class NotesService(override val kodein: Kodein) : KodeinAware {
.sortedByDescending { it.updatedAt }
.toList()
- if(notes.isEmpty()) return emptyList()
+ if (notes.isEmpty()) return emptyList()
val tags = db.sequenceOf(Tags)
.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 {
- 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) {
+ fun createNote(userId: Int, note: FullNoteCreateDTO): UUID {
+ val uuid = UUID.randomUUID()
db.useTransaction {
- val uuid = UUID.randomUUID()
db.insert(Notes) {
it.uuid to uuid
- it.title to title
+ it.title to note.title
it.userId to userId
it.updatedAt to LocalDateTime.now()
}
db.batchInsert(Tags) {
- tags.forEach { tagName ->
+ note.tags.forEach { tagName ->
item {
it.noteUuid to uuid
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 {
- 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)
.select(Tags.name)
.where { Tags.noteUuid eq noteUuid }
@@ -90,10 +107,18 @@ class NotesService(override val kodein: Kodein) : KodeinAware {
.map { ChapterDTO(it[Chapters.title]!!, it[Chapters.content]!!) }
.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) {
- if(patch.uuid == null) return
+ fun updateNote(patch: FullNotePatchDTO) {
+ if (patch.uuid == null) return
db.useTransaction {
if (patch.title != null) {
db.update(Notes) {
@@ -134,7 +159,11 @@ class NotesService(override val kodein: Kodein) : KodeinAware {
.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(
val uuid: UUID,
val title: String,
@@ -143,7 +172,13 @@ data class FullNoteDTO(
val chapters: List
)
-data class FullNoteDTOPatch(
+data class FullNoteCreateDTO(
+ val title: String,
+ val tags: List,
+ val chapters: List
+)
+
+data class FullNotePatchDTO(
val uuid: UUID? = null,
val title: String? = null,
val updatedAt: String? = null,