Skip to content

Latest commit

History

2,085 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Exposed


JetBrains team projectKotlinlang Slack ChannelTC Build statusMaven CentralGitHub License

Welcome to Exposed, an ORM framework for Kotlin.

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).

With Exposed you can have two levels of databases Access. You would like to use exposed because the database access includes wrapping DSL and a lightweight data access object. Also, our official mascot is Cuttlefish, which is well known for its outstanding mimicry ability that enables it to blend seamlessly in any environment. Similar to our mascot, Exposed can be used to mimic a variety of database engines and help you build applications without dependencies on any specific database engine and switch between them with very little or no changes.

Supported Databases

Links

Currently, Exposed is available for maven/gradle builds. Check the Maven Central and read (Getting started) to get an insight on setting up Exposed.

For more information visit the links below:

Community

Do you have questions? Feel free to ask and join our project conversation at our #exposed channel on kotlinlang.slack.com.

Pull requests

We actively welcome your pull requests. However, linking your work to an existing issue is preferred.

  • Fork the repo and create your branch from main.
  • Name your branch something that is descriptive to the work you are doing. i.e. adds-new-thing.
  • If you've added code that should be tested, add tests and ensure the test suite passes.
  • Make sure you address any lint warnings.
  • If you make the existing code better, please let us know in your PR description.

Examples

SQL DSL

importorg.jetbrains.exposed.sql.*importorg.jetbrains.exposed.sql.transactions.transactionobject Users : Table() {
val id = varchar("id", 10) // Column<String>val name = varchar("name", length =50) // Column<String>val cityId = (integer("city_id") references Cities.id).nullable() // Column<Int?>overrideval primaryKey =PrimaryKey(id, name ="PK_User_ID") // name is optional here
}
object Cities : Table() {
val id = integer("id").autoIncrement() // Column<Int>val name = varchar("name", 50) // Column<String>overrideval primaryKey =PrimaryKey(id, name ="PK_Cities_ID")
}
funmain() {
Database.connect("jdbc:h2:mem:test", driver ="org.h2.Driver", user ="root", password ="")
transaction {
addLogger(StdOutSqlLogger)
SchemaUtils.create (Cities, Users)
val saintPetersburgId =Cities.insert {
it[name] ="St. Petersburg"
} get Cities.id
val munichId =Cities.insert {
it[name] ="Munich"
} get Cities.id
val pragueId =Cities.insert {
it.update(name, stringLiteral(" Prague ").trim().substring(1, 2))
}[Cities.id]
val pragueName =Cities.select { Cities.id eq pragueId }.single()[Cities.name]
assertEquals(pragueName, "Pr")
Users.insert {
it[id] ="andrey"
it[name] ="Andrey"
it[Users.cityId] = saintPetersburgId
}
Users.insert {
it[id] ="sergey"
it[name] ="Sergey"
it[Users.cityId] = munichId
}
Users.insert {
it[id] ="eugene"
it[name] ="Eugene"
it[Users.cityId] = munichId
}
Users.insert {
it[id] ="alex"
it[name] ="Alex"
it[Users.cityId] =null
}
Users.insert {
it[id] ="smth"
it[name] ="Something"
it[Users.cityId] =null
}
Users.update({ Users.id eq "alex"}) {
it[name] ="Alexey"
}
Users.deleteWhere{ Users.name like "%thing"}
println("All cities:")
for (city inCities.selectAll()) {
println("${city[Cities.id]}: ${city[Cities.name]}")
}
println("Manual join:")
(Users innerJoin Cities).slice(Users.name, Cities.name).
select {(Users.id.eq("andrey") orUsers.name.eq("Sergey")) andUsers.id.eq("sergey") andUsers.cityId.eq(Cities.id)}.forEach {
println("${it[Users.name]} lives in ${it[Cities.name]}")
}
println("Join with foreign key:")
(Users innerJoin Cities).slice(Users.name, Users.cityId, Cities.name).
select { Cities.name.eq("St. Petersburg") orUsers.cityId.isNull()}.forEach {
if (it[Users.cityId] !=null) {
println("${it[Users.name]} lives in ${it[Cities.name]}")
}
else {
println("${it[Users.name]} lives nowhere")
}
}
println("Functions and group by:")
((Cities innerJoin Users).slice(Cities.name, Users.id.count()).selectAll().groupBy(Cities.name)).forEach {
val cityName = it[Cities.name]
val userCount = it[Users.id.count()]
if (userCount >0) {
println("$userCount user(s) live(s) in $cityName")
} else {
println("Nobody lives in $cityName")
}
}
SchemaUtils.drop (Users, Cities)
}
}

Generated SQL:

 SQL: CREATE TABLE IF NOT EXISTS Cities (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(50) NOT NULL, CONSTRAINT PK_Cities_ID PRIMARY KEY (id))
SQL: CREATE TABLE IF NOT EXISTS Users (id VARCHAR(10) NOT NULL, name VARCHAR(50) NOT NULL, city_id INTNULL, CONSTRAINT PK_User_ID PRIMARY KEY (id))
SQL: ALTER TABLE Users ADD FOREIGN KEY (city_id) REFERENCES Cities(id)
SQL: INSERT INTO Cities (name) VALUES ('St. Petersburg')
SQL: INSERT INTO Cities (name) VALUES ('Munich')
SQL: INSERT INTO Cities (name) VALUES ('Prague')
SQL: INSERT INTO Users (id, name, city_id) VALUES ('andrey', 'Andrey', 1)
SQL: INSERT INTO Users (id, name, city_id) VALUES ('sergey', 'Sergey', 2)
SQL: INSERT INTO Users (id, name, city_id) VALUES ('eugene', 'Eugene', 2)
SQL: INSERT INTO Users (id, name, city_id) VALUES ('alex', 'Alex', NULL)
SQL: INSERT INTO Users (id, name, city_id) VALUES ('smth', 'Something', NULL)
SQL: UPDATE Users SET name='Alexey'WHEREUsers.id='alex'
SQL: DELETEFROM Users WHEREUsers.nameLIKE'%thing'
All cities:
SQL: SELECTCities.id, Cities.nameFROM Cities
1: St. Petersburg
2: Munich
3: Prague
Manual join:
SQL: SELECTUsers.name, Cities.nameFROM Users INNER JOIN Cities ONCities.id=Users.city_idWHERE ((Users.id='andrey') or (Users.name='Sergey')) andUsers.id='sergey'andUsers.city_id=Cities.id
Sergey lives in Munich
Join with foreign key:
SQL: SELECTUsers.name, Users.city_id, Cities.nameFROM Users INNER JOIN Cities ONCities.id=Users.city_idWHERE (Cities.name='St. Petersburg') or (Users.city_id IS NULL)
Andrey lives in St. Petersburg
Functions andgroup by:
SQL: SELECTCities.name, COUNT(Users.id) FROM Cities INNER JOIN Users ONCities.id=Users.city_idGROUP BYCities.name1 user(s) live(s) in St. Petersburg
2 user(s) live(s) in Munich
SQL: DROPTABLEUsers
SQL: DROPTABLECities

DAO

importorg.jetbrains.exposed.dao.*importorg.jetbrains.exposed.dao.id.EntityIDimportorg.jetbrains.exposed.dao.id.IntIdTableimportorg.jetbrains.exposed.sql.*importorg.jetbrains.exposed.sql.transactions.transactionobject Users : IntIdTable() {
val name = varchar("name", 50).index()
val city = reference("city", Cities)
val age = integer("age")
}
object Cities: IntIdTable() {
val name = varchar("name", 50)
}
classUser(id:EntityID<Int>) : IntEntity(id) {
companionobject:IntEntityClass<User>(Users)
var name by Users.name
var city by City referencedOn Users.city
var age by Users.age
}
classCity(id:EntityID<Int>) : IntEntity(id) {
companionobject:IntEntityClass<City>(Cities)
var name by Cities.name
val users by User referrersOn Users.city
}
funmain() {
Database.connect("jdbc:h2:mem:test", driver ="org.h2.Driver", user ="root", password ="")
transaction {
addLogger(StdOutSqlLogger)
SchemaUtils.create (Cities, Users)
val stPete =City.new {
name ="St. Petersburg"
}
val munich =City.new {
name ="Munich"
}
User.new {
name ="a"
city = stPete
age =5
}
User.new {
name ="b"
city = stPete
age =27
}
User.new {
name ="c"
city = munich
age =42
}
println("Cities: ${City.all().joinToString {it.name}}")
println("Users in ${stPete.name}: ${stPete.users.joinToString {it.name}}")
println("Adults: ${User.find { Users.age greaterEq 18 }.joinToString {it.name}}")
}
}

Generated SQL:

 SQL: CREATE TABLE IF NOT EXISTS Cities (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(50) NOT NULL, CONSTRAINT pk_Cities PRIMARY KEY (id))
SQL: CREATE TABLE IF NOT EXISTS Users (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(50) NOT NULL, city INTNOT NULL, age INTNOT NULL, CONSTRAINT pk_Users PRIMARY KEY (id))
SQL: CREATE INDEX Users_name ON Users (name)
SQL: ALTER TABLE Users ADD FOREIGN KEY (city) REFERENCES Cities(id)
SQL: INSERT INTO Cities (name) VALUES ('St. Petersburg'),('Munich')
SQL: SELECTCities.id, Cities.nameFROM Cities
Cities: St. Petersburg, Munich
SQL: INSERT INTO Users (name, city, age) VALUES ('a', 1, 5),('b', 1, 27),('c', 2, 42)
SQL: SELECTUsers.id, Users.name, Users.city, Users.ageFROM Users WHEREUsers.city=1
Users in St. Petersburg: a, b
SQL: SELECTUsers.id, Users.name, Users.city, Users.ageFROM Users WHEREUsers.age>=18
Adults: b, c

⚖️ LICENSE

By contributing to the Open Sauced project, you agree that your contributions will be licensed under Apache License, Version 2.0.

About

Kotlin SQL Framework

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
GitHub - aktdaaaa/Exposed: Kotlin SQL Framework · GitHub
Skip to content

Latest commit

History

2,085 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Exposed


JetBrains team projectKotlinlang Slack ChannelTC Build statusMaven CentralGitHub License

Welcome to Exposed, an ORM framework for Kotlin.

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).

With Exposed you can have two levels of databases Access. You would like to use exposed because the database access includes wrapping DSL and a lightweight data access object. Also, our official mascot is Cuttlefish, which is well known for its outstanding mimicry ability that enables it to blend seamlessly in any environment. Similar to our mascot, Exposed can be used to mimic a variety of database engines and help you build applications without dependencies on any specific database engine and switch between them with very little or no changes.

Supported Databases

Links

Currently, Exposed is available for maven/gradle builds. Check the Maven Central and read (Getting started) to get an insight on setting up Exposed.

For more information visit the links below:

Community

Do you have questions? Feel free to ask and join our project conversation at our #exposed channel on kotlinlang.slack.com.

Pull requests

We actively welcome your pull requests. However, linking your work to an existing issue is preferred.

  • Fork the repo and create your branch from main.
  • Name your branch something that is descriptive to the work you are doing. i.e. adds-new-thing.
  • If you've added code that should be tested, add tests and ensure the test suite passes.
  • Make sure you address any lint warnings.
  • If you make the existing code better, please let us know in your PR description.

Examples

SQL DSL

importorg.jetbrains.exposed.sql.*importorg.jetbrains.exposed.sql.transactions.transactionobject Users : Table() {
val id = varchar("id", 10) // Column<String>val name = varchar("name", length =50) // Column<String>val cityId = (integer("city_id") references Cities.id).nullable() // Column<Int?>overrideval primaryKey =PrimaryKey(id, name ="PK_User_ID") // name is optional here
}
object Cities : Table() {
val id = integer("id").autoIncrement() // Column<Int>val name = varchar("name", 50) // Column<String>overrideval primaryKey =PrimaryKey(id, name ="PK_Cities_ID")
}
funmain() {
Database.connect("jdbc:h2:mem:test", driver ="org.h2.Driver", user ="root", password ="")
transaction {
addLogger(StdOutSqlLogger)
SchemaUtils.create (Cities, Users)
val saintPetersburgId =Cities.insert {
it[name] ="St. Petersburg"
} get Cities.id
val munichId =Cities.insert {
it[name] ="Munich"
} get Cities.id
val pragueId =Cities.insert {
it.update(name, stringLiteral(" Prague ").trim().substring(1, 2))
}[Cities.id]
val pragueName =Cities.select { Cities.id eq pragueId }.single()[Cities.name]
assertEquals(pragueName, "Pr")
Users.insert {
it[id] ="andrey"
it[name] ="Andrey"
it[Users.cityId] = saintPetersburgId
}
Users.insert {
it[id] ="sergey"
it[name] ="Sergey"
it[Users.cityId] = munichId
}
Users.insert {
it[id] ="eugene"
it[name] ="Eugene"
it[Users.cityId] = munichId
}
Users.insert {
it[id] ="alex"
it[name] ="Alex"
it[Users.cityId] =null
}
Users.insert {
it[id] ="smth"
it[name] ="Something"
it[Users.cityId] =null
}
Users.update({ Users.id eq "alex"}) {
it[name] ="Alexey"
}
Users.deleteWhere{ Users.name like "%thing"}
println("All cities:")
for (city inCities.selectAll()) {
println("${city[Cities.id]}: ${city[Cities.name]}")
}
println("Manual join:")
(Users innerJoin Cities).slice(Users.name, Cities.name).
select {(Users.id.eq("andrey") orUsers.name.eq("Sergey")) andUsers.id.eq("sergey") andUsers.cityId.eq(Cities.id)}.forEach {
println("${it[Users.name]} lives in ${it[Cities.name]}")
}
println("Join with foreign key:")
(Users innerJoin Cities).slice(Users.name, Users.cityId, Cities.name).
select { Cities.name.eq("St. Petersburg") orUsers.cityId.isNull()}.forEach {
if (it[Users.cityId] !=null) {
println("${it[Users.name]} lives in ${it[Cities.name]}")
}
else {
println("${it[Users.name]} lives nowhere")
}
}
println("Functions and group by:")
((Cities innerJoin Users).slice(Cities.name, Users.id.count()).selectAll().groupBy(Cities.name)).forEach {
val cityName = it[Cities.name]
val userCount = it[Users.id.count()]
if (userCount >0) {
println("$userCount user(s) live(s) in $cityName")
} else {
println("Nobody lives in $cityName")
}
}
SchemaUtils.drop (Users, Cities)
}
}

Generated SQL:

 SQL: CREATE TABLE IF NOT EXISTS Cities (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(50) NOT NULL, CONSTRAINT PK_Cities_ID PRIMARY KEY (id))
SQL: CREATE TABLE IF NOT EXISTS Users (id VARCHAR(10) NOT NULL, name VARCHAR(50) NOT NULL, city_id INTNULL, CONSTRAINT PK_User_ID PRIMARY KEY (id))
SQL: ALTER TABLE Users ADD FOREIGN KEY (city_id) REFERENCES Cities(id)
SQL: INSERT INTO Cities (name) VALUES ('St. Petersburg')
SQL: INSERT INTO Cities (name) VALUES ('Munich')
SQL: INSERT INTO Cities (name) VALUES ('Prague')
SQL: INSERT INTO Users (id, name, city_id) VALUES ('andrey', 'Andrey', 1)
SQL: INSERT INTO Users (id, name, city_id) VALUES ('sergey', 'Sergey', 2)
SQL: INSERT INTO Users (id, name, city_id) VALUES ('eugene', 'Eugene', 2)
SQL: INSERT INTO Users (id, name, city_id) VALUES ('alex', 'Alex', NULL)
SQL: INSERT INTO Users (id, name, city_id) VALUES ('smth', 'Something', NULL)
SQL: UPDATE Users SET name='Alexey'WHEREUsers.id='alex'
SQL: DELETEFROM Users WHEREUsers.nameLIKE'%thing'
All cities:
SQL: SELECTCities.id, Cities.nameFROM Cities
1: St. Petersburg
2: Munich
3: Prague
Manual join:
SQL: SELECTUsers.name, Cities.nameFROM Users INNER JOIN Cities ONCities.id=Users.city_idWHERE ((Users.id='andrey') or (Users.name='Sergey')) andUsers.id='sergey'andUsers.city_id=Cities.id
Sergey lives in Munich
Join with foreign key:
SQL: SELECTUsers.name, Users.city_id, Cities.nameFROM Users INNER JOIN Cities ONCities.id=Users.city_idWHERE (Cities.name='St. Petersburg') or (Users.city_id IS NULL)
Andrey lives in St. Petersburg
Functions andgroup by:
SQL: SELECTCities.name, COUNT(Users.id) FROM Cities INNER JOIN Users ONCities.id=Users.city_idGROUP BYCities.name1 user(s) live(s) in St. Petersburg
2 user(s) live(s) in Munich
SQL: DROPTABLEUsers
SQL: DROPTABLECities

DAO

importorg.jetbrains.exposed.dao.*importorg.jetbrains.exposed.dao.id.EntityIDimportorg.jetbrains.exposed.dao.id.IntIdTableimportorg.jetbrains.exposed.sql.*importorg.jetbrains.exposed.sql.transactions.transactionobject Users : IntIdTable() {
val name = varchar("name", 50).index()
val city = reference("city", Cities)
val age = integer("age")
}
object Cities: IntIdTable() {
val name = varchar("name", 50)
}
classUser(id:EntityID<Int>) : IntEntity(id) {
companionobject:IntEntityClass<User>(Users)
var name by Users.name
var city by City referencedOn Users.city
var age by Users.age
}
classCity(id:EntityID<Int>) : IntEntity(id) {
companionobject:IntEntityClass<City>(Cities)
var name by Cities.name
val users by User referrersOn Users.city
}
funmain() {
Database.connect("jdbc:h2:mem:test", driver ="org.h2.Driver", user ="root", password ="")
transaction {
addLogger(StdOutSqlLogger)
SchemaUtils.create (Cities, Users)
val stPete =City.new {
name ="St. Petersburg"
}
val munich =City.new {
name ="Munich"
}
User.new {
name ="a"
city = stPete
age =5
}
User.new {
name ="b"
city = stPete
age =27
}
User.new {
name ="c"
city = munich
age =42
}
println("Cities: ${City.all().joinToString {it.name}}")
println("Users in ${stPete.name}: ${stPete.users.joinToString {it.name}}")
println("Adults: ${User.find { Users.age greaterEq 18 }.joinToString {it.name}}")
}
}

Generated SQL:

 SQL: CREATE TABLE IF NOT EXISTS Cities (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(50) NOT NULL, CONSTRAINT pk_Cities PRIMARY KEY (id))
SQL: CREATE TABLE IF NOT EXISTS Users (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(50) NOT NULL, city INTNOT NULL, age INTNOT NULL, CONSTRAINT pk_Users PRIMARY KEY (id))
SQL: CREATE INDEX Users_name ON Users (name)
SQL: ALTER TABLE Users ADD FOREIGN KEY (city) REFERENCES Cities(id)
SQL: INSERT INTO Cities (name) VALUES ('St. Petersburg'),('Munich')
SQL: SELECTCities.id, Cities.nameFROM Cities
Cities: St. Petersburg, Munich
SQL: INSERT INTO Users (name, city, age) VALUES ('a', 1, 5),('b', 1, 27),('c', 2, 42)
SQL: SELECTUsers.id, Users.name, Users.city, Users.ageFROM Users WHEREUsers.city=1
Users in St. Petersburg: a, b
SQL: SELECTUsers.id, Users.name, Users.city, Users.ageFROM Users WHEREUsers.age>=18
Adults: b, c

⚖️ LICENSE

By contributing to the Open Sauced project, you agree that your contributions will be licensed under Apache License, Version 2.0.

About

Kotlin SQL Framework

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - aktdaaaa/Exposed: Kotlin SQL Framework · GitHub
Skip to content

Latest commit

History

2,085 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Exposed


JetBrains team projectKotlinlang Slack ChannelTC Build statusMaven CentralGitHub License

Welcome to Exposed, an ORM framework for Kotlin.

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).

With Exposed you can have two levels of databases Access. You would like to use exposed because the database access includes wrapping DSL and a lightweight data access object. Also, our official mascot is Cuttlefish, which is well known for its outstanding mimicry ability that enables it to blend seamlessly in any environment. Similar to our mascot, Exposed can be used to mimic a variety of database engines and help you build applications without dependencies on any specific database engine and switch between them with very little or no changes.

Supported Databases

Links

Currently, Exposed is available for maven/gradle builds. Check the Maven Central and read (Getting started) to get an insight on setting up Exposed.

For more information visit the links below:

Community

Do you have questions? Feel free to ask and join our project conversation at our #exposed channel on kotlinlang.slack.com.

Pull requests

We actively welcome your pull requests. However, linking your work to an existing issue is preferred.

  • Fork the repo and create your branch from main.
  • Name your branch something that is descriptive to the work you are doing. i.e. adds-new-thing.
  • If you've added code that should be tested, add tests and ensure the test suite passes.
  • Make sure you address any lint warnings.
  • If you make the existing code better, please let us know in your PR description.

Examples

SQL DSL

importorg.jetbrains.exposed.sql.*importorg.jetbrains.exposed.sql.transactions.transactionobject Users : Table() {
val id = varchar("id", 10) // Column<String>val name = varchar("name", length =50) // Column<String>val cityId = (integer("city_id") references Cities.id).nullable() // Column<Int?>overrideval primaryKey =PrimaryKey(id, name ="PK_User_ID") // name is optional here
}
object Cities : Table() {
val id = integer("id").autoIncrement() // Column<Int>val name = varchar("name", 50) // Column<String>overrideval primaryKey =PrimaryKey(id, name ="PK_Cities_ID")
}
funmain() {
Database.connect("jdbc:h2:mem:test", driver ="org.h2.Driver", user ="root", password ="")
transaction {
addLogger(StdOutSqlLogger)
SchemaUtils.create (Cities, Users)
val saintPetersburgId =Cities.insert {
it[name] ="St. Petersburg"
} get Cities.id
val munichId =Cities.insert {
it[name] ="Munich"
} get Cities.id
val pragueId =Cities.insert {
it.update(name, stringLiteral(" Prague ").trim().substring(1, 2))
}[Cities.id]
val pragueName =Cities.select { Cities.id eq pragueId }.single()[Cities.name]
assertEquals(pragueName, "Pr")
Users.insert {
it[id] ="andrey"
it[name] ="Andrey"
it[Users.cityId] = saintPetersburgId
}
Users.insert {
it[id] ="sergey"
it[name] ="Sergey"
it[Users.cityId] = munichId
}
Users.insert {
it[id] ="eugene"
it[name] ="Eugene"
it[Users.cityId] = munichId
}
Users.insert {
it[id] ="alex"
it[name] ="Alex"
it[Users.cityId] =null
}
Users.insert {
it[id] ="smth"
it[name] ="Something"
it[Users.cityId] =null
}
Users.update({ Users.id eq "alex"}) {
it[name] ="Alexey"
}
Users.deleteWhere{ Users.name like "%thing"}
println("All cities:")
for (city inCities.selectAll()) {
println("${city[Cities.id]}: ${city[Cities.name]}")
}
println("Manual join:")
(Users innerJoin Cities).slice(Users.name, Cities.name).
select {(Users.id.eq("andrey") orUsers.name.eq("Sergey")) andUsers.id.eq("sergey") andUsers.cityId.eq(Cities.id)}.forEach {
println("${it[Users.name]} lives in ${it[Cities.name]}")
}
println("Join with foreign key:")
(Users innerJoin Cities).slice(Users.name, Users.cityId, Cities.name).
select { Cities.name.eq("St. Petersburg") orUsers.cityId.isNull()}.forEach {
if (it[Users.cityId] !=null) {
println("${it[Users.name]} lives in ${it[Cities.name]}")
}
else {
println("${it[Users.name]} lives nowhere")
}
}
println("Functions and group by:")
((Cities innerJoin Users).slice(Cities.name, Users.id.count()).selectAll().groupBy(Cities.name)).forEach {
val cityName = it[Cities.name]
val userCount = it[Users.id.count()]
if (userCount >0) {
println("$userCount user(s) live(s) in $cityName")
} else {
println("Nobody lives in $cityName")
}
}
SchemaUtils.drop (Users, Cities)
}
}

Generated SQL:

 SQL: CREATE TABLE IF NOT EXISTS Cities (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(50) NOT NULL, CONSTRAINT PK_Cities_ID PRIMARY KEY (id))
SQL: CREATE TABLE IF NOT EXISTS Users (id VARCHAR(10) NOT NULL, name VARCHAR(50) NOT NULL, city_id INTNULL, CONSTRAINT PK_User_ID PRIMARY KEY (id))
SQL: ALTER TABLE Users ADD FOREIGN KEY (city_id) REFERENCES Cities(id)
SQL: INSERT INTO Cities (name) VALUES ('St. Petersburg')
SQL: INSERT INTO Cities (name) VALUES ('Munich')
SQL: INSERT INTO Cities (name) VALUES ('Prague')
SQL: INSERT INTO Users (id, name, city_id) VALUES ('andrey', 'Andrey', 1)
SQL: INSERT INTO Users (id, name, city_id) VALUES ('sergey', 'Sergey', 2)
SQL: INSERT INTO Users (id, name, city_id) VALUES ('eugene', 'Eugene', 2)
SQL: INSERT INTO Users (id, name, city_id) VALUES ('alex', 'Alex', NULL)
SQL: INSERT INTO Users (id, name, city_id) VALUES ('smth', 'Something', NULL)
SQL: UPDATE Users SET name='Alexey'WHEREUsers.id='alex'
SQL: DELETEFROM Users WHEREUsers.nameLIKE'%thing'
All cities:
SQL: SELECTCities.id, Cities.nameFROM Cities
1: St. Petersburg
2: Munich
3: Prague
Manual join:
SQL: SELECTUsers.name, Cities.nameFROM Users INNER JOIN Cities ONCities.id=Users.city_idWHERE ((Users.id='andrey') or (Users.name='Sergey')) andUsers.id='sergey'andUsers.city_id=Cities.id
Sergey lives in Munich
Join with foreign key:
SQL: SELECTUsers.name, Users.city_id, Cities.nameFROM Users INNER JOIN Cities ONCities.id=Users.city_idWHERE (Cities.name='St. Petersburg') or (Users.city_id IS NULL)
Andrey lives in St. Petersburg
Functions andgroup by:
SQL: SELECTCities.name, COUNT(Users.id) FROM Cities INNER JOIN Users ONCities.id=Users.city_idGROUP BYCities.name1 user(s) live(s) in St. Petersburg
2 user(s) live(s) in Munich
SQL: DROPTABLEUsers
SQL: DROPTABLECities

DAO

importorg.jetbrains.exposed.dao.*importorg.jetbrains.exposed.dao.id.EntityIDimportorg.jetbrains.exposed.dao.id.IntIdTableimportorg.jetbrains.exposed.sql.*importorg.jetbrains.exposed.sql.transactions.transactionobject Users : IntIdTable() {
val name = varchar("name", 50).index()
val city = reference("city", Cities)
val age = integer("age")
}
object Cities: IntIdTable() {
val name = varchar("name", 50)
}
classUser(id:EntityID<Int>) : IntEntity(id) {
companionobject:IntEntityClass<User>(Users)
var name by Users.name
var city by City referencedOn Users.city
var age by Users.age
}
classCity(id:EntityID<Int>) : IntEntity(id) {
companionobject:IntEntityClass<City>(Cities)
var name by Cities.name
val users by User referrersOn Users.city
}
funmain() {
Database.connect("jdbc:h2:mem:test", driver ="org.h2.Driver", user ="root", password ="")
transaction {
addLogger(StdOutSqlLogger)
SchemaUtils.create (Cities, Users)
val stPete =City.new {
name ="St. Petersburg"
}
val munich =City.new {
name ="Munich"
}
User.new {
name ="a"
city = stPete
age =5
}
User.new {
name ="b"
city = stPete
age =27
}
User.new {
name ="c"
city = munich
age =42
}
println("Cities: ${City.all().joinToString {it.name}}")
println("Users in ${stPete.name}: ${stPete.users.joinToString {it.name}}")
println("Adults: ${User.find { Users.age greaterEq 18 }.joinToString {it.name}}")
}
}

Generated SQL:

 SQL: CREATE TABLE IF NOT EXISTS Cities (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(50) NOT NULL, CONSTRAINT pk_Cities PRIMARY KEY (id))
SQL: CREATE TABLE IF NOT EXISTS Users (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(50) NOT NULL, city INTNOT NULL, age INTNOT NULL, CONSTRAINT pk_Users PRIMARY KEY (id))
SQL: CREATE INDEX Users_name ON Users (name)
SQL: ALTER TABLE Users ADD FOREIGN KEY (city) REFERENCES Cities(id)
SQL: INSERT INTO Cities (name) VALUES ('St. Petersburg'),('Munich')
SQL: SELECTCities.id, Cities.nameFROM Cities
Cities: St. Petersburg, Munich
SQL: INSERT INTO Users (name, city, age) VALUES ('a', 1, 5),('b', 1, 27),('c', 2, 42)
SQL: SELECTUsers.id, Users.name, Users.city, Users.ageFROM Users WHEREUsers.city=1
Users in St. Petersburg: a, b
SQL: SELECTUsers.id, Users.name, Users.city, Users.ageFROM Users WHEREUsers.age>=18
Adults: b, c

⚖️ LICENSE

By contributing to the Open Sauced project, you agree that your contributions will be licensed under Apache License, Version 2.0.

About

Kotlin SQL Framework

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - aktdaaaa/Exposed: Kotlin SQL Framework · GitHub
Skip to content

Latest commit

History

2,085 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Exposed


JetBrains team projectKotlinlang Slack ChannelTC Build statusMaven CentralGitHub License

Welcome to Exposed, an ORM framework for Kotlin.

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).

With Exposed you can have two levels of databases Access. You would like to use exposed because the database access includes wrapping DSL and a lightweight data access object. Also, our official mascot is Cuttlefish, which is well known for its outstanding mimicry ability that enables it to blend seamlessly in any environment. Similar to our mascot, Exposed can be used to mimic a variety of database engines and help you build applications without dependencies on any specific database engine and switch between them with very little or no changes.

Supported Databases

Links

Currently, Exposed is available for maven/gradle builds. Check the Maven Central and read (Getting started) to get an insight on setting up Exposed.

For more information visit the links below:

Community

Do you have questions? Feel free to ask and join our project conversation at our #exposed channel on kotlinlang.slack.com.

Pull requests

We actively welcome your pull requests. However, linking your work to an existing issue is preferred.

  • Fork the repo and create your branch from main.
  • Name your branch something that is descriptive to the work you are doing. i.e. adds-new-thing.
  • If you've added code that should be tested, add tests and ensure the test suite passes.
  • Make sure you address any lint warnings.
  • If you make the existing code better, please let us know in your PR description.

Examples

SQL DSL

importorg.jetbrains.exposed.sql.*importorg.jetbrains.exposed.sql.transactions.transactionobject Users : Table() {
val id = varchar("id", 10) // Column<String>val name = varchar("name", length =50) // Column<String>val cityId = (integer("city_id") references Cities.id).nullable() // Column<Int?>overrideval primaryKey =PrimaryKey(id, name ="PK_User_ID") // name is optional here
}
object Cities : Table() {
val id = integer("id").autoIncrement() // Column<Int>val name = varchar("name", 50) // Column<String>overrideval primaryKey =PrimaryKey(id, name ="PK_Cities_ID")
}
funmain() {
Database.connect("jdbc:h2:mem:test", driver ="org.h2.Driver", user ="root", password ="")
transaction {
addLogger(StdOutSqlLogger)
SchemaUtils.create (Cities, Users)
val saintPetersburgId =Cities.insert {
it[name] ="St. Petersburg"
} get Cities.id
val munichId =Cities.insert {
it[name] ="Munich"
} get Cities.id
val pragueId =Cities.insert {
it.update(name, stringLiteral(" Prague ").trim().substring(1, 2))
}[Cities.id]
val pragueName =Cities.select { Cities.id eq pragueId }.single()[Cities.name]
assertEquals(pragueName, "Pr")
Users.insert {
it[id] ="andrey"
it[name] ="Andrey"
it[Users.cityId] = saintPetersburgId
}
Users.insert {
it[id] ="sergey"
it[name] ="Sergey"
it[Users.cityId] = munichId
}
Users.insert {
it[id] ="eugene"
it[name] ="Eugene"
it[Users.cityId] = munichId
}
Users.insert {
it[id] ="alex"
it[name] ="Alex"
it[Users.cityId] =null
}
Users.insert {
it[id] ="smth"
it[name] ="Something"
it[Users.cityId] =null
}
Users.update({ Users.id eq "alex"}) {
it[name] ="Alexey"
}
Users.deleteWhere{ Users.name like "%thing"}
println("All cities:")
for (city inCities.selectAll()) {
println("${city[Cities.id]}: ${city[Cities.name]}")
}
println("Manual join:")
(Users innerJoin Cities).slice(Users.name, Cities.name).
select {(Users.id.eq("andrey") orUsers.name.eq("Sergey")) andUsers.id.eq("sergey") andUsers.cityId.eq(Cities.id)}.forEach {
println("${it[Users.name]} lives in ${it[Cities.name]}")
}
println("Join with foreign key:")
(Users innerJoin Cities).slice(Users.name, Users.cityId, Cities.name).
select { Cities.name.eq("St. Petersburg") orUsers.cityId.isNull()}.forEach {
if (it[Users.cityId] !=null) {
println("${it[Users.name]} lives in ${it[Cities.name]}")
}
else {
println("${it[Users.name]} lives nowhere")
}
}
println("Functions and group by:")
((Cities innerJoin Users).slice(Cities.name, Users.id.count()).selectAll().groupBy(Cities.name)).forEach {
val cityName = it[Cities.name]
val userCount = it[Users.id.count()]
if (userCount >0) {
println("$userCount user(s) live(s) in $cityName")
} else {
println("Nobody lives in $cityName")
}
}
SchemaUtils.drop (Users, Cities)
}
}

Generated SQL:

 SQL: CREATE TABLE IF NOT EXISTS Cities (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(50) NOT NULL, CONSTRAINT PK_Cities_ID PRIMARY KEY (id))
SQL: CREATE TABLE IF NOT EXISTS Users (id VARCHAR(10) NOT NULL, name VARCHAR(50) NOT NULL, city_id INTNULL, CONSTRAINT PK_User_ID PRIMARY KEY (id))
SQL: ALTER TABLE Users ADD FOREIGN KEY (city_id) REFERENCES Cities(id)
SQL: INSERT INTO Cities (name) VALUES ('St. Petersburg')
SQL: INSERT INTO Cities (name) VALUES ('Munich')
SQL: INSERT INTO Cities (name) VALUES ('Prague')
SQL: INSERT INTO Users (id, name, city_id) VALUES ('andrey', 'Andrey', 1)
SQL: INSERT INTO Users (id, name, city_id) VALUES ('sergey', 'Sergey', 2)
SQL: INSERT INTO Users (id, name, city_id) VALUES ('eugene', 'Eugene', 2)
SQL: INSERT INTO Users (id, name, city_id) VALUES ('alex', 'Alex', NULL)
SQL: INSERT INTO Users (id, name, city_id) VALUES ('smth', 'Something', NULL)
SQL: UPDATE Users SET name='Alexey'WHEREUsers.id='alex'
SQL: DELETEFROM Users WHEREUsers.nameLIKE'%thing'
All cities:
SQL: SELECTCities.id, Cities.nameFROM Cities
1: St. Petersburg
2: Munich
3: Prague
Manual join:
SQL: SELECTUsers.name, Cities.nameFROM Users INNER JOIN Cities ONCities.id=Users.city_idWHERE ((Users.id='andrey') or (Users.name='Sergey')) andUsers.id='sergey'andUsers.city_id=Cities.id
Sergey lives in Munich
Join with foreign key:
SQL: SELECTUsers.name, Users.city_id, Cities.nameFROM Users INNER JOIN Cities ONCities.id=Users.city_idWHERE (Cities.name='St. Petersburg') or (Users.city_id IS NULL)
Andrey lives in St. Petersburg
Functions andgroup by:
SQL: SELECTCities.name, COUNT(Users.id) FROM Cities INNER JOIN Users ONCities.id=Users.city_idGROUP BYCities.name1 user(s) live(s) in St. Petersburg
2 user(s) live(s) in Munich
SQL: DROPTABLEUsers
SQL: DROPTABLECities

DAO

importorg.jetbrains.exposed.dao.*importorg.jetbrains.exposed.dao.id.EntityIDimportorg.jetbrains.exposed.dao.id.IntIdTableimportorg.jetbrains.exposed.sql.*importorg.jetbrains.exposed.sql.transactions.transactionobject Users : IntIdTable() {
val name = varchar("name", 50).index()
val city = reference("city", Cities)
val age = integer("age")
}
object Cities: IntIdTable() {
val name = varchar("name", 50)
}
classUser(id:EntityID<Int>) : IntEntity(id) {
companionobject:IntEntityClass<User>(Users)
var name by Users.name
var city by City referencedOn Users.city
var age by Users.age
}
classCity(id:EntityID<Int>) : IntEntity(id) {
companionobject:IntEntityClass<City>(Cities)
var name by Cities.name
val users by User referrersOn Users.city
}
funmain() {
Database.connect("jdbc:h2:mem:test", driver ="org.h2.Driver", user ="root", password ="")
transaction {
addLogger(StdOutSqlLogger)
SchemaUtils.create (Cities, Users)
val stPete =City.new {
name ="St. Petersburg"
}
val munich =City.new {
name ="Munich"
}
User.new {
name ="a"
city = stPete
age =5
}
User.new {
name ="b"
city = stPete
age =27
}
User.new {
name ="c"
city = munich
age =42
}
println("Cities: ${City.all().joinToString {it.name}}")
println("Users in ${stPete.name}: ${stPete.users.joinToString {it.name}}")
println("Adults: ${User.find { Users.age greaterEq 18 }.joinToString {it.name}}")
}
}

Generated SQL:

 SQL: CREATE TABLE IF NOT EXISTS Cities (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(50) NOT NULL, CONSTRAINT pk_Cities PRIMARY KEY (id))
SQL: CREATE TABLE IF NOT EXISTS Users (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(50) NOT NULL, city INTNOT NULL, age INTNOT NULL, CONSTRAINT pk_Users PRIMARY KEY (id))
SQL: CREATE INDEX Users_name ON Users (name)
SQL: ALTER TABLE Users ADD FOREIGN KEY (city) REFERENCES Cities(id)
SQL: INSERT INTO Cities (name) VALUES ('St. Petersburg'),('Munich')
SQL: SELECTCities.id, Cities.nameFROM Cities
Cities: St. Petersburg, Munich
SQL: INSERT INTO Users (name, city, age) VALUES ('a', 1, 5),('b', 1, 27),('c', 2, 42)
SQL: SELECTUsers.id, Users.name, Users.city, Users.ageFROM Users WHEREUsers.city=1
Users in St. Petersburg: a, b
SQL: SELECTUsers.id, Users.name, Users.city, Users.ageFROM Users WHEREUsers.age>=18
Adults: b, c

⚖️ LICENSE

By contributing to the Open Sauced project, you agree that your contributions will be licensed under Apache License, Version 2.0.

About

Kotlin SQL Framework

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' GitHub - aktdaaaa/Exposed: Kotlin SQL Framework · GitHub
Skip to content

