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, 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") }