Skip to content

Commit acb7d41

Browse files
committed
Various samples
1 parent 8a17cea commit acb7d41

File tree

11 files changed

+521
-7
lines changed

11 files changed

+521
-7
lines changed

build.gradle.kts

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
plugins {
22
kotlin("jvm") version "2.1.20" // Currently the plugin is only available for Kotlin-JVM
3-
id("io.exoquery.exoquery-plugin") version "2.1.20-1.1.2.PL"
3+
id("io.exoquery.exoquery-plugin") version "2.1.20-L.1.3.2.PL"
44
kotlin("plugin.serialization") version "2.1.20"
55
}
66

@@ -20,9 +20,8 @@ kotlin {
2020
}
2121

2222
dependencies {
23-
api("io.exoquery:exoquery-jdbc:0.1.0.PL-0.1.0")
23+
api("io.exoquery:exoquery-runner-jdbc:L.1.3.2.PL-L.1.3.2")
2424
implementation("org.postgresql:postgresql:42.7.0")
25-
2625
implementation("io.zonky.test:embedded-postgres:2.0.7")
2726
implementation("io.zonky.test.postgres:embedded-postgres-binaries-linux-amd64:16.2.0")
2827

@@ -32,6 +31,23 @@ dependencies {
3231
testImplementation(kotlin("test-annotations-common"))
3332
}
3433

34+
tasks.register<Jar>("customFatJar") {
35+
// copy the standard `jar` task’s contents first
36+
with(tasks.named<Jar>("jar").get())
37+
38+
manifest {
39+
attributes["Main-Class"] = "com.baeldung.fatjar.Application"
40+
}
41+
42+
archiveBaseName.set("all-in-one-jar")
43+
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
44+
45+
from({
46+
configurations.runtimeClasspath.get()
47+
.map { if (it.isDirectory) it else zipTree(it) }
48+
})
49+
}
50+
3551
// OPTIONAL: Make tests show in the build log even when they pass
3652
tasks.withType<Test>().configureEach {
3753
testLogging {
@@ -40,3 +56,7 @@ tasks.withType<Test>().configureEach {
4056
exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
4157
}
4258
}
59+
60+
configurations.forEach {
61+
it.exclude(group = "com.sschr15.annotations", module = "jb-annotations-kmp")
62+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package io.exoquery.example
2+
3+
import kotlin.reflect.KClass
4+
5+
interface Elem {
6+
data class Static(val name: String) : Elem
7+
object Variable : Elem
8+
}
9+
10+
interface PathBase {
11+
val elems: List<Elem>
12+
}
13+
data class Path0(override val elems: List<Elem>): PathBase
14+
data class Path1<T1>(override val elems: List<Elem>): PathBase
15+
data class Path2<T1, T2>(override val elems: List<Elem>): PathBase
16+
data class Path3<T1, T2, T3>(override val elems: List<Elem>): PathBase
17+
data class Path4<T1, T2, T3, T4>(override val elems: List<Elem>): PathBase
18+
19+
fun <T1, R> Path1<T1>.then(then: (T1) -> R): R = TODO()
20+
fun <T1, T2, R> Path2<T1, T2>.then(then: (T1, T2) -> R): R = TODO()
21+
22+
23+
class Var<T>
24+
25+
26+
interface PathBuilder {
27+
val root get(): Path0 = Path0(emptyList())
28+
operator fun Path0.div(other: String): Path0 = Path0(elems + Elem.Static(other))
29+
30+
operator fun <T1> Path0.div(other: Var<T1>): Path1<T1> = Path1(elems + Elem.Variable)
31+
operator fun <T1> Path1<T1>.div(other: String): Path1<T1> = Path1(elems + Elem.Static(other))
32+
operator fun <T1, T2> Path1<T1>.div(other: Var<T2>): Path2<T1, T2> = Path2(elems + Elem.Variable)
33+
}
34+
35+
fun <P: PathBase> path(builder: PathBuilder.() -> P): P = TODO()
36+
37+
object V {
38+
val String: Var<kotlin.String> = Var()
39+
val Int: Var<kotlin.Int> = Var()
40+
}
41+
42+
43+
fun myStuff() {
44+
path { root/"foo"/V.String/"bar"/V.Int }.then { name: String, id: Int ->
45+
println("id: $id, name: $name")
46+
}
47+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package io.exoquery.example
2+
3+
import io.exoquery.controller.jdbc.JdbcController
4+
import io.exoquery.controller.jdbc.JdbcControllers
5+
import io.exoquery.controller.runActions
6+
import io.zonky.test.db.postgres.embedded.EmbeddedPostgres
7+
import javax.sql.DataSource
8+
9+
object Common {
10+
11+
12+
val postgres = EmbeddedPostgres.start()
13+
val ds: DataSource = postgres.postgresDatabase
14+
15+
val postgresController = JdbcControllers.Postgres(ds)
16+
suspend fun setupDB(ctx: JdbcController) {
17+
ctx.runActions(
18+
"""
19+
CREATE TABLE Person (
20+
id SERIAL PRIMARY KEY,
21+
name VARCHAR(255),
22+
age INT
23+
);
24+
INSERT INTO Person (name, age) VALUES
25+
('Leib', 19),
26+
('Leah', 17),
27+
('Marina', 27),
28+
('Karina', 37);
29+
CREATE TABLE Address (
30+
ownerId INT,
31+
street VARCHAR(255),
32+
zip VARCHAR(255)
33+
);
34+
INSERT INTO Address (ownerId, street, zip) VALUES
35+
(1, '123 St.', '12345'),
36+
(2, '456 St.', '67890'),
37+
(3, '789 St.', '54321');
38+
"""
39+
)
40+
}
41+
}
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
package io.exoquery.example
2+
3+
import io.exoquery.annotation.CapturedFunction
4+
import io.exoquery.capture
5+
6+
7+
8+
fun booleanLogicConversion_20250529() {
9+
10+
data class Client(val name: String, val isRegistered: Boolean)
11+
12+
val q =
13+
capture.select {
14+
val c = from(Table<Client>())
15+
where { c.isRegistered || c.name == "Joe" }
16+
Pair(c.name, c.isRegistered || c.name == "Joe")
17+
}
18+
19+
println(q.buildFor.Postgres().value)
20+
// SELECT p.name FROM Client AS p WHERE p.isRegistered OR p.name = 'Joe'
21+
22+
println(q.buildFor.SqlServer().value)
23+
// SELECT p.name FROM Client AS p WHERE p.isRegistered = 1 OR p.name = 'Joe'
24+
25+
26+
}
27+
28+
29+
fun dateTypesOutOfTheBox_20250529() {
30+
31+
32+
33+
data class Client(val name: String, val birthDate: kotlinx.datetime.LocalDate)
34+
val minBirthday = kotlinx.datetime.LocalDate(2000, 1, 1)
35+
36+
val q =
37+
capture.select {
38+
val c = from(Table<Client>())
39+
where { c.birthDate < param(minBirthday) } // use paramCtx for java.time.*
40+
c.name
41+
}
42+
43+
println(q.buildFor.Postgres().value)
44+
45+
46+
}
47+
48+
49+
50+
fun windowFunctions_20250530_A() {
51+
52+
data class Customer(val name: String, val age: Int, val membership: String)
53+
54+
val q =
55+
capture.select {
56+
val c = from(Table<Customer>())
57+
Pair(
58+
c.name,
59+
// Average age of customers in the same membership group, ordered by name
60+
over().partitionBy(c.membership).orderBy(c.name).avg(c.age)
61+
)
62+
}
63+
64+
println(q.buildFor.Postgres().value)
65+
//> SELECT p.name, AVG(p.age) OVER (PARTITION BY p.membership ORDER BY p.name)
66+
// FROM Customer AS p
67+
68+
69+
70+
}
71+
72+
73+
74+
75+
fun windowFunctions_20250530_B() {
76+
77+
data class Data(val name: String, val a: Int, val b: Int, val c: Int)
78+
79+
80+
data class Customer(val name: String, val age: Int, val membership: String)
81+
data class VipCustomer(val name: String, val statusAge: Int, val tier: Int)
82+
83+
@CapturedFunction
84+
fun ntile(by: Customer, n: Int) = capture.expression {
85+
over()
86+
.partitionBy(by.membership)
87+
.orderBy(by.age)
88+
.frame(free("NTILE($n)").invoke<Int>())
89+
}
90+
91+
92+
@CapturedFunction
93+
fun ntileByAge(by: String, age: Int, n: Int) = capture.expression {
94+
over()
95+
.partitionBy(by)
96+
.orderBy(age)
97+
.frame(free("NTILE($n)").invoke<Int>())
98+
}
99+
100+
101+
102+
103+
104+
val ntile2 = capture.expression {
105+
{ c: Customer, n: Int ->
106+
over()
107+
.partitionBy(c.membership)
108+
.orderBy(c.age)
109+
.sum(n)
110+
}
111+
}
112+
113+
val q =
114+
capture.select {
115+
val c = from(Table<Customer>())
116+
Data(
117+
c.name,
118+
ntile(c, 5).use,
119+
ntile(c, 10).use,
120+
ntile(c, 20).use,
121+
)
122+
}
123+
124+
/*
125+
ntileByAge(c.name, c.age, 5).use,
126+
ntileByAge(c.name, c.age, 10).use,
127+
ntileByAge(c.name, c.age, 20).use,
128+
*/
129+
130+
131+
println(q.buildFor.Postgres().value)
132+
133+
}
134+
135+
136+
fun dateTypesOutOfTheBox_20250529_2() {
137+
138+
data class Client(val name: String, val birthDate: java.time.LocalDate)
139+
val minBirthday = java.time.LocalDate.of(2000, 1, 1)
140+
val q =
141+
capture.select {
142+
val c = from(Table<Client>())
143+
where { c.birthDate < paramCtx(minBirthday) }
144+
c.name
145+
}
146+
147+
println(q.buildFor.Postgres().value)
148+
149+
}
150+
151+
fun paramsWithCustomSerialization_20250529() {
152+
153+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package io.exoquery.example
2+
3+
import io.exoquery.capture
4+
5+
fun correlatedExample1_20250520() {
6+
7+
val q = capture.select {
8+
val p = from(Table<Person>())
9+
where { p.age > Table<Person>().map { it.age }.avg() }
10+
Pair(p.name, p.age)
11+
}
12+
13+
println(q.buildFor.Postgres().value)
14+
}
15+
16+
fun correlatedExample2_20250520() {
17+
val q = capture.select {
18+
val p = from(Table<Person>())
19+
where { p.age >
20+
Table<Person>().map { min(it.age) + avg(it.age) }.value()
21+
}
22+
Pair(p.name, p.age)
23+
}
24+
25+
println(q.buildFor.Postgres().value)
26+
}
27+
28+
fun nullabilityExample_20250521() {
29+
val q = capture.select {
30+
val p: Person = from(Table<Person>())
31+
val a: Address? = joinLeft(Table<Address>()) { p.id == it.ownerId }
32+
Triple(p.name, a?.street ?: "defaultStreet", a?.zip ?: "defaultZip")
33+
}
34+
35+
println(q.buildFor.Postgres().value)
36+
}
37+
38+
fun main() {
39+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package io.exoquery.example
2+
3+
import io.exoquery.capture
4+
import io.exoquery.runOn
5+
import kotlinx.serialization.Serializable
6+
7+
object ExamplesB {
8+
val ctx = Common.postgresController
9+
10+
@JvmInline
11+
@Serializable
12+
value class PersonId(val id: Int)
13+
@Serializable
14+
data class Person(val id: PersonId, val name: String, val age: Int)
15+
@Serializable
16+
data class Address(val ownerId: PersonId, val street: String, val zip: String)
17+
18+
val myId = PersonId(1)
19+
val q =
20+
capture.select {
21+
val p = from(Table<Person>())
22+
val a = join(Table<Address>()) { p.id == it.ownerId }
23+
where { p.id == param(myId) }
24+
p to a
25+
}
26+
27+
suspend fun valueExample_20250521() = q.buildFor.Postgres().runOn(ctx)
28+
}
29+
30+
suspend fun main() {
31+
Common.setupDB(Common.postgresController)
32+
val result = ExamplesB.valueExample_20250521()
33+
println(result)
34+
}

0 commit comments

Comments
 (0)