Latest commit

History

2,085 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Exposed


JetBrains team projectKotlinlang Slack ChannelTC Build statusMaven CentralGitHub License

Welcome to Exposed, an ORM framework for Kotlin.

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).

With Exposed you can have two levels of databases Access. You would like to use exposed because the database access includes wrapping DSL and a lightweight data access object. Also, our official mascot is Cuttlefish, which is well known for its outstanding mimicry ability that enables it to blend seamlessly in any environment. Similar to our mascot, Exposed can be used to mimic a variety of database engines and help you build applications without dependencies on any specific database engine and switch between them with very little or no changes.

Supported Databases

Links

Currently, Exposed is available for maven/gradle builds. Check the Maven Central and read (Getting started) to get an insight on setting up Exposed.

For more information visit the links below:

Community

Do you have questions? Feel free to ask and join our project conversation at our #exposed channel on kotlinlang.slack.com.

Pull requests

We actively welcome your pull requests. However, linking your work to an existing issue is preferred.

  • Fork the repo and create your branch from main.
  • Name your branch something that is descriptive to the work you are doing. i.e. adds-new-thing.
  • If you've added code that should be tested, add tests and ensure the test suite passes.
  • Make sure you address any lint warnings.
  • If you make the existing code better, please let us know in your PR description.

Examples

SQL DSL

importorg.jetbrains.exposed.sql.*importorg.jetbrains.exposed.sql.transactions.transactionobject Users : Table() {
val id = varchar("id", 10) // Column<String>val name = varchar("name", length =50) // Column<String>val cityId = (integer("city_id") references Cities.id).nullable() // Column<Int?>overrideval primaryKey =PrimaryKey(id, name ="PK_User_ID") // name is optional here
}
object Cities : Table() {
val id = integer("id").autoIncrement() // Column<Int>val name = varchar("name", 50) // Column<String>overrideval primaryKey =PrimaryKey(id, name ="PK_Cities_ID")
}
funmain() {
Database.connect("jdbc:h2:mem:test", driver ="org.h2.Driver", user ="root", password ="")
transaction {
addLogger(StdOutSqlLogger)
SchemaUtils.create (Cities, Users)
val saintPetersburgId =Cities.insert {
it[name] ="St. Petersburg"
} get Cities.id
val munichId =Cities.insert {
it[name] ="Munich"
} get Cities.id
val pragueId =Cities.insert {
it.update(name, stringLiteral(" Prague ").trim().substring(1, 2))
}[Cities.id]
val pragueName =Cities.select { Cities.id eq pragueId }.single()[Cities.name]
assertEquals(pragueName, "Pr")
Users.insert {
it[id] ="andrey"
it[name] ="Andrey"
it[Users.cityId] = saintPetersburgId
}
Users.insert {
it[id] ="sergey"
it[name] ="Sergey"
it[Users.cityId] = munichId
}
Users.insert {
it[id] ="eugene"
it[name] ="Eugene"
it[Users.cityId] = munichId
}
Users.insert {
it[id] ="alex"
it[name] ="Alex"
it[Users.cityId] =null
}
Users.insert {
it[id] ="smth"
it[name] ="Something"
it[Users.cityId] =null
}
Users.update({ Users.id eq "alex"}) {
it[name] ="Alexey"
}
Users.deleteWhere{ Users.name like "%thing"}
println("All cities:")
for (city inCities.selectAll()) {
println("${city[Cities.id]}: ${city[Cities.name]}")
}
println("Manual join:")
(Users innerJoin Cities).slice(Users.name, Cities.name).
select {(Users.id.eq("andrey") orUsers.name.eq("Sergey")) andUsers.id.eq("sergey") andUsers.cityId.eq(Cities.id)}.forEach {
println("${it[Users.name]} lives in ${it[Cities.name]}")
}
println("Join with foreign key:")
(Users innerJoin Cities).slice(Users.name, Users.cityId, Cities.name).
select { Cities.name.eq("St. Petersburg") orUsers.cityId.isNull()}.forEach {
if (it[Users.cityId] !=null) {
println("${it[Users.name]} lives in ${it[Cities.name]}")
}
else {
println("${it[Users.name]} lives nowhere")
}
}
println("Functions and group by:")
((Cities innerJoin Users).slice(Cities.name, Users.id.count()).selectAll().groupBy(Cities.name)).forEach {
val cityName = it[Cities.name]
val userCount = it[Users.id.count()]
if (userCount >0) {
println("$userCount user(s) live(s) in $cityName")
} else {
println("Nobody lives in $cityName")
}
}
SchemaUtils.drop (Users, Cities)
}
}

Generated SQL:

 SQL: CREATE TABLE IF NOT EXISTS Cities (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(50) NOT NULL, CONSTRAINT PK_Cities_ID PRIMARY KEY (id))
SQL: CREATE TABLE IF NOT EXISTS Users (id VARCHAR(10) NOT NULL, name VARCHAR(50) NOT NULL, city_id INTNULL, CONSTRAINT PK_User_ID PRIMARY KEY (id))
SQL: ALTER TABLE Users ADD FOREIGN KEY (city_id) REFERENCES Cities(id)
SQL: INSERT INTO Cities (name) VALUES ('St. Petersburg')
SQL: INSERT INTO Cities (name) VALUES ('Munich')
SQL: INSERT INTO Cities (name) VALUES ('Prague')
SQL: INSERT INTO Users (id, name, city_id) VALUES ('andrey', 'Andrey', 1)
SQL: INSERT INTO Users (id, name, city_id) VALUES ('sergey', 'Sergey', 2)
SQL: INSERT INTO Users (id, name, city_id) VALUES ('eugene', 'Eugene', 2)
SQL: INSERT INTO Users (id, name, city_id) VALUES ('alex', 'Alex', NULL)
SQL: INSERT INTO Users (id, name, city_id) VALUES ('smth', 'Something', NULL)
SQL: UPDATE Users SET name='Alexey'WHEREUsers.id='alex'
SQL: DELETEFROM Users WHEREUsers.nameLIKE'%thing'
All cities:
SQL: SELECTCities.id, Cities.nameFROM Cities
1: St. Petersburg
2: Munich
3: Prague
Manual join:
SQL: SELECTUsers.name, Cities.nameFROM Users INNER JOIN Cities ONCities.id=Users.city_idWHERE ((Users.id='andrey') or (Users.name='Sergey')) andUsers.id='sergey'andUsers.city_id=Cities.id
Sergey lives in Munich
Join with foreign key:
SQL: SELECTUsers.name, Users.city_id, Cities.nameFROM Users INNER JOIN Cities ONCities.id=Users.city_idWHERE (Cities.name='St. Petersburg') or (Users.city_id IS NULL)
Andrey lives in St. Petersburg
Functions andgroup by:
SQL: SELECTCities.name, COUNT(Users.id) FROM Cities INNER JOIN Users ONCities.id=Users.city_idGROUP BYCities.name1 user(s) live(s) in St. Petersburg
2 user(s) live(s) in Munich
SQL: DROPTABLEUsers
SQL: DROPTABLECities

DAO

importorg.jetbrains.exposed.dao.*importorg.jetbrains.exposed.dao.id.EntityIDimportorg.jetbrains.exposed.dao.id.IntIdTableimportorg.jetbrains.exposed.sql.*importorg.jetbrains.exposed.sql.transactions.transactionobject Users : IntIdTable() {
val name = varchar("name", 50).index()
val city = reference("city", Cities)
val age = integer("age")
}
object Cities: IntIdTable() {
val name = varchar("name", 50)
}
classUser(id:EntityID<Int>) : IntEntity(id) {
companionobject:IntEntityClass<User>(Users)
var name by Users.name
var city by City referencedOn Users.city
var age by Users.age
}
classCity(id:EntityID<Int>) : IntEntity(id) {
companionobject:IntEntityClass<City>(Cities)
var name by Cities.name
val users by User referrersOn Users.city
}
funmain() {
Database.connect("jdbc:h2:mem:test", driver ="org.h2.Driver", user ="root", password ="")
transaction {
addLogger(StdOutSqlLogger)
SchemaUtils.create (Cities, Users)
val stPete =City.new {
name ="St. Petersburg"
}
val munich =City.new {
name ="Munich"
}
User.new {
name ="a"
city = stPete
age =5
}
User.new {
name ="b"
city = stPete
age =27
}
User.new {
name ="c"
city = munich
age =42
}
println("Cities: ${City.all().joinToString {it.name}}")
println("Users in ${stPete.name}: ${stPete.users.joinToString {it.name}}")
println("Adults: ${User.find { Users.age greaterEq 18 }.joinToString {it.name}}")
}
}

Generated SQL:

 SQL: CREATE TABLE IF NOT EXISTS Cities (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(50) NOT NULL, CONSTRAINT pk_Cities PRIMARY KEY (id))
SQL: CREATE TABLE IF NOT EXISTS Users (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(50) NOT NULL, city INTNOT NULL, age INTNOT NULL, CONSTRAINT pk_Users PRIMARY KEY (id))
SQL: CREATE INDEX Users_name ON Users (name)
SQL: ALTER TABLE Users ADD FOREIGN KEY (city) REFERENCES Cities(id)
SQL: INSERT INTO Cities (name) VALUES ('St. Petersburg'),('Munich')
SQL: SELECTCities.id, Cities.nameFROM Cities
Cities: St. Petersburg, Munich
SQL: INSERT INTO Users (name, city, age) VALUES ('a', 1, 5),('b', 1, 27),('c', 2, 42)
SQL: SELECTUsers.id, Users.name, Users.city, Users.ageFROM Users WHEREUsers.city=1
Users in St. Petersburg: a, b
SQL: SELECTUsers.id, Users.name, Users.city, Users.ageFROM Users WHEREUsers.age>=18
Adults: b, c

⚖️ LICENSE

By contributing to the Open Sauced project, you agree that your contributions will be licensed under Apache License, Version 2.0.

About

Kotlin SQL Framework

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - aktdaaaa/Exposed: Kotlin SQL Framework · GitHub
Skip to content

