Index all notes at start
This commit is contained in:
parent
ab3766b8b8
commit
12619f6550
3
.gitignore
vendored
3
.gitignore
vendored
@ -130,3 +130,6 @@ app/src/main/resources/static/styles*
|
|||||||
|
|
||||||
# h2 db
|
# h2 db
|
||||||
*.db
|
*.db
|
||||||
|
|
||||||
|
# lucene index
|
||||||
|
.lucene/
|
||||||
|
|||||||
@ -14,8 +14,10 @@ import be.simplenotes.app.views.NoteView
|
|||||||
import be.simplenotes.app.views.SettingView
|
import be.simplenotes.app.views.SettingView
|
||||||
import be.simplenotes.app.views.UserView
|
import be.simplenotes.app.views.UserView
|
||||||
import be.simplenotes.domain.domainModule
|
import be.simplenotes.domain.domainModule
|
||||||
|
import be.simplenotes.domain.usecases.NoteService
|
||||||
import be.simplenotes.persistance.DbMigrations
|
import be.simplenotes.persistance.DbMigrations
|
||||||
import be.simplenotes.persistance.persistanceModule
|
import be.simplenotes.persistance.persistanceModule
|
||||||
|
import be.simplenotes.search.searchModule
|
||||||
import be.simplenotes.shared.config.DataSourceConfig
|
import be.simplenotes.shared.config.DataSourceConfig
|
||||||
import be.simplenotes.shared.config.JwtConfig
|
import be.simplenotes.shared.config.JwtConfig
|
||||||
import org.http4k.core.RequestContexts
|
import org.http4k.core.RequestContexts
|
||||||
@ -36,6 +38,7 @@ fun main() {
|
|||||||
baseModule,
|
baseModule,
|
||||||
noteModule,
|
noteModule,
|
||||||
settingsModule,
|
settingsModule,
|
||||||
|
searchModule,
|
||||||
)
|
)
|
||||||
}.koin
|
}.koin
|
||||||
|
|
||||||
@ -50,6 +53,9 @@ fun main() {
|
|||||||
val migrations = koin.get<DbMigrations>()
|
val migrations = koin.get<DbMigrations>()
|
||||||
migrations.migrate()
|
migrations.migrate()
|
||||||
|
|
||||||
|
val noteService = koin.get<NoteService>()
|
||||||
|
noteService.indexAll()
|
||||||
|
|
||||||
koin.get<Server>().start()
|
koin.get<Server>().start()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -26,7 +26,7 @@ val domainModule = module {
|
|||||||
single<PasswordHash> { BcryptPasswordHash() }
|
single<PasswordHash> { BcryptPasswordHash() }
|
||||||
single { SimpleJwt(get()) }
|
single { SimpleJwt(get()) }
|
||||||
single { JwtPayloadExtractor(get()) }
|
single { JwtPayloadExtractor(get()) }
|
||||||
single { NoteService(get(), get(), get()) }
|
single { NoteService(get(), get(), get(), get()) }
|
||||||
single<MarkdownConverter> { MarkdownConverterImpl() }
|
single<MarkdownConverter> { MarkdownConverterImpl() }
|
||||||
single<ExportUseCase> { ExportUseCaseImpl(get()) }
|
single<ExportUseCase> { ExportUseCaseImpl(get()) }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,12 +9,14 @@ import be.simplenotes.domain.security.HtmlSanitizer
|
|||||||
import be.simplenotes.domain.usecases.markdown.MarkdownConverter
|
import be.simplenotes.domain.usecases.markdown.MarkdownConverter
|
||||||
import be.simplenotes.domain.usecases.markdown.MarkdownParsingError
|
import be.simplenotes.domain.usecases.markdown.MarkdownParsingError
|
||||||
import be.simplenotes.domain.usecases.repositories.NoteRepository
|
import be.simplenotes.domain.usecases.repositories.NoteRepository
|
||||||
|
import be.simplenotes.domain.usecases.repositories.UserRepository
|
||||||
import be.simplenotes.search.NoteSearcher
|
import be.simplenotes.search.NoteSearcher
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class NoteService(
|
class NoteService(
|
||||||
private val markdownConverter: MarkdownConverter,
|
private val markdownConverter: MarkdownConverter,
|
||||||
private val noteRepository: NoteRepository,
|
private val noteRepository: NoteRepository,
|
||||||
|
private val userRepository: UserRepository,
|
||||||
private val searcher: NoteSearcher,
|
private val searcher: NoteSearcher,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@ -74,6 +76,13 @@ class NoteService(
|
|||||||
|
|
||||||
fun countDeleted(userId: Int) = noteRepository.count(userId, deleted = true)
|
fun countDeleted(userId: Int) = noteRepository.count(userId, deleted = true)
|
||||||
|
|
||||||
|
fun indexAll() {
|
||||||
|
val userIds = userRepository.findAll()
|
||||||
|
userIds.forEach { id ->
|
||||||
|
val notes = noteRepository.findAllDetails(id)
|
||||||
|
searcher.indexNotes(id, notes)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class PaginatedNotes(val pages: Int, val notes: List<PersistedNoteMetadata>)
|
data class PaginatedNotes(val pages: Int, val notes: List<PersistedNoteMetadata>)
|
||||||
|
|||||||
@ -27,4 +27,5 @@ interface NoteRepository {
|
|||||||
fun find(userId: Int, uuid: UUID): PersistedNote?
|
fun find(userId: Int, uuid: UUID): PersistedNote?
|
||||||
fun update(userId: Int, uuid: UUID, note: Note): PersistedNote?
|
fun update(userId: Int, uuid: UUID, note: Note): PersistedNote?
|
||||||
fun export(userId: Int): List<ExportedNote>
|
fun export(userId: Int): List<ExportedNote>
|
||||||
|
fun findAllDetails(userId: Int): List<PersistedNote>
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,4 +10,5 @@ interface UserRepository {
|
|||||||
fun exists(username: String): Boolean
|
fun exists(username: String): Boolean
|
||||||
fun exists(id: Int): Boolean
|
fun exists(id: Int): Boolean
|
||||||
fun delete(id: Int): Boolean
|
fun delete(id: Int): Boolean
|
||||||
|
fun findAll(): List<Int>
|
||||||
}
|
}
|
||||||
|
|||||||
@ -197,4 +197,25 @@ internal class NoteRepositoryImpl(private val db: Database) : NoteRepository {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun findAllDetails(userId: Int): List<PersistedNote> {
|
||||||
|
val notes = db.notes
|
||||||
|
.filterColumns { it.columns - it.deleted }
|
||||||
|
.filter { (it.userId eq userId) and (it.deleted eq false) }
|
||||||
|
.toList()
|
||||||
|
|
||||||
|
if (notes.isEmpty()) return emptyList()
|
||||||
|
|
||||||
|
val uuids = notes.map { note -> note.uuid }
|
||||||
|
|
||||||
|
val tagsByUuid = db.tags
|
||||||
|
.filterColumns { listOf(it.noteUuid, it.name) }
|
||||||
|
.filter { it.noteUuid inList uuids }
|
||||||
|
.groupByTo(HashMap(), { it.note.uuid }, { it.name })
|
||||||
|
|
||||||
|
return notes.map { note ->
|
||||||
|
val tags = tagsByUuid[note.uuid] ?: emptyList()
|
||||||
|
note.toPersistedNote(tags)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,4 +28,5 @@ internal class UserRepositoryImpl(private val db: Database) : UserRepository {
|
|||||||
override fun exists(username: String) = db.users.any { it.username eq username }
|
override fun exists(username: String) = db.users.any { it.username eq username }
|
||||||
override fun exists(id: Int) = db.users.any { it.id eq id }
|
override fun exists(id: Int) = db.users.any { it.id eq id }
|
||||||
override fun delete(id: Int) = db.useTransaction { db.delete(Users) { it.id eq id } == 1 }
|
override fun delete(id: Int) = db.useTransaction { db.delete(Users) { it.id eq id } == 1 }
|
||||||
|
override fun findAll() = db.from(Users).select(Users.id).map { it[Users.id]!! }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -52,6 +52,21 @@ class NoteSearcher(basePath: Path = Path.of("/tmp", "lucene")) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun indexNotes(userId: Int, notes: List<PersistedNote>) {
|
||||||
|
logger.debug("Indexing notes for user $userId")
|
||||||
|
|
||||||
|
val dir = getDirectory(userId)
|
||||||
|
val config = IndexWriterConfig(StandardAnalyzer())
|
||||||
|
val writer = IndexWriter(dir, config)
|
||||||
|
val docs = notes.map { it.toDocument() }
|
||||||
|
|
||||||
|
with(writer) {
|
||||||
|
addDocuments(docs)
|
||||||
|
commit()
|
||||||
|
close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun deleteIndex(userId: Int, uuid: UUID) {
|
fun deleteIndex(userId: Int, uuid: UUID) {
|
||||||
logger.debug("Deleting indexing $uuid for user $userId")
|
logger.debug("Deleting indexing $uuid for user $userId")
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
package be.simplenotes.search
|
package be.simplenotes.search
|
||||||
|
|
||||||
import org.koin.dsl.module
|
import org.koin.dsl.module
|
||||||
|
import java.nio.file.Path
|
||||||
|
|
||||||
val searchModule = module {
|
val searchModule = module {
|
||||||
single { NoteSearcher() }
|
single { NoteSearcher(Path.of(".lucene")) }
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user