simple api model

This commit is contained in:
gowthaman.b
2023-11-10 11:06:14 +05:30
parent 203c2b97a7
commit 01e197b0f8
14 changed files with 364 additions and 232 deletions

View File

@@ -0,0 +1,75 @@
package com.restapi.domain
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.Module
import com.fasterxml.jackson.databind.SerializationFeature
import com.fasterxml.jackson.databind.module.SimpleModule
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.restapi.config.AppConfig.Companion.appConfig
import io.ebean.Database
import io.ebean.DatabaseFactory
import io.ebean.config.CurrentTenantProvider
import io.ebean.config.CurrentUserProvider
import io.ebean.config.DatabaseConfig
import io.ebean.config.TenantMode
import java.util.*
data class CurrentUser(
val anon: Boolean = true,
val userId: String = "",
val tenantId: String = ""
)
object Session {
private val currentUser = object : ThreadLocal<CurrentUser>() {
override fun initialValue(): CurrentUser {
return CurrentUser()
}
}
private val sc = DatabaseConfig().apply {
loadFromProperties(Properties().apply {
setProperty("datasource.db.username", appConfig.dbUser())
setProperty("datasource.db.password", appConfig.dbPass())
setProperty("datasource.db.url", appConfig.dbUrl())
setProperty("ebean.migration.run", appConfig.dbRunMigration().toString())
})
tenantMode = TenantMode.PARTITION
currentTenantProvider = CurrentTenantProvider { currentUser.get().tenantId }
currentUserProvider = CurrentUserProvider { currentUser.get().userId }
}
val database: Database = DatabaseFactory.create(sc)
val objectMapper = jacksonObjectMapper().apply {
configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
findAndRegisterModules()
}
fun currentUser() = currentUser.get().userId
fun Database.findByEntityAndId(entity: String, id: String): DataModel {
return find(DataModel::class.java)
.where()
.eq("uniqueIdentifier", id)
.eq("entityName", entity)
.findOne() ?: throw DataNotFoundException
}
private fun seqName(entity: String) = "sequence_$entity"
fun creatSeq(entity: String): Int {
return database.sqlUpdate("CREATE SEQUENCE IF NOT EXISTS ${seqName(entity)} START 1;").execute()
}
fun nextUniqId(entity: String): String {
val s = database
.sqlQuery("SELECT nextval('${seqName(entity)}');")
.findOne()?.getLong("nextval") ?: throw DataNotFoundException
return String.format("%s-%s", entity, "$s".padStart(10, '0'))
}
}
object DataNotFoundException : Exception() {
private fun readResolve(): Any = DataNotFoundException
}

View File

@@ -0,0 +1,19 @@
package com.restapi.domain
import io.ebean.annotation.Platform
import io.ebean.dbmigration.DbMigration
object DBMigration {
private fun create(){
val dbMigration: DbMigration = DbMigration.create()
dbMigration.setPlatform(Platform.POSTGRES)
dbMigration.generateMigration()
}
@JvmStatic
fun main(args: Array<String>) {
create()
}
}

View File

@@ -0,0 +1,91 @@
package com.restapi.domain
import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.DeserializationContext
import com.fasterxml.jackson.databind.JsonDeserializer
import com.fasterxml.jackson.databind.annotation.JsonDeserialize
import io.ebean.Model
import io.ebean.annotation.DbArray
import io.ebean.annotation.DbJsonB
import io.ebean.annotation.Index
import io.ebean.annotation.Platform
import io.ebean.annotation.SoftDelete
import io.ebean.annotation.TenantId
import io.ebean.annotation.WhenCreated
import io.ebean.annotation.WhenModified
import io.ebean.annotation.WhoCreated
import io.ebean.annotation.WhoModified
import java.time.LocalDateTime
import javax.persistence.Entity
import javax.persistence.GeneratedValue
import javax.persistence.Id
import javax.persistence.MappedSuperclass
import javax.persistence.Version
data class Comments(val text: String = "", val by: String = "", val at: LocalDateTime = LocalDateTime.now())
@MappedSuperclass
abstract class BaseModel : Model() {
@Id
@GeneratedValue
var sysPk: Long = 0
@SoftDelete
var deleted: Boolean = false
@Version
var version: Int = 0
@WhenCreated
var createdAt: LocalDateTime = LocalDateTime.now()
@WhenModified
var modifiedAt: LocalDateTime? = null
@TenantId
var tenantId: String = ""
@WhoCreated
var createdBy: String = ""
@WhoModified
var modifiedBy: String? = null
var deletedOn: LocalDateTime? = null
var deletedBy: String? = null
@DbArray
var tags: MutableList<String> = arrayListOf()
@DbJsonB
var comments: MutableList<Comments> = arrayListOf()
}
@Entity
@Index(unique = true, name = "entity_unique_id", columnNames = ["entity_name", "unique_identifier", "tenant_id"])
open class DataModel : BaseModel() {
@JsonDeserialize(using = SafeStringDeserializer::class)
var uniqueIdentifier: String = ""
@JsonDeserialize(using = SafeStringDeserializer::class)
var entityName: String = ""
@Index(definition = "create index data_jsonb_idx on data_model using GIN (data) ", platforms = [Platform.POSTGRES])
@DbJsonB
var data: MutableMap<String, Any> = hashMapOf()
}
class SafeStringDeserializer : JsonDeserializer<String>() {
private val regex = Regex("^[a-zA-Z0-9\\-_\\.]+$")
override fun deserialize(p: JsonParser, ctxt: DeserializationContext?): String {
val text = p.text
if (!regex.matches(text)) throw IllegalArgumentException()
return text
}
}