73 lines
3.0 KiB
Kotlin
73 lines
3.0 KiB
Kotlin
package solutions.bitbadger.documents.query
|
|
|
|
import solutions.bitbadger.documents.Configuration
|
|
import solutions.bitbadger.documents.Dialect
|
|
import solutions.bitbadger.documents.Field
|
|
import solutions.bitbadger.documents.FieldFormat
|
|
|
|
/**
|
|
* Functions to create queries to define tables and indexes
|
|
*/
|
|
object Definition {
|
|
|
|
/**
|
|
* SQL statement to create a document table
|
|
*
|
|
* @param tableName The name of the table to create (may include schema)
|
|
* @param dataType The type of data for the column (`JSON`, `JSONB`, etc.)
|
|
* @return A query to create a document table
|
|
*/
|
|
fun ensureTableFor(tableName: String, dataType: String) =
|
|
"CREATE TABLE IF NOT EXISTS $tableName (data $dataType NOT NULL)"
|
|
|
|
/**
|
|
* SQL statement to create a document table in the current dialect
|
|
*
|
|
* @param tableName The name of the table to create (may include schema)
|
|
* @return A query to create a document table
|
|
*/
|
|
fun ensureTable(tableName: String) =
|
|
when (Configuration.dialect("create table creation query")) {
|
|
Dialect.POSTGRESQL -> ensureTableFor(tableName, "JSONB")
|
|
Dialect.SQLITE -> ensureTableFor(tableName, "TEXT")
|
|
}
|
|
|
|
/**
|
|
* Split a schema and table name
|
|
*
|
|
* @param tableName The name of the table, possibly with a schema
|
|
* @return A pair with the first item as the schema and the second as the table name
|
|
*/
|
|
private fun splitSchemaAndTable(tableName: String) =
|
|
tableName.split('.').let { if (it.size == 1) Pair("", tableName) else Pair(it[0], it[1]) }
|
|
|
|
/**
|
|
* SQL statement to create an index on one or more fields in a JSON document
|
|
*
|
|
* @param tableName The table on which an index should be created (may include schema)
|
|
* @param indexName The name of the index to be created
|
|
* @param fields One or more fields to include in the index
|
|
* @param dialect The SQL dialect to use when creating this index
|
|
* @return A query to create the field index
|
|
*/
|
|
fun ensureIndexOn(tableName: String, indexName: String, fields: Collection<String>, dialect: Dialect): String {
|
|
val (_, tbl) = splitSchemaAndTable(tableName)
|
|
val jsonFields = fields.joinToString(", ") {
|
|
val parts = it.split(' ')
|
|
val direction = if (parts.size > 1) " ${parts[1]}" else ""
|
|
"(" + Field.nameToPath(parts[0], dialect, FieldFormat.SQL) + ")$direction"
|
|
}
|
|
return "CREATE INDEX IF NOT EXISTS idx_${tbl}_$indexName ON $tableName ($jsonFields)"
|
|
}
|
|
|
|
/**
|
|
* SQL statement to create a key index for a document table
|
|
*
|
|
* @param tableName The table on which a key index should be created (may include schema)
|
|
* @param dialect The SQL dialect to use when creating this index
|
|
* @return A query to create the key index
|
|
*/
|
|
fun ensureKey(tableName: String, dialect: Dialect) =
|
|
ensureIndexOn(tableName, "key", listOf(Configuration.idField), dialect).replace("INDEX", "UNIQUE INDEX")
|
|
}
|