Knowledge Base

¿Qué es esto?

Kotlin: Exposed: Definir tipos de datos que no existen por defecto

13/11/2018 - 27/12/2018 -  Comentarios - Kotlin Exposed

Exposed es un ORM para kotlin creado por Jetbrains que nos facilita la utilización de bases de datos en nuestros proyectos.

Si lo estamos usando, podremos crear tablas mediante las funciones que trae por defecto.

Podríamos por ejemplo crear una tabla de la siguiente manera:

object tabla: Table() {

    val id = integer("id").autoIncrement().primaryKey()

    val campotexto1 = varchar("campotexto1", length = 255)

    val campotexto2 = text("campotexto2")

    val campofecha = datetime("campofecha")

}

En el ejemplo anterior, las funciones varchar, text o datetime nos crearían un campo en la base de datos con esos tipos. Sin embargo, en MySQL por ejemplo existen varios subtipos de campo para el tipo TEXT (TINYTEXT, TEXT, MEDIUMTEXT y LONGTEXT) y la función anterior, que es propia de Exposed, sólo nos podría crear un campo de tipo TEXT. Exposed no dispone de ninguna función propia que nos permitiera crear campos para los otros tipos.

Entonces, ¿qué hacemos si queremos crear un campo de tipo LONGTEXT?. Podemos hacerlo de la siguiente manera:

1) Creamos una clase como la siguiente:

import org.jetbrains.exposed.sql.IColumnType

import org.jetbrains.exposed.sql.TextColumnType

/**

 * This class allows to define new database data types not defined by default by exposed SQL. It does that overriding the original functions

 */

class MySQL() {

    // Class for to create the LONGTEXT type

    class LongTextColumnType : IColumnType by TextColumnType() {

        override fun sqlType(): String = "LONGTEXT"

    }

}

Con esa clase lo que hacemos es definir el nuevo tipo LONGTEXT, usando como base la función que devolvía el campo de tipo TEXT original de exposed, que se encuentra en el fichero ColumnType.kt y que es esta:

open class TextColumnType(collate: String? = null) : StringColumnType(collate) {

    override fun sqlType(): String = buildString {

        append(currentDialect.dataTypeProvider.textType())

        if (collate != null) {

            append(" COLLATE $collate")

        }

    }

}

2) Luego, a la hora de crear la tabla, no utilizaríamos la función text, sino la nueva que acabamos de crear:

object tabla: Table() {

    val id = integer("id").autoIncrement().primaryKey()

    val campotexto1 = varchar("campotexto1", length = 255)

    val campotexto2 = registerColumn<Any>("campotexto2 ", MySQL.LongTextColumnType())

    val campofecha = datetime("campofecha")

}

Donde podremos ver en negrita como llamamos a la clase que hemos creado anteriormente. Al ejecutar ese código, podremos ver cómo nos ha creado el campo con el tipo LONGTEXT.