Skip to content

Commit 50f0a2b

Browse files
committed
kotlin: exposed module fix jooby-project#1219
1 parent eab6860 commit 50f0a2b

File tree

7 files changed

+397
-0
lines changed

7 files changed

+397
-0
lines changed

doc/doc/exposed/exposed.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# exposed
2+
3+
<a href="https://github.com/JetBrains/Exposed">Exposed</a> is a prototype for a lightweight SQL library written over JDBC driver for Kotlin language
4+
5+
> NOTE: This module depends on [jdbc](https://github.com/jooby-project/jooby/tree/master/jooby-jdbc) module.
6+
7+
## exports
8+
9+
* Database object
10+
11+
## usage
12+
13+
```java
14+
{
15+
use(Jdbc())
16+
use(Exposed())
17+
18+
get("/db") {
19+
val db = require(Database::class)
20+
transaction (db) {
21+
// Work with db...
22+
}
23+
}
24+
}
25+
```
26+
27+
## multiple databases
28+
29+
```java
30+
{
31+
use(Jdbc("db1"))
32+
33+
use(Jdbc("db2"))
34+
35+
use(Exposed("db1"))
36+
37+
use(Exposed("db2"))
38+
39+
get("/db") {
40+
val db1 = require("db1", Database::class)
41+
// Work with db1...
42+
43+
val db2 = require("db2", Database::class)
44+
// Work with db2...
45+
}
46+
}
47+
```
48+
49+
That's all! Happy coding!!!

jooby/src/test/java/org/jooby/test/MockUnit.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,10 @@ public MockUnit expect(final Block block) {
209209
return this;
210210
}
211211

212+
public MockUnit run(final Block block) throws Exception {
213+
return run(new Block[] {block});
214+
}
215+
212216
public MockUnit run(final Block... blocks) throws Exception {
213217

214218
for (Block block : this.blocks) {

modules/jooby-exposed/pom.xml

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
5+
6+
<parent>
7+
<groupId>org.jooby</groupId>
8+
<artifactId>modules</artifactId>
9+
<version>1.5.1-SNAPSHOT</version>
10+
</parent>
11+
12+
<modelVersion>4.0.0</modelVersion>
13+
<artifactId>jooby-exposed</artifactId>
14+
15+
<build>
16+
<plugins>
17+
<plugin>
18+
<artifactId>kotlin-maven-plugin</artifactId>
19+
<groupId>org.jetbrains.kotlin</groupId>
20+
<version>${kotlin.version}</version>
21+
<configuration>
22+
<jvmTarget>1.8</jvmTarget>
23+
<args>
24+
<arg>-java-parameters</arg>
25+
</args>
26+
</configuration>
27+
<executions>
28+
<execution>
29+
<id>compile</id>
30+
<phase>compile</phase>
31+
<goals>
32+
<goal>compile</goal>
33+
</goals>
34+
</execution>
35+
<execution>
36+
<id>test-compile</id>
37+
<phase>test-compile</phase>
38+
<goals>
39+
<goal>test-compile</goal>
40+
</goals>
41+
</execution>
42+
</executions>
43+
</plugin>
44+
45+
<plugin>
46+
<groupId>org.apache.maven.plugins</groupId>
47+
<artifactId>maven-compiler-plugin</artifactId>
48+
<executions>
49+
<!-- Replacing default-compile as it is treated specially by maven -->
50+
<execution>
51+
<id>default-compile</id>
52+
<phase>none</phase>
53+
</execution>
54+
<!-- Replacing default-testCompile as it is treated specially by maven -->
55+
<execution>
56+
<id>default-testCompile</id>
57+
<phase>none</phase>
58+
</execution>
59+
<execution>
60+
<id>java-compile</id>
61+
<phase>compile</phase>
62+
<goals>
63+
<goal>compile</goal>
64+
</goals>
65+
</execution>
66+
<execution>
67+
<id>java-test-compile</id>
68+
<phase>test-compile</phase>
69+
<goals>
70+
<goal>testCompile</goal>
71+
</goals>
72+
</execution>
73+
</executions>
74+
</plugin>
75+
76+
<!-- sure-fire -->
77+
<plugin>
78+
<groupId>org.apache.maven.plugins</groupId>
79+
<artifactId>maven-surefire-plugin</artifactId>
80+
<configuration>
81+
<includes>
82+
<include>**/*Test.java</include>
83+
<include>**/*Feature.java</include>
84+
<include>**/Issue*.java</include>
85+
</includes>
86+
</configuration>
87+
</plugin>
88+
89+
</plugins>
90+
</build>
91+
92+
<dependencies>
93+
<dependency>
94+
<groupId>org.jooby</groupId>
95+
<artifactId>jooby-jdbc</artifactId>
96+
<version>${project.version}</version>
97+
</dependency>
98+
99+
<!-- Jooby -->
100+
<dependency>
101+
<groupId>org.jooby</groupId>
102+
<artifactId>jooby</artifactId>
103+
<version>${project.version}</version>
104+
</dependency>
105+
106+
<!-- exposed -->
107+
<dependency>
108+
<groupId>org.jetbrains.exposed</groupId>
109+
<artifactId>exposed</artifactId>
110+
<version>${exposed.version}</version>
111+
</dependency>
112+
113+
<!-- Test dependencies -->
114+
<dependency>
115+
<groupId>org.jooby</groupId>
116+
<artifactId>jooby</artifactId>
117+
<version>${project.version}</version>
118+
<scope>test</scope>
119+
<classifier>tests</classifier>
120+
</dependency>
121+
122+
<dependency>
123+
<groupId>org.jooby</groupId>
124+
<artifactId>jooby-netty</artifactId>
125+
<version>${project.version}</version>
126+
<scope>test</scope>
127+
</dependency>
128+
129+
<dependency>
130+
<groupId>junit</groupId>
131+
<artifactId>junit</artifactId>
132+
<scope>test</scope>
133+
</dependency>
134+
135+
<dependency>
136+
<groupId>org.easymock</groupId>
137+
<artifactId>easymock</artifactId>
138+
<scope>test</scope>
139+
</dependency>
140+
141+
<dependency>
142+
<groupId>org.powermock</groupId>
143+
<artifactId>powermock-api-easymock</artifactId>
144+
<scope>test</scope>
145+
</dependency>
146+
147+
<dependency>
148+
<groupId>org.powermock</groupId>
149+
<artifactId>powermock-module-junit4</artifactId>
150+
<scope>test</scope>
151+
</dependency>
152+
153+
<dependency>
154+
<groupId>org.jacoco</groupId>
155+
<artifactId>org.jacoco.agent</artifactId>
156+
<classifier>runtime</classifier>
157+
<scope>test</scope>
158+
</dependency>
159+
<dependency>
160+
<groupId>org.jetbrains.kotlin</groupId>
161+
<artifactId>kotlin-stdlib-jdk8</artifactId>
162+
<version>${kotlin.version}</version>
163+
</dependency>
164+
<dependency>
165+
<groupId>org.jetbrains.kotlin</groupId>
166+
<artifactId>kotlin-test</artifactId>
167+
<version>${kotlin.version}</version>
168+
<scope>test</scope>
169+
</dependency>
170+
</dependencies>
171+
172+
<repositories>
173+
<repository>
174+
<id>exposed</id>
175+
<name>exposed</name>
176+
<url>https://dl.bintray.com/kotlin/exposed</url>
177+
</repository>
178+
</repositories>
179+
180+
</project>
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package org.jooby.exposed
2+
3+
import com.google.inject.Binder
4+
import com.google.inject.Key
5+
import com.google.inject.name.Names
6+
import com.typesafe.config.Config
7+
import org.jetbrains.exposed.sql.Database
8+
import org.jooby.Env
9+
import org.jooby.Jooby
10+
import java.util.NoSuchElementException
11+
import javax.sql.DataSource
12+
13+
/**
14+
* <h1>exposed</h1>
15+
* <p>
16+
* <a href="https://github.com/JetBrains/Exposed">Exposed</a> is a prototype for a lightweight SQL
17+
* library written over JDBC driver for Kotlin language
18+
* </p>
19+
*
20+
* <p>
21+
* This module depends on {@link org.jooby.jdbc.Jdbc} module, make sure you read the doc of the
22+
* {@link org.jooby.jdbc.Jdbc} module.
23+
* </p>
24+
*
25+
* <h2>exports</h2>
26+
* <ul>
27+
* <li>One or more Database objects</li>
28+
* </ul>
29+
*
30+
* <h2>usage</h2>
31+
* <pre>{@code
32+
* {
33+
* use(new Jdbc());
34+
*
35+
* use(new Exposed());
36+
*
37+
* get("/db") {
38+
* val db = require(Database::class)
39+
* transaction (db) {
40+
* // Work with db...
41+
* }
42+
* }
43+
* }
44+
* }</pre>
45+
*
46+
* <h2>multiple databases</h2>
47+
*
48+
* <pre>{@code
49+
* {
50+
* use(new Jdbc("db1"));
51+
*
52+
* use(new Jdbc("db2"));
53+
*
54+
* use(new Exposed("db1"));
55+
*
56+
* use(new Exposed("db2"));
57+
*
58+
* get("/db") {
59+
* val db1 = require("db1", Database::class)
60+
* // Work with db1...
61+
*
62+
* val db2 = require("db2", Database::class)
63+
* // Work with db2...
64+
* }
65+
* }
66+
* }</pre>
67+
*
68+
* @author edgar
69+
*/
70+
class Exposed(val name: String = "db") : Jooby.Module {
71+
override fun configure(env: Env, conf: Config, binder: Binder) {
72+
val dskey = Key.get(DataSource::class.java, Names.named(name))
73+
val ds = env.get(dskey)
74+
.orElseThrow { NoSuchElementException("DataSource missing: $dskey") }
75+
val db = Database.connect(ds)
76+
env.serviceKey().generate(Database::class.java, name) { key -> binder.bind(key).toInstance(db) }
77+
}
78+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package org.jooby.exposed
2+
3+
import com.google.inject.Binder
4+
import com.google.inject.Key
5+
import com.google.inject.binder.LinkedBindingBuilder
6+
import com.google.inject.name.Names
7+
import com.typesafe.config.Config
8+
import org.easymock.EasyMock
9+
import org.jetbrains.exposed.sql.Database
10+
import org.jooby.Env
11+
import org.jooby.test.MockUnit
12+
import org.junit.Test
13+
import java.util.*
14+
import java.util.function.Consumer
15+
import javax.sql.DataSource
16+
17+
class ExposedTest {
18+
19+
@Test
20+
fun defaults() {
21+
val dbkey = Key.get(Database::class.java, Names.named("db"))
22+
val blocks = arrayOf(MockUnit.Block { unit ->
23+
Exposed().configure(unit.get(Env::class.java), unit.get(Config::class.java), unit.get(Binder::class.java))
24+
}, MockUnit.Block { unit ->
25+
val binder = unit.captured(Consumer::class.java)[0] as Consumer<Key<Database>>
26+
binder.accept(dbkey)
27+
})
28+
29+
MockUnit(Env::class.java, Binder::class.java, Config::class.java, DataSource::class.java)
30+
.expect(dataSource("db"))
31+
.expect(serviceKey("db"))
32+
.expect(bind(dbkey))
33+
.run(*blocks)
34+
}
35+
36+
@Test(expected = NoSuchElementException::class)
37+
fun noDataSource() {
38+
val blocks = arrayOf(MockUnit.Block { unit ->
39+
Exposed().configure(unit.get(Env::class.java), unit.get(Config::class.java), unit.get(Binder::class.java))
40+
})
41+
42+
MockUnit(Env::class.java, Binder::class.java, Config::class.java, DataSource::class.java)
43+
.expect { unit ->
44+
val env = unit.get(Env::class.java)
45+
EasyMock.expect(env.get(Key.get(DataSource::class.java, Names.named("db")))).andReturn(Optional.empty())
46+
}
47+
.run(*blocks)
48+
}
49+
50+
private fun bind(key: Key<Database>): MockUnit.Block {
51+
return MockUnit.Block { unit ->
52+
val lbb = unit.mock(LinkedBindingBuilder::class.java) as LinkedBindingBuilder<Database>
53+
lbb.toInstance(EasyMock.isA(Database::class.java))
54+
55+
val binder = unit.get(Binder::class.java)
56+
EasyMock.expect(binder.bind(key)).andReturn(lbb)
57+
}
58+
}
59+
60+
private fun serviceKey(name: String): MockUnit.Block {
61+
return MockUnit.Block { unit ->
62+
val skey = unit.mock(Env.ServiceKey::class.java)
63+
skey.generate(EasyMock.eq(Database::class.java), EasyMock.eq(name), unit.capture(Consumer::class.java) as Consumer<Key<Database>>?);
64+
65+
val env = unit.get(Env::class.java)
66+
EasyMock.expect(env.serviceKey()).andReturn(skey)
67+
}
68+
}
69+
70+
private fun dataSource(db: String?): MockUnit.Block {
71+
return MockUnit.Block { unit ->
72+
val ds = unit.get(DataSource::class.java)
73+
val env = unit.get(Env::class.java)
74+
val ods = if (db == null) Optional.empty() else Optional.of(ds)
75+
EasyMock.expect(env.get(Key.get(DataSource::class.java, Names.named(db)))).andReturn(ods)
76+
}
77+
}
78+
}

0 commit comments

Comments
 (0)