Latest commit

History

2,085 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Exposed


JetBrains team projectKotlinlang Slack ChannelTC Build statusMaven CentralGitHub License

Welcome to Exposed, an ORM framework for Kotlin.

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).

With Exposed you can have two levels of databases Access. You would like to use exposed because the database access includes wrapping DSL and a lightweight data access object. Also, our official mascot is Cuttlefish, which is well known for its outstanding mimicry ability that enables it to blend seamlessly in any environment. Similar to our mascot, Exposed can be used to mimic a variety of database engines and help you build applications without dependencies on any specific database engine and switch between them with very little or no changes.

Supported Databases

Links

Currently, Exposed is available for maven/gradle builds. Check the Maven Central and read (Getting started) to get an insight on setting up Exposed.

For more information visit the links below:

Community

Do you have questions? Feel free to ask and join our project conversation at our #exposed channel on kotlinlang.slack.com.

Pull requests

We actively welcome your pull requests. However, linking your work to an existing issue is preferred.

  • Fork the repo and create your branch from main.
  • Name your branch something that is descriptive to the work you are doing. i.e. adds-new-thing.
  • If you've added code that should be tested, add tests and ensure the test suite passes.
  • Make sure you address any lint warnings.
  • If you make the existing code better, please let us know in your PR description.

Examples

SQL DSL

importorg.jetbrains.exposed.sql.*importorg.jetbrains.exposed.sql.transactions.transactionobject Users : Table() {
val id = varchar("id", 10) // Column<String>val name = varchar("name", length =50) // Column<String>val cityId = (integer("city_id") references Cities.id).nullable() // Column<Int?>overrideval primaryKey =PrimaryKey(id, name ="PK_User_ID") // name is optional here
}
object Cities : Table() {
val id = integer("id").autoIncrement() // Column<Int>val name = varchar("name", 50) // Column<String>overrideval primaryKey =PrimaryKey(id, name ="PK_Cities_ID")
}
funmain() {
Database.connect("jdbc:h2:mem:test", driver ="org.h2.Driver", user ="root", password ="")
transaction {
addLogger(StdOutSqlLogger)
SchemaUtils.create (Cities, Users)
val saintPetersburgId =Cities.insert {
it[name] ="St. Petersburg"
} get Cities.id
val munichId =Cities.insert {
it[name] ="Munich"
} get Cities.id
val pragueId =Cities.insert {
it.update(name, stringLiteral(" Prague ").trim().substring(1, 2))
}[Cities.id]
val pragueName =Cities.select { Cities.id eq pragueId }.single()[Cities.name]
assertEquals(pragueName, "Pr")
Users.insert {
it[id] ="andrey"
it[name] ="Andrey"
it[Users.cityId] = saintPetersburgId
}
Users.insert {
it[id] ="sergey"
it[name] ="Sergey"
it[Users.cityId] = munichId
}
Users.insert {
it[id] ="eugene"
it[name] ="Eugene"
it[Users.cityId] = munichId
}
Users.insert {
it[id] ="alex"
it[name] ="Alex"
it[Users.cityId] =null
}
Users.insert {
it[id] ="smth"
it[name] ="Something"
it[Users.cityId] =null
}
Users.update({ Users.id eq "alex"}) {
it[name] ="Alexey"
}
Users.deleteWhere{ Users.name like "%thing"}
println("All cities:")
for (city inCities.selectAll()) {
println("${city[Cities.id]}: ${city[Cities.name]}")
}
println("Manual join:")
(Users innerJoin Cities).slice(Users.name, Cities.name).
select {(Users.id.eq("andrey") orUsers.name.eq("Sergey")) andUsers.id.eq("sergey") andUsers.cityId.eq(Cities.id)}.forEach {
println("${it[Users.name]} lives in ${it[Cities.name]}")
}
println("Join with foreign key:")
(Users innerJoin Cities).slice(Users.name, Users.cityId, Cities.name).
select { Cities.name.eq("St. Petersburg") orUsers.cityId.isNull()}.forEach {
if (it[Users.cityId] !=null) {
println("${it[Users.name]} lives in ${it[Cities.name]}")
}
else {
println("${it[Users.name]} lives nowhere")
}
}
println("Functions and group by:")
((Cities innerJoin Users).slice(Cities.name, Users.id.count()).selectAll().groupBy(Cities.name)).forEach {
val cityName = it[Cities.name]
val userCount = it[Users.id.count()]
if (userCount >0) {
println("$userCount user(s) live(s) in $cityName")
} else {
println("Nobody lives in $cityName")
}
}
SchemaUtils.drop (Users, Cities)
}
}

Generated SQL:

 SQL: CREATE TABLE IF NOT EXISTS Cities (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(50) NOT NULL, CONSTRAINT PK_Cities_ID PRIMARY KEY (id))
SQL: CREATE TABLE IF NOT EXISTS Users (id VARCHAR(10) NOT NULL, name VARCHAR(50) NOT NULL, city_id INTNULL, CONSTRAINT PK_User_ID PRIMARY KEY (id))
SQL: ALTER TABLE Users ADD FOREIGN KEY (city_id) REFERENCES Cities(id)
SQL: INSERT INTO Cities (name) VALUES ('St. Petersburg')
SQL: INSERT INTO Cities (name) VALUES ('Munich')
SQL: INSERT INTO Cities (name) VALUES ('Prague')
SQL: INSERT INTO Users (id, name, city_id) VALUES ('andrey', 'Andrey', 1)
SQL: INSERT INTO Users (id, name, city_id) VALUES ('sergey', 'Sergey', 2)
SQL: INSERT INTO Users (id, name, city_id) VALUES ('eugene', 'Eugene', 2)
SQL: INSERT INTO Users (id, name, city_id) VALUES ('alex', 'Alex', NULL)
SQL: INSERT INTO Users (id, name, city_id) VALUES ('smth', 'Something', NULL)
SQL: UPDATE Users SET name='Alexey'WHEREUsers.id='alex'
SQL: DELETEFROM Users WHEREUsers.nameLIKE'%thing'
All cities:
SQL: SELECTCities.id, Cities.nameFROM Cities
1: St. Petersburg
2: Munich
3: Prague
Manual join:
SQL: SELECTUsers.name, Cities.nameFROM Users INNER JOIN Cities ONCities.id=Users.city_idWHERE ((Users.id='andrey') or (Users.name='Sergey')) andUsers.id='sergey'andUsers.city_id=Cities.id
Sergey lives in Munich
Join with foreign key:
SQL: SELECTUsers.name, Users.city_id, Cities.nameFROM Users INNER JOIN Cities ONCities.id=Users.city_idWHERE (Cities.name='St. Petersburg') or (Users.city_id IS NULL)
Andrey lives in St. Petersburg
Functions andgroup by:
SQL: SELECTCities.name, COUNT(Users.id) FROM Cities INNER JOIN Users ONCities.id=Users.city_idGROUP BYCities.name1 user(s) live(s) in St. Petersburg
2 user(s) live(s) in Munich
SQL: DROPTABLEUsers
SQL: DROPTABLECities

DAO

importorg.jetbrains.exposed.dao.*importorg.jetbrains.exposed.dao.id.EntityIDimportorg.jetbrains.exposed.dao.id.IntIdTableimportorg.jetbrains.exposed.sql.*importorg.jetbrains.exposed.sql.transactions.transactionobject Users : IntIdTable() {
val name = varchar("name", 50).index()
val city = reference("city", Cities)
val age = integer("age")
}
object Cities: IntIdTable() {
val name = varchar("name", 50)
}
classUser(id:EntityID<Int>) : IntEntity(id) {
companionobject:IntEntityClass<User>(Users)
var name by Users.name
var city by City referencedOn Users.city
var age by Users.age
}
classCity(id:EntityID<Int>) : IntEntity(id) {
companionobject:IntEntityClass<City>(Cities)
var name by Cities.name
val users by User referrersOn Users.city
}
funmain() {
Database.connect("jdbc:h2:mem:test", driver ="org.h2.Driver", user ="root", password ="")
transaction {
addLogger(StdOutSqlLogger)
SchemaUtils.create (Cities, Users)
val stPete =City.new {
name ="St. Petersburg"
}
val munich =City.new {
name ="Munich"
}
User.new {
name ="a"
city = stPete
age =5
}
User.new {
name ="b"
city = stPete
age =27
}
User.new {
name ="c"
city = munich
age =42
}
println("Cities: ${City.all().joinToString {it.name}}")
println("Users in ${stPete.name}: ${stPete.users.joinToString {it.name}}")
println("Adults: ${User.find { Users.age greaterEq 18 }.joinToString {it.name}}")
}
}

Generated SQL:

 SQL: CREATE TABLE IF NOT EXISTS Cities (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(50) NOT NULL, CONSTRAINT pk_Cities PRIMARY KEY (id))
SQL: CREATE TABLE IF NOT EXISTS Users (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(50) NOT NULL, city INTNOT NULL, age INTNOT NULL, CONSTRAINT pk_Users PRIMARY KEY (id))
SQL: CREATE INDEX Users_name ON Users (name)
SQL: ALTER TABLE Users ADD FOREIGN KEY (city) REFERENCES Cities(id)
SQL: INSERT INTO Cities (name) VALUES ('St. Petersburg'),('Munich')
SQL: SELECTCities.id, Cities.nameFROM Cities
Cities: St. Petersburg, Munich
SQL: INSERT INTO Users (name, city, age) VALUES ('a', 1, 5),('b', 1, 27),('c', 2, 42)
SQL: SELECTUsers.id, Users.name, Users.city, Users.ageFROM Users WHEREUsers.city=1
Users in St. Petersburg: a, b
SQL: SELECTUsers.id, Users.name, Users.city, Users.ageFROM Users WHEREUsers.age>=18
Adults: b, c

⚖️ LICENSE

By contributing to the Open Sauced project, you agree that your contributions will be licensed under Apache License, Version 2.0.

About

