Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ repositories {
dependencies {
implementation("io.insert-koin:koin-core:4.0.4")
implementation ("org.jetbrains.kotlinx:kotlinx-datetime:0.6.2")

implementation("com.opencsv:opencsv:5.7.1")
testImplementation(kotlin("test"))
testImplementation("org.junit.jupiter:junit-jupiter:5.8.1")
testImplementation("io.mockk:mockk:1.14.0")
Expand Down
17 changes: 17 additions & 0 deletions src/main/kotlin/data/BaseDataSource.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.berlin.data

interface BaseDataSource<T> {

fun getAll(): List<T>

fun getById(id: String): T?

fun update(id: String, entity: T): Boolean

fun delete(id: String): Boolean

fun write(entity: T): Boolean

fun writeAll(entities: List<T>): Boolean

}
10 changes: 10 additions & 0 deletions src/main/kotlin/data/BaseSchema.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.berlin.data

interface BaseSchema<T> {
val fileName: String
val header: List<String>

fun toRow(entity: T): List<String>
fun fromRow(row: List<String>): T?
fun getId(entity: T): String?
}
42 changes: 42 additions & 0 deletions src/main/kotlin/data/indexes.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.berlin.data

object UserIndex {
const val ID = 0
const val USER_NAME = 1
const val PASSWORD = 2
const val ROLE = 3
}

object TaskIndex {
const val ID = 0
const val PROJECT_ID = 1
const val TITLE = 2
const val DESCRIPTION = 3
const val STATE_ID = 4
const val ASSIGNED_TO_USER_ID = 5
const val CREATE_BY_USER_ID = 6
}

object StateIndex {
const val ID = 0
const val NAME = 1
const val PROJECT_ID = 2
}

object ProjectIndex {
const val ID = 0
const val NAME = 1
const val DESCRIPTION = 2
const val STATES_ID = 3
const val TASKS_ID = 4
}

object AuditLogIndex {
const val ID = 0
const val TIMES_TAMP = 1
const val CREATE_BY = 2
const val AUDIT_ACTION = 3
const val CHANGES_DESCRIPTION = 4
const val ENTITY_TYPE = 5
const val ENTITY_ID = 6
}
96 changes: 96 additions & 0 deletions src/main/kotlin/data/schema/AuditSchema.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package com.berlin.data.schema

import com.berlin.data.AuditLogIndex
import com.berlin.data.BaseSchema
import com.berlin.domain.model.AuditAction
import com.berlin.domain.model.AuditLog
import com.berlin.domain.model.EntityType

class AuditSchema(
override val fileName: String, override val header: List<String>
) : BaseSchema<AuditLog> {

init {
require(
fileName.isNotEmpty() && header.size == NUMBER_OF_ATTRIBUTES
)
}

override fun toRow(entity: AuditLog): List<String> {
return if (checkAuditLogIsNotValid(entity)) emptyList()
else auditLogToStringsList(entity)
}

override fun fromRow(row: List<String>): AuditLog? {
return if (checkRowIsNotValidAuditLog(row)) null
else stringsListToAuditLog(row)
}

override fun getId(entity: AuditLog): String? {
return entity.id.ifEmpty { null }
}

private fun auditLogToStringsList(auditLog: AuditLog): List<String> {
return listOf(
auditLog.id,
auditLog.timestamp.toString(),
auditLog.createdByUserId,
auditLog.auditAction.toString(),
auditLog.changesDescription ?: "",
auditLog.entityType.toString(),
auditLog.entityId
)
}

private fun stringsListToAuditLog(row: List<String>): AuditLog {
return AuditLog(
id = row[AuditLogIndex.ID],
timestamp = row[AuditLogIndex.TIMES_TAMP].toLong() ,
createdByUserId = row[AuditLogIndex.CREATE_BY],
auditAction = stringToAuditAction(row[AuditLogIndex.AUDIT_ACTION]),
changesDescription = row[AuditLogIndex.CHANGES_DESCRIPTION].ifEmpty { null },
entityType = stringToEntityType(row[AuditLogIndex.ENTITY_TYPE]),
entityId = row[AuditLogIndex.ENTITY_ID]
)
}

private fun checkRowIsNotValidAuditLog(row: List<String>): Boolean {
return (row[AuditLogIndex.ID].isEmpty() ||
row[AuditLogIndex.TIMES_TAMP].isEmpty() ||
row[AuditLogIndex.CREATE_BY].isEmpty() ||
row[AuditLogIndex.AUDIT_ACTION].isEmpty() ||
row[AuditLogIndex.ENTITY_ID].isEmpty() ||
row[AuditLogIndex.AUDIT_ACTION] !in enumValues<AuditAction>().map { it.name } ||
row[AuditLogIndex.ENTITY_TYPE] !in enumValues<EntityType>().map { it.name }
)
}

private fun stringToAuditAction(auditAction: String): AuditAction {
return when (auditAction) {
AuditAction.CREATE.toString() -> AuditAction.CREATE
AuditAction.UPDATE.toString() -> AuditAction.UPDATE
AuditAction.DELETE.toString() -> AuditAction.DELETE
else -> AuditAction.CREATE
}
}

private fun stringToEntityType(entityType: String): EntityType {
return when (entityType) {
EntityType.TASK.toString() -> EntityType.TASK
EntityType.PROJECT.toString() -> EntityType.PROJECT
else -> EntityType.TASK
}
}

private fun checkAuditLogIsNotValid(auditLog: AuditLog): Boolean {
return (auditLog.id.isEmpty() ||
auditLog.timestamp <= 0 ||
auditLog.createdByUserId.isEmpty() ||
auditLog.entityId.isEmpty()
)
}

private companion object {
const val NUMBER_OF_ATTRIBUTES = 7
}
}
70 changes: 70 additions & 0 deletions src/main/kotlin/data/schema/ProjectSchema.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package com.berlin.data.schema

import com.berlin.data.BaseSchema
import com.berlin.data.ProjectIndex
import com.berlin.domain.model.Project

class ProjectSchema(
override val fileName: String,
override val header: List<String>
) : BaseSchema<Project> {

init {
require(fileName.isNotEmpty() && header.size == NUMBER_OF_ATTRIBUTES)
}

override fun toRow(entity: Project): List<String> {
return if (checkProjectIsNotValid(entity)) emptyList()
else projectToStringsList(entity)
}

override fun fromRow(row: List<String>): Project? {
return if (checkRowIsNotValidProject(row)) null
else stringsListToProject(row)
}

override fun getId(entity: Project): String? {
return entity.id.ifEmpty { null }
}

private fun projectToStringsList(project: Project): List<String> {
return listOf(
project.id,
project.name,
project.description ?: "",
project.statesId?.joinToString(",", "[", "]") ?: "[]",
project.tasksId?.joinToString(",", "[", "]") ?: "[]"
)
}

private fun stringsListToProject(row: List<String>): Project {
return Project(
id = row[ProjectIndex.ID],
name = row[ProjectIndex.NAME],
description = row[ProjectIndex.DESCRIPTION].ifEmpty { null },
statesId = row[ProjectIndex.STATES_ID].let { if (it == "[]") null else stringListToList(it) },
tasksId = row[ProjectIndex.TASKS_ID].let { if (it == "[]") null else stringListToList(it) }
)
}

private fun checkRowIsNotValidProject(row: List<String>): Boolean {
return (row.isEmpty()||
row[ProjectIndex.ID].isEmpty() ||
row[ProjectIndex.NAME].isEmpty())
}

private fun checkProjectIsNotValid(project: Project): Boolean {
return project.id.isEmpty() ||
project.name.isEmpty()
}

private fun stringListToList(listString: String): List<String> {
return listString
.removeSurrounding("[", "]")
.split(",")
}

private companion object {
const val NUMBER_OF_ATTRIBUTES = 5
}
}
61 changes: 61 additions & 0 deletions src/main/kotlin/data/schema/StateSchema.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.berlin.data.schema

import com.berlin.data.BaseSchema
import com.berlin.data.StateIndex
import com.berlin.domain.model.State

class StateSchema(
override val fileName: String,
override val header: List<String>
) : BaseSchema<State> {

init {
require(fileName.isNotEmpty() && header.size == NUMBER_OF_ATTRIBUTES)
}

override fun toRow(entity: State): List<String> {
return if (checkStateIsNotValid(entity)) emptyList()
else stateToStringsList(entity)
}

override fun fromRow(row: List<String>): State? {
return if (checkRowIsNotValidState(row)) null
else stringsListToState(row)
}

override fun getId(entity: State): String? {
return entity.id.ifEmpty { null }
}

private fun stateToStringsList(state: State): List<String> {
return listOf(
state.id,
state.name,
state.projectId
)
}

private fun stringsListToState(row: List<String>): State {
return State(
id = row[StateIndex.ID],
name = row[StateIndex.NAME],
projectId = row[StateIndex.PROJECT_ID]
)
}

private fun checkRowIsNotValidState(row: List<String>): Boolean {
return (row[StateIndex.ID].isEmpty() ||
row[StateIndex.NAME].isEmpty() ||
row[StateIndex.PROJECT_ID].isEmpty())
}

private fun checkStateIsNotValid(state: State): Boolean {
return (state.id.isEmpty() ||
state.name.isEmpty() ||
state.projectId.isEmpty())
}

private companion object {
const val NUMBER_OF_ATTRIBUTES = 3
}
}
75 changes: 75 additions & 0 deletions src/main/kotlin/data/schema/TaskSchema.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package com.berlin.data.schema

import com.berlin.data.BaseSchema
import com.berlin.data.TaskIndex
import com.berlin.domain.model.Task

class TaskSchema(
override val fileName: String,
override val header: List<String>
) : BaseSchema<Task> {

init {
require(fileName.isNotEmpty() && header.size == NUMBER_OF_ATTRIBUTES)
}

override fun toRow(entity: Task): List<String> {
return if (checkTaskIsNotValid(entity)) emptyList()
else taskToStringsList(entity)
}

override fun fromRow(row: List<String>): Task? {
return if (checkRowIsNotValidTask(row)) null
else stringsListToTask(row)
}

override fun getId(entity: Task): String? {
return entity.id.ifEmpty { null }
}

private fun taskToStringsList(task: Task): List<String> {
return listOf(
task.id,
task.projectId,
task.title,
task.description ?: "",
task.stateId,
task.assignedToUserId,
task.createByUserId
)
}

private fun stringsListToTask(row: List<String>): Task {
return Task(
id = row[TaskIndex.ID],
projectId = row[TaskIndex.PROJECT_ID],
title = row[TaskIndex.TITLE],
description = row[TaskIndex.DESCRIPTION].ifEmpty { null },
stateId = row[TaskIndex.STATE_ID],
assignedToUserId = row[TaskIndex.ASSIGNED_TO_USER_ID],
createByUserId = row[TaskIndex.CREATE_BY_USER_ID]
)
}

private fun checkRowIsNotValidTask(row: List<String>): Boolean {
return (row[TaskIndex.ID].isEmpty() ||
row[TaskIndex.PROJECT_ID].isEmpty() ||
row[TaskIndex.TITLE].isEmpty() ||
row[TaskIndex.STATE_ID].isEmpty() ||
row[TaskIndex.ASSIGNED_TO_USER_ID].isEmpty() ||
row[TaskIndex.CREATE_BY_USER_ID].isEmpty())
}

private fun checkTaskIsNotValid(task: Task): Boolean {
return (task.id.isEmpty() ||
task.projectId.isEmpty() ||
task.title.isEmpty() ||
task.stateId.isEmpty() ||
task.assignedToUserId.isEmpty() ||
task.createByUserId.isEmpty())
}

private companion object {
const val NUMBER_OF_ATTRIBUTES = 7
}
}
Loading