Initial Development #1
@ -2,6 +2,7 @@ package solutions.bitbadger.documents.scala
|
|||||||
|
|
||||||
import solutions.bitbadger.documents.{Configuration, Parameter}
|
import solutions.bitbadger.documents.{Configuration, Parameter}
|
||||||
|
|
||||||
|
import java.io.PrintWriter
|
||||||
import java.sql.{Connection, ResultSet}
|
import java.sql.{Connection, ResultSet}
|
||||||
import scala.reflect.ClassTag
|
import scala.reflect.ClassTag
|
||||||
import scala.util.Using
|
import scala.util.Using
|
||||||
@ -107,6 +108,60 @@ object Custom:
|
|||||||
def jsonArray(query: String, mapFunc: ResultSet => String): String =
|
def jsonArray(query: String, mapFunc: ResultSet => String): String =
|
||||||
jsonArray(query, Nil, mapFunc)
|
jsonArray(query, Nil, mapFunc)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute a query that writes a JSON array of results to the given `PrintWriter`
|
||||||
|
*
|
||||||
|
* @param query The query to retrieve the results
|
||||||
|
* @param parameters Parameters to use for the query
|
||||||
|
* @param writer The writer to which the results should be written
|
||||||
|
* @param conn The connection over which the query should be executed
|
||||||
|
* @param mapFunc The mapping function to extract the JSON from the query
|
||||||
|
* @return A JSON array of results for the given query
|
||||||
|
* @throws DocumentException If parameters are invalid
|
||||||
|
*/
|
||||||
|
def writeJsonArray(query: String, parameters: Seq[Parameter[?]], writer: PrintWriter, conn: Connection,
|
||||||
|
mapFunc: ResultSet => String): Unit =
|
||||||
|
Using(Parameters.apply(conn, query, parameters)) { stmt => Results.writeJsonArray(writer, stmt, mapFunc) }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute a query that returns a JSON array of results
|
||||||
|
*
|
||||||
|
* @param query The query to retrieve the results
|
||||||
|
* @param writer The writer to which the results should be written
|
||||||
|
* @param conn The connection over which the query should be executed
|
||||||
|
* @param mapFunc The mapping function to extract the JSON from the query
|
||||||
|
* @return A JSON array of results for the given query
|
||||||
|
* @throws DocumentException If parameters are invalid
|
||||||
|
*/
|
||||||
|
def writeJsonArray(query: String, conn: Connection, writer: PrintWriter, mapFunc: ResultSet => String): Unit =
|
||||||
|
writeJsonArray(query, Nil, writer, conn, mapFunc)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute a query that returns a JSON array of results (creates connection)
|
||||||
|
*
|
||||||
|
* @param query The query to retrieve the results
|
||||||
|
* @param parameters Parameters to use for the query
|
||||||
|
* @param writer The writer to which the results should be written
|
||||||
|
* @param mapFunc The mapping function to extract the JSON from the query
|
||||||
|
* @return A JSON array of results for the given query
|
||||||
|
* @throws DocumentException If parameters are invalid
|
||||||
|
*/
|
||||||
|
def writeJsonArray(query: String, parameters: Seq[Parameter[?]], writer: PrintWriter,
|
||||||
|
mapFunc: ResultSet => String): Unit =
|
||||||
|
Using(Configuration.dbConn()) { conn => writeJsonArray(query, parameters, writer, conn, mapFunc) }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute a query that returns a JSON array of results (creates connection)
|
||||||
|
*
|
||||||
|
* @param query The query to retrieve the results
|
||||||
|
* @param writer The writer to which the results should be written
|
||||||
|
* @param mapFunc The mapping function to extract the JSON from the query
|
||||||
|
* @return A JSON array of results for the given query
|
||||||
|
* @throws DocumentException If parameters are invalid
|
||||||
|
*/
|
||||||
|
def writeJsonArray(query: String, writer: PrintWriter, mapFunc: ResultSet => String): Unit =
|
||||||
|
writeJsonArray(query, Nil, writer, mapFunc)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute a query that returns one or no results
|
* Execute a query that returns one or no results
|
||||||
*
|
*
|
||||||
|
@ -3,6 +3,7 @@ package solutions.bitbadger.documents.scala
|
|||||||
import solutions.bitbadger.documents.DocumentException
|
import solutions.bitbadger.documents.DocumentException
|
||||||
import solutions.bitbadger.documents.java.Results as CoreResults
|
import solutions.bitbadger.documents.java.Results as CoreResults
|
||||||
|
|
||||||
|
import java.io.PrintWriter
|
||||||
import java.sql.{PreparedStatement, ResultSet, SQLException}
|
import java.sql.{PreparedStatement, ResultSet, SQLException}
|
||||||
import scala.collection.mutable.ListBuffer
|
import scala.collection.mutable.ListBuffer
|
||||||
import scala.reflect.ClassTag
|
import scala.reflect.ClassTag
|
||||||
@ -47,9 +48,8 @@ object Results:
|
|||||||
try
|
try
|
||||||
val buffer = ListBuffer[Doc]()
|
val buffer = ListBuffer[Doc]()
|
||||||
Using(stmt.executeQuery()) { rs =>
|
Using(stmt.executeQuery()) { rs =>
|
||||||
while (rs.next()) {
|
while rs.next() do
|
||||||
buffer.append(mapFunc(rs, tag))
|
buffer.append(mapFunc(rs, tag))
|
||||||
}
|
|
||||||
}
|
}
|
||||||
buffer.toList
|
buffer.toList
|
||||||
catch
|
catch
|
||||||
@ -107,12 +107,37 @@ object Results:
|
|||||||
try
|
try
|
||||||
val results = StringBuilder("[")
|
val results = StringBuilder("[")
|
||||||
Using(stmt.executeQuery()) { rs =>
|
Using(stmt.executeQuery()) { rs =>
|
||||||
while (rs.next()) {
|
while rs.next() do
|
||||||
if (results.length > 2) results.append(",")
|
if (results.length > 2) results.append(",")
|
||||||
results.append(mapFunc(rs))
|
results.append(mapFunc(rs))
|
||||||
}
|
|
||||||
}
|
}
|
||||||
results.append("]").toString()
|
results.append("]").toString()
|
||||||
catch
|
catch
|
||||||
case ex: SQLException =>
|
case ex: SQLException => throw DocumentException("Error retrieving documents from query: ${ex.message}", ex)
|
||||||
throw DocumentException("Error retrieving documents from query: ${ex.message}", ex)
|
|
||||||
|
/**
|
||||||
|
* Write a JSON array of items for the results of the given command to the given `PrintWriter`, using the specified
|
||||||
|
* mapping function
|
||||||
|
*
|
||||||
|
* @param writer The writer for the results of the query
|
||||||
|
* @param stmt The prepared statement to execute
|
||||||
|
* @param mapFunc The mapping function from data reader to JSON text
|
||||||
|
* @return A string with a JSON array of documents from the query's result
|
||||||
|
* @throws DocumentException If there is a problem executing the query (unchecked)
|
||||||
|
*/
|
||||||
|
def writeJsonArray(writer: PrintWriter, stmt: PreparedStatement, mapFunc: ResultSet => String): Unit =
|
||||||
|
try
|
||||||
|
writer.write("[")
|
||||||
|
Using(stmt.executeQuery()) { rs =>
|
||||||
|
var isFirst = true
|
||||||
|
while rs.next() do
|
||||||
|
if isFirst then
|
||||||
|
isFirst = false
|
||||||
|
else
|
||||||
|
writer.write(",")
|
||||||
|
writer.write(mapFunc(rs))
|
||||||
|
}
|
||||||
|
writer.write("]")
|
||||||
|
catch
|
||||||
|
case ex: SQLException => throw DocumentException("Error writing documents from query: ${ex.message}", ex)
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package solutions.bitbadger.documents.scala.extensions
|
|||||||
import solutions.bitbadger.documents.{DocumentIndex, Field, FieldMatch, Parameter}
|
import solutions.bitbadger.documents.{DocumentIndex, Field, FieldMatch, Parameter}
|
||||||
import solutions.bitbadger.documents.scala.*
|
import solutions.bitbadger.documents.scala.*
|
||||||
|
|
||||||
|
import java.io.PrintWriter
|
||||||
import java.sql.{Connection, ResultSet}
|
import java.sql.{Connection, ResultSet}
|
||||||
import scala.reflect.ClassTag
|
import scala.reflect.ClassTag
|
||||||
|
|
||||||
@ -58,6 +59,32 @@ extension (conn: Connection)
|
|||||||
def customJsonArray(query: String, mapFunc: ResultSet => String): String =
|
def customJsonArray(query: String, mapFunc: ResultSet => String): String =
|
||||||
Custom.jsonArray(query, mapFunc)
|
Custom.jsonArray(query, mapFunc)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute a query that writes a JSON array of results to the given `PrintWriter`
|
||||||
|
*
|
||||||
|
* @param query The query to retrieve the results
|
||||||
|
* @param parameters Parameters to use for the query
|
||||||
|
* @param writer The writer to which the results should be written
|
||||||
|
* @param mapFunc The mapping function to extract the JSON from the query
|
||||||
|
* @return A JSON array of results for the given query
|
||||||
|
* @throws DocumentException If parameters are invalid
|
||||||
|
*/
|
||||||
|
def writeCustomJsonArray(query: String, parameters: Seq[Parameter[?]], writer: PrintWriter,
|
||||||
|
mapFunc: ResultSet => String): Unit =
|
||||||
|
Custom.writeJsonArray(query, parameters, writer, conn, mapFunc)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute a query that writes a JSON array of results to the given `PrintWriter`
|
||||||
|
*
|
||||||
|
* @param query The query to retrieve the results
|
||||||
|
* @param writer The writer to which the results should be written
|
||||||
|
* @param mapFunc The mapping function to extract the JSON from the query
|
||||||
|
* @return A JSON array of results for the given query
|
||||||
|
* @throws DocumentException If parameters are invalid
|
||||||
|
*/
|
||||||
|
def writeCustomJsonArray(query: String, writer: PrintWriter, mapFunc: ResultSet => String): Unit =
|
||||||
|
Custom.writeJsonArray(query, writer, mapFunc)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute a query that returns one or no results
|
* Execute a query that returns one or no results
|
||||||
*
|
*
|
||||||
|
@ -7,6 +7,7 @@ import solutions.bitbadger.documents.scala.extensions.*
|
|||||||
import solutions.bitbadger.documents.scala.tests.TEST_TABLE
|
import solutions.bitbadger.documents.scala.tests.TEST_TABLE
|
||||||
import solutions.bitbadger.documents.{Configuration, Field, Parameter, ParameterType}
|
import solutions.bitbadger.documents.{Configuration, Field, Parameter, ParameterType}
|
||||||
|
|
||||||
|
import java.io.{PrintWriter, StringWriter}
|
||||||
import scala.jdk.CollectionConverters.*
|
import scala.jdk.CollectionConverters.*
|
||||||
|
|
||||||
object CustomFunctions:
|
object CustomFunctions:
|
||||||
@ -29,19 +30,43 @@ object CustomFunctions:
|
|||||||
|
|
||||||
def jsonArraySingle(db: ThrowawayDatabase): Unit =
|
def jsonArraySingle(db: ThrowawayDatabase): Unit =
|
||||||
db.conn.insert(TEST_TABLE, ArrayDocument("one", "2" :: "3" :: Nil))
|
db.conn.insert(TEST_TABLE, ArrayDocument("one", "2" :: "3" :: Nil))
|
||||||
assertEquals(JsonFunctions.maybeJsonB("[{\"id\":\"one\",\"values\":[\"2\",\"3\"]}]"),
|
assertEquals(JsonFunctions.maybeJsonB("""[{"id":"one","values":["2","3"]}]"""),
|
||||||
db.conn.customJsonArray(FindQuery.all(TEST_TABLE), Nil, Results.jsonFromData),
|
db.conn.customJsonArray(FindQuery.all(TEST_TABLE), Nil, Results.jsonFromData),
|
||||||
"A single document list was not represented correctly")
|
"A single document list was not represented correctly")
|
||||||
|
|
||||||
def jsonArrayMany(db: ThrowawayDatabase): Unit =
|
def jsonArrayMany(db: ThrowawayDatabase): Unit =
|
||||||
ArrayDocument.testDocuments.foreach { doc => db.conn.insert(TEST_TABLE, doc) }
|
ArrayDocument.testDocuments.foreach { doc => db.conn.insert(TEST_TABLE, doc) }
|
||||||
assertEquals(JsonFunctions.maybeJsonB("[{\"id\":\"first\",\"values\":[\"a\",\"b\",\"c\"]},"
|
assertEquals(JsonFunctions.maybeJsonB("""[{"id":"first","values":["a","b","c"]},"""
|
||||||
+ "{\"id\":\"second\",\"values\":[\"c\",\"d\",\"e\"]},"
|
+ """{"id":"second","values":["c","d","e"]},{"id":"third","values":["x","y","z"]}]"""),
|
||||||
+ "{\"id\":\"third\",\"values\":[\"x\",\"y\",\"z\"]}]"),
|
|
||||||
db.conn.customJsonArray(FindQuery.all(TEST_TABLE) + QueryUtils.orderBy((Field.named("id") :: Nil).asJava), Nil,
|
db.conn.customJsonArray(FindQuery.all(TEST_TABLE) + QueryUtils.orderBy((Field.named("id") :: Nil).asJava), Nil,
|
||||||
Results.jsonFromData),
|
Results.jsonFromData),
|
||||||
"A multiple document list was not represented correctly")
|
"A multiple document list was not represented correctly")
|
||||||
|
|
||||||
|
def writeJsonArrayEmpty(db: ThrowawayDatabase): Unit =
|
||||||
|
assertEquals(0L, db.conn.countAll(TEST_TABLE), "The test table should be empty")
|
||||||
|
val output = StringWriter()
|
||||||
|
val writer = PrintWriter(output)
|
||||||
|
db.conn.writeCustomJsonArray(FindQuery.all(TEST_TABLE), Nil, writer, Results.jsonFromData)
|
||||||
|
assertEquals("[]", output.toString, "An empty list was not represented correctly")
|
||||||
|
|
||||||
|
def writeJsonArraySingle(db: ThrowawayDatabase): Unit =
|
||||||
|
db.conn.insert(TEST_TABLE, ArrayDocument("one", "2" :: "3" :: Nil))
|
||||||
|
val output = StringWriter()
|
||||||
|
val writer = PrintWriter(output)
|
||||||
|
db.conn.writeCustomJsonArray(FindQuery.all(TEST_TABLE), Nil, writer, Results.jsonFromData)
|
||||||
|
assertEquals(JsonFunctions.maybeJsonB("""[{"id":"one","values":["2","3"]}]"""), output.toString,
|
||||||
|
"A single document list was not represented correctly")
|
||||||
|
|
||||||
|
def writeJsonArrayMany(db: ThrowawayDatabase): Unit =
|
||||||
|
ArrayDocument.testDocuments.foreach { doc => db.conn.insert(TEST_TABLE, doc) }
|
||||||
|
val output = StringWriter()
|
||||||
|
val writer = PrintWriter(output)
|
||||||
|
db.conn.writeCustomJsonArray(FindQuery.all(TEST_TABLE) + QueryUtils.orderBy((Field.named("id") :: Nil).asJava), Nil,
|
||||||
|
writer, Results.jsonFromData)
|
||||||
|
assertEquals(JsonFunctions.maybeJsonB("""[{"id":"first","values":["a","b","c"]},"""
|
||||||
|
+ """{"id":"second","values":["c","d","e"]},{"id":"third","values":["x","y","z"]}]"""),
|
||||||
|
output.toString, "A multiple document list was not represented correctly")
|
||||||
|
|
||||||
def singleNone(db: ThrowawayDatabase): Unit =
|
def singleNone(db: ThrowawayDatabase): Unit =
|
||||||
assertTrue(db.conn.customSingle[JsonDocument](FindQuery.all(TEST_TABLE), Results.fromData).isEmpty,
|
assertTrue(db.conn.customSingle[JsonDocument](FindQuery.all(TEST_TABLE), Results.fromData).isEmpty,
|
||||||
"There should not have been a document returned")
|
"There should not have been a document returned")
|
||||||
|
@ -32,6 +32,21 @@ class PostgreSQLCustomIT:
|
|||||||
def jsonArrayMany(): Unit =
|
def jsonArrayMany(): Unit =
|
||||||
Using(PgDB()) { db => CustomFunctions.jsonArrayMany(db) }
|
Using(PgDB()) { db => CustomFunctions.jsonArrayMany(db) }
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("writeJsonArray succeeds with empty array")
|
||||||
|
def writeJsonArrayEmpty(): Unit =
|
||||||
|
Using(PgDB()) { db => CustomFunctions.writeJsonArrayEmpty(db) }
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("writeJsonArray succeeds with a single-item array")
|
||||||
|
def writeJsonArraySingle(): Unit =
|
||||||
|
Using(PgDB()) { db => CustomFunctions.writeJsonArraySingle(db) }
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("writeJsonArray succeeds with a multi-item array")
|
||||||
|
def writeJsonArrayMany(): Unit =
|
||||||
|
Using(PgDB()) { db => CustomFunctions.writeJsonArrayMany(db) }
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("single succeeds when document not found")
|
@DisplayName("single succeeds when document not found")
|
||||||
def singleNone(): Unit =
|
def singleNone(): Unit =
|
||||||
|
@ -32,6 +32,21 @@ class SQLiteCustomIT:
|
|||||||
def jsonArrayMany(): Unit =
|
def jsonArrayMany(): Unit =
|
||||||
Using(SQLiteDB()) { db => CustomFunctions.jsonArrayMany(db) }
|
Using(SQLiteDB()) { db => CustomFunctions.jsonArrayMany(db) }
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("writeJsonArray succeeds with empty array")
|
||||||
|
def writeJsonArrayEmpty(): Unit =
|
||||||
|
Using(SQLiteDB()) { db => CustomFunctions.writeJsonArrayEmpty(db) }
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("writeJsonArray succeeds with a single-item array")
|
||||||
|
def writeJsonArraySingle(): Unit =
|
||||||
|
Using(SQLiteDB()) { db => CustomFunctions.writeJsonArraySingle(db) }
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("writeJsonArray succeeds with a multi-item array")
|
||||||
|
def writeJsonArrayMany(): Unit =
|
||||||
|
Using(SQLiteDB()) { db => CustomFunctions.writeJsonArrayMany(db) }
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("single succeeds when document not found")
|
@DisplayName("single succeeds when document not found")
|
||||||
def singleNone(): Unit =
|
def singleNone(): Unit =
|
||||||
|
Loading…
x
Reference in New Issue
Block a user