Kotlin SQL Framework

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - aktdaaaa/Exposed: Kotlin SQL Framework · GitHub
Skip to content

Latest commit

History

2,085 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Exposed


JetBrains team projectKotlinlang Slack ChannelTC Build statusMaven CentralGitHub License

Welcome to Exposed, an ORM framework for Kotlin.

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).

With Exposed you can have two levels of databases Access. You would like to use exposed because the database access includes wrapping DSL and a lightweight data access object. Also, our official mascot is Cuttlefish, which is well known for its outstanding mimicry ability that enables it to blend seamlessly in any environment. Similar to our mascot, Exposed can be used to mimic a variety of database engines and help you build applications without dependencies on any specific database engine and switch between them with very little or no changes.

Supported Databases

Links

Currently, Exposed is available for maven/gradle builds. Check the Maven Central and read (Getting started) to get an insight on setting up Exposed.

For more information visit the links below:

Community

Do you have questions? Feel free to ask and join our project conversation at our #exposed channel on kotlinlang.slack.com.

Pull requests

We actively welcome your pull requests. However, linking your work to an existing issue is preferred.

  • Fork the repo and create your branch from main.
  • Name your branch something that is descriptive to the work you are doing. i.e. adds-new-thing.
  • If you've added code that should be tested, add tests and ensure the test suite passes.
  • Make sure you address any lint warnings.
  • If you make the existing code better, please let us know in your PR description.

Examples

SQL DSL

importorg.jetbrains.exposed.sql.*importorg.jetbrains.exposed.sql.transactions.transactionobject Users : Table() {
val id = varchar("id", 10) // Column<String>val name = varchar("name", length =50) // Column<String>val cityId = (integer("city_id") references Cities.id).nullable() // Column<Int?>overrideval primaryKey =PrimaryKey(id, name ="PK_User_ID") // name is optional here
}
object Cities : Table() {
val id = integer("id").autoIncrement() // Column<Int>val name = varchar("name", 50) // Column<String>overrideval primaryKey =PrimaryKey(id, name ="PK_Cities_ID")
}
funmain() {
Database.connect("jdbc:h2:mem:test", driver ="org.h2.Driver", user ="root", password ="")
transaction {
addLogger(StdOutSqlLogger)
SchemaUtils.create (Cities, Users)
val saintPetersburgId =Cities.insert {
it[name] ="St. Petersburg"
} get Cities.id
val munichId =Cities.insert {
it[name] ="Munich"
} get Cities.id
val pragueId =Cities.insert {
it.update(name, stringLiteral(" Prague ").trim().substring(1, 2))
}[Cities.id]
val pragueName =Cities.select { Cities.id eq pragueId }.single()[Cities.name]
assertEquals(pragueName, "Pr")
Users.insert {
it[id] ="andrey"
it[name] ="Andrey"
it[Users.cityId] = saintPetersburgId
}
Users.insert {
it[id] ="sergey"
it[name] ="Sergey"
it[Users.cityId] = munichId
}
Users.insert {
it[id] ="eugene"
it[name] ="Eugene"
it[Users.cityId] = munichId
}
Users.insert {
it[id] ="alex"
it[name] ="Alex"
it[Users.cityId] =null
}
Users.insert {
it[id] ="smth"
it[name] ="Something"
it[Users.cityId] =null
}
Users.update({ Users.id eq "alex"}) {
it[name] ="Alexey"
}
Users.deleteWhere{ Users.name like "%thing"}
println("All cities:")
for (city inCities.selectAll()) {
println("${city[Cities.id]}: ${city[Cities.name]}")
}
println("Manual join:")
(Users innerJoin Cities).slice(Users.name, Cities.name).
select {(Users.id.eq("andrey") orUsers.name.eq("Sergey")) andUsers.id.eq("sergey") andUsers.cityId.eq(Cities.id)}.forEach {
println("${it[Users.name]} lives in ${it[Cities.name]}")
}
println("Join with foreign key:")
(Users innerJoin Cities).slice(Users.name, Users.cityId, Cities.name).
select { Cities.name.eq("St. Petersburg") orUsers.cityId.isNull()}.forEach {
if (it[Users.cityId] !=null) {
println("${it[Users.name]} lives in ${it[Cities.name]}")
}
else {
println("${it[Users.name]} lives nowhere")
}
}
println("Functions and group by:")
((Cities innerJoin Users).slice(Cities.name, Users.id.count()).selectAll().groupBy(Cities.name)).forEach {
val cityName = it[Cities.name]
val userCount = it[Users.id.count()]
if (userCount >0) {
println("$userCount user(s) live(s) in $cityName")
} else {
println("Nobody lives in $cityName")
}
}
SchemaUtils.drop (Users, Cities)
}
}

Generated SQL:

 SQL: CREATE TABLE IF NOT EXISTS Cities (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(50) NOT NULL, CONSTRAINT PK_Cities_ID PRIMARY KEY (id))
SQL: CREATE TABLE IF NOT EXISTS Users (id VARCHAR(10) NOT NULL, name VARCHAR(50) NOT NULL, city_id INTNULL, CONSTRAINT PK_User_ID PRIMARY KEY (id))
SQL: ALTER TABLE Users ADD FOREIGN KEY (city_id) REFERENCES Cities(id)
SQL: INSERT INTO Cities (name) VALUES ('St. Petersburg')
SQL: INSERT INTO Cities (name) VALUES ('Munich')
SQL: INSERT INTO Cities (name) VALUES ('Prague')
SQL: INSERT INTO Users (id, name, city_id) VALUES ('andrey', 'Andrey', 1)
SQL: INSERT INTO Users (id, name, city_id) VALUES ('sergey', 'Sergey', 2)
SQL: INSERT INTO Users (id, name, city_id) VALUES ('eugene', 'Eugene', 2)
SQL: INSERT INTO Users (id, name, city_id) VALUES ('alex', 'Alex', NULL)
SQL: INSERT INTO Users (id, name, city_id) VALUES ('smth', 'Something', NULL)
SQL: UPDATE Users SET name='Alexey'WHEREUsers.id='alex'
SQL: DELETEFROM Users WHEREUsers.nameLIKE'%thing'
All cities:
SQL: SELECTCities.id, Cities.nameFROM Cities
1: St. Petersburg
2: Munich
3: Prague
Manual join:
SQL: SELECTUsers.name, Cities.nameFROM Users INNER JOIN Cities ONCities.id=Users.city_idWHERE ((Users.id='andrey') or (Users.name='Sergey')) andUsers.id='sergey'andUsers.city_id=Cities.id
Sergey lives in Munich
Join with foreign key:
SQL: SELECTUsers.name, Users.city_id, Cities.nameFROM Users INNER JOIN Cities ONCities.id=Users.city_idWHERE (Cities.name='St. Petersburg') or (Users.city_id IS NULL)
Andrey lives in St. Petersburg
Functions andgroup by:
SQL: SELECTCities.name, COUNT(Users.id) FROM Cities INNER JOIN Users ONCities.id=Users.city_idGROUP BYCities.name1 user(s) live(s) in St. Petersburg
2 user(s) live(s) in Munich
SQL: DROPTABLEUsers
SQL: DROPTABLECities

DAO

importorg.jetbrains.exposed.dao.*importorg.jetbrains.exposed.dao.id.EntityIDimportorg.jetbrains.exposed.dao.id.IntIdTableimportorg.jetbrains.exposed.sql.*importorg.jetbrains.exposed.sql.transactions.transactionobject Users : IntIdTable() {
val name = varchar("name", 50).index()
val city = reference("city", Cities)
val age = integer("age")
}
object Cities: IntIdTable() {
val name = varchar("name", 50)
}
classUser(id:EntityID<Int>) : IntEntity(id) {
companionobject:IntEntityClass<User>(Users)
var name by Users.name
var city by City referencedOn Users.city
var age by Users.age
}
classCity(id:EntityID<Int>) : IntEntity(id) {
companionobject:IntEntityClass<City>(Cities)
var name by Cities.name
val users by User referrersOn Users.city
}
funmain() {
Database.connect("jdbc:h2:mem:test", driver ="org.h2.Driver", user ="root", password ="")
transaction {
addLogger(StdOutSqlLogger)
SchemaUtils.create (Cities, Users)
val stPete =City.new {
name ="St. Petersburg"
}
val munich =City.new {
name ="Munich"
}
User.new {
name ="a"
city = stPete
age =5
}
User.new {
name ="b"
city = stPete
age =27
}
User.new {
name ="c"
city = munich
age =42
}
println("Cities: ${City.all().joinToString {it.name}}")
println("Users in ${stPete.name}: ${stPete.users.joinToString {it.name}}")
println("Adults: ${User.find { Users.age greaterEq 18 }.joinToString {it.name}}")
}
}

Generated SQL:

 SQL: CREATE TABLE IF NOT EXISTS Cities (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(50) NOT NULL, CONSTRAINT pk_Cities PRIMARY KEY (id))
SQL: CREATE TABLE IF NOT EXISTS Users (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(50) NOT NULL, city INTNOT NULL, age INTNOT NULL, CONSTRAINT pk_Users PRIMARY KEY (id))
SQL: CREATE INDEX Users_name ON Users (name)
SQL: ALTER TABLE Users ADD FOREIGN KEY (city) REFERENCES Cities(id)
SQL: INSERT INTO Cities (name) VALUES ('St. Petersburg'),('Munich')
SQL: SELECTCities.id, Cities.nameFROM Cities
Cities: St. Petersburg, Munich
SQL: INSERT INTO Users (name, city, age) VALUES ('a', 1, 5),('b', 1, 27),('c', 2, 42)
SQL: SELECTUsers.id, Users.name, Users.city, Users.ageFROM Users WHEREUsers.city=1
Users in St. Petersburg: a, b
SQL: SELECTUsers.id, Users.name, Users.city, Users.ageFROM Users WHEREUsers.age>=18
Adults: b, c

⚖️ LICENSE

By contributing to the Open Sauced project, you agree that your contributions will be licensed under Apache License, Version 2.0.

About

