Skip to content

Commit

Permalink
fix: Field order in JDBC Driver closes#72
Browse files Browse the repository at this point in the history
  • Loading branch information
QuadStingray committed Feb 3, 2025
1 parent 9cd33ce commit 76d4bc6
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ import javax.sql.rowset.serial.SerialBlob
import scala.util.Try
import java.nio.charset.StandardCharsets

class MongoDbResultSet(collectionDao: MongoDAO[Document], data: List[Document], queryTimeOut: Int) extends ResultSet with MongoJdbcCloseable {
class MongoDbResultSet(collectionDao: MongoDAO[Document], data: List[Document], queryTimeOut: Int, keySet: List[String] = List.empty)
extends ResultSet
with MongoJdbcCloseable {
private var currentRow: Document = _
private var index: Int = 0

private lazy val metaData = new MongoDbResultSetMetaData(collectionDao, data)
private lazy val metaData = new MongoDbResultSetMetaData(collectionDao, data, keySet)

def getDocument: Document = currentRow

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import java.sql.{ ResultSetMetaData, SQLException }
class MongoDbResultSetMetaData extends ResultSetMetaData {
private var document: Document = _
private var collectionDao: MongoDAO[Document] = _
private var keySet: List[String] = List.empty

def this(dao: MongoDAO[Document]) = {
this()
Expand All @@ -31,6 +32,14 @@ class MongoDbResultSetMetaData extends ResultSetMetaData {
this.collectionDao = dao
}

def this(dao: MongoDAO[Document], data: List[Document], keySet: List[String]) = {
this()
val row: Document = extractDocumentFromDataList(data)
this.document = row
this.collectionDao = dao
this.keySet = keySet
}

private def extractDocumentFromDataList(data: List[Document]) = {
var row = data.headOption.getOrElse(throw new SQLException("No data in ResultSet")).copy()
val distinctKeys = data.flatMap(_.keys).distinct
Expand Down Expand Up @@ -59,7 +68,14 @@ class MongoDbResultSetMetaData extends ResultSetMetaData {

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

override def getColumnLabel(column: Int): String = document.keys.toList(column - 1)
override def getColumnLabel(column: Int): String = {
val keys : Iterable[String] =if (keySet.nonEmpty) {
keySet
} else {
document.keys
}
keys.toList(column - 1)
}

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ case class MongoPreparedStatement(connection: MongoJdbcConnection) extends Calla
var response = queryHolder.run(connection.getDatabaseProvider).results(getQueryTimeout)
if (response.isEmpty && queryHolder.hasFunctionCallInSelect) {
val emptyDocument = mutable.Map[String, Any]()
queryHolder.getKeysForEmptyDocument.foreach(key => emptyDocument.put(key, null))
queryHolder.getKeysFromSelect.foreach(key => emptyDocument.put(key, null))
val doc = Converter.toDocument(emptyDocument.toMap)
response = Seq(doc)
}
Expand All @@ -89,7 +89,7 @@ case class MongoPreparedStatement(connection: MongoJdbcConnection) extends Calla
newDoc
})
}
val resultSet = new MongoDbResultSet(collectionName.orNull, response.toList, getQueryTimeout)
val resultSet = new MongoDbResultSet(collectionName.orNull, response.toList, getQueryTimeout, queryHolder.getKeysFromSelect)
_lastResultSet = resultSet
resultSet
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,27 @@ import dev.mongocamp.driver.mongodb.database.DatabaseProvider.CollectionSeparato
import dev.mongocamp.driver.mongodb.exception.SqlCommandNotSupportedException
import dev.mongocamp.driver.mongodb.sql.SQLCommandType.SQLCommandType
import net.sf.jsqlparser.expression.operators.arithmetic.Concat
import net.sf.jsqlparser.expression.operators.conditional.{AndExpression, OrExpression}
import net.sf.jsqlparser.expression.operators.conditional.{ AndExpression, OrExpression }
import net.sf.jsqlparser.expression.operators.relational._
import net.sf.jsqlparser.expression.{ArrayConstructor, Expression, NotExpression, SignedExpression}
import net.sf.jsqlparser.parser.{CCJSqlParser, StreamProvider}
import net.sf.jsqlparser.schema.{Column, Table}
import net.sf.jsqlparser.expression.{ ArrayConstructor, Expression, NotExpression, SignedExpression }
import net.sf.jsqlparser.parser.{ CCJSqlParser, StreamProvider }
import net.sf.jsqlparser.schema.{ Column, Table }
import net.sf.jsqlparser.statement.alter.Alter
import net.sf.jsqlparser.statement.create.index.CreateIndex
import net.sf.jsqlparser.statement.create.table.CreateTable
import net.sf.jsqlparser.statement.delete.Delete
import net.sf.jsqlparser.statement.drop.Drop
import net.sf.jsqlparser.statement.execute.Execute
import net.sf.jsqlparser.statement.insert.Insert
import net.sf.jsqlparser.statement.select.{FromItem, PlainSelect, Select, SelectItem}
import net.sf.jsqlparser.statement.select.{ FromItem, PlainSelect, Select, SelectItem }
import net.sf.jsqlparser.statement.show.ShowTablesStatement
import net.sf.jsqlparser.statement.truncate.Truncate
import net.sf.jsqlparser.statement.update.Update
import net.sf.jsqlparser.statement.{ShowStatement, Statement}
import net.sf.jsqlparser.statement.{ ShowStatement, Statement }
import org.bson.conversions.Bson
import org.mongodb.scala.model.IndexOptions
import org.mongodb.scala.model.Sorts.ascending
import org.mongodb.scala.{Document, Observable, SingleObservable}
import org.mongodb.scala.{ Document, Observable, SingleObservable }

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

def this(statement: net.sf.jsqlparser.statement.Statement) = {
this()
Expand Down Expand Up @@ -211,7 +211,7 @@ class MongoSqlQueryHolder {
}
}

def getKeysForEmptyDocument: Set[String] = keysForEmptyDocument.toSet
def getKeysFromSelect: List[String] = keysFromSelect.toList

def hasFunctionCallInSelect: Boolean = keepOneDocument

Expand All @@ -235,7 +235,7 @@ class MongoSqlQueryHolder {
case e: net.sf.jsqlparser.expression.TimeValue => e.getValue
case e: net.sf.jsqlparser.expression.TimestampValue => e.getValue
case _: net.sf.jsqlparser.expression.NullValue => null
case e: Concat => Map("$concat" -> List(convertValue(e.getLeftExpression), convertValue(e.getRightExpression)))
case e: Concat => Map("$concat" -> List(convertValue(e.getLeftExpression), convertValue(e.getRightExpression)))
case t: net.sf.jsqlparser.expression.TimeKeyExpression =>
t.getStringValue.toUpperCase match {
case "CURRENT_TIMESTAMP" => new Date()
Expand Down Expand Up @@ -343,6 +343,14 @@ class MongoSqlQueryHolder {
if (classOf[net.sf.jsqlparser.expression.Function].isAssignableFrom(sI.getExpression.getClass)) {
keepOneDocument = maybeDistinct.isEmpty
}
sI match {
case se: SelectItem[Expression] =>
val expressionName = se.getExpression.toString
val keyFromSelect = Option(se.getAlias).map(_.getName).getOrElse(expressionName)
if (keyFromSelect != "*") {
keysFromSelect += keyFromSelect
}
}
})
val aliasList = ArrayBuffer[String]()
sqlCommandType = SQLCommandType.Select
Expand Down Expand Up @@ -496,7 +504,6 @@ class MongoSqlQueryHolder {
val expression = if (functionName.equalsIgnoreCase(espr.last)) Map("$first" -> espr.last) else Map(functionName -> espr.last)
group += expressionName -> expression
}
keysForEmptyDocument += Option(se.getAlias).map(_.getName).getOrElse(expressionName)
}

val groupMap = Map("_id" -> idGroupMap) ++ group.toMap
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dev.mongocamp.driver.mongodb.jdbc

import com.typesafe.scalalogging.LazyLogging
import dev.mongocamp.driver.mongodb.test.TestDatabase
import liquibase.database.jvm.JdbcConnection
import liquibase.exception.LiquibaseException
import liquibase.resource.ClassLoaderResourceAccessor
Expand All @@ -11,26 +12,29 @@ import scala.language.implicitConversions

class LiquibaseJdbcSuite extends BaseJdbcSuite with LazyLogging {

override def beforeAll(): Unit = {
TestDatabase.provider.dropDatabase("mongocamp-unit-test")
super.beforeAll()
}

test("Jdbc Connection should migrate database with liquibase") {
val jdbcConnection = new JdbcConnection(connection)
val liquibase: Liquibase = new Liquibase("liquibase/changelog.xml", new ClassLoaderResourceAccessor(), jdbcConnection)
val contexts = new Contexts()
val unrunChangesets = liquibase.listUnrunChangeSets(contexts, new LabelExpression())
val changes = unrunChangesets.asScala.toList
if (changes.isEmpty) {
logger.info("liquibase - nothing to update")
assert(true)
}
assert(changes.nonEmpty)
logger.info("liquibase - %s changesets to update".format(changes))
try {
liquibase.update(contexts)
assert(true)
}
catch {
case e: LiquibaseException =>
logger.error(e.getMessage, e)
assert(false)
}
val unrunChangesetsAfter = liquibase.listUnrunChangeSets(contexts, new LabelExpression())
assert(unrunChangesetsAfter.asScala.nonEmpty)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ class SelectJDBCSuite extends BaseJdbcSuite {
var i = 0
val arrayBuffer = ArrayBuffer[ResultSet]()
while (result.next()) {
assertEquals(result.getLong(1),result.getLong("id"))
assertEquals(result.getString(2),result.getString("guid"))
assertEquals(result.getString(3),result.getString("name"))
assertEquals(result.getInt(4),result.getInt("age"))
assertEquals(result.getDouble(5),result.getDouble("balance"))
i += 1
arrayBuffer += result
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class SelectSqlSuite extends BasePersonSuite {
val selectResponse = queryConverter.run(TestDatabase.provider).resultList()
assertEquals(selectResponse.head.getInteger("anz").toInt, 99)
assertEquals(queryConverter.getCollection, "people")
assertEquals(queryConverter.getKeysForEmptyDocument, Set("anz"))
assertEquals(queryConverter.getKeysFromSelect, List("anz"))
assertEquals(queryConverter.hasFunctionCallInSelect, true)
}

Expand Down

0 comments on commit 76d4bc6

Please sign in to comment.