instep.dao.sql.Table.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of instep-dao Show documentation
Show all versions of instep-dao Show documentation
Tools are designed for more easier coding.
The newest version!
package instep.dao.sql
import instep.ImpossibleBranch
import instep.Instep
import instep.dao.DaoException
import instep.reflection.Property
/**
* Abstract DAO object.
*/
@Suppress("unused", "FoldInitializerAndIfToElvis", "MemberVisibilityCanBePrivate")
abstract class Table(val tableName: String, val tableComment: String, val dialect: Dialect) {
constructor(tableName: String, tableComment: String) : this(tableName, tableComment, Instep.make(ConnectionProvider::class.java).dialect)
constructor(tableName: String) : this(tableName, "")
/**
* for java interop.
*/
open fun bool(name: String): BooleanColumn {
return boolean(name)
}
open fun boolean(name: String): BooleanColumn {
return BooleanColumn(name, this)
}
open fun char(name: String, length: Int): StringColumn {
return StringColumn(name, this, StringColumnType.Char, length)
}
/**
* for java interop.
*/
open fun charColumn(name: String, length: Int): StringColumn {
return char(name, length)
}
open fun varchar(name: String, length: Int): StringColumn {
return StringColumn(name, this, StringColumnType.Varchar, length)
}
@JvmOverloads
open fun text(name: String, length: Int = 0): StringColumn {
return StringColumn(name, this, StringColumnType.Text, length)
}
open fun uuid(name: String): StringColumn {
return StringColumn(name, this, StringColumnType.UUID)
}
open fun json(name: String): StringColumn {
return StringColumn(name, this, StringColumnType.JSON)
}
open fun tinyInt(name: String): IntegerColumn {
return IntegerColumn(name, this, IntegerColumnType.Tiny)
}
open fun smallInt(name: String): IntegerColumn {
return IntegerColumn(name, this, IntegerColumnType.Small)
}
open fun int(name: String): IntegerColumn {
return IntegerColumn(name, this, IntegerColumnType.Int)
}
/**
* for java interop.
*/
open fun integer(name: String): IntegerColumn {
return int(name)
}
open fun long(name: String): IntegerColumn {
return IntegerColumn(name, this, IntegerColumnType.Long)
}
/**
* for java interop.
*/
open fun longColumn(name: String): IntegerColumn {
return long(name)
}
open fun autoIncrement(name: String): IntegerColumn {
return IntegerColumn(name, this, IntegerColumnType.Int).apply {
autoIncrement = true
}
}
open fun autoIncrementLong(name: String): IntegerColumn {
return IntegerColumn(name, this, IntegerColumnType.Long).apply {
autoIncrement = true
}
}
open fun float(name: String): FloatingColumn {
return FloatingColumn(name, this, FloatingColumnType.Float)
}
/**
* for java interop.
*/
open fun floatColumn(name: String): FloatingColumn {
return float(name)
}
open fun double(name: String): FloatingColumn {
return FloatingColumn(name, this, FloatingColumnType.Double)
}
/**
* for java interop.
*/
open fun doubleColumn(name: String): FloatingColumn {
return double(name)
}
open fun numeric(name: String, precision: Int, scale: Int): FloatingColumn {
return FloatingColumn(name, this, FloatingColumnType.Numeric, precision, scale)
}
open fun date(name: String): DateTimeColumn {
return DateTimeColumn(name, this, DateTimeColumnType.Date)
}
open fun time(name: String): DateTimeColumn {
return DateTimeColumn(name, this, DateTimeColumnType.Time)
}
open fun datetime(name: String): DateTimeColumn {
return DateTimeColumn(name, this, DateTimeColumnType.DateTime)
}
open fun offsetDateTime(name: String): DateTimeColumn {
return DateTimeColumn(name, this, DateTimeColumnType.OffsetDateTime)
}
open fun instant(name: String): DateTimeColumn {
return DateTimeColumn(name, this, DateTimeColumnType.Instant)
}
open fun bytes(name: String, length: Int): BinaryColumn {
return BinaryColumn(name, this, BinaryColumnType.Varying, length)
}
@JvmOverloads
open fun lob(name: String, length: Int = 0): BinaryColumn {
return BinaryColumn(name, this, BinaryColumnType.BLOB, length)
}
open fun arbitrary(name: String, definition: String): ArbitraryColumn {
return ArbitraryColumn(name, this, definition)
}
val columnProperties: List
get() = Instep.reflect(this).getPropertiesUntil(Table::class.java).filter { Column::class.java.isAssignableFrom(it.field.type) }
val columns: List>
get() = columnProperties.map {
if (null != it.getter) {
it.getter!!.invoke(this)
}
else {
it.field.get(this)
} as Column<*>
}
val primaryKey: Column<*>?
get() = columns.singleOrNull { it.primary }
@JvmOverloads
open fun create(checkExists: Boolean = true): SQLPlan<*> {
return if (checkExists) dialect.createTableIfNotExists(tableName, tableComment, columns) else dialect.createTable(tableName, tableComment, columns)
}
@JvmOverloads
open fun drop(checkExists: Boolean = true): SQLPlan<*> {
return if (checkExists) dialect.dropTableIfExists(tableName) else dialect.dropTable(tableName)
}
open fun rename(name: String): SQLPlan<*> {
return dialect.renameTable(tableName, name)
}
open fun addColumn(column: Column<*>): SQLPlan<*> {
return dialect.addColumn(column)
}
open fun dropColumn(column: Column<*>): SQLPlan<*> {
return dialect.dropColumn(column)
}
open fun renameColumn(column: Column<*>, oldName: String): SQLPlan<*> {
return dialect.renameColumn(column, oldName)
}
open fun alterColumnNotNull(column: Column<*>): SQLPlan<*> {
return dialect.alterColumnNotNull(column)
}
open fun alterColumnDefault(column: Column<*>): SQLPlan<*> {
return dialect.alterColumnDefault(column)
}
open fun insert(): TableInsertPlan {
val factory = Instep.make(TableInsertPlanFactory::class.java)
return factory.createInstance(this)
}
open fun select(vararg columns: Column<*>): TableSelectPlan {
val factory = Instep.make(TableSelectPlanFactory::class.java)
return factory.createInstance(this).select(*columns)
}
open fun selectExpression(vararg selectExpression: SelectExpression): TableSelectPlan {
val factory = Instep.make(TableSelectPlanFactory::class.java)
return factory.createInstance(this).selectExpression(*selectExpression)
}
open fun selectExcept(vararg exception: Column<*>): TableSelectPlan {
val factory = Instep.make(TableSelectPlanFactory::class.java)
val cols = this.columns.dropWhile { exception.contains(it) }
return factory.createInstance(this).select(*cols.toTypedArray())
}
open fun update(): TableUpdatePlan {
val factory = Instep.make(TableUpdatePlanFactory::class.java)
return factory.createInstance(this)
}
open fun delete(): TableDeletePlan {
val factory = Instep.make(TableDeletePlanFactory::class.java)
return factory.createInstance(this)
}
@Throws(SQLPlanExecutionException::class)
open fun get(key: Number, cls: Class): T? {
if (null == primaryKey) throw DaoException("Table $tableName should has primary key")
val pk = primaryKey as IntegerColumn
return select().where(pk eq key).execute(cls).singleOrNull()
}
@Throws(SQLPlanExecutionException::class)
open fun get(key: String, cls: Class): T? {
if (null == primaryKey) throw DaoException("Table $tableName should has primary key")
val pk = primaryKey as StringColumn
return select().where(pk eq key).execute(cls).singleOrNull()
}
@Throws(SQLPlanExecutionException::class)
open operator fun get(key: Number): TableRow? {
if (null == primaryKey) throw DaoException("Table $tableName should has primary key")
val pk = primaryKey as IntegerColumn
return select().where(pk eq key).execute().singleOrNull()
}
@Throws(SQLPlanExecutionException::class)
open operator fun get(key: String): TableRow? {
if (null == primaryKey) throw DaoException("Table $tableName should has primary key")
val pk = primaryKey as StringColumn
return select().where(pk eq key).execute().singleOrNull()
}
@Throws(SQLPlanExecutionException::class)
open operator fun set(key: Number, obj: Any) {
insertOrUpdate(key, obj)
}
@Throws(SQLPlanExecutionException::class)
open operator fun set(key: String, obj: Any) {
insertOrUpdate(key, obj)
}
private fun insertOrUpdate(key: Any, obj: Any) {
val pk = primaryKey
if (null == pk) throw DaoException("Table $tableName should has primary key")
when (key) {
is Number -> {
val existsRow = this[key]
if (null != existsRow) {
val plan = update()
when (obj) {
is TableRow -> {
columns.filterNot { it == pk }.forEach {
plan.set(it, obj[it])
}
plan.where(pk as NumberColumn eq key).execute()
}
else -> plan.set(obj).whereKey(key).execute()
}
return
}
}
is String -> {
val existsRow = this[key]
if (null != existsRow) {
val plan = update()
when (obj) {
is TableRow -> {
columns.filterNot { it == pk }.forEach {
plan.set(it, obj[it])
}
plan.where(pk as StringColumn eq key).execute()
}
else -> plan.set(obj).whereKey(key).execute()
}
return
}
}
else -> throw ImpossibleBranch()
}
val plan = insert()
when (obj) {
is TableRow -> {
columns.filterNot { it == pk }.forEach {
plan.addValue(it, obj[it])
}
plan.addValue(pk, key)
plan.execute()
}
else -> plan.set(obj).execute()
}
}
companion object {
val DefaultInsertValue = object {}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy