Skip to content

Commit 474a166

Browse files
committed
1 parent 3da9a43 commit 474a166

19 files changed

Lines changed: 359 additions & 151 deletions

File tree

pom.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,18 @@
101101
</dependency>
102102

103103

104+
<dependency>
105+
<groupId>io.projectreactor</groupId>
106+
<artifactId>reactor-core</artifactId>
107+
</dependency>
108+
<dependency>
109+
<groupId>io.projectreactor</groupId>
110+
<artifactId>reactor-test</artifactId>
111+
<scope>test</scope>
112+
</dependency>
113+
114+
115+
104116
<dependency>
105117
<groupId>org.jetbrains.kotlin</groupId>
106118
<artifactId>kotlin-test-junit</artifactId>

src/main/kotlin/com/github/mgramin/sqlboot/model/connection/DbConnection.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,6 @@ interface DbConnection {
3030

3131
fun name(): String
3232
fun getDataSource(): DataSource
33+
fun paginationQueryTemplate(): String
3334

3435
}

src/main/kotlin/com/github/mgramin/sqlboot/model/connection/FakeDbConnection.kt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,17 @@ package com.github.mgramin.sqlboot.model.connection
2727
import javax.sql.DataSource
2828

2929
class FakeDbConnection : DbConnection {
30+
31+
override fun name(): String {
32+
return "Simple fake connection"
33+
}
34+
3035
override fun getDataSource(): DataSource {
3136
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
3237
}
3338

34-
override fun name(): String {
35-
return "Simple fake connection"
39+
override fun paginationQueryTemplate(): String {
40+
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
3641
}
42+
3743
}

src/main/kotlin/com/github/mgramin/sqlboot/model/connection/SimpleDbConnection.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import org.springframework.core.io.Resource
3636
*/
3737
open class SimpleDbConnection : DbConnection {
3838

39+
override fun paginationQueryTemplate() = this.paginationQueryTemplate!!
3940

4041
override fun name(): String {
4142
return name!!

src/main/kotlin/com/github/mgramin/sqlboot/model/resourcetype/impl/composite/FsResourceTypes.kt

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -57,24 +57,17 @@ class FsResourceTypes(private val dbConnections: List<SimpleDbConnection>, uri:
5757
val map = MarkdownFile(File(dir, "README.md").readText(UTF_8)).parse()
5858
if (map.isNotEmpty()) {
5959
val sql = map[uri.action()] ?: map.entries.iterator().next().value
60-
// val selectQuery =
61-
// JdbcSelectQuery(
62-
// TemplatedSelectQuery(
63-
// SimpleSelectQuery(GroovyTemplateGenerator(sql)),
64-
// variables = mapOf("uri" to uri),
65-
// dbConnection = dbConnections.first()),
66-
// dataSource = connection.getDataSource())
6760
val resourceType =
6861
// CacheWrapper(
69-
SortWrapper(
70-
SelectWrapper(
71-
BodyWrapper(
72-
SqlResourceType(
73-
aliases = listOf(dir.name),
74-
sql = sql,
75-
connections = dbConnections),
76-
templateGenerator = GroovyTemplateGenerator("[EMPTY BODY]")))
77-
)
62+
SelectWrapper(
63+
// PageWrapper(
64+
SortWrapper(
65+
BodyWrapper(
66+
SqlResourceType(
67+
aliases = listOf(dir.name),
68+
sql = sql,
69+
connections = dbConnections),
70+
templateGenerator = GroovyTemplateGenerator("[EMPTY BODY]"))))
7871
// )
7972
result.add(resourceType)
8073
}

src/main/kotlin/com/github/mgramin/sqlboot/model/resourcetype/impl/sql/SqlResourceType.kt

Lines changed: 41 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,21 @@
2525
package com.github.mgramin.sqlboot.model.resourcetype.impl.sql
2626

2727
import com.github.mgramin.sqlboot.model.connection.DbConnection
28-
import com.github.mgramin.sqlboot.model.connection.SimpleDbConnection
2928
import com.github.mgramin.sqlboot.model.resource.DbResource
3029
import com.github.mgramin.sqlboot.model.resource.impl.DbResourceImpl
3130
import com.github.mgramin.sqlboot.model.resourcetype.ResourceType
3231
import com.github.mgramin.sqlboot.model.uri.Uri
3332
import com.github.mgramin.sqlboot.model.uri.impl.DbUri
3433
import com.github.mgramin.sqlboot.sql.select.impl.SimpleSelectQuery
3534
import com.github.mgramin.sqlboot.sql.select.wrappers.JdbcSelectQuery
36-
import com.github.mgramin.sqlboot.sql.select.wrappers.TemplatedSelectQuery
35+
import com.github.mgramin.sqlboot.sql.select.wrappers.OrderedSelectQuery
36+
import com.github.mgramin.sqlboot.sql.select.wrappers.PaginatedSelectQuery
3737
import com.github.mgramin.sqlboot.template.generator.impl.GroovyTemplateGenerator
3838
import org.apache.commons.lang3.StringUtils.strip
39+
import reactor.core.publisher.Flux
40+
import reactor.core.publisher.Mono
41+
import reactor.core.publisher.toFlux
42+
import reactor.core.scheduler.Schedulers
3943

4044
/**
4145
* Created by MGramin on 12.07.2017.
@@ -59,60 +63,35 @@ class SqlResourceType(
5963
}
6064

6165
override fun read(uri: Uri): Sequence<DbResource> {
62-
63-
/*val map: Sequence<DbResourceImpl> = connections
64-
.asSequence()
65-
.map {
66-
JdbcSelectQuery(
67-
TemplatedSelectQuery(simpleSelectQuery, mapOf("uri" to uri), it as SimpleDbConnection),
68-
dataSource = it.getDataSource())
69-
}
70-
.map { it.execute(hashMapOf("uri" to uri)) }
71-
.flatMap { it.asSequence() }
72-
.map { o ->
73-
val path = o.entries
74-
.filter { v -> v.key.startsWith("@") }
75-
.map { it.value.toString() }
76-
val name = path[path.size - 1]
77-
val headers = o.entries
78-
.map { strip(it.key, "@") to it.value }
79-
.toMap()
80-
81-
return@map DbResourceImpl(name, this, DbUri(this.name(), path), headers)
82-
}.asSequence()
83-
return map*/
84-
85-
var result: ArrayList<DbResourceImpl> = arrayListOf()
86-
66+
val result: ArrayList<Mono<Sequence<DbResourceImpl>>> = arrayListOf()
8767
for (connection in connections) {
88-
val selectQuery =
89-
JdbcSelectQuery(
90-
TemplatedSelectQuery(
91-
simpleSelectQuery,
92-
variables = mapOf("uri" to uri),
93-
dbConnection = connection as SimpleDbConnection),
94-
dataSource = connection.getDataSource())
9568

96-
val map: Sequence<DbResourceImpl> = selectQuery.execute(hashMapOf("uri" to uri))
97-
.map { o ->
98-
val path = o.entries
99-
.filter { v -> v.key.startsWith("@") }
100-
.map { it.value.toString() }
101-
val name = path[path.size - 1]
102-
val headers = o.entries
103-
.map { strip(it.key, "@") to it.value }
104-
.toMap()
105-
val newHeaders = headers.toMutableMap()
106-
newHeaders["database"] = connection.name()
107-
108-
DbResourceImpl(name, this, DbUri(this.name(), path), newHeaders)
109-
}
110-
111-
result.addAll(map.toList())
69+
val fromCallable = Mono.fromCallable {
70+
val map: Sequence<DbResourceImpl> =
71+
createQuery(uri, connection)
72+
.execute(hashMapOf("uri" to uri))
73+
.map { o ->
74+
val path = o.entries
75+
.filter { v -> v.key.startsWith("@") }
76+
.map { it.value.toString() }
77+
val name = path[path.size - 1]
78+
val headers = o.entries
79+
.map { strip(it.key, "@") to it.value }
80+
.toMap()
81+
val newHeaders = headers.toMutableMap()
82+
newHeaders["database"] = connection.name()
83+
DbResourceImpl(name, this, DbUri(this.name(), path), newHeaders)
84+
}
85+
return@fromCallable map
86+
}.publishOn(Schedulers.parallel())
87+
88+
result.add(fromCallable)
11289
}
11390

91+
val mergeSequential: Flux<Sequence<DbResourceImpl>> = Flux.mergeSequential(result)
92+
val map = mergeSequential.map { it.toFlux() }.flatMap { it }.collectList().block()
11493

115-
return result.asSequence()
94+
return map.asSequence()
11695
}
11796

11897
override fun metaData(): Map<String, String> {
@@ -122,4 +101,15 @@ class SqlResourceType(
122101
return newColumns
123102
}
124103

104+
private fun createQuery(uri: Uri, connection: DbConnection): JdbcSelectQuery {
105+
return JdbcSelectQuery(
106+
PaginatedSelectQuery(
107+
OrderedSelectQuery(
108+
simpleSelectQuery,
109+
uri.orderedColumns()),
110+
uri,
111+
connection.paginationQueryTemplate()),
112+
dataSource = connection.getDataSource())
113+
}
114+
125115
}

src/main/kotlin/com/github/mgramin/sqlboot/model/resourcetype/wrappers/list/PageWrapper.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,5 @@ class PageWrapper constructor(
6262
origin.read(uri)
6363
}
6464
}
65+
6566
}

src/main/kotlin/com/github/mgramin/sqlboot/model/resourcetype/wrappers/list/SortWrapper.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,12 @@ class SortWrapper(private val origin: ResourceType,
4747

4848
override fun read(uri: Uri): Sequence<DbResource> {
4949
val read: Sequence<DbResource> = origin.read(uri)
50-
val parameters = uri.params()[parameterName] ?: return read
50+
val parameters = uri.orderedColumns()
51+
if (parameters.isEmpty()) {
52+
return read
53+
}
5154
val arrayOf: Array<(DbResource) -> Comparable<*>> = parameters
52-
.split(",")
53-
.map { return@map { it1: DbResource -> (it1.headers()[it] ?: "") as Comparable<*> } }
55+
.map { return@map { it1: DbResource -> (it1.headers()[it.key] ?: "") as Comparable<*> } }
5456
.toTypedArray()
5557
return read.sortedWith(compareByDescending(*arrayOf))
5658
}

src/main/kotlin/com/github/mgramin/sqlboot/model/uri/Uri.kt

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,7 @@ interface Uri : Serializable {
9393

9494
fun pageSize(): Int {
9595
val pageParameter = params()["page"]
96-
val pageSize: Int
97-
pageSize = if (pageParameter != null) {
96+
return if (pageParameter != null) {
9897
val delimiter = ","
9998
if (StringUtils.substringAfter(pageParameter, delimiter).isEmpty()) {
10099
10
@@ -104,7 +103,16 @@ interface Uri : Serializable {
104103
} else {
105104
10
106105
}
107-
return pageSize
106+
}
107+
108+
fun orderedColumns(): Map<String, String> {
109+
return (params()["orderby"] ?: "")
110+
.split(",")
111+
.asSequence()
112+
.filter { it.isNotBlank() }
113+
.map { return@map if (!it.contains("-")) "$it-asc" else it }
114+
.map { it.substringBefore("-") to it.substringAfter("-") }
115+
.toMap()
108116
}
109117

110118
}

src/main/kotlin/com/github/mgramin/sqlboot/sql/select/wrappers/SortedSelectQuery.kt renamed to src/main/kotlin/com/github/mgramin/sqlboot/sql/select/wrappers/OrderedSelectQuery.kt

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,21 @@ package com.github.mgramin.sqlboot.sql.select.wrappers
2626

2727
import com.github.mgramin.sqlboot.sql.select.SelectQuery
2828

29-
class SortedSelectQuery : SelectQuery {
29+
class OrderedSelectQuery(
30+
private val origin: SelectQuery,
31+
private val orderedColumns: Map<String, String>
32+
) : SelectQuery {
3033

3134
override fun query(): String {
32-
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
35+
if (orderedColumns.isEmpty()) return origin.query()
36+
val orderExpression = orderedColumns.map { "${it.key} ${it.value}" }.joinToString { it }
37+
return """select *
38+
| from (${origin.query()})
39+
| order by $orderExpression""".trimMargin()
3340
}
3441

35-
override fun columns(): Map<String, String> {
36-
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
37-
}
42+
override fun columns() = origin.columns()
3843

39-
override fun execute(variables: Map<String, Any>): Sequence<Map<String, Any>> {
40-
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
41-
}
44+
override fun execute(variables: Map<String, Any>) = origin.execute(variables)
4245

4346
}

0 commit comments

Comments
 (0)