diff --git a/documentation-website/Writerside/topics/DAO-Table-Types.topic b/documentation-website/Writerside/topics/DAO-Table-Types.topic index 7bf03b8e23..214967a260 100644 --- a/documentation-website/Writerside/topics/DAO-Table-Types.topic +++ b/documentation-website/Writerside/topics/DAO-Table-Types.topic @@ -11,7 +11,10 @@

Apart from the core Table class, Exposed provides the base - IdTable class and its subclasses through the DAO API. + + IdTable + + class and its subclasses through the DAO API.

The IdTable class extends Table and is diff --git a/documentation-website/Writerside/topics/Data-Types.topic b/documentation-website/Writerside/topics/Data-Types.topic index 0904e208c8..663c984f6c 100644 --- a/documentation-website/Writerside/topics/Data-Types.topic +++ b/documentation-website/Writerside/topics/Data-Types.topic @@ -6,44 +6,119 @@

Exposed supports the following data types in the table definition:

- -
  • integer - translates to DB INT
  • -
  • short - translates to DB SMALLINT
  • -
  • long - BIGINT
  • -
  • float - FLOAT
  • -
  • decimal - DECIMAL with scale and precision
  • -
  • bool - BOOLEAN
  • -
  • char - CHAR
  • -
  • varchar - VARCHAR with length
  • -
  • text - TEXT
  • -
  • enumeration - INT ordinal value
  • -
  • enumerationByName - VARCHAR
  • -
  • customEnumeration - see additional section
  • -
  • blob - BLOB
  • -
  • binary - VARBINARY with length
  • -
  • uuid - BINARY(16)
  • -
  • reference - a foreign key
  • -
  • array - ARRAY
  • -
    + + + <code>integer</code> + Translates to a database INT + + + <code>short</code> + Translates to DB SMALLINT + + + <code>long</code> + BIGINT + + + <code>float</code> + FLOAT + + + <code>decimal</code> + DECIMAL with scale and precision + + + <code>bool</code> + BOOLEAN + + + <code>char</code> + CHAR + + + <code>varchar</code> + VARCHAR with length + + + <code>text</code> + TEXT + + + <code>enumeration</code> + INT ordinal value + + + <code>enumerationByName</code> + VARCHAR + + + <code>customEnumeration</code> + See additional section + + + <code>blob</code> + BLOB + + + <code>binary</code> + VARBINARY with length + + + <code>uuid</code> + BINARY(16) + + + <code>reference</code> + A foreign key + + + <code>array</code> + ARRAY + +

    The exposed-java-time extension (org.jetbrains.exposed:exposed-java-time:$exposed_version) provides additional types:

    - -
  • date - DATETIME
  • -
  • time - TIME
  • -
  • datetime - DATETIME
  • -
  • timestamp - TIMESTAMP
  • -
  • duration - DURATION
  • -
    + + + <code>date</code> + DATETIME + + + <code>time</code> + TIME + + + <code>datetime</code> + DATETIME + + + <code>timestamp</code> + TIMESTAMP + + + <code>duration</code> + DURATION + + - Some types are different for specific DB dialect. + Some types may differ for specific database dialects. -

    The exposed-json extension (org.jetbrains.exposed:exposed-json:$exposed_version) - provides additional types - (see how to use):

    - -
  • json - JSON
  • -
  • jsonb - JSONB
  • -
    +

    + The exposed-json extension (org.jetbrains.exposed:exposed-json:$exposed_version) + provides the following additional types. For more information, see + + : +

    + + + <code>json</code> + JSON + + + <code>jsonb</code> + JSONB + + Databases store JSON values either in text or binary format, so Exposed provides two types to account for any potential @@ -69,28 +144,40 @@ - -

    Some of the databases (e.g. MySQL, PostgreSQL, H2) support explicit ENUM types. Because keeping such columns - in sync with - Kotlin enumerations using only JDBC metadata could be a huge challenge, Exposed doesn't provide a - possibility to manage - such columns in an automatic way, but that doesn't mean that you can't use such column types.

    -

    You have two options to work with ENUM database types and you should use customEnumeration() - (available since version 0.10.3) in both cases:

    + +

    + Some databases (e.g. MySQL, PostgreSQL, H2) support explicit enum types. Because keeping such columns + in sync with Kotlin enumerations using only JDBC metadata could be a huge challenge, Exposed doesn't + provide a possibility to manage such columns in an automatic way, but that doesn't mean that you can't + use such column types. +

    +

    + To work with enum database types, use the + + .customEnumeration() + + function in one of the following ways: +

    -
  • Use an existing ENUM column from your table. In this case, the sql parameter in customEnumeration() +
  • + Use an existing enum column from your table. + In this case, the sql parameter in .customEnumeration() can be left as null.
  • -
  • Create a new ENUM column using Exposed by providing the raw definition SQL to the sql - parameter in customEnumeration(). +
  • + Create a new ENUM column using Exposed by providing the raw definition SQL to the sql + parameter in .customEnumeration().
  • -

    As a JDBC driver can provide/expect specific classes for ENUM types, you must also provide from/to - transformation functions for - them when defining a customEnumeration.

    -

    For a class like enum class Foo { BAR, BAZ }, you can use the provided code below for your - specific database:

    - +

    + As a JDBC driver can provide/expect specific classes for enum types, you must also provide from/to + transformation functions for them when defining a custom enumeration. +

    +

    + For a class like enum class Foo { BAR, BAZ }, you can use the following code for your + specific database: +

    + val existingEnumColumn = customEnumeration("enumColumn", { value -> Foo.valueOf(value as String) }, { it.name }) @@ -98,7 +185,7 @@ -

    PostgreSQL requires that ENUM is defined as a separate type, so you have to create it before creating +

    PostgreSQL requires that enum is defined as a separate type, so you have to create it before creating your table. Also, the PostgreSQL JDBC driver returns PGobject instances for such values, so a PGobject with its type manually set to the ENUM type needs to be used for the toDb parameter. @@ -124,8 +211,11 @@ -

    Add the following dependencies to your build.gradle.kts:

    - +

    + Add the following dependencies to your + build.gradle.kts + : +

    val exposedVersion: String by project @@ -143,7 +233,11 @@ fun jsonb(name: String, serialize: (T) -> String, deserialize: (String) -> T): Column ]]> -

    Here's an example that leverages kotlinx.serialization +

    + Here's an example that leverages + + kotlinx.serialization + to support @Serializable classes. It uses a simpler form of json() that relies on the library's KSerializer interface:

    @@ -187,7 +281,7 @@ val project = json("project", { mapper.writeValueAsString(it) }, { mapper.readValue(it) }) } ]]> - +

    JSON path strings can be used to extract values (either as JSON or as a scalar value) at a specific field/key:

    @@ -203,7 +297,16 @@ if MySQL is being used, the provided path arguments should be .name and .language respectively. -

    The JSON functions exists() and contains() are currently supported as well:

    +

    The JSON functions + + .exists() + + and + + .contains() + + are currently supported as well: +

    val hasActiveStatus = Teams.project.exists(".active") @@ -224,7 +327,7 @@ val kotlinTeams = Teams.selectAll().where { usesKotlin }.count()
    - +

    JSON columns also accept JSON arrays as input values. For example, using the serializable data class Project from the example above, the following details some ways to create such a column:

    @@ -251,9 +354,9 @@ ]]>
    - -

    PostgreSQL and H2 databases support the explicit ARRAY data type, - with multi-dimensional arrays being supported by PostgreSQL.

    + +

    PostgreSQL and H2 databases support the explicit array data type, + with multidimensional arrays being supported by PostgreSQL.

    Exposed allows defining columns as arrays, with the stored contents being any out-of-the-box or custom data type. If the contents are of a type with a supported ColumnType in the exposed-core module, @@ -318,7 +421,7 @@ } } } } - +

    A single element in a stored array can be accessed using the index reference get() operator:

    @@ -340,20 +443,28 @@ Both PostgreSQL and H2 use a one-based indexing convention, so the first element is retrieved by using index 1. -

    A new subarray can also be accessed by using slice(), which takes a lower and upper bound - (inclusive):

    +

    + A new subarray can also be accessed by using + + .slice() + + , which takes a lower and upper bound + (inclusive): +

    Teams.select(Teams.deadlines.slice(1, 3)) -

    In the case of multidimensional arrays, the slice() calls can be nested:

    +

    In the case of multidimensional arrays, the .slice() calls can be nested:

    Teams.select(Teams.hierarchicalMemberNames.slice(1, 2).slice(3, 4))

    Both arguments for these bounds are optional if using PostgreSQL.

    -

    An array column can also be used as an argument for the ANY and ALL SQL - operators, either by providing the entire column or a new array expression via slice():

    +

    + An array column can also be used as an argument for the ANY and ALL SQL + operators, either by providing the entire column or a new array expression via .slice(): +

    Teams @@ -366,10 +477,15 @@
    - -

    If a database-specific data type is not immediately supported by Exposed, any existing and open column type - class can be extended or - a custom ColumnType class can be implemented to achieve the same functionality.

    + +

    + If a database-specific data type is not immediately supported by Exposed, any existing and open column type + class can be extended, or a custom + + ColumnType + + class can be implemented to achieve the same functionality. +

    The following examples describe different ways to customize a column type, register a column with the custom type, and then start using it in transactions.

    @@ -864,18 +980,28 @@ ) } -

    The transform function is used to apply custom transformations to the mealTime - column:

    +

    + The + + .transform() + + function is used to apply custom transformations to the mealTime + column: +

    -
  • The wrap function transforms the stored LocalTime values into +
  • The wrap() function transforms the stored LocalTime values into Meal enums. It checks the hour of the stored time and returns the corresponding meal type.
  • -
  • The unwrap function transforms Meal enums back into LocalTime +
  • The unwrap() function transforms Meal enums back into LocalTime values for storage in the database.
  • -

    Transformation could be also defined as an implementation of ColumnTransformer interface and - reused among different tables:

    +

    Transformation could be also defined as an implementation of the + + ColumnTransformer + + interface and reused across different tables: +

    class MealTimeTransformer : ColumnTransformer<LocalTime, Meal> { @@ -905,9 +1031,12 @@

    - Special case is nullTransform() method. - That method applies a special transformation that allows a non-nullable database column - to accept and/or return values as `null` on the client side. + The + + .nullTransform() + + method applies a special transformation that allows a non-nullable database column + to accept and/or return values as null on the client side.

    diff --git a/documentation-website/Writerside/topics/SQL-Functions.md b/documentation-website/Writerside/topics/SQL-Functions.md index e8ff51c155..746ebd1192 100644 --- a/documentation-website/Writerside/topics/SQL-Functions.md +++ b/documentation-website/Writerside/topics/SQL-Functions.md @@ -20,36 +20,48 @@ val fullNames = FooTable.select(trimmedAndLoweredFullName).map { it[trimmedAndLo ``` ## String functions -### LowerCase/UpperCase -Returns a lower-cased/upper-cased string value. +### Lower case and upper case +To convert a string expression to lower-case or upper-case, use the [`.lowerCase()`](https://jetbrains.github.io/Exposed/api/exposed-core/org.jetbrains.exposed.sql/lower-case.html) +and +[`.upperCase()`](https://jetbrains.github.io/Exposed/api/exposed-core/org.jetbrains.exposed.sql/upper-case.html) +functions respectively. + ```kotlin val lowerCasedName = FooTable.name.lowerCase() val lowerCasedNames = FooTable.select(lowerCasedName).map { it[lowerCasedName] } ``` ### Substring -Returns a substring value from the specified start and with the specified length. +The [.substring()](https://jetbrains.github.io/Exposed/api/exposed-core/org.jetbrains.exposed.sql/substring.html) +function returns a substring value from the specified start and with the specified length. + ```kotlin val shortenedName = FooTable.name.substring(start = 1, length = 3) val shortenedNames = FooTable.select(shortenedName).map { it[shortenedName] } ``` -### Concat -Returns a string value that concatenates the text representations of all non-null input values, separated by an optional separator. +### Concatenate +The [concat()](https://jetbrains.github.io/Exposed/api/exposed-core/org.jetbrains.exposed.sql/-i-sql-expression-builder/concat.html) +function returns a string value that concatenates the text representations of all non-null input values, separated by an optional separator. + ```kotlin val userName = concat(stringLiteral("User - "), FooTable.name) val userNames = FooTable.select(userName).map { it[userName] } ``` ### Locate -Returns the index of the first occurrence of a specified substring or 0. +The [.locate()](https://jetbrains.github.io/Exposed/api/exposed-core/org.jetbrains.exposed.sql/locate.html) +function returns the index of the first occurrence of a specified substring or 0. + ```kotlin val firstAIndex = FooTable.name.locate("a") val firstAIndices = FooTable.select(firstAIndex).map { it[firstAIndex] } ``` -### CharLength -Returns the length, measured in characters, or `null` if the String value is null. +### Character length +The [.charLength()](https://jetbrains.github.io/Exposed/api/exposed-core/org.jetbrains.exposed.sql/char-length.html) +function returns the length, measured in characters, or `null` if the String value is null. + ```kotlin val nameLength = FooTable.name.charLength() val nameLengths = FooTable.select(nameLength).map { it[nameLength] } @@ -59,7 +71,12 @@ val nameLengths = FooTable.select(nameLength).map { it[nameLength] } ## Aggregating functions These functions should be used in queries with [groupBy](DSL-Querying-data.topic#group-by). ### Min/Max/Average -Returns minimum/maximum/average value and can be applied to any comparable expression: +To get the minimum, maximum, and average values, use the +[.min()](https://jetbrains.github.io/Exposed/api/exposed-core/org.jetbrains.exposed.sql/min.html) +[.max()](https://jetbrains.github.io/Exposed/api/exposed-core/org.jetbrains.exposed.sql/max.html) +and [.avg](https://jetbrains.github.io/Exposed/api/exposed-core/org.jetbrains.exposed.sql/avg.html) functions +respectively. These functions can be applied to any comparable expression: + ```kotlin val minId = FooTable.id.min() val maxId = FooTable.id.max() @@ -88,9 +105,9 @@ val replacedName = CustomFunction("REPLACE", VarCharColumnType(), FooTa `CustomFunction` class accepts a function name as a first parameter and the resulting column type as second. After that, you can provide any amount of parameters separated by a comma. There are also shortcuts for string, long, and datetime functions: -* `CustomStringFunction` -* `CustomLongFunction` -* `CustomDateTimeFunction` +* [`CustomStringFunction`](https://jetbrains.github.io/Exposed/api/exposed-core/org.jetbrains.exposed.sql/-custom-string-function.html) +* [`CustomLongFunction`](https://jetbrains.github.io/Exposed/api/exposed-core/org.jetbrains.exposed.sql/-custom-long-function.html) +* [`CustomDateTimeFunction`](https://jetbrains.github.io/Exposed/api/exposed-jodatime/org.jetbrains.exposed.sql.jodatime/-custom-date-time-function.html) The code above could be simplified to: ```kotlin @@ -109,9 +126,14 @@ val lastDayOfMonth = CustomDateFunction( ``` 3. Function that requires more complex query building: -All functions in Exposed extend the abstract class `Function`, which takes a column type and allows overriding `toQueryBuilder()`. This is what `CustomFunction` actually does, which can be leveraged to create more complex queries. +All functions in Exposed extend the abstract class [`Function`](https://jetbrains.github.io/Exposed/api/exposed-core/org.jetbrains.exposed.sql/-function/index.html), +which takes a column type and allows overriding `toQueryBuilder()`. This is what `CustomFunction` actually does, +which can be leveraged to create more complex queries. + +For example, Exposed provides a `trim()` function that removes leading and trailing whitespace from a String. In MySQL, +this is just the default behavior as specifiers can be provided to limit the trim to either leading or trailing, as well +as providing a specific substring other than spaces to remove. The custom function below supports this extended behavior: -For example, Exposed provides a `trim()` function that removes leading and trailing whitespace from a String. In MySQL, this is just the default behavior as specifiers can be provided to limit the trim to either leading or trailing, as well as providing a specific substring other than spaces to remove. The custom function below supports this extended behavior: ```kotlin enum class TrimSpecifier { BOTH, LEADING, TRAILING } diff --git a/documentation-website/Writerside/topics/Working-with-Schema.topic b/documentation-website/Writerside/topics/Working-with-Schema.topic index dcf83ebf56..e3a0c920a5 100644 --- a/documentation-website/Writerside/topics/Working-with-Schema.topic +++ b/documentation-website/Writerside/topics/Working-with-Schema.topic @@ -10,7 +10,11 @@

    - To define a schema in Exposed, use the Schema class: + To define a schema in Exposed, use the + + Schema + + class:

    val schema = Schema("my_schema") // my_schema is the schema name. @@ -23,14 +27,21 @@

    - To create a new schema, use the createSchema() method provided by SchemaUtils: + To create a new schema, use the + + .createSchema() + + method provided by SchemaUtils:

    SchemaUtils.createSchema(schema)
    -

    If you have many schemas, and you want to set a default one, you can use the setSchema() +

    If you have many schemas, and you want to set a default one, you can use the + + .setSchema() + method from SchemaUtils:

    @@ -39,7 +50,11 @@

    - To drop a schema, use the dropSchema() method provided by SchemaUtils: + To drop a schema, use the + + .dropSchema() + + method provided by SchemaUtils:

    SchemaUtils.dropSchema(schema) diff --git a/documentation-website/Writerside/topics/Working-with-Tables.topic b/documentation-website/Writerside/topics/Working-with-Tables.topic index d262042c38..97a5374e83 100644 --- a/documentation-website/Writerside/topics/Working-with-Tables.topic +++ b/documentation-website/Writerside/topics/Working-with-Tables.topic @@ -20,7 +20,7 @@

    - A database table is represented by an object inherited from a table class. + A database table is represented by an object inherited from a Table class.

    object StarWarsFilms : Table() {} @@ -74,7 +74,7 @@ include-lines="10-14"/>

    To configure a custom name for a table, which will be used in actual SQL queries, pass it to the name - parameter of the Table() constructor. + parameter of the Table constructor.

    -

    The NOT NULL SQL constraint restricts the column to accept the null value. By +

    + The NOT NULL SQL constraint restricts the column to accept the null value. By default, Exposed applies this constraint to - all the columns. To allow the column to be nullable, apply the nullable() method to a - definition of an appropriate column.

    -

    For example, to make the population column nullable, use the following code:

    - + all the columns. To allow the column to be nullable, apply the + + .nullable() + + method to a definition of an appropriate column.

    +

    + For example, to make the population column nullable, use the following code: +

    // SQL: POPULATION INT NULL val population: Column<Int?> = integer("population").nullable() @@ -112,12 +117,28 @@ methods for configuring default values:

    -
  • default(defaultValue: T) accepts a value with a type of the column.
  • -
  • defaultExpression(defaultValue: Expression<T>) accepts an expression.
  • -
  • clientDefault(defaultValue: () -> T) accepts a function.
  • +
  • + + default(defaultValue: T) + + accepts a value with a type of the column. +
  • +
  • + + defaultExpression(defaultValue: Expression<T>) + + accepts an expression. +
  • +
  • + + clientDefault(defaultValue: () -> T) + + accepts a function. +
  • -

    For example, to configure the default value for the name column, use the following code:

    - +

    + For example, to configure the default value for the name column, use the following code: +

    // SQL: "NAME" VARCHAR(50) DEFAULT 'Unknown' val name: Column<String> = varchar("name", 50).default("Unknown") @@ -127,8 +148,8 @@ time of table creation and/or if it depends on other columns. It makes it possible to omit setting a value for the column when inserting a new record, without getting an error. The value for the column can be set by - creating a TRIGGER - or with a DEFAULT clause, for example.

    + creating a TRIGGER + or with a DEFAULT clause, for example.

    For example:

    @@ -136,25 +157,39 @@
    -

    The INDEX SQL constraint makes traversing through tables quicker. Exposed supports the - index() method. - It has six parameters, most of which are optional:

    - -
  • val customIndexName: String? = null is a custom name for the index, which will be used - in actual SQL queries. -
  • -
  • val unique: Boolean defines whether the index is unique or not.
  • -
  • val columns: List<Column<*>> defines a column set.
  • -
  • val functions: List<ExpressionWithColumnType<*>>? = null defines functional - key parts. -
  • -
  • val indexType: String? = null is a custom type. Can be "BTREE" - or "HASH". -
  • -
  • val filterCondition: (SqlExpressionBuilder.() -> Op<Boolean>)? = null defines - a condition used to create a partial index. -
  • -
    +

    + The INDEX SQL constraint makes traversing through tables quicker. Exposed supports the + + .index() + + method. It has six parameters, most of which are optional: +

    + + + <code>customIndexName: String? = null</code> + A custom name for the index, which will be used in actual SQL queries. + + + <code>unique: Boolean</code> + Defines whether the index is unique or not. + + + <code>columns: List<Column<*>></code> + Defines a column set. + + + <code>functions: List<ExpressionWithColumnType<*>>? = null</code> + Defines functional key parts. + + + <code>indexType: String? = null</code> + A custom type. Can be "BTREE" or "HASH". + + + <code>filterCondition: (SqlExpressionBuilder.() -> Op<Boolean>)? = null</code> + Defines a condition used to create a partial index. + +

    The simplest way to create an index is to use an extension function directly on a column. For example, to apply a non-unique INDEX constraint to the name column, use the following code:

    @@ -162,28 +197,36 @@ val name = varchar("name", 50).index() -

    If the parameter customIndexName is not set, the name of the index is determined by the - table and column names.

    -

    Also, Exposed supports complex indexes. If you have a frequent query for two columns, Exposed can perform - it more efficiently. - It creates a tree from the first column with the references to the second one. For example, to create a - non-unique complex - index on the name and population columns, paste the following code:

    +

    + If the customIndexName parameter is not set, the name of the index is determined by the + table and column names. +

    + +

    + If you have a frequent query for two columns, Exposed can perform it more efficiently. + It creates a tree from the first column with the references to the second one. For example, + to create a non-unique complex index on the name and population columns, + paste the following code: +

    + + val indexName = index("indexName", false, *arrayOf(name, population)) + // or inside an init block within the table object + init { + index("indexName", isUnique = false, name, population) + } + +
    + +

    + Exposed also supports creating an index with a custom type. For example, to retrieve data from the + name column faster with a hash function for traversing, use the following code: +

    - - val indexName = index("indexName", false, *arrayOf(name, population)) - // or inside an init block within the table object - init { - index("indexName", isUnique = false, name, population) - } - -

    Exposed also supports creating an index with a custom type. For example, to retrieve data from the name - column faster - with a hash function for traversing, use the following code:

    + + val indexName = index("indexName", false, *arrayOf(name), indexType = "HASH") + +
    - - val indexName = index("indexName", false, *arrayOf(name), indexType = "HASH") -

    Some databases support functional key parts that index expressions instead of columns directly:

    @@ -195,12 +238,14 @@ ) } -

    Operator expressions, like plus(), are also accepted by the functions - parameter.

    -

    Some databases support creating a partial index by defining a filter expression to improve querying - performance. The - created index will only contain entries for the table rows that match this predicate:

    - +

    + Operator expressions, like plus(), are also accepted by the functions + parameter. +

    +

    + Some databases support creating a partial index by defining a filter expression to improve querying + performance. The created index will only contain entries for the table rows that match this predicate: +

    init { index(columns = arrayOf(name, flag)) { flag eq true } @@ -212,14 +257,18 @@ ) { (name like "A%") and (population greaterEq 10) } } -

    Once a table has been created, the list of its indices can be accessed using the property Table.indices. - Table indices - are represented by the data class Index, so its properties can be checked in the following - manner, for example:

    - - - Table.indices.map { it.indexName to it.createStatement().first() } - + +

    + Once a table has been created, the list of its indices can be accessed using the property + Table.indices. Table indices are represented by the data class + + Index + + , so its properties can be checked in the following way:

    + + Table.indices.map { it.indexName to it.createStatement().first() } + +
    An instance of the Index data class can be created directly using its public constructor, for the purpose of @@ -231,28 +280,35 @@
    -

    The UNIQUE SQL constraint restricts duplicates within this column. Exposed supports the - uniqueIndex() method which - creates a unique index for the column. This method is the composition of UNIQUE and INDEX - constraint, the quicker - modification of UNIQUE constraint.

    -

    For example, to apply UNIQUE and INDEX constraint to the name - column, use the following code:

    - +

    + The UNIQUE SQL constraint restricts duplicates within this column. Exposed supports the + + .uniqueIndex() + + method which creates a unique index for the column. This method is the composition of + UNIQUE and INDEX constraint, the quicker modification of UNIQUE + constraint. +

    +

    + For example, to apply UNIQUE and INDEX constraint to the name + column, use the following code: +

    val name = varchar("name", 50).uniqueIndex()
    -

    The PRIMARY KEY SQL constraint applied to a column means each value in that column +

    + The PRIMARY KEY SQL constraint applied to a column means each value in that column identifies the row. This constraint is the composition of NOT NULL and UNIQUE constraints. To change the column set, add columns, or - change the primary key name to a custom one, override this field of the table class.

    -

    For example, to define the name column as the primary key, use the following code. The - "Cities_name" string - will be used as the constraint name in the actual SQL query, if provided; otherwise a name will be - generated based on the table's name.

    - + change the primary key name to a custom one, override this field of the table class. +

    +

    + For example, to define the name column as the primary key, use the following code. The + "Cities_name" string will be used as the constraint name in the actual SQL query, if provided; + otherwise a name will be generated based on the table's name. +

    override val primaryKey = PrimaryKey(name, name = "Cities_name") @@ -260,8 +316,9 @@ CONSTRAINT Cities_name PRIMARY KEY ("name") -

    It is also possible to define a primary key on a table using multiple columns:

    - +

    + It is also possible to define a primary key on a table using multiple columns: +

    override val primaryKey = PrimaryKey(id, name) @@ -269,13 +326,17 @@ CONSTRAINT pk_Cities PRIMARY KEY (ID, "name") -

    Except for CompositeIdTable, each available class in Exposed that inherits from IdTable +

    + Except for CompositeIdTable, each available class in Exposed that inherits from IdTable has the primaryKey field automatically defined. For example, the IntIdTable by default has an auto-incrementing integer column, - id, which is defined as the primary key.

    -

    An IdTable that requires a primary key with multiple columns can be defined using CompositeIdTable. - In this case, each column that is a component of the table's id should be identified by - entityId():

    + id, which is defined as the primary key. +

    +

    + An IdTable that requires a primary key with multiple columns can be defined using CompositeIdTable. + In this case, each column that is a component of the table's ID should be identified by + .entityId(): +

    object Towns : CompositeIdTable("towns") { @@ -315,13 +376,24 @@
    -

    The FOREIGN KEY SQL constraint links two tables. A foreign key is a column from one table - that refers to the primary key - or columns with a unique index from another table. To configure a foreign key on a column, use reference() - or optReference() +

    + The FOREIGN KEY SQL constraint links two tables. A foreign key is a column from one table + that refers to the primary key or columns with a unique index from another table. To configure a + foreign key on a column, use + + reference() + + or + + optReference() + methods. The latter lets the foreign key accept a null value. To configure a foreign key on - multiple columns, - use foreignKey() directly within an init block.

    + multiple columns, use the + + foreignKey() + + function directly within an init block. +

    reference() and optReference() methods have several parameters:

    @@ -345,27 +417,33 @@

    A name for the foreign key constraint.

    -

    Enum class ReferenceOption has five values:

    - - +

    + Enum class + + ReferenceOption + + has five values: +

    + + <code>RESTRICT</code>

    An option that restricts changes on a referenced column, and the default option for most dialects.

    - + <code>NO_ACTION</code> -

    The same as RESTRICT in some, but not all, databases, and the default option for Oracle and SQL - Server dialects.

    +

    The same as RESTRICT in some, but not all, databases, and the default option for + Oracle and SQL Server dialects.

    - + <code>CASCADE</code>

    An option that allows updating or deleting the referring rows.

    - + <code>SET_NULL</code> -

    An option that sets the referring column values to null.

    +

    An option that sets the referring column values to null.

    - + <code>SET_DEFAULT</code>

    An option that sets the referring column values to the default value.

    @@ -413,12 +491,18 @@
    -

    The CHECK SQL constraint checks that all values in a column match some condition. Exposed - supports the check() method. - You apply this method to a column and pass the appropriate condition to it.

    -

    For example, to check that the name column contains strings that begin with a capital - letter, use the following code:

    - +

    + The CHECK SQL constraint checks that all values in a column match some condition. Exposed + supports the + + .check() + + method. You apply this method to a column and pass the appropriate condition to it. +

    +

    + For example, to check that the name column contains strings that begin with a capital + letter, use the following code: +

    // SQL: CONSTRAINT check_Cities_0 CHECK (REGEXP_LIKE("NAME", '^[A-Z].*', 'c'))) val name = varchar("name", 50).check { it regexp "^[A-Z].*" } @@ -429,8 +513,15 @@

    - To create a table within a database, you need to use the SchemaUtils.create() - method within a transaction: + To create a table within a database, you need to use the + + SchemaUtils.create() + + method within a + + transaction + + :

    transaction {