Kotlin SQL Framework

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); GitHub - aktdaaaa/Exposed: Kotlin SQL Framework · GitHub
Skip to content

Latest commit

History

2,085 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Exposed


JetBrains team projectKotlinlang Slack ChannelTC Build statusMaven CentralGitHub License

Welcome to Exposed, an ORM framework for Kotlin.

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).

With Exposed you can have two levels of databases Access. You would like to use exposed because the database access includes wrapping DSL and a lightweight data access object. Also, our official mascot is Cuttlefish, which is well known for its outstanding mimicry ability that enables it to blend seamlessly in any environment. Similar to our mascot, Exposed can be used to mimic a variety of database engines and help you build applications without dependencies on any specific database engine and switch between them with very little or no changes.

Supported Databases

Links

Currently, Exposed is available for maven/gradle builds. Check the Maven Central and read (Getting started) to get an insight on setting up Exposed.

For more information visit the links below:

Community

Do you have questions? Feel free to ask and join our project conversation at our #exposed channel on kotlinlang.slack.com.

Pull requests

We actively welcome your pull requests. However, linking your work to an existing issue is preferred.

  • Fork the repo and create your branch from main.
  • Name your branch something that is descriptive to the work you are doing. i.e. adds-new-thing.
  • If you've added code that should be tested, add tests and ensure the test suite passes.
  • Make sure you address any lint warnings.
  • If you make the existing code better, please let us know in your PR description.

Examples

SQL DSL

importorg.jetbrains.exposed.sql.*importorg.jetbrains.exposed.sql.transactions.transactionobject Users : Table() {
val id = varchar("id", 10) // Column<String>val name = varchar("name", length =50) // Column<String>val cityId = (integer("city_id") references Cities.id).nullable() // Column<Int?>overrideval primaryKey =PrimaryKey(id, name ="PK_User_ID") // name is optional here
}
object Cities : Table() {
val id = integer("id").autoIncrement() // Column<Int>val name = varchar("name", 50) // Column<String>overrideval primaryKey =PrimaryKey(id, name ="PK_Cities_ID")
}
funmain() {
Database.connect("jdbc:h2:mem:test", driver ="org.h2.Driver", user ="root", password ="")
transaction {
addLogger(StdOutSqlLogger)
SchemaUtils.create (Cities, Users)
val saintPetersburgId =Cities.insert {
it[name] ="St. Petersburg"
} get Cities.id
val munichId =Cities.insert {
it[name] ="Munich"
} get Cities.id
val pragueId =Cities.insert {
it.update(name, stringLiteral(" Prague ").trim().substring(1, 2))
}[Cities.id]
val pragueName =Cities.select { Cities.id eq pragueId }.single()[Cities.name]
assertEquals(pragueName, "Pr")
Users.insert {
it[id] ="andrey"
it[name] ="Andrey"
it[Users.cityId] = saintPetersburgId
}
Users.insert {
it[id] ="sergey"
it[name] ="Sergey"
it[Users.cityId] = munichId
}
Users.insert {
it[id] ="eugene"
it[name] ="Eugene"
it[Users.cityId] = munichId
}
Users.insert {
it[id] ="alex"
it[name] ="Alex"
it[Users.cityId] =null
}
Users.insert {
it[id] ="smth"
it[name] ="Something"
it[Users.cityId] =null
}
Users.update({ Users.id eq "alex"}) {
it[name] ="Alexey"
}
Users.deleteWhere{ Users.name like "%thing"}
println("All cities:")
for (city inCities.selectAll()) {
println("${city[Cities.id]}: ${city[Cities.name]}")
}
println("Manual join:")
(Users innerJoin Cities).slice(Users.name, Cities.name).
select {(Users.id.eq("andrey") orUsers.name.eq("Sergey")) andUsers.id.eq("sergey") andUsers.cityId.eq(Cities.id)}.forEach {
println("${it[Users.name]} lives in ${it[Cities.name]}")
}
println("Join with foreign key:")
(Users innerJoin Cities).slice(Users.name, Users.cityId, Cities.name).
select { Cities.name.eq("St. Petersburg") orUsers.cityId.isNull()}.forEach {
if (it[Users.cityId] !=null) {
println("${it[Users.name]} lives in ${it[Cities.name]}")
}
else {
println("${it[Users.name]} lives nowhere")
}
}
println("Functions and group by:")
((Cities innerJoin Users).slice(Cities.name, Users.id.count()).selectAll().groupBy(Cities.name)).forEach {
val cityName = it[Cities.name]
val userCount = it[Users.id.count()]
if (userCount >0) {
println("$userCount user(s) live(s) in $cityName")
} else {
println("Nobody lives in $cityName")
}
}
SchemaUtils.drop (Users, Cities)
}
}

Generated SQL:

 SQL: CREATE TABLE IF NOT EXISTS Cities (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(50) NOT NULL, CONSTRAINT PK_Cities_ID PRIMARY KEY (id))
SQL: CREATE TABLE IF NOT EXISTS Users (id VARCHAR(10) NOT NULL, name VARCHAR(50) NOT NULL, city_id INTNULL, CONSTRAINT PK_User_ID PRIMARY KEY (id))
SQL: ALTER TABLE Users ADD FOREIGN KEY (city_id) REFERENCES Cities(id)
SQL: INSERT INTO Cities (name) VALUES ('St. Petersburg')
SQL: INSERT INTO Cities (name) VALUES ('Munich')
SQL: INSERT INTO Cities (name) VALUES ('Prague')
SQL: INSERT INTO Users (id, name, city_id) VALUES ('andrey', 'Andrey', 1)
SQL: INSERT INTO Users (id, name, city_id) VALUES ('sergey', 'Sergey', 2)
SQL: INSERT INTO Users (id, name, city_id) VALUES ('eugene', 'Eugene', 2)
SQL: INSERT INTO Users (id, name, city_id) VALUES ('alex', 'Alex', NULL)
SQL: INSERT INTO Users (id, name, city_id) VALUES ('smth', 'Something', NULL)
SQL: UPDATE Users SET name='Alexey'WHEREUsers.id='alex'
SQL: DELETEFROM Users WHEREUsers.nameLIKE'%thing'
All cities:
SQL: SELECTCities.id, Cities.nameFROM Cities
1: St. Petersburg
2: Munich
3: Prague
Manual join:
SQL: SELECTUsers.name, Cities.nameFROM Users INNER JOIN Cities ONCities.id=Users.city_idWHERE ((Users.id='andrey') or (Users.name='Sergey')) andUsers.id='sergey'andUsers.city_id=Cities.id
Sergey lives in Munich
Join with foreign key:
SQL: SELECTUsers.name, Users.city_id, Cities.nameFROM Users INNER JOIN Cities ONCities.id=Users.city_idWHERE (Cities.name='St. Petersburg') or (Users.city_id IS NULL)
Andrey lives in St. Petersburg
Functions andgroup by:
SQL: SELECTCities.name, COUNT(Users.id) FROM Cities INNER JOIN Users ONCities.id=Users.city_idGROUP BYCities.name1 user(s) live(s) in St. Petersburg
2 user(s) live(s) in Munich
SQL: DROPTABLEUsers
SQL: DROPTABLECities

DAO

importorg.jetbrains.exposed.dao.*importorg.jetbrains.exposed.dao.id.EntityIDimportorg.jetbrains.exposed.dao.id.IntIdTableimportorg.jetbrains.exposed.sql.*importorg.jetbrains.exposed.sql.transactions.transactionobject Users : IntIdTable() {
val name = varchar("name", 50).index()
val city = reference("city", Cities)
val age = integer("age")
}
object Cities: IntIdTable() {
val name = varchar("name", 50)
}
classUser(id:EntityID<Int>) : IntEntity(id) {
companionobject:IntEntityClass<User>(Users)
var name by Users.name
var city by City referencedOn Users.city
var age by Users.age
}
classCity(id:EntityID<Int>) : IntEntity(id) {
companionobject:IntEntityClass<City>(Cities)
var name by Cities.name
val users by User referrersOn Users.city
}
funmain() {
Database.connect("jdbc:h2:mem:test", driver ="org.h2.Driver", user ="root", password ="")
transaction {
addLogger(StdOutSqlLogger)
SchemaUtils.create (Cities, Users)
val stPete =City.new {
name ="St. Petersburg"
}
val munich =City.new {
name ="Munich"
}
User.new {
name ="a"
city = stPete
age =5
}
User.new {
name ="b"
city = stPete
age =27
}
User.new {
name ="c"
city = munich
age =42
}
println("Cities: ${City.all().joinToString {it.name}}")
println("Users in ${stPete.name}: ${stPete.users.joinToString {it.name}}")
println("Adults: ${User.find { Users.age greaterEq 18 }.joinToString {it.name}}")
}
}

Generated SQL:

 SQL: CREATE TABLE IF NOT EXISTS Cities (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(50) NOT NULL, CONSTRAINT pk_Cities PRIMARY KEY (id))
SQL: CREATE TABLE IF NOT EXISTS Users (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(50) NOT NULL, city INTNOT NULL, age INTNOT NULL, CONSTRAINT pk_Users PRIMARY KEY (id))
SQL: CREATE INDEX Users_name ON Users (name)
SQL: ALTER TABLE Users ADD FOREIGN KEY (city) REFERENCES Cities(id)
SQL: INSERT INTO Cities (name) VALUES ('St. Petersburg'),('Munich')
SQL: SELECTCities.id, Cities.nameFROM Cities
Cities: St. Petersburg, Munich
SQL: INSERT INTO Users (name, city, age) VALUES ('a', 1, 5),('b', 1, 27),('c', 2, 42)
SQL: SELECTUsers.id, Users.name, Users.city, Users.ageFROM Users WHEREUsers.city=1
Users in St. Petersburg: a, b
SQL: SELECTUsers.id, Users.name, Users.city, Users.ageFROM Users WHEREUsers.age>=18
Adults: b, c

⚖️ LICENSE

By contributing to the Open Sauced project, you agree that your contributions will be licensed under Apache License, Version 2.0.

About

Kotlin SQL Framework

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages