From 2056aa56cf0b1d9e833a0f65f602e93d51b576f5 Mon Sep 17 00:00:00 2001 From: Jocelyne Date: Mon, 19 Jun 2023 17:57:25 +0200 Subject: [PATCH] docs: reorganize structure --- documentation-website/Writerside/hi.tree | 12 +- .../Writerside/redirection-rules.xml | 20 ++ .../topics/Database-and-DataSource.md | 177 -------------- .../Writerside/topics/Databases.md | 8 + .../Writerside/topics/Getting-Started.md | 230 +++++++++++++----- .../Writerside/topics/Introduction.md | 24 +- .../topics/Modules-Documentation.md | 2 +- .../Writerside/topics/Samples.md | 3 + .../topics/Tutorials-and-Samples.md | 7 + .../topics/Working-with-DataSource.md | 31 +++ .../topics/Working-with-Database.md | 181 ++++++++++++++ ...actions.md => Working-with-Transaction.md} | 2 +- 12 files changed, 441 insertions(+), 256 deletions(-) delete mode 100644 documentation-website/Writerside/topics/Database-and-DataSource.md create mode 100644 documentation-website/Writerside/topics/Databases.md create mode 100644 documentation-website/Writerside/topics/Samples.md create mode 100644 documentation-website/Writerside/topics/Tutorials-and-Samples.md create mode 100644 documentation-website/Writerside/topics/Working-with-DataSource.md create mode 100644 documentation-website/Writerside/topics/Working-with-Database.md rename documentation-website/Writerside/topics/{Transactions.md => Working-with-Transaction.md} (99%) diff --git a/documentation-website/Writerside/hi.tree b/documentation-website/Writerside/hi.tree index 47ca3b1763..5df5401902 100644 --- a/documentation-website/Writerside/hi.tree +++ b/documentation-website/Writerside/hi.tree @@ -8,9 +8,15 @@ - - - + + + + + + + + + diff --git a/documentation-website/Writerside/redirection-rules.xml b/documentation-website/Writerside/redirection-rules.xml index 548c5f7a06..b0b5742f9b 100644 --- a/documentation-website/Writerside/redirection-rules.xml +++ b/documentation-website/Writerside/redirection-rules.xml @@ -8,4 +8,24 @@ Created after removal of "Introduction" from Exposed Documentation Introduction.html + + Created after removal of "Working with Database" from Exposed Documentation + Working-with-databases.html + + + Created after removal of "Working with DataSource" from Exposed Documentation + Working-with-data-sources.html + + + Created after removal of "Working with Transaction" from Exposed Documentation + Working-with-transactions.html + + + " from Exposed Documentation]]> + Samples-md.html + + + Created after removal of "Transactions" from Exposed Documentation + Transactions.html + diff --git a/documentation-website/Writerside/topics/Database-and-DataSource.md b/documentation-website/Writerside/topics/Database-and-DataSource.md deleted file mode 100644 index b2e1b91bce..0000000000 --- a/documentation-website/Writerside/topics/Database-and-DataSource.md +++ /dev/null @@ -1,177 +0,0 @@ -# Database and DataSource - -## Working with Database and DataSource -Every database access using Exposed is starting by obtaining a connection and creating a transaction. -First of all, you have to tell Exposed how to connect to a database by using `Database.connect` function. -It won't create a real database connection but only provide a descriptor for future usage. - -A real connection will be instantiated later by calling `transaction` lambda (see [Transaction](Transactions.md) for more details). - -To get a Database instance by simple providing connection parameters: -```kotlin -val db = Database.connect("jdbc:h2:mem:test", driver = "org.h2.Driver") -``` -It is also possible to provide `javax.sql.DataSource` for advanced behaviors such as connection pooling: -```kotlin -val db = Database.connect(dataSource) -``` -* Note: Starting Exposed 0.10 executing this code more than once per db will create leaks in your application, hence it is recommended to store it for later use. - For example: -```kotlin -object DbSettings { - val db by lazy { - Database.connect(/* setup connection */) - } -} -``` -## DataSource - - -### PostgreSQL -Add dependency: -```kotlin -implementation("org.postgresql:postgresql:42.2.2") -``` - -Connect to database: -```kotlin -Database.connect( - "jdbc:postgresql://localhost:12346/test", - driver = "org.postgresql.Driver", - user = "user", - password = "password" -) -``` - -### PostgreSQL using the pgjdbc-ng JDBC driver - -Add dependency: -```kotlin -implementation("com.impossibl.pgjdbc-ng", "pgjdbc-ng", "0.8.3") -``` - -Connect to database: -```kotlin -Database.connect( - "jdbc:pgsql://localhost:12346/test", - driver = "com.impossibl.postgres.jdbc.PGDriver", - user = "user", - password = "password" -) -``` -### MySQL/MariaDB - -Add dependency: -```kotlin -implementation("mysql:mysql-connector-java:8.0.2") -``` - -Connect to database: -```kotlin -Database.connect( - "jdbc:mysql://localhost:3306/test", - driver = "com.mysql.cj.jdbc.Driver", - user = "user", - password = "password" -) -``` - -### MySQL/MariaDB with latest JDBC driver + Hikari pooling - -Add dependency: -```kotlin -implementation("mysql:mysql-connector-java:8.0.19") -implementation("com.zaxxer:HikariCP:3.4.2") -``` - -Connect to database: -```kotlin -val config = HikariConfig().apply { - jdbcUrl = "jdbc:mysql://localhost/dbname" - driverClassName = "com.mysql.cj.jdbc.Driver" - username = "user" - password = "password" - maximumPoolSize = 10 -} -val dataSource = HikariDataSource(config) -Database.connect(dataSource) -``` - -### Oracle - -Add Dependency: -```kotlin -implementation("com.oracle.database.jdbc:ojdbc8:12.2.0.1") -``` - -Then connect to database: -```kotlin -Database.connect( - "jdbc:oracle:thin:@//localhost:1521/test", - driver = "oracle.jdbc.OracleDriver", - user = "user", - password = "password" -) -``` - -### SQLite - -In order to use SQLite, you need to add the dependency to the SQLite JDBC driver. -```kotlin -implementation("org.xerial:sqlite-jdbc:3.30.1") -``` - -Then connect to file-database: -```kotlin -Database.connect("jdbc:sqlite:/data/data.db", "org.sqlite.JDBC") -``` - -Or in-memory database: -```kotlin -Database.connect("jdbc:sqlite:file:test?mode=memory&cache=shared", "org.sqlite.JDBC") -``` - -For both: set SQLite compatible isolation level: [FAQ](Frequently-Asked-Questions.md). -```kotlin -TransactionManager.manager.defaultIsolationLevel = Connection.TRANSACTION_SERIALIZABLE - // or Connection.TRANSACTION_READ_UNCOMMITTED -``` - -### H2 - -In order to use H2, you need to add the dependency to the H2 driver: -```kotlin -implementation("com.h2database:h2:2.1.214") -``` - -Then connect to database in file: -```kotlin -Database.connect("jdbc:h2:./myh2file", "org.h2.Driver") -``` - -Or in memory: -```kotlin -Database.connect("jdbc:h2:mem:regular", "org.h2.Driver") -``` - -By default, H2 closes the database when the last connection is closed. If you want to keep the database open, you can use the DB_CLOSE_DELAY=-1 option: -```kotlin -Database.connect("jdbc:h2:mem:regular;DB_CLOSE_DELAY=-1;", "org.h2.Driver") -``` - -### MSSQL Server - -Add dependency: -```kotlin -implementation("com.microsoft.sqlserver:mssql-jdbc:6.4.0.jre7") -``` - -Connect to database: -```kotlin -Database.connect( - "jdbc:sqlserver://localhost:32768;databaseName=test", - "com.microsoft.sqlserver.jdbc.SQLServerDriver", - user = "user", - password = "password" -) -``` diff --git a/documentation-website/Writerside/topics/Databases.md b/documentation-website/Writerside/topics/Databases.md new file mode 100644 index 0000000000..0ad2797688 --- /dev/null +++ b/documentation-website/Writerside/topics/Databases.md @@ -0,0 +1,8 @@ +# Databases + + +[Working with Database](Working-with-Database.md) + +[Working with DataSource](Working-with-DataSource.md) + +[Working with Transaction](Working-with-Transaction.md) diff --git a/documentation-website/Writerside/topics/Getting-Started.md b/documentation-website/Writerside/topics/Getting-Started.md index 8a40fd19da..ee7de73fc4 100644 --- a/documentation-website/Writerside/topics/Getting-Started.md +++ b/documentation-website/Writerside/topics/Getting-Started.md @@ -1,6 +1,6 @@ # Getting Started -## Adding Dependency +## Adding the Exposed dependency @@ -49,7 +49,7 @@ dependencies { -- Note: There are another modules. Detailed information located in [Modules Documentation](Modules-Documentation.md) section. +- Note: There are other modules. Detailed information is located in [Modules Documentation](Modules-Documentation.md) section. ## Starting a transaction @@ -67,9 +67,9 @@ It is also possible to provide `javax.sql.DataSource` for advanced behaviors suc Database.connect(dataSource) ``` -More details on [Database and DataSource](Database-and-DataSource.md) +More details in [Databases](Databases.md) -After obtaining a connection all SQL statements should be placed inside a transaction: +After obtaining a connection, all SQL statements should be placed inside a transaction: ```kotlin transaction { @@ -77,90 +77,190 @@ transaction { } ``` -To see the actual DB calls, add a logger: +To see the actual database calls, add a logger: ```kotlin transaction { - // print sql to std-out + // print SQL to stdout addLogger(StdOutSqlLogger) } ``` -### DSL & DAO +## Access Layers -Exposed comes in two flavors: DSL (Domain Specific Language) and DAO (Data Access Object). -On a high level, DSL means type-safe syntax that is similar to SQL whereas DAO means doing CRUD operations on entities. -Observe the below examples and head on to the specific section of each API for more details. +Exposed comes in two flavors: DSL and DAO. -### Your first Exposed DSL +- DSL stands for Domain-Specific Language, and for Exposed it means type-safe syntax similar to SQL statements to access a database. For more + information, see [DSL](DSL-API.md). -```kotlin - - -fun main(args: Array) { - //an example connection to H2 DB - Database.connect("jdbc:h2:mem:test", driver = "org.h2.Driver") - - transaction { - // print sql to std-out - addLogger(StdOutSqlLogger) - - SchemaUtils.create (Cities) +- DAO means Data Access Object, and it allows treating the data from database as entities and performing CRUD operations. For more information, see + [DAO](DAO-API.md). - // insert new city. SQL: INSERT INTO Cities (name) VALUES ('St. Petersburg') - val stPeteId = Cities.insert { - it[name] = "St. Petersburg" - } get Cities.id +To get an idea of the difference, compare the following code samples and corresponding SQL outputs: - // 'select *' SQL: SELECT Cities.id, Cities.name FROM Cities - println("Cities: ${Cities.selectAll()}") - } + + + +) { - //an example connection to H2 DB - Database.connect("jdbc:h2:mem:test", driver = "org.h2.Driver") - - transaction { - // print sql to std-out - addLogger(StdOutSqlLogger) - - SchemaUtils.create (Cities) - - // insert new city. SQL: INSERT INTO Cities (name) VALUES ('St. Petersburg') - val stPete = City.new { - name = "St. Petersburg" +fun init() { +Database.connect( +"jdbc:h2:mem:test;DB_CLOSE_DELAY=-1", +driver = "org.h2.Driver" +) + + transaction { + // print sql to std-out + addLogger(StdOutSqlLogger) + + // create table Cities + SchemaUtils.create(Cities) + + // insert new city and return id to nyId + val nyId = Cities.insert { + it[name] = "New York" + it[country] = Country.USA + it[population] = 1000 + } get Cities.id + + // insert new city and return id to moscId + val mosId = Cities.insertAndGetId { + it[name] = "Moscow" + it[country] = Country.RUSSIA + it[population] = 500 + } + + // insert new city and return id to stPetId + val stPetId = Cities.insertAndGetId { + it[name] = "St. Petersburg" + it[country] = Country.RUSSIA + it[population] = 300 + } } - - // 'select *' SQL: SELECT Cities.id, Cities.name FROM Cities - println("Cities: ${City.all()}") - } } -object Cities: IntIdTable() { - val name = varchar("name", 50) +fun main() { +init() +} +]]> + + + + + = integer("population").uniqueIndex() +val country = Cities.customEnumeration( +"country", +"ENUM('RUSSIA', 'CHINA', 'USA', 'UNKNOWN')", +{ Country.values()[it as Int] }, +{ it.name } +).default(Country.UNKNOWN) +override val primaryKey = PrimaryKey(id, name = "Cities_ID") } - class City(id: EntityID) : IntEntity(id) { - companion object : IntEntityClass(Cities) +companion object : IntEntityClass(Cities) var name by Cities.name + var country by Cities.country + var population by Cities.population +} + +enum class Country { +RUSSIA, CHINA, USA, UNKNOWN +} + +fun init() { +Database.connect( +"jdbc:h2:mem:test;DB_CLOSE_DELAY=-1", +driver = "org.h2.Driver" +) + + transaction { + // print sql calls to stdout + addLogger(StdOutSqlLogger) + + // create a table Cities + SchemaUtils.create(Cities) + + // insert a new city + val ny = City.new { + name = "New York" + country = Country.USA + population = 1000 + } + + // insert a new city + val mos = City.new { + name = "Moscow" + country = Country.RUSSIA + population = 500 + } + + // insert a new city + val stPet = City.new { + name = "St. Petersburg" + country = Country.RUSSIA + population = 300 + } + } } -``` -More information: [DAO API](DAO-API.md) +fun main() { +init() +} +]]> + + + -Read Next [Database and DataSource](Database-and-DataSource.md) +SQL output: + + +SQL: SELECT VALUE FROM INFORMATION_SCHEMA.SETTINGS WHERE NAME = 'MODE' +SQL: CREATE TABLE IF NOT EXISTS CITIES ( + ID INT AUTO_INCREMENT, + "NAME" VARCHAR(50) DEFAULT 'Unknown' NOT NULL, + POPULATION INT NULL, + COUNTRY ENUM('RUSSIA', 'CHINA', 'USA') NULL, + CONSTRAINT Cities_ID PRIMARY KEY (ID) +) +SQL: INSERT INTO CITIES (COUNTRY, "NAME", POPULATION) VALUES ('USA', 'New York', 1000) +SQL: INSERT INTO CITIES (COUNTRY, "NAME", POPULATION) VALUES ('RUSSIA', 'Moscow', 500) +SQL: INSERT INTO CITIES (COUNTRY, "NAME", POPULATION) VALUES ('RUSSIA', 'St. Petersburg', 300) + + +More on [DSL](DSL-API.md) and [DAO](DAO-API.md). diff --git a/documentation-website/Writerside/topics/Introduction.md b/documentation-website/Writerside/topics/Introduction.md index 065b066c6e..6f331aed8e 100644 --- a/documentation-website/Writerside/topics/Introduction.md +++ b/documentation-website/Writerside/topics/Introduction.md @@ -1,18 +1,24 @@ # Introduction -Welcome to the Exposed Documentation! +Welcome to the Exposed documentation! -Exposed is a lightweight SQL library on top of JDBC driver for Kotlin language. -Exposed has two flavors of database access: typesafe SQL wrapping DSL and lightweight Data Access Objects (DAO) +Exposed is a lightweight SQL library on top of JDBC driver for Kotlin. +It has two flavors of database access: type-safe SQL wrapping DSL (Domain-Specific Language) and lightweight DAO (Data Access Object). -Currently, supported database dialects are: +Exposed supports the following databases: -* PostgreSQL +* H2 +* MariaDB * MySQL * Oracle -* SQLite -* H2 +* PostgreSQL * SQL Server -* MariaDB +* SQLite + +Exposed requires Java 6 or later versions. To check the version of Java you have installed, run the following command from the terminal: + +```shell +java -version +``` -Read Next [Getting Started](Getting-Started.md) +Exposed is an open-source project and is available on GitHub. diff --git a/documentation-website/Writerside/topics/Modules-Documentation.md b/documentation-website/Writerside/topics/Modules-Documentation.md index 41e8336ad4..9ed1d0ad7d 100644 --- a/documentation-website/Writerside/topics/Modules-Documentation.md +++ b/documentation-website/Writerside/topics/Modules-Documentation.md @@ -134,7 +134,7 @@ exposedVersion=0.40.1 ``` ### JDBC driver and logging -You also need a JDBC driver for the database system you are using (see [Database and DataSource](Database-and-DataSource.md)) and a logger for `addLogger(StdOutSqlLogger)`. Example (Gradle syntax): +You also need a JDBC driver for the database system you are using (see [Databases](Databases.md)) and a logger for `addLogger(StdOutSqlLogger)`. Example (Gradle syntax): ```kotlin dependencies { // for H2 diff --git a/documentation-website/Writerside/topics/Samples.md b/documentation-website/Writerside/topics/Samples.md new file mode 100644 index 0000000000..49d4c8e5b8 --- /dev/null +++ b/documentation-website/Writerside/topics/Samples.md @@ -0,0 +1,3 @@ +# Samples + +Samples can be found [here](https://github.com/JetBrains/Exposed/tree/main/samples). diff --git a/documentation-website/Writerside/topics/Tutorials-and-Samples.md b/documentation-website/Writerside/topics/Tutorials-and-Samples.md new file mode 100644 index 0000000000..aef50b7579 --- /dev/null +++ b/documentation-website/Writerside/topics/Tutorials-and-Samples.md @@ -0,0 +1,7 @@ +# Tutorials and Samples + +This section will demonstrate how to get started with Exposed. + +[Getting Started](Getting-Started.md) + +[Samples](Samples.md) diff --git a/documentation-website/Writerside/topics/Working-with-DataSource.md b/documentation-website/Writerside/topics/Working-with-DataSource.md new file mode 100644 index 0000000000..58bdb4bfe1 --- /dev/null +++ b/documentation-website/Writerside/topics/Working-with-DataSource.md @@ -0,0 +1,31 @@ +# Working with DataSource + +It is also possible to provide a `javax.sql.DataSource` to the `Database.connect` function. This allows you to use more advanced features like +connection pooling, and lets you set configuration options like maximum number of connections, connection timeouts, etc. + +```kotlin +val db = Database.connect(dataSource) +``` + +## MariaDB/MySQL with latest JDBC driver + Hikari pooling + +Add dependency: + +```kotlin +implementation("mysql:mysql-connector-java:8.0.19") +implementation("com.zaxxer:HikariCP:3.4.2") +``` + +Connect to database: + +```kotlin +val config = HikariConfig().apply { + jdbcUrl = "jdbc:mysql://localhost/dbname" + driverClassName = "com.mysql.cj.jdbc.Driver" + username = "user" + password = "password" + maximumPoolSize = 10 +} +val dataSource = HikariDataSource(config) +Database.connect(dataSource) +``` diff --git a/documentation-website/Writerside/topics/Working-with-Database.md b/documentation-website/Writerside/topics/Working-with-Database.md new file mode 100644 index 0000000000..7a3443d6a5 --- /dev/null +++ b/documentation-website/Writerside/topics/Working-with-Database.md @@ -0,0 +1,181 @@ +# Working with Database + +In Exposed, the `Database` class represents a logical database instance or schema within a database server. It encapsulates the necessary connection +details and configuration required to interact with a specific database. + +## Connecting to a Database + +To connect to a database using `Database`, you need to provide the appropriate JDBC driver and connection URL. Here's an example of how to establish a +connection: + +```kotlin +val db = Database.connect("jdbc:h2:mem:test", driver = "org.h2.Driver") +``` + +The `Database.connect` function tells Exposed _how_ to connect to a database, but won't _create_ a database connection. It only provides a +descriptor for future usage. A connection will be created later by calling the `transaction` lambda (see [Transaction](Working-with-Transaction.md) for more +details). + + +Starting from Exposed 0.10, executing this code more than once per database will create leaks in your application; hence, it is recommended to + store it for later use. + + +Creating a database only when it is accessed for the first time can be done like this: + +```kotlin +object DbSettings { + val db by lazy { + Database.connect(/* setup connection */) + } +} +``` + +### H2 + +In order to use H2, you need to add the H2 driver dependency: + +```kotlin +implementation("com.h2database:h2:2.1.214") +``` + +Then connect to a database: + +```kotlin +Database.connect("jdbc:h2:./myh2file", "org.h2.Driver") +``` + +Or in-memory database: + +```kotlin +Database.connect("jdbc:h2:mem:regular", "org.h2.Driver") +``` + +By default, H2 closes the database when the last connection is closed. If you want to keep the database open, you can use the `DB_CLOSE_DELAY=-1` +option: + +```kotlin +Database.connect("jdbc:h2:mem:regular;DB_CLOSE_DELAY=-1;", "org.h2.Driver") +``` + +### MariaDB/MySQL + +Add dependency: + +```kotlin +implementation("mysql:mysql-connector-java:8.0.2") +``` + +Connect to database: + +```kotlin +Database.connect( + "jdbc:mysql://localhost:3306/test", + driver = "com.mysql.cj.jdbc.Driver", + user = "user", + password = "password" +) +``` + +### Oracle + +Add dependency: + +```kotlin +implementation("com.oracle.database.jdbc:ojdbc8:12.2.0.1") +``` + +Connect to database: + +```kotlin +Database.connect( + "jdbc:oracle:thin:@//localhost:1521/test", + driver = "oracle.jdbc.OracleDriver", + user = "user", + password = "password" +) +``` + +### PostgreSQL + +Add dependency: + +```kotlin +implementation("org.postgresql:postgresql:42.2.2") +``` + +Connect to database: + +```kotlin +Database.connect( + "jdbc:postgresql://localhost:12346/test", + driver = "org.postgresql.Driver", + user = "user", + password = "password" +) +``` + +### PostgreSQL using the pgjdbc-ng JDBC driver + +Add dependency: + +```kotlin +implementation("com.impossibl.pgjdbc-ng", "pgjdbc-ng", "0.8.3") +``` + +Connect to database: + +```kotlin +Database.connect( + "jdbc:pgsql://localhost:12346/test", + driver = "com.impossibl.postgres.jdbc.PGDriver", + user = "user", + password = "password" +) +``` + +### SQL Server + +Add dependency: + +```kotlin +implementation("com.microsoft.sqlserver:mssql-jdbc:6.4.0.jre7") +``` + +Connect to database: + +```kotlin +Database.connect( + "jdbc:sqlserver://localhost:32768;databaseName=test", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", + user = "user", + password = "password" +) +``` + +### SQLite + +Add the dependency: + +```kotlin +implementation("org.xerial:sqlite-jdbc:3.30.1") +``` + +Connect to database: + +```kotlin +Database.connect("jdbc:sqlite:/data/data.db", "org.sqlite.JDBC") +``` + +Or in-memory database: + +```kotlin +Database.connect("jdbc:sqlite:file:test?mode=memory&cache=shared", "org.sqlite.JDBC") +``` + +For both: set SQLite compatible isolation level: [FAQ](Frequently-Asked-Questions.md). + +```kotlin +TransactionManager.manager.defaultIsolationLevel = Connection.TRANSACTION_SERIALIZABLE +// or Connection.TRANSACTION_READ_UNCOMMITTED +``` diff --git a/documentation-website/Writerside/topics/Transactions.md b/documentation-website/Writerside/topics/Working-with-Transaction.md similarity index 99% rename from documentation-website/Writerside/topics/Transactions.md rename to documentation-website/Writerside/topics/Working-with-Transaction.md index 57b0e628cd..d220bd66ec 100644 --- a/documentation-website/Writerside/topics/Transactions.md +++ b/documentation-website/Writerside/topics/Working-with-Transaction.md @@ -1,4 +1,4 @@ -# Transactions +# Working with Transaction ## Overview