Skip to content

Commit

Permalink
docs: Add missing KDocs for exposed-core api package (#1896)
Browse files Browse the repository at this point in the history
* docs: Add missing KDocs for exposed-core api package

Add KDocs to `statements.api` package.
  • Loading branch information
bog-walk authored Nov 25, 2023
1 parent 84723ce commit 6e74f94
Show file tree
Hide file tree
Showing 7 changed files with 134 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,68 @@

package org.jetbrains.exposed.sql.statements.api

/** Represents a wrapper for a database connection. */
interface ExposedConnection<OriginalConnection : Any> {
/** Whether the connection has been closed. */
val isClosed: Boolean

/** Saves all changes since the last commit or rollback operation. */
fun commit()

/** Reverts all changes since the last commit or rollback operation. */
fun rollback()

/** Closes the connection and releases any of its database and/or driver resources. */
fun close()

/** Whether the connection is in auto-commit mode. */
var autoCommit: Boolean

/** Whether the connection is in read-only mode. */
var readOnly: Boolean

/** The transaction isolation level of the connection. */
var transactionIsolation: Int

/** The underlying database connection object contained by this wrapper. */
val connection: OriginalConnection

/**
* Returns a precompiled [sql] statement stored as a [PreparedStatementApi] implementation.
*
* To indicate that auto-generated keys should be made available for retrieval, set [returnKeys] to `true`.
*/
fun prepareStatement(sql: String, returnKeys: Boolean): PreparedStatementApi

/**
* Returns a precompiled [sql] statement stored as a [PreparedStatementApi] implementation.
*
* To indicate that auto-generated keys should be made available for retrieval, provide the names of
* the target [columns] that contain the keys to be returned.
*/
fun prepareStatement(sql: String, columns: Array<String>): PreparedStatementApi

/** Sends a collection of SQL strings to the database for execution as a batch statement. */
fun executeInBatch(sqls: List<String>)

/** The name of the connection's catalog. */
var catalog: String

/** The name of the connection's schema. */
var schema: String

/**
* Calls the specified function [body] with an [ExposedDatabaseMetadata] implementation as its receiver and
* returns the retrieved metadata as a result.
*/
fun <T> metadata(body: ExposedDatabaseMetadata.() -> T): T

/** Sets and returns a new savepoint with the specified [name]. */
fun setSavepoint(name: String): ExposedSavepoint

/** Removes the specified [savepoint]. */
fun releaseSavepoint(savepoint: ExposedSavepoint)

/** Reverts all changes since the specified [savepoint] was set. */
fun rollback(savepoint: ExposedSavepoint)
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ import org.jetbrains.exposed.sql.vendors.currentDialectIfAvailable
import java.io.IOException
import java.io.InputStream

/** Represents a wrapper for an [inputStream] of bytes to be used in binary columns. */
class ExposedBlob(inputStream: InputStream) {
constructor(bytes: ByteArray) : this (bytes.inputStream())

/** The [InputStream] contained by this wrapper. */
var inputStream = inputStream
private set

/** The `ByteArray` returned as a result of reading the contained [InputStream] completely. */
val bytes: ByteArray
get() = inputStream.readBytes().also {
if (inputStream.markSupported()) {
Expand All @@ -35,6 +38,7 @@ class ExposedBlob(inputStream: InputStream) {

override fun hashCode(): Int = bytes.contentHashCode()

/** Returns the hex-encoded string of the contained [InputStream] after being read. */
fun hexString(): String = bytes.toHexString()

/** Returns the hex-encoded string of a ByteArray. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,40 +8,74 @@ import org.jetbrains.exposed.sql.vendors.PrimaryKeyMetadata
import org.jetbrains.exposed.sql.vendors.SchemaMetadata
import java.math.BigDecimal

/**
* Base class responsible for retrieving and storing information about the JDBC driver and underlying [database].
*/
abstract class ExposedDatabaseMetadata(val database: String) {

/** The connection URL for the database. */
abstract val url: String

/** The version number of the database as a `BigDecimal`. */
abstract val version: BigDecimal

/** The name of the database based on the name of the underlying JDBC driver. */
abstract val databaseDialectName: String

/** The version number of the database product as a `String`. */
abstract val databaseProductVersion: String

/** The default transaction isolation level for the database. */
abstract val defaultIsolationLevel: Int

/** Whether the database supports `ALTER TABLE` with an add column clause. */
abstract val supportsAlterTableWithAddColumn: Boolean

/** Whether the database supports getting multiple result sets from a single execute. */
abstract val supportsMultipleResultSets: Boolean

/** Whether the database supports `SELECT FOR UPDATE` statements. */
abstract val supportsSelectForUpdate: Boolean

@Deprecated(
message = "it's temporary solution which will be replaced in a future releases. Do not use it in your code",
level = DeprecationLevel.ERROR
)
abstract val currentScheme: String

/** Clears and resets any stored information about the database's current schema to default values. */
abstract fun resetCurrentScheme()

/** A mapping of all schema names in the database to a list of all defined table names in each schema. */
abstract val tableNames: Map<String, List<String>>

/** A list of existing schema names. */
abstract val schemaNames: List<String>

/**
* Returns the current schema name and a list of its existing table names, stored as [SchemaMetadata].
*
* A [tableNamesCache] of previously read metadata, if applicable, can be provided to avoid retrieving new metadata.
*/
abstract fun tableNamesByCurrentSchema(tableNamesCache: Map<String, List<String>>?): SchemaMetadata

/** Returns a map with the [ColumnMetadata] of all the defined columns in each of the specified [tables]. */
abstract fun columns(vararg tables: Table): Map<Table, List<ColumnMetadata>>

/** Returns a map with all the defined indices in each of the specified [tables]. */
abstract fun existingIndices(vararg tables: Table): Map<Table, List<Index>>

/** Returns a map with the [PrimaryKeyMetadata] in each of the specified [tables]. */
abstract fun existingPrimaryKeys(vararg tables: Table): Map<Table, PrimaryKeyMetadata?>

/**
* Returns a map with the [ForeignKeyConstraint] of all the defined columns in each of the specified [tables],
* with the table name used as the key.
*/
abstract fun tableConstraints(tables: List<Table>): Map<String, List<ForeignKeyConstraint>>

/** Clears any cached values. */
abstract fun cleanCache()

/** The database-specific and metadata-reliant implementation of [IdentifierManagerApi]. */
abstract val identifierManager: IdentifierManagerApi
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
package org.jetbrains.exposed.sql.statements.api

/**
* Base class representing a savepoint, with the specified [name], which can be referenced during a
* rollback operation to undo any changes made after the point in the transaction.
*/
@Suppress("UnnecessaryAbstractClass")
abstract class ExposedSavepoint(val name: String)
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,50 @@ import org.jetbrains.exposed.sql.vendors.ANSI_SQL_2003_KEYWORDS
import org.jetbrains.exposed.sql.vendors.VENDORS_KEYWORDS
import org.jetbrains.exposed.sql.vendors.currentDialect

/** Base class responsible for the parsing and processing of identifier tokens in SQL command syntax. */
abstract class IdentifierManagerApi {
/** The string used to quote SQL identifiers for the database. */
abstract val quoteString: String

/** Whether the database treats mixed case unquoted identifiers as case-insensitive and stores them in upper case. */
protected abstract val isUpperCaseIdentifiers: Boolean

/** Whether the database treats mixed case quoted identifiers as case-insensitive and stores them in upper case. */
protected abstract val isUpperCaseQuotedIdentifiers: Boolean

/** Whether the database treats mixed case unquoted identifiers as case-insensitive and stores them in lower case. */
protected abstract val isLowerCaseIdentifiers: Boolean

/** Whether the database treats mixed case quoted identifiers as case-insensitive and stores them in lower case. */
protected abstract val isLowerCaseQuotedIdentifiers: Boolean

/** Whether the database treats and stores mixed case unquoted identifiers as case-sensitive. */
protected abstract val supportsMixedIdentifiers: Boolean

/** Whether the database treats and stores mixed case quoted identifiers as case-sensitive. */
protected abstract val supportsMixedQuotedIdentifiers: Boolean

/** Returns all keywords for the database beyond the [ANSI_SQL_2003_KEYWORDS]. */
protected abstract fun dbKeywords(): List<String>
val keywords by lazy { ANSI_SQL_2003_KEYWORDS + VENDORS_KEYWORDS[currentDialect.name].orEmpty() + dbKeywords() }

/** All keywords for the database, including [ANSI_SQL_2003_KEYWORDS] and database-specific keywords. */
val keywords by lazy {
ANSI_SQL_2003_KEYWORDS + VENDORS_KEYWORDS[currentDialect.name].orEmpty() + dbKeywords()
}

/** The database-specific special characters that can be additionally used in unquoted identifiers. */
protected abstract val extraNameCharacters: String

/** The [OracleVersion] of the database, if Oracle is the underlying DBMS; otherwise, [OracleVersion.NonOracle]. */
protected abstract val oracleVersion: OracleVersion

/** The maximum number of characters in a column name allowed by the database. */
protected abstract val maxColumnNameLength: Int

/** Oracle version number classifier. */
protected enum class OracleVersion { Oracle11g, Oracle12_1g, Oracle12plus, NonOracle }

/** The maximum number of characters in an identifier allowed by the database. */
protected val identifierLengthLimit by lazy {
@Suppress("MagicNumber")
when (oracleVersion) {
Expand Down Expand Up @@ -57,6 +85,7 @@ abstract class IdentifierManagerApi {
TransactionManager.currentOrNull()?.db?.config?.preserveKeywordCasing == true
}

/** Returns whether an SQL token should be wrapped in quotations and caches the returned value. */
fun needQuotes(identity: String): Boolean {
return checkedIdentitiesCache.getOrPut(identity.lowercase()) {
!identity.isAlreadyQuoted() && (identity.isAKeyword() || !identity.isIdentifier())
Expand All @@ -65,6 +94,7 @@ abstract class IdentifierManagerApi {

private fun String.isAlreadyQuoted() = startsWith(quoteString) && endsWith(quoteString)

/** Returns whether an [identity] should be wrapped in quotations and caches the returned value. */
fun shouldQuoteIdentifier(identity: String): Boolean = shouldQuoteIdentifiersCache.getOrPut(identity) {
val alreadyQuoted = identity.isAlreadyQuoted()
val alreadyLower = identity == identity.lowercase()
Expand All @@ -81,6 +111,10 @@ abstract class IdentifierManagerApi {
}
}

/**
* Returns an [identity] in a casing appropriate for its identifier status and the database,
* then caches the returned value.
*/
fun inProperCase(identity: String): String = identifiersInProperCaseCache.getOrPut(identity) {
val alreadyQuoted = identity.isAlreadyQuoted()
when {
Expand All @@ -96,6 +130,7 @@ abstract class IdentifierManagerApi {
}
}

/** Returns an SQL token wrapped in quotations, if validated as necessary. */
fun quoteIfNecessary(identity: String): String {
return if (identity.contains('.') && !identity.isAlreadyQuoted()) {
identity.split('.').joinToString(".") { quoteTokenIfNecessary(it) }
Expand All @@ -104,6 +139,7 @@ abstract class IdentifierManagerApi {
}
}

/** Returns an [identity] wrapped in quotations, if validated as necessary. */
fun quoteIdentifierWhenWrongCaseOrNecessary(identity: String): String {
val inProperCase = inProperCase(identity)
return if (shouldQuoteIdentifier(identity) && inProperCase != identity) {
Expand All @@ -113,6 +149,7 @@ abstract class IdentifierManagerApi {
}
}

/** Returns an [identity] wrapped in quotations and containing no more than the maximum [identifierLengthLimit]. */
fun cutIfNecessaryAndQuote(identity: String) = quoteIfNecessary(identity.take(identifierLengthLimit))

private fun quoteTokenIfNecessary(token: String): String = if (needQuotes(token)) quote(token) else token
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,19 @@ import java.io.InputStream
import java.sql.PreparedStatement
import java.sql.ResultSet

/** Represents a precompiled SQL statement. */
@Suppress("TooManyFunctions")
interface PreparedStatementApi {

/** The number of result set rows that should be fetched when generated by an executed statement. */
var fetchSize: Int?

/** The number of seconds the JDBC driver will wait for a statement to execute. */
var timeout: Int?

/**
* Sets the value for each column or expression in [args] into the appropriate statement parameter and
* returns the number of parameters filled.
*/
fun fillParameters(args: Iterable<Pair<IColumnType, Any?>>): Int {
args.forEachIndexed { index, (c, v) ->
c.setParameter(this, index + 1, c.valueToDB(v))
Expand All @@ -21,6 +27,7 @@ interface PreparedStatementApi {
return args.count() + 1
}

/** Adds parameters to the statement's batch of SQL commands. */
fun addBatch()

/**
Expand All @@ -46,14 +53,18 @@ interface PreparedStatementApi {
*/
fun executeMultiple(): List<StatementResult>

/** The [ResultSet] object generated by the executed statement, or `null` if none was retrieved. */
val resultSet: ResultSet?

operator fun set(index: Int, value: Any)

/** Sets the statement parameter at the [index] position to SQL NULL, if allowed wih the specified [columnType]. */
fun setNull(index: Int, columnType: IColumnType)

/** Sets the statement parameter at the [index] position to the provided [inputStream]. */
fun setInputStream(index: Int, inputStream: InputStream)

/** Closes the statement, if still open, and releases any of its database and/or driver resources. */
fun closeIfPossible()

/**
Expand All @@ -64,5 +75,6 @@ interface PreparedStatementApi {
*/
fun executeBatch(): List<Int>

/** Cancels the statement, if supported by the database. */
fun cancel()
}
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ class JdbcDatabaseMetadataImpl(database: String, val metadata: DatabaseMetaData)
}
}

/** Returns a list of existing schema names. */
override val schemaNames: List<String> get() = schemaNames()

/** Returns a list of existing schema names. */
Expand All @@ -132,10 +131,6 @@ class JdbcDatabaseMetadataImpl(database: String, val metadata: DatabaseMetaData)
return schemas.map { identifierManager.inProperCase(it) }
}

/**
* Returns the default schema name and a list of its existing table names, as [SchemaMetadata],
* found either by reading metadata or from a cache of previously read metadata.
*/
override fun tableNamesByCurrentSchema(tableNamesCache: Map<String, List<String>>?): SchemaMetadata {
val tablesInSchema = (tableNamesCache ?: tableNames).getValue(currentSchema!!)
return SchemaMetadata(currentSchema!!, tablesInSchema)
Expand Down

0 comments on commit 6e74f94

Please sign in to comment.