com.vladsch.kotlin.jdbc.DbEntity.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kotlin-jdbc Show documentation
Show all versions of kotlin-jdbc Show documentation
A thin library that exposes JDBC API with the convenience of Kotlin and gets out of the way when not needed.
The newest version!
package com.vladsch.kotlin.jdbc
import java.io.File
import java.io.FilenameFilter
@Suppress("MemberVisibilityCanBePrivate")
enum class DbEntity(val dbEntity: String, val displayName: String, val dbEntityDirectory: String, val fileSuffix: String) {
FUNCTION("FUNCTION", "function", "functions", ".udf.sql"),
PROCEDURE("PROCEDURE", "procedure", "procedures", ".prc.sql"),
TABLE("TABLE", "table", "tables", ".tbl.sql"),
TRIGGER("TRIGGER", "insert trigger", "triggers", ".trg.sql"),
VIEW("VIEW", "view", "views", ".view.sql"),
MIGRATION("", "migration", "migrations", ".up.sql"),
ROLLBACK("", "rollback", "migrations", ".down.sql"),
;
companion object {
fun isEntityDirectory(name: String): Boolean {
return values().any { it.dbEntityDirectory == name }
}
}
fun getEntityDirectory(dbVersionDir: File, createDir: Boolean?): File {
if (createDir != null) {
dbVersionDir.ensureExistingDirectory("dbDir/dbVersion")
}
// may need to create table directory
val entityDir = dbVersionDir + this.dbEntityDirectory
if (createDir == true) {
entityDir.ensureCreateDirectory("dbDir/dbVersion/${this.dbEntityDirectory}")
} else if (createDir == false) {
entityDir.ensureExistingDirectory("dbDir/dbVersion/${this.dbEntityDirectory}")
}
return entityDir
}
fun removeSuffix(fileName: String): String {
return fileName.removeSuffix(fileSuffix)
}
fun addSuffix(fileName: String): String {
return fileName + fileSuffix
}
fun getEntityDirectory(dbDir: File, dbProfile: String, dbVersion: String, createDir: Boolean?): File {
val dbVersionDir = getVersionDirectory(dbDir, dbProfile, dbVersion, createDir)
return getEntityDirectory(dbVersionDir, createDir)
}
fun getEntityResourceDirectory(dbProfile: String, dbVersion: String): File {
val dbVersionDir = File("/db/$dbProfile") + dbVersion
// may need to create table directory
val entityDir = dbVersionDir + this.dbEntityDirectory
return entityDir
}
fun getEntitySample(dbDir: File, resourceClass: Class<*>): String {
val templateFile = ((dbDir + "templates") + dbEntityDirectory) + getEntitySampleName()
var sampleText: String? = null
if (templateFile.exists()) {
sampleText = getFileContent(templateFile)
}
if (sampleText == null) {
val samplesResourcePath = "/sample-db/V0_0_0/$dbEntityDirectory/${getEntitySampleName()}"
sampleText = getResourceAsString(resourceClass, samplesResourcePath)
}
return sampleText
}
fun isEntityFile(file: String): Boolean {
return file.endsWith(this.fileSuffix)
}
fun isEntityFile(file: File): Boolean {
return file.name.endsWith(this.fileSuffix)
}
fun getEntitySampleName(): String {
return if (this === MIGRATION || this === ROLLBACK) {
"0.sample$fileSuffix"
} else {
"sample$fileSuffix"
}
}
fun getEntityName(fileName: String): String {
var entityName = fileName
if (this === MIGRATION || this === ROLLBACK) {
// has optional leading count with .
val (count, name) = fileName.extractLeadingDigits()
entityName = name
}
return entityName.substring(0, entityName.length - this.fileSuffix.length)
}
fun getEntityName(file: File): String {
return getEntityName(file.name)
}
fun getEntityFiles(entityDir: File): List {
val entityList = ArrayList()
if (entityDir.exists()) {
entityDir.list(FilenameFilter { file, name -> name.endsWith(this.fileSuffix) })
.map { entityDir + it }
.filter { it.isFile }
.forEach {
entityList.add(it.path)
}
}
return entityList
}
fun getEntityFiles(dbDir: File, dbProfile: String, dbVersion: String, createDir: Boolean? = true): List {
val entityDir = this.getEntityDirectory(dbDir, dbProfile, dbVersion, createDir)
if (createDir == true) {
entityDir.ensureCreateDirectory("dbDir/dbProfile/dbVersion/${this.dbEntityDirectory}")
} else if (createDir == false) {
entityDir.ensureExistingDirectory("dbDir/dbProfile/dbVersion/${this.dbEntityDirectory}")
} else {
return listOf()
}
return getEntityFiles(entityDir)
}
fun getEntityResourceFiles(resourceClass: Class<*>, dbProfile:String, dbVersion: String): List {
val entityDir = this.getEntityResourceDirectory(dbProfile, dbVersion)
return getResourceFiles(resourceClass, entityDir.path)
}
fun getEntityFile(entityDir: File, entityName: String): File {
return entityDir + (entityName + this.fileSuffix)
}
fun getEntityFile(dbDir: File, dbProfile: String, dbVersion: String, entityName: String, createDir: Boolean? = true): File {
val entityDir = getEntityDirectory(dbDir, dbProfile, dbVersion, createDir)
return getEntityFile(entityDir, entityName)
}
data class EntityData(val entityName: String, val entityResourceName: String, val entityResourcePath: String, val entitySql: String)
object MIGRATIONS_COMPARATOR : Comparator {
override fun compare(o1: DbEntity.EntityData?, o2: DbEntity.EntityData?): Int {
val (num1, name1) = o1?.entityResourceName.extractLeadingDigits()
val (num2, name2) = o2?.entityResourceName.extractLeadingDigits()
return if (num1 != null && num2 != null) {
val nums = num1.compareTo(num2)
if (nums == 0) name1.compareTo(name2)
else nums
} else {
name1.compareTo(name2)
}
}
}
object MIGRATIONS_NAME_COMPARATOR : Comparator {
override fun compare(o1: String?, o2: String?): Int {
val (num1, name1) = o1.extractLeadingDigits()
val (num2, name2) = o2.extractLeadingDigits()
return if (num1 != null && num2 != null) {
val nums = num1.compareTo(num2)
if (nums == 0) name1.compareTo(name2)
else nums
} else {
name1.compareTo(name2)
}
}
}
fun extractEntityName(dbEntityExtractor: DbEntityExtractor, entitySql: String): String? {
val entityNameRegEx = dbEntityExtractor.getExtractEntityNameRegEx(this) ?: return null
return extractEntityName(entityNameRegEx, entitySql)
}
fun extractEntityName(entityNameRegEx: Regex, entitySql: String): String? {
val matchGroup = entityNameRegEx.find(entitySql)
if (matchGroup != null) {
return matchGroup.groupValues[1].removeSurrounding("`")
}
return null
}
fun validEntityFileName(entityName: String, entityNameFile: String): String? {
if (entityName != entityNameFile) {
return "$entityName${this.fileSuffix}"
}
return null
}
/**
* Get entity to EntityScript
*
* @return Map
*/
fun getEntityResourceScripts(resourceClass: Class<*>, dbEntityExtractor: DbEntityExtractor, entityDir: File): Map {
val entityNameRegEx = dbEntityExtractor.getExtractEntityNameRegEx(this);
val files = getResourceFiles(resourceClass, entityDir.path)
val entities = HashMap()
for (file in files) {
if (file.endsWith(fileSuffix)) {
val entityNameFile = file.substring(0, file.length - this.fileSuffix.length)
val entitySql = getResourceAsString(resourceClass, (entityDir + file).path)
if (entityNameRegEx == null) {
// no name check
val entityName = this.removeSuffix(entityNameFile)
val entityLowercaseName = entityName.toLowerCase()
entities[entityLowercaseName] = EntityData(entityName, file, (entityDir + file).path, entitySql);
} else {
val matchGroup = entityNameRegEx.find(entitySql)
if (matchGroup != null) {
val entityName = matchGroup.groupValues[1].removeSurrounding("`")
val entityLowercaseName = entityName.toLowerCase()
if (entityName != entityNameFile) {
throw IllegalStateException("File $file for $displayName $entityName should be named $entityName${this.fileSuffix}")
}
if (entities.contains(entityLowercaseName)) {
throw IllegalStateException("Duplicate SQL $displayName in File $file, $entityName already defined in ${entities[entityName]}")
}
entities[entityLowercaseName] = EntityData(entityName, file, (entityDir + file).path, entitySql);
} else {
throw IllegalStateException("Invalid SQL $displayName file $file, cannot find $displayName name")
}
}
}
}
return entities
}
fun getEntityResourceScripts(resourceClass: Class<*>, dbEntityExtractor: DbEntityExtractor, dbProfile: String, dbVersion: String): Map {
val entityDir = getEntityDirectory(File("/db"), dbProfile, dbVersion, null)
return getEntityResourceScripts(resourceClass, dbEntityExtractor, entityDir)
}
}