Skip to content

Commit 76d4bc6

Browse files
committed
fix: Field order in JDBC Driver closes#72
1 parent 9cd33ce commit 76d4bc6

File tree

7 files changed

+56
-22
lines changed

7 files changed

+56
-22
lines changed

src/main/scala/dev/mongocamp/driver/mongodb/jdbc/resultSet/MongoDbResultSet.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@ import javax.sql.rowset.serial.SerialBlob
1818
import scala.util.Try
1919
import java.nio.charset.StandardCharsets
2020

21-
class MongoDbResultSet(collectionDao: MongoDAO[Document], data: List[Document], queryTimeOut: Int) extends ResultSet with MongoJdbcCloseable {
21+
class MongoDbResultSet(collectionDao: MongoDAO[Document], data: List[Document], queryTimeOut: Int, keySet: List[String] = List.empty)
22+
extends ResultSet
23+
with MongoJdbcCloseable {
2224
private var currentRow: Document = _
2325
private var index: Int = 0
2426

25-
private lazy val metaData = new MongoDbResultSetMetaData(collectionDao, data)
27+
private lazy val metaData = new MongoDbResultSetMetaData(collectionDao, data, keySet)
2628

2729
def getDocument: Document = currentRow
2830

src/main/scala/dev/mongocamp/driver/mongodb/jdbc/resultSet/MongoDbResultSetMetaData.scala

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import java.sql.{ ResultSetMetaData, SQLException }
1010
class MongoDbResultSetMetaData extends ResultSetMetaData {
1111
private var document: Document = _
1212
private var collectionDao: MongoDAO[Document] = _
13+
private var keySet: List[String] = List.empty
1314

1415
def this(dao: MongoDAO[Document]) = {
1516
this()
@@ -31,6 +32,14 @@ class MongoDbResultSetMetaData extends ResultSetMetaData {
3132
this.collectionDao = dao
3233
}
3334

35+
def this(dao: MongoDAO[Document], data: List[Document], keySet: List[String]) = {
36+
this()
37+
val row: Document = extractDocumentFromDataList(data)
38+
this.document = row
39+
this.collectionDao = dao
40+
this.keySet = keySet
41+
}
42+
3443
private def extractDocumentFromDataList(data: List[Document]) = {
3544
var row = data.headOption.getOrElse(throw new SQLException("No data in ResultSet")).copy()
3645
val distinctKeys = data.flatMap(_.keys).distinct
@@ -59,7 +68,14 @@ class MongoDbResultSetMetaData extends ResultSetMetaData {
5968

6069
override def getColumnDisplaySize(column: Int): Int = Int.MaxValue
6170

62-
override def getColumnLabel(column: Int): String = document.keys.toList(column - 1)
71+
override def getColumnLabel(column: Int): String = {
72+
val keys : Iterable[String] =if (keySet.nonEmpty) {
73+
keySet
74+
} else {
75+
document.keys
76+
}
77+
keys.toList(column - 1)
78+
}
6379

6480
override def getColumnName(column: Int): String = getColumnLabel(column)
6581

src/main/scala/dev/mongocamp/driver/mongodb/jdbc/statement/MongoPreparedStatement.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ case class MongoPreparedStatement(connection: MongoJdbcConnection) extends Calla
7878
var response = queryHolder.run(connection.getDatabaseProvider).results(getQueryTimeout)
7979
if (response.isEmpty && queryHolder.hasFunctionCallInSelect) {
8080
val emptyDocument = mutable.Map[String, Any]()
81-
queryHolder.getKeysForEmptyDocument.foreach(key => emptyDocument.put(key, null))
81+
queryHolder.getKeysFromSelect.foreach(key => emptyDocument.put(key, null))
8282
val doc = Converter.toDocument(emptyDocument.toMap)
8383
response = Seq(doc)
8484
}
@@ -89,7 +89,7 @@ case class MongoPreparedStatement(connection: MongoJdbcConnection) extends Calla
8989
newDoc
9090
})
9191
}
92-
val resultSet = new MongoDbResultSet(collectionName.orNull, response.toList, getQueryTimeout)
92+
val resultSet = new MongoDbResultSet(collectionName.orNull, response.toList, getQueryTimeout, queryHolder.getKeysFromSelect)
9393
_lastResultSet = resultSet
9494
resultSet
9595
}

src/main/scala/dev/mongocamp/driver/mongodb/sql/MongoSqlQueryHolder.scala

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,27 @@ import dev.mongocamp.driver.mongodb.database.DatabaseProvider.CollectionSeparato
77
import dev.mongocamp.driver.mongodb.exception.SqlCommandNotSupportedException
88
import dev.mongocamp.driver.mongodb.sql.SQLCommandType.SQLCommandType
99
import net.sf.jsqlparser.expression.operators.arithmetic.Concat
10-
import net.sf.jsqlparser.expression.operators.conditional.{AndExpression, OrExpression}
10+
import net.sf.jsqlparser.expression.operators.conditional.{ AndExpression, OrExpression }
1111
import net.sf.jsqlparser.expression.operators.relational._
12-
import net.sf.jsqlparser.expression.{ArrayConstructor, Expression, NotExpression, SignedExpression}
13-
import net.sf.jsqlparser.parser.{CCJSqlParser, StreamProvider}
14-
import net.sf.jsqlparser.schema.{Column, Table}
12+
import net.sf.jsqlparser.expression.{ ArrayConstructor, Expression, NotExpression, SignedExpression }
13+
import net.sf.jsqlparser.parser.{ CCJSqlParser, StreamProvider }
14+
import net.sf.jsqlparser.schema.{ Column, Table }
1515
import net.sf.jsqlparser.statement.alter.Alter
1616
import net.sf.jsqlparser.statement.create.index.CreateIndex
1717
import net.sf.jsqlparser.statement.create.table.CreateTable
1818
import net.sf.jsqlparser.statement.delete.Delete
1919
import net.sf.jsqlparser.statement.drop.Drop
2020
import net.sf.jsqlparser.statement.execute.Execute
2121
import net.sf.jsqlparser.statement.insert.Insert
22-
import net.sf.jsqlparser.statement.select.{FromItem, PlainSelect, Select, SelectItem}
22+
import net.sf.jsqlparser.statement.select.{ FromItem, PlainSelect, Select, SelectItem }
2323
import net.sf.jsqlparser.statement.show.ShowTablesStatement
2424
import net.sf.jsqlparser.statement.truncate.Truncate
2525
import net.sf.jsqlparser.statement.update.Update
26-
import net.sf.jsqlparser.statement.{ShowStatement, Statement}
26+
import net.sf.jsqlparser.statement.{ ShowStatement, Statement }
2727
import org.bson.conversions.Bson
2828
import org.mongodb.scala.model.IndexOptions
2929
import org.mongodb.scala.model.Sorts.ascending
30-
import org.mongodb.scala.{Document, Observable, SingleObservable}
30+
import org.mongodb.scala.{ Document, Observable, SingleObservable }
3131

3232
import java.sql.SQLException
3333
import java.util.Date
@@ -48,7 +48,7 @@ class MongoSqlQueryHolder {
4848
private var indexOptions: Option[IndexOptions] = None
4949
private var callFunction: Option[String] = None
5050
private var keepOneDocument: Boolean = false
51-
private val keysForEmptyDocument: mutable.Set[String] = mutable.Set.empty
51+
private val keysFromSelect: mutable.ListBuffer[String] = mutable.ListBuffer.empty
5252

5353
def this(statement: net.sf.jsqlparser.statement.Statement) = {
5454
this()
@@ -211,7 +211,7 @@ class MongoSqlQueryHolder {
211211
}
212212
}
213213

214-
def getKeysForEmptyDocument: Set[String] = keysForEmptyDocument.toSet
214+
def getKeysFromSelect: List[String] = keysFromSelect.toList
215215

216216
def hasFunctionCallInSelect: Boolean = keepOneDocument
217217

@@ -235,7 +235,7 @@ class MongoSqlQueryHolder {
235235
case e: net.sf.jsqlparser.expression.TimeValue => e.getValue
236236
case e: net.sf.jsqlparser.expression.TimestampValue => e.getValue
237237
case _: net.sf.jsqlparser.expression.NullValue => null
238-
case e: Concat => Map("$concat" -> List(convertValue(e.getLeftExpression), convertValue(e.getRightExpression)))
238+
case e: Concat => Map("$concat" -> List(convertValue(e.getLeftExpression), convertValue(e.getRightExpression)))
239239
case t: net.sf.jsqlparser.expression.TimeKeyExpression =>
240240
t.getStringValue.toUpperCase match {
241241
case "CURRENT_TIMESTAMP" => new Date()
@@ -343,6 +343,14 @@ class MongoSqlQueryHolder {
343343
if (classOf[net.sf.jsqlparser.expression.Function].isAssignableFrom(sI.getExpression.getClass)) {
344344
keepOneDocument = maybeDistinct.isEmpty
345345
}
346+
sI match {
347+
case se: SelectItem[Expression] =>
348+
val expressionName = se.getExpression.toString
349+
val keyFromSelect = Option(se.getAlias).map(_.getName).getOrElse(expressionName)
350+
if (keyFromSelect != "*") {
351+
keysFromSelect += keyFromSelect
352+
}
353+
}
346354
})
347355
val aliasList = ArrayBuffer[String]()
348356
sqlCommandType = SQLCommandType.Select
@@ -496,7 +504,6 @@ class MongoSqlQueryHolder {
496504
val expression = if (functionName.equalsIgnoreCase(espr.last)) Map("$first" -> espr.last) else Map(functionName -> espr.last)
497505
group += expressionName -> expression
498506
}
499-
keysForEmptyDocument += Option(se.getAlias).map(_.getName).getOrElse(expressionName)
500507
}
501508

502509
val groupMap = Map("_id" -> idGroupMap) ++ group.toMap
Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package dev.mongocamp.driver.mongodb.jdbc
22

33
import com.typesafe.scalalogging.LazyLogging
4+
import dev.mongocamp.driver.mongodb.test.TestDatabase
45
import liquibase.database.jvm.JdbcConnection
56
import liquibase.exception.LiquibaseException
67
import liquibase.resource.ClassLoaderResourceAccessor
@@ -11,26 +12,29 @@ import scala.language.implicitConversions
1112

1213
class LiquibaseJdbcSuite extends BaseJdbcSuite with LazyLogging {
1314

15+
override def beforeAll(): Unit = {
16+
TestDatabase.provider.dropDatabase("mongocamp-unit-test")
17+
super.beforeAll()
18+
}
19+
1420
test("Jdbc Connection should migrate database with liquibase") {
1521
val jdbcConnection = new JdbcConnection(connection)
1622
val liquibase: Liquibase = new Liquibase("liquibase/changelog.xml", new ClassLoaderResourceAccessor(), jdbcConnection)
1723
val contexts = new Contexts()
1824
val unrunChangesets = liquibase.listUnrunChangeSets(contexts, new LabelExpression())
1925
val changes = unrunChangesets.asScala.toList
20-
if (changes.isEmpty) {
21-
logger.info("liquibase - nothing to update")
22-
assert(true)
23-
}
26+
assert(changes.nonEmpty)
2427
logger.info("liquibase - %s changesets to update".format(changes))
2528
try {
2629
liquibase.update(contexts)
27-
assert(true)
2830
}
2931
catch {
3032
case e: LiquibaseException =>
3133
logger.error(e.getMessage, e)
3234
assert(false)
3335
}
36+
val unrunChangesetsAfter = liquibase.listUnrunChangeSets(contexts, new LabelExpression())
37+
assert(unrunChangesetsAfter.asScala.nonEmpty)
3438
}
3539

3640
}

src/test/scala/dev/mongocamp/driver/mongodb/jdbc/SelectJDBCSuite.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ class SelectJDBCSuite extends BaseJdbcSuite {
1111
var i = 0
1212
val arrayBuffer = ArrayBuffer[ResultSet]()
1313
while (result.next()) {
14+
assertEquals(result.getLong(1),result.getLong("id"))
15+
assertEquals(result.getString(2),result.getString("guid"))
16+
assertEquals(result.getString(3),result.getString("name"))
17+
assertEquals(result.getInt(4),result.getInt("age"))
18+
assertEquals(result.getDouble(5),result.getDouble("balance"))
1419
i += 1
1520
arrayBuffer += result
1621
}

src/test/scala/dev/mongocamp/driver/mongodb/sql/SelectSqlSuite.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class SelectSqlSuite extends BasePersonSuite {
5353
val selectResponse = queryConverter.run(TestDatabase.provider).resultList()
5454
assertEquals(selectResponse.head.getInteger("anz").toInt, 99)
5555
assertEquals(queryConverter.getCollection, "people")
56-
assertEquals(queryConverter.getKeysForEmptyDocument, Set("anz"))
56+
assertEquals(queryConverter.getKeysFromSelect, List("anz"))
5757
assertEquals(queryConverter.hasFunctionCallInSelect, true)
5858
}
5959

0 commit comments

Comments
 (0)