From c047fbb0fd12209da5ef08327de13aca6f7cba6c Mon Sep 17 00:00:00 2001 From: QuadStingray Date: Wed, 5 Feb 2025 22:43:55 +0100 Subject: [PATCH] test: added more tests for jdbc package --- README.md | 3 +- .../mongocamp/driver/DocumentIncludes.scala | 13 +- .../jdbc/resultSet/MongoDbResultSet.scala | 5 +- .../statement/MongoPreparedStatement.scala | 619 ++++++++++++++---- .../mongodb/jdbc/MongoDbResultSetSuite.scala | 87 ++- .../jdbc/MongoPreparedStatementSuite.scala | 291 ++++++++ 6 files changed, 858 insertions(+), 160 deletions(-) create mode 100644 src/test/scala/dev/mongocamp/driver/mongodb/jdbc/MongoPreparedStatementSuite.scala diff --git a/README.md b/README.md index c2a6ca84..ac7a6d12 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Documentation can be found [here](https://mongodb-driver.mongocamp.dev/). ## Version -Scala Version is 2.13.x / 2.12.x. +Scala Version is 3.6.x / 2.13.x ## CI @@ -153,7 +153,6 @@ class RestaurantDemoSpec extends Specification with RestaurantDemoDatabaseFuncti ```shell docker rm -f mongodb; docker run -d --publish 27017:27017 --name mongodb mongocamp/mongodb:latest; -sbt +test; ``` ## Supporters diff --git a/src/main/scala/dev/mongocamp/driver/DocumentIncludes.scala b/src/main/scala/dev/mongocamp/driver/DocumentIncludes.scala index f0428af8..1caffec5 100644 --- a/src/main/scala/dev/mongocamp/driver/DocumentIncludes.scala +++ b/src/main/scala/dev/mongocamp/driver/DocumentIncludes.scala @@ -17,11 +17,9 @@ trait DocumentIncludes { implicit def luceneQueryBson(query: Query): Bson = LuceneQueryConverter.toDocument(query) - implicit def documentFromJavaMap(map: java.util.Map[String, Any]): Document = - documentFromScalaMap(map.asScala.toMap) + implicit def documentFromJavaMap(map: java.util.Map[String, Any]): Document = documentFromScalaMap(map.asScala.toMap) - implicit def documentFromMutableMap(map: collection.mutable.Map[String, Any]): Document = - documentFromScalaMap(map.toMap) + implicit def documentFromMutableMap(map: collection.mutable.Map[String, Any]): Document = documentFromScalaMap(map.toMap) implicit def documentFromScalaMap(map: Map[String, Any]): Document = { var result = Document() @@ -44,11 +42,9 @@ trait DocumentIncludes { result } - implicit def mapFromDocument(document: Document): Map[String, Any] = - BsonConverter.asMap(document) + implicit def mapFromDocument(document: Document): Map[String, Any] = BsonConverter.asMap(document) - implicit def mapListFromDocuments(documents: List[Document]): List[Map[String, Any]] = - BsonConverter.asMapList(documents) + implicit def mapListFromDocuments(documents: List[Document]): List[Map[String, Any]] = BsonConverter.asMapList(documents) // ObjectId implicit def stringToObjectId(str: String): ObjectId = new ObjectId(str) @@ -56,4 +52,5 @@ trait DocumentIncludes { implicit def documentToObjectId(doc: Document): ObjectId = { doc.getObjectId(DatabaseProvider.ObjectIdKey) } + } diff --git a/src/main/scala/dev/mongocamp/driver/mongodb/jdbc/resultSet/MongoDbResultSet.scala b/src/main/scala/dev/mongocamp/driver/mongodb/jdbc/resultSet/MongoDbResultSet.scala index 22c31e6a..62ad2d6a 100644 --- a/src/main/scala/dev/mongocamp/driver/mongodb/jdbc/resultSet/MongoDbResultSet.scala +++ b/src/main/scala/dev/mongocamp/driver/mongodb/jdbc/resultSet/MongoDbResultSet.scala @@ -1,11 +1,10 @@ package dev.mongocamp.driver.mongodb.jdbc.resultSet -import dev.mongocamp.driver.mongodb._ +import dev.mongocamp.driver.mongodb.* import dev.mongocamp.driver.mongodb.bson.BsonConverter import dev.mongocamp.driver.mongodb.jdbc.MongoJdbcCloseable -import dev.mongocamp.driver.mongodb.json._ import org.mongodb.scala.bson.collection.immutable.Document -import org.mongodb.scala.bson.{ BsonArray, BsonBoolean, BsonDateTime, BsonDouble, BsonInt32, BsonInt64, BsonNull, BsonNumber, BsonObjectId, BsonString } +import org.mongodb.scala.bson.{ BsonDouble, BsonInt32, BsonInt64, BsonObjectId, BsonString } import org.mongodb.scala.documentToUntypedDocument import java.io.{ InputStream, Reader } diff --git a/src/main/scala/dev/mongocamp/driver/mongodb/jdbc/statement/MongoPreparedStatement.scala b/src/main/scala/dev/mongocamp/driver/mongodb/jdbc/statement/MongoPreparedStatement.scala index d58751d1..1a8344b5 100644 --- a/src/main/scala/dev/mongocamp/driver/mongodb/jdbc/statement/MongoPreparedStatement.scala +++ b/src/main/scala/dev/mongocamp/driver/mongodb/jdbc/statement/MongoPreparedStatement.scala @@ -3,32 +3,18 @@ package dev.mongocamp.driver.mongodb.jdbc.statement import com.typesafe.scalalogging.LazyLogging import dev.mongocamp.driver.mongodb.exception.SqlCommandNotSupportedException import dev.mongocamp.driver.mongodb.jdbc.resultSet.MongoDbResultSet -import dev.mongocamp.driver.mongodb.jdbc.{ MongoJdbcCloseable, MongoJdbcConnection } +import dev.mongocamp.driver.mongodb.jdbc.{MongoJdbcCloseable, MongoJdbcConnection} +import dev.mongocamp.driver.mongodb.json.JsonConverter import dev.mongocamp.driver.mongodb.sql.MongoSqlQueryHolder -import dev.mongocamp.driver.mongodb.{ Converter, GenericObservable } +import dev.mongocamp.driver.mongodb.{Converter, GenericObservable} +import jdk.graal.compiler.util.json.JsonParser import org.joda.time.DateTime -import java.io.{ InputStream, Reader } +import java.io.{InputStream, Reader} import java.net.URL -import java.sql.{ - Blob, - CallableStatement, - Clob, - Connection, - Date, - NClob, - ParameterMetaData, - Ref, - ResultSet, - ResultSetMetaData, - RowId, - SQLWarning, - SQLXML, - Time, - Timestamp -} +import java.sql.{Blob, CallableStatement, Clob, Connection, Date, NClob, ParameterMetaData, Ref, ResultSet, ResultSetMetaData, RowId, SQLWarning, SQLXML, Time, Timestamp} import java.util.Calendar -import java.{ sql, util } +import java.{sql, util} import scala.collection.mutable import scala.util.Try @@ -67,6 +53,9 @@ case class MongoPreparedStatement(connection: MongoJdbcConnection) extends Calla val queryHolder: MongoSqlQueryHolder = try MongoSqlQueryHolder(sql) catch { + case e: java.sql.SQLException => + logger.error(e.getMessage, e) + null case e: SqlCommandNotSupportedException => logger.error(e.getMessage, e) null @@ -164,22 +153,22 @@ case class MongoPreparedStatement(connection: MongoJdbcConnection) extends Calla override def setBytes(parameterIndex: Int, x: Array[Byte]): Unit = { checkClosed() - setObject(parameterIndex, x) + setObject(parameterIndex, x.mkString("[", ",", "]")) } override def setDate(parameterIndex: Int, x: Date): Unit = { checkClosed() - setObject(parameterIndex, s"'${x.toInstant.toString}'") + setObject(parameterIndex, s"'${new DateTime(x).toInstant.toString}'") } override def setTime(parameterIndex: Int, x: Time): Unit = { checkClosed() - setObject(parameterIndex, s"'${x.toInstant.toString}'") + setObject(parameterIndex, s"'${new DateTime(x).toInstant.toString}'") } override def setTimestamp(parameterIndex: Int, x: Timestamp): Unit = { checkClosed() - setObject(parameterIndex, s"'${x.toInstant.toString}'") + setObject(parameterIndex, s"'${new DateTime(x).toInstant.toString}'") } override def setAsciiStream(parameterIndex: Int, x: InputStream, length: Int): Unit = { @@ -219,12 +208,15 @@ case class MongoPreparedStatement(connection: MongoJdbcConnection) extends Calla } override def setObject(parameterIndex: Int, x: Any, targetSqlType: Int): Unit = { + checkClosed() setObject(parameterIndex, x) } override def setObject(parameterIndex: Int, x: Any): Unit = { checkClosed() x match { + case null => + parameters.put(parameterIndex, "null") case d: Date => parameters.put(parameterIndex, s"'${d.toInstant.toString}'") case d: DateTime => @@ -286,7 +278,7 @@ case class MongoPreparedStatement(connection: MongoJdbcConnection) extends Calla } override def setURL(parameterIndex: Int, x: URL): Unit = { - sqlFeatureNotSupported() + setString(parameterIndex, x.toString) } override def getParameterMetaData: ParameterMetaData = { @@ -373,7 +365,7 @@ case class MongoPreparedStatement(connection: MongoJdbcConnection) extends Calla checkClosed() val updateResponse = executeQuery(sql) updateResponse.next() - val updateCount = updateResponse.getInt("matchedCount") + updateResponse.getInt("deletedCount") + updateResponse.getInt("insertedCount") + val updateCount = updateResponse.getInt("modifiedCount") + updateResponse.getInt("deletedCount") + updateResponse.getInt("insertedCount") _lastUpdateCount = updateCount updateCount } @@ -518,7 +510,6 @@ case class MongoPreparedStatement(connection: MongoJdbcConnection) extends Calla override def setPoolable(poolable: Boolean): Unit = { checkClosed() - 0 } override def isPoolable: Boolean = { @@ -534,235 +525,575 @@ case class MongoPreparedStatement(connection: MongoJdbcConnection) extends Calla checkClosed() false } -// todo - override def unwrap[T](iface: Class[T]): T = null.asInstanceOf[T] - override def isWrapperFor(iface: Class[_]): Boolean = false + override def unwrap[T](iface: Class[T]): T = { + checkClosed() + null.asInstanceOf[T] + } - override def registerOutParameter(parameterIndex: Int, sqlType: Int): Unit = ??? + override def isWrapperFor(iface: Class[_]): Boolean = { + checkClosed() + false + } - override def registerOutParameter(parameterIndex: Int, sqlType: Int, scale: Int): Unit = ??? + override def wasNull(): Boolean = { + checkClosed() + false + } - override def wasNull(): Boolean = ??? + def getStringOption(parameterIndex: Int): Option[String] = { + checkClosed() + parameters.get(parameterIndex).map(_.replace("'", "")) + } - override def getString(parameterIndex: Int): String = parameters.get(parameterIndex).orNull + override def getString(parameterIndex: Int): String = { + getStringOption(parameterIndex).orNull + } - override def getBoolean(parameterIndex: Int): Boolean = parameters.get(parameterIndex).flatMap(v => Try(v.toBoolean).toOption).getOrElse(false) + override def getBoolean(parameterIndex: Int): Boolean = { + checkClosed() + getStringOption(parameterIndex).flatMap(v => Try(v.toBoolean).toOption).orNull.asInstanceOf[Boolean] + } - override def getByte(parameterIndex: Int): Byte = parameters.get(parameterIndex).flatMap(v => Try(v.toByte).toOption).getOrElse(0) + override def getByte(parameterIndex: Int): Byte = { + checkClosed() + getStringOption(parameterIndex).flatMap(v => Try(v.toByte).toOption).orNull.asInstanceOf[Byte] + } - override def getShort(parameterIndex: Int): Short = parameters.get(parameterIndex).flatMap(v => Try(v.toShort).toOption).getOrElse(0) + override def getShort(parameterIndex: Int): Short = { + checkClosed() + getStringOption(parameterIndex).flatMap(v => Try(v.toShort).toOption).orNull.asInstanceOf[Short] + } - override def getInt(parameterIndex: Int): Int = parameters.get(parameterIndex).flatMap(v => Try(v.toInt).toOption).getOrElse(0) + override def getInt(parameterIndex: Int): Int = { + checkClosed() + getStringOption(parameterIndex).flatMap(v => Try(v.toInt).toOption).orNull.asInstanceOf[Int] + } - override def getLong(parameterIndex: Int): Long = parameters.get(parameterIndex).flatMap(v => Try(v.toLong).toOption).getOrElse(0) + override def getLong(parameterIndex: Int): Long = { + checkClosed() + getStringOption(parameterIndex).flatMap(v => Try(v.toLong).toOption).orNull.asInstanceOf[Long] + } - override def getFloat(parameterIndex: Int): Float = parameters.get(parameterIndex).flatMap(v => Try(v.toFloat).toOption).getOrElse(0.0.toFloat) + override def getFloat(parameterIndex: Int): Float = { + checkClosed() + getStringOption(parameterIndex).flatMap(v => Try(v.toFloat).toOption).orNull.asInstanceOf[Float] + } - override def getDouble(parameterIndex: Int): Double = parameters.get(parameterIndex).flatMap(v => Try(v.toDouble).toOption).getOrElse(0.0) + override def getDouble(parameterIndex: Int): Double = { + checkClosed() + getStringOption(parameterIndex).flatMap(v => Try(v.toDouble).toOption).orNull.asInstanceOf[Double] + } override def getBigDecimal(parameterIndex: Int, scale: Int): java.math.BigDecimal = getBigDecimal(parameterIndex) - override def getBytes(parameterIndex: Int): Array[Byte] = ??? + override def getBytes(parameterIndex: Int): Array[Byte] = { + checkClosed() + getStringOption(parameterIndex).flatMap(v => Try(new JsonConverter().toObject[Array[Byte]](v)).toOption).orNull + } - override def getDate(parameterIndex: Int): Date = ??? + override def getDate(parameterIndex: Int): Date = { + checkClosed() + getStringOption(parameterIndex).flatMap(v => Try(new Date(DateTime.parse(v).getMillis)).toOption).orNull + } - override def getTime(parameterIndex: Int): Time = ??? + override def getTime(parameterIndex: Int): Time = { + checkClosed() + getStringOption(parameterIndex).flatMap(v => Try(new Time(DateTime.parse(v).getMillis)).toOption).orNull + } - override def getTimestamp(parameterIndex: Int): Timestamp = ??? + override def getTimestamp(parameterIndex: Int): Timestamp = { + checkClosed() + getStringOption(parameterIndex).flatMap(v => Try(new Timestamp(DateTime.parse(v).getMillis)).toOption).orNull + } - override def getObject(parameterIndex: Int): AnyRef = ??? + override def getObject(parameterIndex: Int): AnyRef = { + checkClosed() + getStringOption(parameterIndex).orNull + } - override def getBigDecimal(parameterIndex: Int): java.math.BigDecimal = - parameters.get(parameterIndex).flatMap(v => Try(v.toDouble).toOption).map(new java.math.BigDecimal(_)).orNull + override def getBigDecimal(parameterIndex: Int): java.math.BigDecimal = { + checkClosed() + getStringOption(parameterIndex).flatMap(v => Try(new java.math.BigDecimal(v.toDouble)).toOption).orNull + } - override def getObject(parameterIndex: Int, map: util.Map[String, Class[_]]): AnyRef = ??? + override def getObject(parameterIndex: Int, map: util.Map[String, Class[_]]): AnyRef = { + checkClosed() + getStringOption(parameterIndex).orNull + } - override def getRef(parameterIndex: Int): Ref = ??? + override def getRef(parameterIndex: Int): Ref = { + checkClosed() + sqlFeatureNotSupported() + } - override def getBlob(parameterIndex: Int): Blob = ??? + override def getBlob(parameterIndex: Int): Blob = { + checkClosed() + sqlFeatureNotSupported() + } - override def getClob(parameterIndex: Int): Clob = ??? + override def getClob(parameterIndex: Int): Clob = { + checkClosed() + sqlFeatureNotSupported() + } - override def getArray(parameterIndex: Int): sql.Array = ??? + override def getArray(parameterIndex: Int): sql.Array = { + checkClosed() + sqlFeatureNotSupported() + } - override def getDate(parameterIndex: Int, cal: Calendar): Date = ??? + override def getDate(parameterIndex: Int, cal: Calendar): Date = getDate(parameterIndex) - override def getTime(parameterIndex: Int, cal: Calendar): Time = ??? + override def getTime(parameterIndex: Int, cal: Calendar): Time = getTime(parameterIndex) - override def getTimestamp(parameterIndex: Int, cal: Calendar): Timestamp = ??? + override def getTimestamp(parameterIndex: Int, cal: Calendar): Timestamp = getTimestamp(parameterIndex) - override def registerOutParameter(parameterIndex: Int, sqlType: Int, typeName: String): Unit = ??? + override def registerOutParameter(parameterIndex: Int, sqlType: Int, typeName: String): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def registerOutParameter(parameterName: String, sqlType: Int): Unit = ??? + override def registerOutParameter(parameterName: String, sqlType: Int): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def registerOutParameter(parameterName: String, sqlType: Int, scale: Int): Unit = ??? + override def registerOutParameter(parameterName: String, sqlType: Int, scale: Int): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def registerOutParameter(parameterName: String, sqlType: Int, typeName: String): Unit = ??? + override def registerOutParameter(parameterName: String, sqlType: Int, typeName: String): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def getURL(parameterIndex: Int): URL = ??? + override def registerOutParameter(parameterIndex: Int, sqlType: Int): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def setURL(parameterName: String, `val`: URL): Unit = ??? + override def registerOutParameter(parameterIndex: Int, sqlType: Int, scale: Int): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def setNull(parameterName: String, sqlType: Int): Unit = ??? + override def getURL(parameterIndex: Int): URL = { + checkClosed() + Option(getString(parameterIndex)).flatMap(v => { + val urlParser = Try(java.net.URI(v).toURL) + urlParser.toOption + }).orNull + } - override def setBoolean(parameterName: String, x: Boolean): Unit = ??? + override def getString(parameterName: String): String = { + checkClosed() + sqlFeatureNotSupported() + } - override def setByte(parameterName: String, x: Byte): Unit = ??? + override def getBoolean(parameterName: String): Boolean = { + checkClosed() + sqlFeatureNotSupported() + } - override def setShort(parameterName: String, x: Short): Unit = ??? + override def getByte(parameterName: String): Byte = { + checkClosed() + sqlFeatureNotSupported() + } - override def setInt(parameterName: String, x: Int): Unit = ??? + override def getShort(parameterName: String): Short = { + checkClosed() + sqlFeatureNotSupported() + } - override def setLong(parameterName: String, x: Long): Unit = ??? + override def getInt(parameterName: String): Int = { + checkClosed() + sqlFeatureNotSupported() + } - override def setFloat(parameterName: String, x: Float): Unit = ??? + override def getLong(parameterName: String): Long = { + checkClosed() + sqlFeatureNotSupported() + } - override def setDouble(parameterName: String, x: Double): Unit = ??? + override def getFloat(parameterName: String): Float = { + checkClosed() + sqlFeatureNotSupported() + } - override def setBigDecimal(parameterName: String, x: java.math.BigDecimal): Unit = ??? + override def getDouble(parameterName: String): Double = { + checkClosed() + sqlFeatureNotSupported() + } - override def setString(parameterName: String, x: String): Unit = ??? + override def getBytes(parameterName: String): Array[Byte] = { + checkClosed() + sqlFeatureNotSupported() + } - override def setBytes(parameterName: String, x: Array[Byte]): Unit = ??? + override def getDate(parameterName: String): Date = { + checkClosed() + sqlFeatureNotSupported() + } - override def setDate(parameterName: String, x: Date): Unit = ??? + override def getTime(parameterName: String): Time = { + checkClosed() + sqlFeatureNotSupported() + } - override def setTime(parameterName: String, x: Time): Unit = ??? + override def getTimestamp(parameterName: String): Timestamp = { + checkClosed() + sqlFeatureNotSupported() + } - override def setTimestamp(parameterName: String, x: Timestamp): Unit = ??? + override def getObject(parameterName: String): AnyRef = { + checkClosed() + sqlFeatureNotSupported() + } - override def setAsciiStream(parameterName: String, x: InputStream, length: Int): Unit = ??? + override def getBigDecimal(parameterName: String): java.math.BigDecimal = { + checkClosed() + sqlFeatureNotSupported() + } - override def setBinaryStream(parameterName: String, x: InputStream, length: Int): Unit = ??? + override def getObject(parameterName: String, map: util.Map[String, Class[_]]): AnyRef = { + checkClosed() + sqlFeatureNotSupported() + } - override def setObject(parameterName: String, x: Any, targetSqlType: Int, scale: Int): Unit = ??? + override def getRef(parameterName: String): Ref = { + checkClosed() + sqlFeatureNotSupported() + } - override def setObject(parameterName: String, x: Any, targetSqlType: Int): Unit = ??? + override def getBlob(parameterName: String): Blob = { + checkClosed() + sqlFeatureNotSupported() + } - override def setObject(parameterName: String, x: Any): Unit = ??? + override def getClob(parameterName: String): Clob = { + checkClosed() + sqlFeatureNotSupported() + } - override def setCharacterStream(parameterName: String, reader: Reader, length: Int): Unit = ??? + override def getArray(parameterName: String): sql.Array = { + checkClosed() + sqlFeatureNotSupported() + } - override def setDate(parameterName: String, x: Date, cal: Calendar): Unit = ??? + override def getDate(parameterName: String, cal: Calendar): Date = { + checkClosed() + sqlFeatureNotSupported() + } - override def setTime(parameterName: String, x: Time, cal: Calendar): Unit = ??? + override def getTime(parameterName: String, cal: Calendar): Time = { + checkClosed() + sqlFeatureNotSupported() + } - override def setTimestamp(parameterName: String, x: Timestamp, cal: Calendar): Unit = ??? + override def getTimestamp(parameterName: String, cal: Calendar): Timestamp = { + checkClosed() + sqlFeatureNotSupported() + } - override def setNull(parameterName: String, sqlType: Int, typeName: String): Unit = ??? + override def getURL(parameterName: String): URL = { + checkClosed() + sqlFeatureNotSupported() + } - override def getString(parameterName: String): String = ??? + override def getRowId(parameterIndex: Int): RowId = { + checkClosed() + sqlFeatureNotSupported() + } - override def getBoolean(parameterName: String): Boolean = ??? + override def getRowId(parameterName: String): RowId = { + checkClosed() + sqlFeatureNotSupported() + } - override def getByte(parameterName: String): Byte = ??? + override def setRowId(parameterName: String, x: RowId): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def getShort(parameterName: String): Short = ??? + override def setNString(parameterName: String, value: String): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def getInt(parameterName: String): Int = ??? + override def setNCharacterStream(parameterName: String, value: Reader, length: Long): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def getLong(parameterName: String): Long = ??? + override def setNClob(parameterName: String, value: NClob): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def getFloat(parameterName: String): Float = ??? + override def setClob(parameterName: String, reader: Reader, length: Long): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def getDouble(parameterName: String): Double = ??? + override def setBlob(parameterName: String, inputStream: InputStream, length: Long): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def getBytes(parameterName: String): Array[Byte] = ??? + override def setNClob(parameterName: String, reader: Reader, length: Long): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def getDate(parameterName: String): Date = ??? + override def getNClob(parameterIndex: Int): NClob = { + checkClosed() + sqlFeatureNotSupported() + } - override def getTime(parameterName: String): Time = ??? + override def getNClob(parameterName: String): NClob = { + checkClosed() + sqlFeatureNotSupported() + } - override def getTimestamp(parameterName: String): Timestamp = ??? + override def setSQLXML(parameterName: String, xmlObject: SQLXML): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def getObject(parameterName: String): AnyRef = ??? + override def getSQLXML(parameterIndex: Int): SQLXML = { + checkClosed() + sqlFeatureNotSupported() + } - override def getBigDecimal(parameterName: String): java.math.BigDecimal = ??? + override def getSQLXML(parameterName: String): SQLXML = { + checkClosed() + sqlFeatureNotSupported() + } - override def getObject(parameterName: String, map: util.Map[String, Class[_]]): AnyRef = ??? + override def getNString(parameterIndex: Int): String = { + checkClosed() + sqlFeatureNotSupported() + } - override def getRef(parameterName: String): Ref = ??? + override def getNString(parameterName: String): String = { + checkClosed() + sqlFeatureNotSupported() + } - override def getBlob(parameterName: String): Blob = ??? + override def getNCharacterStream(parameterIndex: Int): Reader = { + checkClosed() + sqlFeatureNotSupported() + } - override def getClob(parameterName: String): Clob = ??? + override def getNCharacterStream(parameterName: String): Reader = { + checkClosed() + sqlFeatureNotSupported() + } - override def getArray(parameterName: String): sql.Array = ??? + override def getCharacterStream(parameterIndex: Int): Reader = { + checkClosed() + sqlFeatureNotSupported() + } - override def getDate(parameterName: String, cal: Calendar): Date = ??? + override def getCharacterStream(parameterName: String): Reader = { + checkClosed() + sqlFeatureNotSupported() + } - override def getTime(parameterName: String, cal: Calendar): Time = ??? + override def setBlob(parameterName: String, x: Blob): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def getTimestamp(parameterName: String, cal: Calendar): Timestamp = ??? + override def setClob(parameterName: String, x: Clob): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def getURL(parameterName: String): URL = ??? + override def setAsciiStream(parameterName: String, x: InputStream, length: Long): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def getRowId(parameterIndex: Int): RowId = ??? + override def setBinaryStream(parameterName: String, x: InputStream, length: Long): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def getRowId(parameterName: String): RowId = ??? + override def setCharacterStream(parameterName: String, reader: Reader, length: Long): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def setRowId(parameterName: String, x: RowId): Unit = ??? + override def setAsciiStream(parameterName: String, x: InputStream): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def setNString(parameterName: String, value: String): Unit = ??? + override def setBinaryStream(parameterName: String, x: InputStream): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def setNCharacterStream(parameterName: String, value: Reader, length: Long): Unit = ??? + override def setCharacterStream(parameterName: String, reader: Reader): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def setNClob(parameterName: String, value: NClob): Unit = ??? + override def setNCharacterStream(parameterName: String, value: Reader): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def setClob(parameterName: String, reader: Reader, length: Long): Unit = ??? + override def setClob(parameterName: String, reader: Reader): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def setBlob(parameterName: String, inputStream: InputStream, length: Long): Unit = ??? + override def setBlob(parameterName: String, inputStream: InputStream): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def setNClob(parameterName: String, reader: Reader, length: Long): Unit = ??? + override def setNClob(parameterName: String, reader: Reader): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def getNClob(parameterIndex: Int): NClob = ??? + override def getObject[T](parameterIndex: Int, `type`: Class[T]): T = { + checkClosed() + sqlFeatureNotSupported() + } - override def getNClob(parameterName: String): NClob = ??? + override def getObject[T](parameterName: String, `type`: Class[T]): T = { + checkClosed() + sqlFeatureNotSupported() + } - override def setSQLXML(parameterName: String, xmlObject: SQLXML): Unit = ??? + override def setURL(parameterName: String, `val`: URL): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def getSQLXML(parameterIndex: Int): SQLXML = ??? + override def setNull(parameterName: String, sqlType: Int): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def getSQLXML(parameterName: String): SQLXML = ??? + override def setBoolean(parameterName: String, x: Boolean): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def getNString(parameterIndex: Int): String = ??? + override def setByte(parameterName: String, x: Byte): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def getNString(parameterName: String): String = ??? + override def setShort(parameterName: String, x: Short): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def getNCharacterStream(parameterIndex: Int): Reader = ??? + override def setInt(parameterName: String, x: Int): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def getNCharacterStream(parameterName: String): Reader = ??? + override def setLong(parameterName: String, x: Long): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def getCharacterStream(parameterIndex: Int): Reader = ??? + override def setFloat(parameterName: String, x: Float): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def getCharacterStream(parameterName: String): Reader = ??? + override def setDouble(parameterName: String, x: Double): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def setBlob(parameterName: String, x: Blob): Unit = ??? + override def setBigDecimal(parameterName: String, x: java.math.BigDecimal): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def setClob(parameterName: String, x: Clob): Unit = ??? + override def setString(parameterName: String, x: String): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def setAsciiStream(parameterName: String, x: InputStream, length: Long): Unit = ??? + override def setBytes(parameterName: String, x: Array[Byte]): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def setBinaryStream(parameterName: String, x: InputStream, length: Long): Unit = ??? + override def setDate(parameterName: String, x: Date): Unit = { + checkClosed() + sqlFeatureNotSupported() + } + + override def setTime(parameterName: String, x: Time): Unit = { + checkClosed() + sqlFeatureNotSupported() + } + + override def setTimestamp(parameterName: String, x: Timestamp): Unit = { + checkClosed() + sqlFeatureNotSupported() + } + + override def setAsciiStream(parameterName: String, x: InputStream, length: Int): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def setCharacterStream(parameterName: String, reader: Reader, length: Long): Unit = ??? + override def setBinaryStream(parameterName: String, x: InputStream, length: Int): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def setAsciiStream(parameterName: String, x: InputStream): Unit = ??? + override def setObject(parameterName: String, x: Any, targetSqlType: Int, scale: Int): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def setBinaryStream(parameterName: String, x: InputStream): Unit = ??? + override def setObject(parameterName: String, x: Any, targetSqlType: Int): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def setCharacterStream(parameterName: String, reader: Reader): Unit = ??? + override def setObject(parameterName: String, x: Any): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def setNCharacterStream(parameterName: String, value: Reader): Unit = ??? + override def setCharacterStream(parameterName: String, reader: Reader, length: Int): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def setClob(parameterName: String, reader: Reader): Unit = ??? + override def setDate(parameterName: String, x: Date, cal: Calendar): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def setBlob(parameterName: String, inputStream: InputStream): Unit = ??? + override def setTime(parameterName: String, x: Time, cal: Calendar): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def setNClob(parameterName: String, reader: Reader): Unit = ??? + override def setTimestamp(parameterName: String, x: Timestamp, cal: Calendar): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def getObject[T](parameterIndex: Int, `type`: Class[T]): T = ??? + override def setNull(parameterName: String, sqlType: Int, typeName: String): Unit = { + checkClosed() + sqlFeatureNotSupported() + } - override def getObject[T](parameterName: String, `type`: Class[T]): T = ??? } diff --git a/src/test/scala/dev/mongocamp/driver/mongodb/jdbc/MongoDbResultSetSuite.scala b/src/test/scala/dev/mongocamp/driver/mongodb/jdbc/MongoDbResultSetSuite.scala index 0f1ea64c..f1729ff9 100644 --- a/src/test/scala/dev/mongocamp/driver/mongodb/jdbc/MongoDbResultSetSuite.scala +++ b/src/test/scala/dev/mongocamp/driver/mongodb/jdbc/MongoDbResultSetSuite.scala @@ -1,15 +1,15 @@ package dev.mongocamp.driver.mongodb.jdbc -import dev.mongocamp.driver.mongodb._ +import dev.mongocamp.driver.mongodb.* import dev.mongocamp.driver.mongodb.jdbc.resultSet.MongoDbResultSet import org.joda.time.DateTime import org.mongodb.scala.bson.collection.immutable.Document import org.mongodb.scala.model.Updates -import java.sql.{ResultSet, SQLFeatureNotSupportedException, Time} +import java.sql.{Date, ResultSet, SQLFeatureNotSupportedException, Time, Timestamp} class MongoDbResultSetSuite extends BaseJdbcSuite { - + def initializeResultSet(): ResultSet = { super.beforeAll() val data = List( @@ -227,4 +227,85 @@ class MongoDbResultSetSuite extends BaseJdbcSuite { val resultSet = initializeResultSet() assert(!resultSet.isWrapperFor(classOf[MongoDbResultSet])) } + + test("updateNull should update the value to null") { + val resultSet = initializeResultSet() + resultSet.next() + resultSet.updateNull(1) + assert(resultSet.getObject(1) == null) + } + + test("updateBoolean should update the value") { + val resultSet = initializeResultSet() + resultSet.next() + resultSet.updateBoolean(3, false) + assert(!resultSet.getBoolean(3)) + } + + test("updateInt should update the value") { + val resultSet = initializeResultSet() + resultSet.next() + resultSet.updateInt(1, 42) + assert(resultSet.getInt(1) == 42) + } + + test("updateString should update the value") { + val resultSet = initializeResultSet() + resultSet.next() + resultSet.updateString(2, "updated_name") + assert(resultSet.getString(2) == "updated_name") + } + + test("updateDate should update the value") { + val resultSet = initializeResultSet() + resultSet.next() + val newDate = new Date(1622505600000L) + resultSet.updateDate(4, newDate) + assert(resultSet.getDate(4) == newDate) + } + + test("updateTime should update the value") { + val resultSet = initializeResultSet() + resultSet.next() + val newTime = new Time(1622505600000L) + resultSet.updateTime(4, newTime) + assert(resultSet.getTime(4) == newTime) + } + + test("updateTimestamp should update the value") { + val resultSet = initializeResultSet() + resultSet.next() + val newTimestamp = new Timestamp(1622505600000L) + resultSet.updateTimestamp(4, newTimestamp) + assert(resultSet.getTimestamp(4) == newTimestamp) + } + + test("updateObject should update the value") { + val resultSet = initializeResultSet() + resultSet.next() + resultSet.updateObject(1, 99) + assertEquals(resultSet.getObject(1).asInstanceOf[Int], 99) + } + + test("rowUpdated should return false") { + val resultSet = initializeResultSet() + assert(!resultSet.rowUpdated()) + } + + test("rowInserted should return false") { + val resultSet = initializeResultSet() + assert(!resultSet.rowInserted()) + } + + test("rowDeleted should return false") { + val resultSet = initializeResultSet() + assert(!resultSet.rowDeleted()) + } + + test("getConcurrency should throw SQLFeatureNotSupportedException") { + val resultSet = initializeResultSet() + intercept[SQLFeatureNotSupportedException] { + resultSet.getConcurrency + } + } } diff --git a/src/test/scala/dev/mongocamp/driver/mongodb/jdbc/MongoPreparedStatementSuite.scala b/src/test/scala/dev/mongocamp/driver/mongodb/jdbc/MongoPreparedStatementSuite.scala new file mode 100644 index 00000000..be8a8f84 --- /dev/null +++ b/src/test/scala/dev/mongocamp/driver/mongodb/jdbc/MongoPreparedStatementSuite.scala @@ -0,0 +1,291 @@ +package dev.mongocamp.driver.mongodb.jdbc + +import dev.mongocamp.driver.mongodb.jdbc.statement.MongoPreparedStatement +import scala.collection.convert._ +import java.sql.{Date, Time, Timestamp} + +class MongoPreparedStatementSuite extends BaseJdbcSuite { + var preparedStatement: MongoPreparedStatement = _ + + override def beforeAll(): Unit = { + super.beforeAll() + preparedStatement = MongoPreparedStatement(connection.asInstanceOf[MongoJdbcConnection]) + val preparedStatement2 = MongoPreparedStatement(connection.asInstanceOf[MongoJdbcConnection]) + preparedStatement2.executeUpdate("DELETE FROM table_name WHERE column2 = 123;") + } + + test("execute should return false for null SQL") { + assert(!preparedStatement.execute(null)) + } + + test("executeQuery should return empty result set for unsupported SQL") { + val resultSet = preparedStatement.executeQuery("unsupported SQL") + assert(resultSet != null) + assertEquals(resultSet.next(), false) + } + + test("setSql should set the SQL string") { + preparedStatement.setSql("SELECT * FROM test") + assertNotEquals(preparedStatement.executeQuery(), null) + } + + test("setNull should set parameter to null") { + preparedStatement.setNull(1, java.sql.Types.VARCHAR) + assertEquals(preparedStatement.getString(1), "null") + } + + test("setBoolean should set boolean parameter") { + preparedStatement.setBoolean(1, true) + assert(preparedStatement.getBoolean(1)) + } + + test("setByte should set byte parameter") { + preparedStatement.setByte(1, 1.toByte) + assertEquals(preparedStatement.getByte(1), 1.toByte) + } + + test("setShort should set short parameter") { + preparedStatement.setShort(1, 1.toShort) + assertEquals(preparedStatement.getShort(1), 1.toShort) + } + + test("setInt should set int parameter") { + preparedStatement.setInt(1, 1) + assertEquals(preparedStatement.getInt(1), 1) + } + + test("setLong should set long parameter") { + preparedStatement.setLong(1, 1L) + assertEquals(preparedStatement.getLong(1), 1L) + } + + test("setFloat should set float parameter") { + preparedStatement.setFloat(1, 1.0f) + assertEquals(preparedStatement.getFloat(1), 1.0f) + } + + test("setDouble should set double parameter") { + preparedStatement.setDouble(1, 1.0) + assertEquals(preparedStatement.getDouble(1), 1.0) + } + + test("setBigDecimal should set BigDecimal parameter") { + preparedStatement.setBigDecimal(1, new java.math.BigDecimal("1.0")) + assertEquals(preparedStatement.getBigDecimal(1), new java.math.BigDecimal(1.0)) + } + + test("setString should set string parameter") { + preparedStatement.setString(1, "test") + assertEquals(preparedStatement.getString(1), "test") + } + + test("setBytes should set byte array parameter") { + val bytes = Array[Byte](1, 2, 3) + preparedStatement.setBytes(1, bytes) + assertEquals(preparedStatement.getBytes(1).toList, bytes.toList) + } + + test("setDate should set date parameter") { + val date = new Date(System.currentTimeMillis()) + preparedStatement.setDate(1, date) + assertEquals(preparedStatement.getDate(1), date) + } + + test("setTime should set time parameter") { + val time = new Time(System.currentTimeMillis()) + preparedStatement.setTime(1, time) + assertEquals(preparedStatement.getTime(1) , time) + } + + test("setTimestamp should set timestamp parameter") { + val timestamp = new Timestamp(System.currentTimeMillis()) + preparedStatement.setTimestamp(1, timestamp) + assertEquals(preparedStatement.getTimestamp(1) , timestamp) + } + + test("clearParameters should clear all parameters") { + preparedStatement.setString(1, "test") + preparedStatement.clearParameters() + assertEquals(preparedStatement.getString(1) , null) + } + + test("getConnection should return the connection") { + assertEquals(preparedStatement.getConnection, connection) + } + + test("getQueryTimeout should return the query timeout") { + assertEquals(preparedStatement.getQueryTimeout , 10) + } + + test("setQueryTimeout should set the query timeout") { + preparedStatement.setQueryTimeout(20) + assertEquals(preparedStatement.getQueryTimeout , 20) + } + + test("getWarnings should return null") { + assertEquals(preparedStatement.getWarnings , null) + } + + test("clearWarnings should not throw exception") { + preparedStatement.clearWarnings() + } + + test("getResultSet should return the last result set") { + assertNotEquals(preparedStatement.getResultSet , null) + } + + test("getUpdateCount should return the last update count") { + assertEquals(preparedStatement.getUpdateCount , -1) + preparedStatement.executeUpdate("INSERT INTO table_name (column1, column2, column3) VALUES ('value1', 123, '2022-01-01T00:00:00.000Z'), ('value2', 456, '2022-02-01T00:00:00.000Z');") + assertEquals(preparedStatement.getUpdateCount , 2) + preparedStatement.executeUpdate("Update table_name SET column1 = 'value3' WHERE column2 = 123;") + assertEquals(preparedStatement.getUpdateCount , 1) + preparedStatement.executeUpdate("DELETE FROM table_name WHERE column2 = 123;") + assertEquals(preparedStatement.getUpdateCount , 1) + } + + test("getMoreResults should return false") { + assert(!preparedStatement.getMoreResults) + } + + test("getFetchDirection should return FETCH_FORWARD") { + assertEquals(preparedStatement.getFetchDirection , java.sql.ResultSet.FETCH_FORWARD) + } + + test("getFetchSize should return -1") { + assertEquals(preparedStatement.getFetchSize , -1) + } + + test("getResultSetType should return TYPE_FORWARD_ONLY") { + assertEquals(preparedStatement.getResultSetType , java.sql.ResultSet.TYPE_FORWARD_ONLY) + } + + test("getGeneratedKeys should return null") { + assertEquals(preparedStatement.getGeneratedKeys , null) + } + + test("getResultSetHoldability should return 0") { + assertEquals(preparedStatement.getResultSetHoldability , 0) + } + + test("isPoolable should return false") { + assert(!preparedStatement.isPoolable) + } + + test("isCloseOnCompletion should return false") { + assert(!preparedStatement.isCloseOnCompletion) + } + + test("wasNull should return false") { + assert(!preparedStatement.wasNull()) + } + + test("getObject should return the parameter value") { + preparedStatement.setString(1, "test") + assertEquals(preparedStatement.getObject(1) , "test") + } + + test("getURL should return the URL parameter") { + preparedStatement.setString(1, "http://example.com") + assertEquals(preparedStatement.getURL(1) , new java.net.URL("http://example.com")) + } + + test("set URL should set the URL parameter") { + preparedStatement.setURL(1, new java.net.URL("http://example.com")) + assertEquals(preparedStatement.getURL(1) , new java.net.URL("http://example.com")) + assertEquals(preparedStatement.getString(1) , "http://example.com") + } + + import java.sql.SQLFeatureNotSupportedException + + test("All unsupported methods should throw SQLFeatureNotSupportedException") { + val preparedStatement = new MongoPreparedStatement(connection.asInstanceOf[MongoJdbcConnection]) + + def assertThrowsFeatureNotSupportedException(f: => Unit): Unit = { + intercept[SQLFeatureNotSupportedException](f) + } + + assertThrowsFeatureNotSupportedException(preparedStatement.getString("param")) + assertThrowsFeatureNotSupportedException(preparedStatement.getBoolean("param")) + assertThrowsFeatureNotSupportedException(preparedStatement.getByte("param")) + assertThrowsFeatureNotSupportedException(preparedStatement.getShort("param")) + assertThrowsFeatureNotSupportedException(preparedStatement.getInt("param")) + assertThrowsFeatureNotSupportedException(preparedStatement.getLong("param")) + assertThrowsFeatureNotSupportedException(preparedStatement.getFloat("param")) + assertThrowsFeatureNotSupportedException(preparedStatement.getDouble("param")) + assertThrowsFeatureNotSupportedException(preparedStatement.getBytes("param")) + assertThrowsFeatureNotSupportedException(preparedStatement.getDate("param")) + assertThrowsFeatureNotSupportedException(preparedStatement.getTime("param")) + assertThrowsFeatureNotSupportedException(preparedStatement.getTimestamp("param")) + assertThrowsFeatureNotSupportedException(preparedStatement.getObject("param")) + assertThrowsFeatureNotSupportedException(preparedStatement.getBigDecimal("param")) + assertThrowsFeatureNotSupportedException(preparedStatement.getObject("param", classOf[Any])) + assertThrowsFeatureNotSupportedException(preparedStatement.getRef("param")) + assertThrowsFeatureNotSupportedException(preparedStatement.getBlob("param")) + assertThrowsFeatureNotSupportedException(preparedStatement.getClob("param")) + assertThrowsFeatureNotSupportedException(preparedStatement.getArray("param")) + assertThrowsFeatureNotSupportedException(preparedStatement.getDate("param", null)) + assertThrowsFeatureNotSupportedException(preparedStatement.getTime("param", null)) + assertThrowsFeatureNotSupportedException(preparedStatement.getTimestamp("param", null)) + assertThrowsFeatureNotSupportedException(preparedStatement.getURL("param")) + assertThrowsFeatureNotSupportedException(preparedStatement.getRowId(1)) + assertThrowsFeatureNotSupportedException(preparedStatement.getRowId("param")) + assertThrowsFeatureNotSupportedException(preparedStatement.setRowId("param", null)) + assertThrowsFeatureNotSupportedException(preparedStatement.setNString("param", null)) + assertThrowsFeatureNotSupportedException(preparedStatement.setNCharacterStream("param", null, 0L)) + assertThrowsFeatureNotSupportedException(preparedStatement.setNClob("param", null.asInstanceOf[java.sql.NClob])) + assertThrowsFeatureNotSupportedException(preparedStatement.setClob("param", null, 0L)) + assertThrowsFeatureNotSupportedException(preparedStatement.setBlob("param", null, 0L)) + assertThrowsFeatureNotSupportedException(preparedStatement.setNClob("param", null, 0L)) + assertThrowsFeatureNotSupportedException(preparedStatement.getNClob(1)) + assertThrowsFeatureNotSupportedException(preparedStatement.getNClob("param")) + assertThrowsFeatureNotSupportedException(preparedStatement.setSQLXML("param", null)) + assertThrowsFeatureNotSupportedException(preparedStatement.getSQLXML(1)) + assertThrowsFeatureNotSupportedException(preparedStatement.getSQLXML("param")) + assertThrowsFeatureNotSupportedException(preparedStatement.getNString(1)) + assertThrowsFeatureNotSupportedException(preparedStatement.getNString("param")) + assertThrowsFeatureNotSupportedException(preparedStatement.getNCharacterStream(1)) + assertThrowsFeatureNotSupportedException(preparedStatement.getNCharacterStream("param")) + assertThrowsFeatureNotSupportedException(preparedStatement.getCharacterStream(1)) + assertThrowsFeatureNotSupportedException(preparedStatement.getCharacterStream("param")) + assertThrowsFeatureNotSupportedException(preparedStatement.setBlob("param", null.asInstanceOf[java.sql.Blob])) + assertThrowsFeatureNotSupportedException(preparedStatement.setClob("param", null.asInstanceOf[java.sql.NClob])) + assertThrowsFeatureNotSupportedException(preparedStatement.setAsciiStream("param", null, 0L)) + assertThrowsFeatureNotSupportedException(preparedStatement.setBinaryStream("param", null, 0L)) + assertThrowsFeatureNotSupportedException(preparedStatement.setCharacterStream("param", null, 0L)) + assertThrowsFeatureNotSupportedException(preparedStatement.setAsciiStream("param", null)) + assertThrowsFeatureNotSupportedException(preparedStatement.setBinaryStream("param", null)) + assertThrowsFeatureNotSupportedException(preparedStatement.setCharacterStream("param", null)) + assertThrowsFeatureNotSupportedException(preparedStatement.setNCharacterStream("param", null)) + assertThrowsFeatureNotSupportedException(preparedStatement.setClob("param", null.asInstanceOf[java.sql.NClob])) + assertThrowsFeatureNotSupportedException(preparedStatement.setBlob("param", null.asInstanceOf[java.sql.Blob])) + assertThrowsFeatureNotSupportedException(preparedStatement.setNClob("param", null.asInstanceOf[java.sql.NClob])) + assertThrowsFeatureNotSupportedException(preparedStatement.getObject(1, classOf[Any])) + assertThrowsFeatureNotSupportedException(preparedStatement.getObject("param", classOf[Any])) + assertThrowsFeatureNotSupportedException(preparedStatement.setURL("param", null)) + assertThrowsFeatureNotSupportedException(preparedStatement.setNull("param", 0)) + assertThrowsFeatureNotSupportedException(preparedStatement.setBoolean("param", false)) + assertThrowsFeatureNotSupportedException(preparedStatement.setByte("param", 0.toByte)) + assertThrowsFeatureNotSupportedException(preparedStatement.setShort("param", 0.toShort)) + assertThrowsFeatureNotSupportedException(preparedStatement.setInt("param", 0)) + assertThrowsFeatureNotSupportedException(preparedStatement.setLong("param", 0L)) + assertThrowsFeatureNotSupportedException(preparedStatement.setFloat("param", 0.0f)) + assertThrowsFeatureNotSupportedException(preparedStatement.setDouble("param", 0.0)) + assertThrowsFeatureNotSupportedException(preparedStatement.setBigDecimal("param", null)) + assertThrowsFeatureNotSupportedException(preparedStatement.setString("param", null)) + assertThrowsFeatureNotSupportedException(preparedStatement.setBytes("param", null)) + assertThrowsFeatureNotSupportedException(preparedStatement.setDate("param", null)) + assertThrowsFeatureNotSupportedException(preparedStatement.setTime("param", null)) + assertThrowsFeatureNotSupportedException(preparedStatement.setTimestamp("param", null)) + assertThrowsFeatureNotSupportedException(preparedStatement.setAsciiStream("param", null, 0)) + assertThrowsFeatureNotSupportedException(preparedStatement.setBinaryStream("param", null, 0)) + assertThrowsFeatureNotSupportedException(preparedStatement.setObject("param", null, 0, 0)) + assertThrowsFeatureNotSupportedException(preparedStatement.setObject("param", null, 0)) + assertThrowsFeatureNotSupportedException(preparedStatement.setObject("param", null)) + assertThrowsFeatureNotSupportedException(preparedStatement.setCharacterStream("param", null, 0)) + assertThrowsFeatureNotSupportedException(preparedStatement.setDate("param", null, null)) + assertThrowsFeatureNotSupportedException(preparedStatement.setTime("param", null, null)) + assertThrowsFeatureNotSupportedException(preparedStatement.setTimestamp("param", null, null)) + assertThrowsFeatureNotSupportedException(preparedStatement.setNull("param", 0, null)) + } +}