All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ufoss.kotysa.Table.kt Maven / Gradle / Ivy

package org.ufoss.kotysa

import org.ufoss.kotysa.columns.AbstractColumn
import org.ufoss.kotysa.columns.AbstractDbColumn
import org.ufoss.kotysa.columns.TsvectorColumn

public interface Table

/**
 * Represents a Table
 *
 * @param T Entity type associated with this table
 */
public abstract class AbstractTable(internal val tableName: String?) : Table {
    internal lateinit var kotysaName: String
    internal val kotysaColumns = mutableSetOf>()
    internal lateinit var kotysaPk: PrimaryKey
    internal val kotysaForeignKeys = mutableSetOf>()
    internal val kotysaIndexes = mutableSetOf>()

    protected fun primaryKey(
        columns: Set>,
        pkName: String? = null,
    ): PrimaryKey {
        check(!::kotysaPk.isInitialized) {
            "Table must not declare more than one Primary Key"
        }
        return PrimaryKey(pkName, columns).also { primaryKey -> kotysaPk = primaryKey }
    }

    protected fun primaryKey(vararg columns: AbstractDbColumn): PrimaryKey = primaryKey(columns.toSet())

    protected fun  U.primaryKey(pkName: String? = null)
            : U where U : AbstractDbColumn,
                      U : ColumnNotNull {
        check(!isPkInitialized()) {
            "Table must not declare more than one Primary Key"
        }
        kotysaPk = PrimaryKey(pkName, setOf(this))
        return this
    }

    /*protected fun  foreignKey(
            referencedTable: H2Table,
            vararg columns: DbColumn,
            fkName: String? = null
    ) {
        foreignKeys.add(ForeignKey(referencedTable, columns.toList(), fkName))
    }*/

    protected fun , V : Any> U.foreignKey(references: AbstractDbColumn, fkName: String? = null): U =
        this.also {
            kotysaForeignKeys.add(ForeignKey(mapOf(this to references), fkName))
        }

    protected fun index(
        columns: Set>,
        type: IndexType? = null,
        indexName: String? = null,
    ): Index = Index(columns, type, indexName).apply { kotysaIndexes.add(this) }

    protected fun index(vararg columns: AbstractDbColumn): Index = index(columns.toSet())

    protected fun > U.unique(indexName: String? = null): U =
        this.also {
            kotysaIndexes.add(Index(setOf(this), IndexType.UNIQUE, indexName))
        }

    /**
     * Creates a GIN index associated to a tsvector column
     */
    protected fun TsvectorColumn.withGinIndex(indexName: String? = null): TsvectorColumn =
        this.also {
            kotysaIndexes.add(Index(setOf(this), IndexType.GIN, indexName))
        }

    /**
     * Creates a GIN index associated to a tsvector column
     */
    protected fun TsvectorColumn.withGistIndex(indexName: String? = null): TsvectorColumn =
        this.also {
            kotysaIndexes.add(Index(setOf(this), IndexType.GIST, indexName))
        }

    internal fun addColumn(column: AbstractColumn) {
        if (column is AbstractDbColumn) {
            require(!kotysaColumns
                .filterIsInstance>()
                .any { col -> col.entityGetter == column.entityGetter }) {
                "Trying to map property \"${column.entityGetter}\" to multiple columns"
            }
        }
        kotysaColumns += column
    }

    internal fun isPkInitialized() = ::kotysaPk.isInitialized
}