Initial Development #1
4
.idea/compiler.xml
generated
4
.idea/compiler.xml
generated
@ -6,11 +6,13 @@
|
|||||||
<sourceOutputDir name="target/generated-sources/annotations" />
|
<sourceOutputDir name="target/generated-sources/annotations" />
|
||||||
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
||||||
<outputRelativeToContentRoot value="true" />
|
<outputRelativeToContentRoot value="true" />
|
||||||
<module name="documents" />
|
<module name="jvm" />
|
||||||
|
<module name="kotlin" />
|
||||||
</profile>
|
</profile>
|
||||||
</annotationProcessing>
|
</annotationProcessing>
|
||||||
<bytecodeTargetLevel>
|
<bytecodeTargetLevel>
|
||||||
<module name="common" target="1.8" />
|
<module name="common" target="1.8" />
|
||||||
|
<module name="documents" target="9" />
|
||||||
<module name="sqlite" target="1.8" />
|
<module name="sqlite" target="1.8" />
|
||||||
</bytecodeTargetLevel>
|
</bytecodeTargetLevel>
|
||||||
</component>
|
</component>
|
||||||
|
6
.idea/encodings.xml
generated
6
.idea/encodings.xml
generated
@ -1,9 +1,15 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="Encoding">
|
<component name="Encoding">
|
||||||
|
<file url="file://$PROJECT_DIR$/src/jvm/src/main/kotlin" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/src/jvm/src/main/resources" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/src/kotlin/src/main/kotlin" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/src/kotlin/src/main/resources" charset="UTF-8" />
|
||||||
<file url="file://$PROJECT_DIR$/src/main/kotlin" charset="UTF-8" />
|
<file url="file://$PROJECT_DIR$/src/main/kotlin" charset="UTF-8" />
|
||||||
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
|
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
|
||||||
<file url="file://$PROJECT_DIR$/src/sqlite/src/main/kotlin" charset="UTF-8" />
|
<file url="file://$PROJECT_DIR$/src/sqlite/src/main/kotlin" charset="UTF-8" />
|
||||||
<file url="file://$PROJECT_DIR$/src/sqlite/src/main/resources" charset="UTF-8" />
|
<file url="file://$PROJECT_DIR$/src/sqlite/src/main/resources" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/src/src/main/java" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/src/src/main/resources" charset="UTF-8" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
2
.idea/kotlinc.xml
generated
2
.idea/kotlinc.xml
generated
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="KotlinJpsPluginSettings">
|
<component name="KotlinJpsPluginSettings">
|
||||||
<option name="version" value="2.1.0" />
|
<option name="version" value="2.1.10" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
8
.idea/modules.xml
generated
8
.idea/modules.xml
generated
@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ProjectModuleManager">
|
|
||||||
<modules>
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/documents.iml" filepath="$PROJECT_DIR$/documents.iml" />
|
|
||||||
</modules>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
123
pom.xml
123
pom.xml
@ -43,125 +43,8 @@
|
|||||||
<serialization.version>1.8.0</serialization.version>
|
<serialization.version>1.8.0</serialization.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<!-- <repositories>
|
<modules>
|
||||||
<repository>
|
<module>src</module>
|
||||||
<id>mavenCentral</id>
|
</modules>
|
||||||
<url>https://repo1.maven.org/maven2/</url>
|
|
||||||
</repository>
|
|
||||||
</repositories> -->
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<sourceDirectory>src/main/kotlin</sourceDirectory>
|
|
||||||
<testSourceDirectory>src/test/kotlin</testSourceDirectory>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.jetbrains.kotlin</groupId>
|
|
||||||
<artifactId>kotlin-maven-plugin</artifactId>
|
|
||||||
<version>${kotlin.version}</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>compile</id>
|
|
||||||
<phase>process-sources</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>compile</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>test-compile</id>
|
|
||||||
<phase>test-compile</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>test-compile</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
<configuration>
|
|
||||||
<compilerPlugins>
|
|
||||||
<plugin>kotlinx-serialization</plugin>
|
|
||||||
</compilerPlugins>
|
|
||||||
</configuration>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.jetbrains.kotlin</groupId>
|
|
||||||
<artifactId>kotlin-maven-serialization</artifactId>
|
|
||||||
<version>${kotlin.version}</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
|
||||||
<version>2.22.2</version>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<artifactId>maven-failsafe-plugin</artifactId>
|
|
||||||
<version>2.22.2</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<goals>
|
|
||||||
<goal>integration-test</goal>
|
|
||||||
<goal>verify</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
|
||||||
<artifactId>exec-maven-plugin</artifactId>
|
|
||||||
<version>1.6.0</version>
|
|
||||||
<configuration>
|
|
||||||
<mainClass>MainKt</mainClass>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
<source>9</source>
|
|
||||||
<target>9</target>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.junit.jupiter</groupId>
|
|
||||||
<artifactId>junit-jupiter</artifactId>
|
|
||||||
<version>5.11.1</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.jetbrains.kotlin</groupId>
|
|
||||||
<artifactId>kotlin-test-junit5</artifactId>
|
|
||||||
<version>${kotlin.version}</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.jetbrains.kotlin</groupId>
|
|
||||||
<artifactId>kotlin-stdlib</artifactId>
|
|
||||||
<version>${kotlin.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.jetbrains.kotlin</groupId>
|
|
||||||
<artifactId>kotlin-reflect</artifactId>
|
|
||||||
<version>${kotlin.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.jetbrains.kotlinx</groupId>
|
|
||||||
<artifactId>kotlinx-serialization-json</artifactId>
|
|
||||||
<version>${serialization.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.xerial</groupId>
|
|
||||||
<artifactId>sqlite-jdbc</artifactId>
|
|
||||||
<version>3.46.1.2</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.postgresql</groupId>
|
|
||||||
<artifactId>postgresql</artifactId>
|
|
||||||
<version>42.7.5</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
</project>
|
</project>
|
@ -24,7 +24,7 @@ fun <TDoc> Connection.customList(
|
|||||||
clazz: Class<TDoc>,
|
clazz: Class<TDoc>,
|
||||||
mapFunc: (ResultSet, Class<TDoc>) -> TDoc
|
mapFunc: (ResultSet, Class<TDoc>) -> TDoc
|
||||||
) =
|
) =
|
||||||
solutions.bitbadger.documents.jvm.Custom.list(query, parameters, clazz, this, mapFunc)
|
Custom.list(query, parameters, clazz, this, mapFunc)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute a query that returns one or no results
|
* Execute a query that returns one or no results
|
||||||
@ -41,7 +41,7 @@ fun <TDoc> Connection.customSingle(
|
|||||||
clazz: Class<TDoc>,
|
clazz: Class<TDoc>,
|
||||||
mapFunc: (ResultSet, Class<TDoc>) -> TDoc
|
mapFunc: (ResultSet, Class<TDoc>) -> TDoc
|
||||||
) =
|
) =
|
||||||
solutions.bitbadger.documents.jvm.Custom.single(query, parameters, clazz, this, mapFunc)
|
Custom.single(query, parameters, clazz, this, mapFunc)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute a query that returns no results
|
* Execute a query that returns no results
|
||||||
@ -50,7 +50,7 @@ fun <TDoc> Connection.customSingle(
|
|||||||
* @param parameters Parameters to use for the query
|
* @param parameters Parameters to use for the query
|
||||||
*/
|
*/
|
||||||
fun Connection.customNonQuery(query: String, parameters: Collection<Parameter<*>> = listOf()) =
|
fun Connection.customNonQuery(query: String, parameters: Collection<Parameter<*>> = listOf()) =
|
||||||
solutions.bitbadger.documents.jvm.Custom.nonQuery(query, parameters, this)
|
Custom.nonQuery(query, parameters, this)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute a query that returns a scalar result
|
* Execute a query that returns a scalar result
|
||||||
@ -67,7 +67,7 @@ fun <T : Any> Connection.customScalar(
|
|||||||
clazz: Class<T>,
|
clazz: Class<T>,
|
||||||
mapFunc: (ResultSet, Class<T>) -> T
|
mapFunc: (ResultSet, Class<T>) -> T
|
||||||
) =
|
) =
|
||||||
solutions.bitbadger.documents.jvm.Custom.scalar(query, parameters, clazz, this, mapFunc)
|
Custom.scalar(query, parameters, clazz, this, mapFunc)
|
||||||
|
|
||||||
// ~~~ DEFINITION QUERIES ~~~
|
// ~~~ DEFINITION QUERIES ~~~
|
||||||
|
|
||||||
@ -109,7 +109,7 @@ fun Connection.ensureDocumentIndex(tableName: String, indexType: DocumentIndex)
|
|||||||
* @param document The document to be inserted
|
* @param document The document to be inserted
|
||||||
*/
|
*/
|
||||||
fun <TDoc> Connection.insert(tableName: String, document: TDoc) =
|
fun <TDoc> Connection.insert(tableName: String, document: TDoc) =
|
||||||
Document.insert(tableName, document, this)
|
Document.insert<TDoc>(tableName, document, this)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save a document, inserting it if it does not exist and updating it if it does (AKA "upsert")
|
* Save a document, inserting it if it does not exist and updating it if it does (AKA "upsert")
|
||||||
@ -149,6 +149,7 @@ fun Connection.countAll(tableName: String) =
|
|||||||
* @param howMatched How the fields should be matched
|
* @param howMatched How the fields should be matched
|
||||||
* @return A count of the matching documents in the table
|
* @return A count of the matching documents in the table
|
||||||
*/
|
*/
|
||||||
|
@JvmOverloads
|
||||||
fun Connection.countByFields(tableName: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
fun Connection.countByFields(tableName: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
||||||
Count.byFields(tableName, fields, howMatched, this)
|
Count.byFields(tableName, fields, howMatched, this)
|
||||||
|
|
||||||
@ -196,6 +197,7 @@ fun <TKey> Connection.existsById(tableName: String, docId: TKey) =
|
|||||||
* @param howMatched How the fields should be matched
|
* @param howMatched How the fields should be matched
|
||||||
* @return True if any matching documents exist, false if not
|
* @return True if any matching documents exist, false if not
|
||||||
*/
|
*/
|
||||||
|
@JvmOverloads
|
||||||
fun Connection.existsByFields(tableName: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
fun Connection.existsByFields(tableName: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
||||||
Exists.byFields(tableName, fields, howMatched, this)
|
Exists.byFields(tableName, fields, howMatched, this)
|
||||||
|
|
||||||
@ -499,6 +501,7 @@ fun <TKey> Connection.deleteById(tableName: String, docId: TKey) =
|
|||||||
* @param fields The fields which should be compared
|
* @param fields The fields which should be compared
|
||||||
* @param howMatched How the fields should be matched
|
* @param howMatched How the fields should be matched
|
||||||
*/
|
*/
|
||||||
|
@JvmOverloads
|
||||||
fun Connection.deleteByFields(tableName: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
fun Connection.deleteByFields(tableName: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
||||||
Delete.byFields(tableName, fields, howMatched, this)
|
Delete.byFields(tableName, fields, howMatched, this)
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package solutions.bitbadger.documents.jvm
|
package solutions.bitbadger.documents.jvm
|
||||||
|
|
||||||
import solutions.bitbadger.documents.*
|
import solutions.bitbadger.documents.*
|
||||||
import solutions.bitbadger.documents.query.Count
|
import solutions.bitbadger.documents.query.CountQuery
|
||||||
import solutions.bitbadger.documents.extensions.customScalar
|
import solutions.bitbadger.documents.extensions.customScalar
|
||||||
import java.sql.Connection
|
import java.sql.Connection
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ object Count {
|
|||||||
*/
|
*/
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun all(tableName: String, conn: Connection) =
|
fun all(tableName: String, conn: Connection) =
|
||||||
conn.customScalar(Count.all(tableName), listOf(), Long::class.java, Results::toCount)
|
conn.customScalar(CountQuery.all(tableName), listOf(), Long::class.java, Results::toCount)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Count all documents in the table
|
* Count all documents in the table
|
||||||
@ -50,7 +50,7 @@ object Count {
|
|||||||
): Long {
|
): Long {
|
||||||
val named = Parameters.nameFields(fields)
|
val named = Parameters.nameFields(fields)
|
||||||
return conn.customScalar(
|
return conn.customScalar(
|
||||||
Count.byFields(tableName, named, howMatched),
|
CountQuery.byFields(tableName, named, howMatched),
|
||||||
Parameters.addFields(named),
|
Parameters.addFields(named),
|
||||||
Long::class.java,
|
Long::class.java,
|
||||||
Results::toCount
|
Results::toCount
|
||||||
@ -82,7 +82,7 @@ object Count {
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun <TContains> byContains(tableName: String, criteria: TContains, conn: Connection) =
|
fun <TContains> byContains(tableName: String, criteria: TContains, conn: Connection) =
|
||||||
conn.customScalar(
|
conn.customScalar(
|
||||||
Count.byContains(tableName),
|
CountQuery.byContains(tableName),
|
||||||
listOf(Parameters.json(":criteria", criteria)),
|
listOf(Parameters.json(":criteria", criteria)),
|
||||||
Long::class.java,
|
Long::class.java,
|
||||||
Results::toCount
|
Results::toCount
|
||||||
@ -112,7 +112,7 @@ object Count {
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun byJsonPath(tableName: String, path: String, conn: Connection) =
|
fun byJsonPath(tableName: String, path: String, conn: Connection) =
|
||||||
conn.customScalar(
|
conn.customScalar(
|
||||||
Count.byJsonPath(tableName),
|
CountQuery.byJsonPath(tableName),
|
||||||
listOf(Parameter(":path", ParameterType.STRING, path)),
|
listOf(Parameter(":path", ParameterType.STRING, path)),
|
||||||
Long::class.java,
|
Long::class.java,
|
||||||
Results::toCount
|
Results::toCount
|
||||||
|
@ -4,7 +4,7 @@ import solutions.bitbadger.documents.Configuration
|
|||||||
import solutions.bitbadger.documents.DocumentException
|
import solutions.bitbadger.documents.DocumentException
|
||||||
import solutions.bitbadger.documents.DocumentIndex
|
import solutions.bitbadger.documents.DocumentIndex
|
||||||
import solutions.bitbadger.documents.extensions.customNonQuery
|
import solutions.bitbadger.documents.extensions.customNonQuery
|
||||||
import solutions.bitbadger.documents.query.Definition
|
import solutions.bitbadger.documents.query.DefinitionQuery
|
||||||
import java.sql.Connection
|
import java.sql.Connection
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -21,8 +21,8 @@ object Definition {
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun ensureTable(tableName: String, conn: Connection) =
|
fun ensureTable(tableName: String, conn: Connection) =
|
||||||
Configuration.dialect("ensure $tableName exists").let {
|
Configuration.dialect("ensure $tableName exists").let {
|
||||||
conn.customNonQuery(Definition.ensureTable(tableName, it))
|
conn.customNonQuery(DefinitionQuery.ensureTable(tableName, it))
|
||||||
conn.customNonQuery(Definition.ensureKey(tableName, it))
|
conn.customNonQuery(DefinitionQuery.ensureKey(tableName, it))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -44,7 +44,7 @@ object Definition {
|
|||||||
*/
|
*/
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun ensureFieldIndex(tableName: String, indexName: String, fields: Collection<String>, conn: Connection) =
|
fun ensureFieldIndex(tableName: String, indexName: String, fields: Collection<String>, conn: Connection) =
|
||||||
conn.customNonQuery(Definition.ensureIndexOn(tableName, indexName, fields))
|
conn.customNonQuery(DefinitionQuery.ensureIndexOn(tableName, indexName, fields))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an index on field(s) within documents in the specified table if necessary
|
* Create an index on field(s) within documents in the specified table if necessary
|
||||||
@ -68,7 +68,7 @@ object Definition {
|
|||||||
@Throws(DocumentException::class)
|
@Throws(DocumentException::class)
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun ensureDocumentIndex(tableName: String, indexType: DocumentIndex, conn: Connection) =
|
fun ensureDocumentIndex(tableName: String, indexType: DocumentIndex, conn: Connection) =
|
||||||
conn.customNonQuery(Definition.ensureDocumentIndexOn(tableName, indexType))
|
conn.customNonQuery(DefinitionQuery.ensureDocumentIndexOn(tableName, indexType))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a document index on a table (PostgreSQL only)
|
* Create a document index on a table (PostgreSQL only)
|
||||||
|
@ -2,7 +2,7 @@ package solutions.bitbadger.documents.jvm
|
|||||||
|
|
||||||
import solutions.bitbadger.documents.*
|
import solutions.bitbadger.documents.*
|
||||||
import solutions.bitbadger.documents.extensions.customNonQuery
|
import solutions.bitbadger.documents.extensions.customNonQuery
|
||||||
import solutions.bitbadger.documents.query.Delete
|
import solutions.bitbadger.documents.query.DeleteQuery
|
||||||
import java.sql.Connection
|
import java.sql.Connection
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -20,7 +20,7 @@ object Delete {
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun <TKey> byId(tableName: String, docId: TKey, conn: Connection) =
|
fun <TKey> byId(tableName: String, docId: TKey, conn: Connection) =
|
||||||
conn.customNonQuery(
|
conn.customNonQuery(
|
||||||
Delete.byId(tableName, docId),
|
DeleteQuery.byId(tableName, docId),
|
||||||
Parameters.addFields(listOf(Field.equal(Configuration.idField, docId, ":id")))
|
Parameters.addFields(listOf(Field.equal(Configuration.idField, docId, ":id")))
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ object Delete {
|
|||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun byFields(tableName: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null, conn: Connection) {
|
fun byFields(tableName: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null, conn: Connection) {
|
||||||
val named = Parameters.nameFields(fields)
|
val named = Parameters.nameFields(fields)
|
||||||
conn.customNonQuery(Delete.byFields(tableName, named, howMatched), Parameters.addFields(named))
|
conn.customNonQuery(DeleteQuery.byFields(tableName, named, howMatched), Parameters.addFields(named))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -72,7 +72,7 @@ object Delete {
|
|||||||
@Throws(DocumentException::class)
|
@Throws(DocumentException::class)
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun <TContains> byContains(tableName: String, criteria: TContains, conn: Connection) =
|
fun <TContains> byContains(tableName: String, criteria: TContains, conn: Connection) =
|
||||||
conn.customNonQuery(Delete.byContains(tableName), listOf(Parameters.json(":criteria", criteria)))
|
conn.customNonQuery(DeleteQuery.byContains(tableName), listOf(Parameters.json(":criteria", criteria)))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete documents using a JSON containment query (PostgreSQL only)
|
* Delete documents using a JSON containment query (PostgreSQL only)
|
||||||
@ -97,7 +97,7 @@ object Delete {
|
|||||||
@Throws(DocumentException::class)
|
@Throws(DocumentException::class)
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun byJsonPath(tableName: String, path: String, conn: Connection) =
|
fun byJsonPath(tableName: String, path: String, conn: Connection) =
|
||||||
conn.customNonQuery(Delete.byJsonPath(tableName), listOf(Parameter(":path", ParameterType.STRING, path)))
|
conn.customNonQuery(DeleteQuery.byJsonPath(tableName), listOf(Parameter(":path", ParameterType.STRING, path)))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete documents using a JSON Path match query (PostgreSQL only)
|
* Delete documents using a JSON Path match query (PostgreSQL only)
|
||||||
|
@ -2,10 +2,9 @@ package solutions.bitbadger.documents.jvm
|
|||||||
|
|
||||||
import solutions.bitbadger.documents.AutoId
|
import solutions.bitbadger.documents.AutoId
|
||||||
import solutions.bitbadger.documents.Configuration
|
import solutions.bitbadger.documents.Configuration
|
||||||
import solutions.bitbadger.documents.Dialect
|
|
||||||
import solutions.bitbadger.documents.Field
|
import solutions.bitbadger.documents.Field
|
||||||
import solutions.bitbadger.documents.extensions.customNonQuery
|
import solutions.bitbadger.documents.extensions.customNonQuery
|
||||||
import solutions.bitbadger.documents.query.Document
|
import solutions.bitbadger.documents.query.DocumentQuery
|
||||||
import solutions.bitbadger.documents.query.Where
|
import solutions.bitbadger.documents.query.Where
|
||||||
import solutions.bitbadger.documents.query.statementWhere
|
import solutions.bitbadger.documents.query.statementWhere
|
||||||
import java.sql.Connection
|
import java.sql.Connection
|
||||||
@ -25,35 +24,10 @@ object Document {
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun <TDoc> insert(tableName: String, document: TDoc, conn: Connection) {
|
fun <TDoc> insert(tableName: String, document: TDoc, conn: Connection) {
|
||||||
val strategy = Configuration.autoIdStrategy
|
val strategy = Configuration.autoIdStrategy
|
||||||
val query = if (strategy == AutoId.DISABLED) {
|
val query = if (strategy == AutoId.DISABLED || !AutoId.needsAutoId(strategy, document, Configuration.idField)) {
|
||||||
Document.insert(tableName)
|
DocumentQuery.insert(tableName)
|
||||||
} else {
|
} else {
|
||||||
val idField = Configuration.idField
|
DocumentQuery.insert(tableName, strategy)
|
||||||
val dialect = Configuration.dialect("Create auto-ID insert query")
|
|
||||||
val dataParam = if (AutoId.needsAutoId(strategy, document, idField)) {
|
|
||||||
when (dialect) {
|
|
||||||
Dialect.POSTGRESQL ->
|
|
||||||
when (strategy) {
|
|
||||||
AutoId.NUMBER -> "' || (SELECT coalesce(max(data->>'$idField')::numeric, 0) + 1 " +
|
|
||||||
"FROM $tableName) || '"
|
|
||||||
AutoId.UUID -> "\"${AutoId.generateUUID()}\""
|
|
||||||
AutoId.RANDOM_STRING -> "\"${AutoId.generateRandomString()}\""
|
|
||||||
else -> "\"' || (:data)->>'$idField' || '\""
|
|
||||||
}.let { ":data::jsonb || ('{\"$idField\":$it}')::jsonb" }
|
|
||||||
|
|
||||||
Dialect.SQLITE ->
|
|
||||||
when (strategy) {
|
|
||||||
AutoId.NUMBER -> "(SELECT coalesce(max(data->>'$idField'), 0) + 1 FROM $tableName)"
|
|
||||||
AutoId.UUID -> "'${AutoId.generateUUID()}'"
|
|
||||||
AutoId.RANDOM_STRING -> "'${AutoId.generateRandomString()}'"
|
|
||||||
else -> "(:data)->>'$idField'"
|
|
||||||
}.let { "json_set(:data, '$.$idField', $it)" }
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
":data"
|
|
||||||
}
|
|
||||||
|
|
||||||
Document.insert(tableName).replace(":data", dataParam)
|
|
||||||
}
|
}
|
||||||
conn.customNonQuery(query, listOf(Parameters.json(":data", document)))
|
conn.customNonQuery(query, listOf(Parameters.json(":data", document)))
|
||||||
}
|
}
|
||||||
@ -77,7 +51,7 @@ object Document {
|
|||||||
*/
|
*/
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun <TDoc> save(tableName: String, document: TDoc, conn: Connection) =
|
fun <TDoc> save(tableName: String, document: TDoc, conn: Connection) =
|
||||||
conn.customNonQuery(Document.save(tableName), listOf(Parameters.json(":data", document)))
|
conn.customNonQuery(DocumentQuery.save(tableName), listOf(Parameters.json(":data", document)))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save a document, inserting it if it does not exist and updating it if it does (AKA "upsert")
|
* Save a document, inserting it if it does not exist and updating it if it does (AKA "upsert")
|
||||||
@ -100,7 +74,7 @@ object Document {
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun <TKey, TDoc> update(tableName: String, docId: TKey, document: TDoc, conn: Connection) =
|
fun <TKey, TDoc> update(tableName: String, docId: TKey, document: TDoc, conn: Connection) =
|
||||||
conn.customNonQuery(
|
conn.customNonQuery(
|
||||||
statementWhere(Document.update(tableName), Where.byId(":id", docId)),
|
statementWhere(DocumentQuery.update(tableName), Where.byId(":id", docId)),
|
||||||
Parameters.addFields(
|
Parameters.addFields(
|
||||||
listOf(Field.equal(Configuration.idField, docId, ":id")),
|
listOf(Field.equal(Configuration.idField, docId, ":id")),
|
||||||
mutableListOf(Parameters.json(":data", document))
|
mutableListOf(Parameters.json(":data", document))
|
||||||
|
@ -2,7 +2,7 @@ package solutions.bitbadger.documents.jvm
|
|||||||
|
|
||||||
import solutions.bitbadger.documents.*
|
import solutions.bitbadger.documents.*
|
||||||
import solutions.bitbadger.documents.extensions.customScalar
|
import solutions.bitbadger.documents.extensions.customScalar
|
||||||
import solutions.bitbadger.documents.query.Exists
|
import solutions.bitbadger.documents.query.ExistsQuery
|
||||||
import java.sql.Connection
|
import java.sql.Connection
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -21,7 +21,7 @@ object Exists {
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun <TKey> byId(tableName: String, docId: TKey, conn: Connection) =
|
fun <TKey> byId(tableName: String, docId: TKey, conn: Connection) =
|
||||||
conn.customScalar(
|
conn.customScalar(
|
||||||
Exists.byId(tableName, docId),
|
ExistsQuery.byId(tableName, docId),
|
||||||
Parameters.addFields(listOf(Field.equal(Configuration.idField, docId, ":id"))),
|
Parameters.addFields(listOf(Field.equal(Configuration.idField, docId, ":id"))),
|
||||||
Boolean::class.java,
|
Boolean::class.java,
|
||||||
Results::toExists
|
Results::toExists
|
||||||
@ -57,7 +57,7 @@ object Exists {
|
|||||||
): Boolean {
|
): Boolean {
|
||||||
val named = Parameters.nameFields(fields)
|
val named = Parameters.nameFields(fields)
|
||||||
return conn.customScalar(
|
return conn.customScalar(
|
||||||
Exists.byFields(tableName, named, howMatched),
|
ExistsQuery.byFields(tableName, named, howMatched),
|
||||||
Parameters.addFields(named),
|
Parameters.addFields(named),
|
||||||
Boolean::class.java,
|
Boolean::class.java,
|
||||||
Results::toExists
|
Results::toExists
|
||||||
@ -90,7 +90,7 @@ object Exists {
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun <TContains> byContains(tableName: String, criteria: TContains, conn: Connection) =
|
fun <TContains> byContains(tableName: String, criteria: TContains, conn: Connection) =
|
||||||
conn.customScalar(
|
conn.customScalar(
|
||||||
Exists.byContains(tableName),
|
ExistsQuery.byContains(tableName),
|
||||||
listOf(Parameters.json(":criteria", criteria)),
|
listOf(Parameters.json(":criteria", criteria)),
|
||||||
Boolean::class.java,
|
Boolean::class.java,
|
||||||
Results::toExists
|
Results::toExists
|
||||||
@ -122,7 +122,7 @@ object Exists {
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun byJsonPath(tableName: String, path: String, conn: Connection) =
|
fun byJsonPath(tableName: String, path: String, conn: Connection) =
|
||||||
conn.customScalar(
|
conn.customScalar(
|
||||||
Exists.byJsonPath(tableName),
|
ExistsQuery.byJsonPath(tableName),
|
||||||
listOf(Parameter(":path", ParameterType.STRING, path)),
|
listOf(Parameter(":path", ParameterType.STRING, path)),
|
||||||
Boolean::class.java,
|
Boolean::class.java,
|
||||||
Results::toExists
|
Results::toExists
|
||||||
|
@ -3,7 +3,7 @@ package solutions.bitbadger.documents.jvm
|
|||||||
import solutions.bitbadger.documents.*
|
import solutions.bitbadger.documents.*
|
||||||
import solutions.bitbadger.documents.extensions.customList
|
import solutions.bitbadger.documents.extensions.customList
|
||||||
import solutions.bitbadger.documents.extensions.customSingle
|
import solutions.bitbadger.documents.extensions.customSingle
|
||||||
import solutions.bitbadger.documents.query.Find
|
import solutions.bitbadger.documents.query.FindQuery
|
||||||
import solutions.bitbadger.documents.query.orderBy
|
import solutions.bitbadger.documents.query.orderBy
|
||||||
import java.sql.Connection
|
import java.sql.Connection
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ object Find {
|
|||||||
*/
|
*/
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun <TDoc> all(tableName: String, clazz: Class<TDoc>, orderBy: Collection<Field<*>>? = null, conn: Connection) =
|
fun <TDoc> all(tableName: String, clazz: Class<TDoc>, orderBy: Collection<Field<*>>? = null, conn: Connection) =
|
||||||
conn.customList(Find.all(tableName) + (orderBy?.let(::orderBy) ?: ""), listOf(), clazz, Results::fromData)
|
conn.customList(FindQuery.all(tableName) + (orderBy?.let(::orderBy) ?: ""), listOf(), clazz, Results::fromData)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve all documents in the given table
|
* Retrieve all documents in the given table
|
||||||
@ -62,7 +62,7 @@ object Find {
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun <TKey, TDoc> byId(tableName: String, docId: TKey, clazz: Class<TDoc>, conn: Connection) =
|
fun <TKey, TDoc> byId(tableName: String, docId: TKey, clazz: Class<TDoc>, conn: Connection) =
|
||||||
conn.customSingle(
|
conn.customSingle(
|
||||||
Find.byId(tableName, docId),
|
FindQuery.byId(tableName, docId),
|
||||||
Parameters.addFields(listOf(Field.equal(Configuration.idField, docId, ":id"))),
|
Parameters.addFields(listOf(Field.equal(Configuration.idField, docId, ":id"))),
|
||||||
clazz,
|
clazz,
|
||||||
Results::fromData
|
Results::fromData
|
||||||
@ -102,7 +102,7 @@ object Find {
|
|||||||
): List<TDoc> {
|
): List<TDoc> {
|
||||||
val named = Parameters.nameFields(fields)
|
val named = Parameters.nameFields(fields)
|
||||||
return conn.customList(
|
return conn.customList(
|
||||||
Find.byFields(tableName, named, howMatched) + (orderBy?.let(::orderBy) ?: ""),
|
FindQuery.byFields(tableName, named, howMatched) + (orderBy?.let(::orderBy) ?: ""),
|
||||||
Parameters.addFields(named),
|
Parameters.addFields(named),
|
||||||
clazz,
|
clazz,
|
||||||
Results::fromData
|
Results::fromData
|
||||||
@ -171,7 +171,7 @@ object Find {
|
|||||||
conn: Connection
|
conn: Connection
|
||||||
) =
|
) =
|
||||||
conn.customList(
|
conn.customList(
|
||||||
Find.byContains(tableName) + (orderBy?.let(::orderBy) ?: ""),
|
FindQuery.byContains(tableName) + (orderBy?.let(::orderBy) ?: ""),
|
||||||
listOf(Parameters.json(":criteria", criteria)),
|
listOf(Parameters.json(":criteria", criteria)),
|
||||||
clazz,
|
clazz,
|
||||||
Results::fromData
|
Results::fromData
|
||||||
@ -234,7 +234,7 @@ object Find {
|
|||||||
conn: Connection
|
conn: Connection
|
||||||
) =
|
) =
|
||||||
conn.customList(
|
conn.customList(
|
||||||
Find.byJsonPath(tableName) + (orderBy?.let(::orderBy) ?: ""),
|
FindQuery.byJsonPath(tableName) + (orderBy?.let(::orderBy) ?: ""),
|
||||||
listOf(Parameter(":path", ParameterType.STRING, path)),
|
listOf(Parameter(":path", ParameterType.STRING, path)),
|
||||||
clazz,
|
clazz,
|
||||||
Results::fromData
|
Results::fromData
|
||||||
@ -293,7 +293,7 @@ object Find {
|
|||||||
): TDoc? {
|
): TDoc? {
|
||||||
val named = Parameters.nameFields(fields)
|
val named = Parameters.nameFields(fields)
|
||||||
return conn.customSingle(
|
return conn.customSingle(
|
||||||
Find.byFields(tableName, named, howMatched) + (orderBy?.let(::orderBy) ?: ""),
|
FindQuery.byFields(tableName, named, howMatched) + (orderBy?.let(::orderBy) ?: ""),
|
||||||
Parameters.addFields(named),
|
Parameters.addFields(named),
|
||||||
clazz,
|
clazz,
|
||||||
Results::fromData
|
Results::fromData
|
||||||
@ -361,7 +361,7 @@ object Find {
|
|||||||
conn: Connection
|
conn: Connection
|
||||||
) =
|
) =
|
||||||
conn.customSingle(
|
conn.customSingle(
|
||||||
Find.byContains(tableName) + (orderBy?.let(::orderBy) ?: ""),
|
FindQuery.byContains(tableName) + (orderBy?.let(::orderBy) ?: ""),
|
||||||
listOf(Parameters.json(":criteria", criteria)),
|
listOf(Parameters.json(":criteria", criteria)),
|
||||||
clazz,
|
clazz,
|
||||||
Results::fromData
|
Results::fromData
|
||||||
@ -429,7 +429,7 @@ object Find {
|
|||||||
conn: Connection
|
conn: Connection
|
||||||
) =
|
) =
|
||||||
conn.customSingle(
|
conn.customSingle(
|
||||||
Find.byJsonPath(tableName) + (orderBy?.let(::orderBy) ?: ""),
|
FindQuery.byJsonPath(tableName) + (orderBy?.let(::orderBy) ?: ""),
|
||||||
listOf(Parameter(":path", ParameterType.STRING, path)),
|
listOf(Parameter(":path", ParameterType.STRING, path)),
|
||||||
clazz,
|
clazz,
|
||||||
Results::fromData
|
Results::fromData
|
||||||
|
@ -2,7 +2,7 @@ package solutions.bitbadger.documents.jvm
|
|||||||
|
|
||||||
import solutions.bitbadger.documents.*
|
import solutions.bitbadger.documents.*
|
||||||
import solutions.bitbadger.documents.extensions.customNonQuery
|
import solutions.bitbadger.documents.extensions.customNonQuery
|
||||||
import solutions.bitbadger.documents.query.Patch
|
import solutions.bitbadger.documents.query.PatchQuery
|
||||||
import java.sql.Connection
|
import java.sql.Connection
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -21,7 +21,7 @@ object Patch {
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun <TKey, TPatch> byId(tableName: String, docId: TKey, patch: TPatch, conn: Connection) =
|
fun <TKey, TPatch> byId(tableName: String, docId: TKey, patch: TPatch, conn: Connection) =
|
||||||
conn.customNonQuery(
|
conn.customNonQuery(
|
||||||
Patch.byId(tableName, docId),
|
PatchQuery.byId(tableName, docId),
|
||||||
Parameters.addFields(
|
Parameters.addFields(
|
||||||
listOf(Field.equal(Configuration.idField, docId, ":id")),
|
listOf(Field.equal(Configuration.idField, docId, ":id")),
|
||||||
mutableListOf(Parameters.json(":data", patch))
|
mutableListOf(Parameters.json(":data", patch))
|
||||||
@ -58,7 +58,7 @@ object Patch {
|
|||||||
) {
|
) {
|
||||||
val named = Parameters.nameFields(fields)
|
val named = Parameters.nameFields(fields)
|
||||||
conn.customNonQuery(
|
conn.customNonQuery(
|
||||||
Patch.byFields(tableName, named, howMatched), Parameters.addFields(
|
PatchQuery.byFields(tableName, named, howMatched), Parameters.addFields(
|
||||||
named,
|
named,
|
||||||
mutableListOf(Parameters.json(":data", patch))
|
mutableListOf(Parameters.json(":data", patch))
|
||||||
)
|
)
|
||||||
@ -96,7 +96,7 @@ object Patch {
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun <TContains, TPatch> byContains(tableName: String, criteria: TContains, patch: TPatch, conn: Connection) =
|
fun <TContains, TPatch> byContains(tableName: String, criteria: TContains, patch: TPatch, conn: Connection) =
|
||||||
conn.customNonQuery(
|
conn.customNonQuery(
|
||||||
Patch.byContains(tableName),
|
PatchQuery.byContains(tableName),
|
||||||
listOf(Parameters.json(":criteria", criteria), Parameters.json(":data", patch))
|
listOf(Parameters.json(":criteria", criteria), Parameters.json(":data", patch))
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -126,7 +126,7 @@ object Patch {
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun <TPatch> byJsonPath(tableName: String, path: String, patch: TPatch, conn: Connection) =
|
fun <TPatch> byJsonPath(tableName: String, path: String, patch: TPatch, conn: Connection) =
|
||||||
conn.customNonQuery(
|
conn.customNonQuery(
|
||||||
Patch.byJsonPath(tableName),
|
PatchQuery.byJsonPath(tableName),
|
||||||
listOf(Parameter(":path", ParameterType.STRING, path), Parameters.json(":data", patch))
|
listOf(Parameter(":path", ParameterType.STRING, path), Parameters.json(":data", patch))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ package solutions.bitbadger.documents.jvm
|
|||||||
|
|
||||||
import solutions.bitbadger.documents.*
|
import solutions.bitbadger.documents.*
|
||||||
import solutions.bitbadger.documents.extensions.customNonQuery
|
import solutions.bitbadger.documents.extensions.customNonQuery
|
||||||
import solutions.bitbadger.documents.query.RemoveFields
|
import solutions.bitbadger.documents.query.RemoveFieldsQuery
|
||||||
import java.sql.Connection
|
import java.sql.Connection
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -36,7 +36,7 @@ object RemoveFields {
|
|||||||
fun <TKey> byId(tableName: String, docId: TKey, toRemove: Collection<String>, conn: Connection) {
|
fun <TKey> byId(tableName: String, docId: TKey, toRemove: Collection<String>, conn: Connection) {
|
||||||
val nameParams = Parameters.fieldNames(toRemove)
|
val nameParams = Parameters.fieldNames(toRemove)
|
||||||
conn.customNonQuery(
|
conn.customNonQuery(
|
||||||
RemoveFields.byId(tableName, nameParams, docId),
|
RemoveFieldsQuery.byId(tableName, nameParams, docId),
|
||||||
Parameters.addFields(
|
Parameters.addFields(
|
||||||
listOf(Field.equal(Configuration.idField, docId, ":id")),
|
listOf(Field.equal(Configuration.idField, docId, ":id")),
|
||||||
translatePath(nameParams)
|
translatePath(nameParams)
|
||||||
@ -75,7 +75,7 @@ object RemoveFields {
|
|||||||
val named = Parameters.nameFields(fields)
|
val named = Parameters.nameFields(fields)
|
||||||
val nameParams = Parameters.fieldNames(toRemove)
|
val nameParams = Parameters.fieldNames(toRemove)
|
||||||
conn.customNonQuery(
|
conn.customNonQuery(
|
||||||
RemoveFields.byFields(tableName, nameParams, named, howMatched),
|
RemoveFieldsQuery.byFields(tableName, nameParams, named, howMatched),
|
||||||
Parameters.addFields(named, translatePath(nameParams))
|
Parameters.addFields(named, translatePath(nameParams))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -117,7 +117,7 @@ object RemoveFields {
|
|||||||
) {
|
) {
|
||||||
val nameParams = Parameters.fieldNames(toRemove)
|
val nameParams = Parameters.fieldNames(toRemove)
|
||||||
conn.customNonQuery(
|
conn.customNonQuery(
|
||||||
RemoveFields.byContains(tableName, nameParams),
|
RemoveFieldsQuery.byContains(tableName, nameParams),
|
||||||
listOf(Parameters.json(":criteria", criteria), *nameParams.toTypedArray())
|
listOf(Parameters.json(":criteria", criteria), *nameParams.toTypedArray())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -149,7 +149,7 @@ object RemoveFields {
|
|||||||
fun byJsonPath(tableName: String, path: String, toRemove: Collection<String>, conn: Connection) {
|
fun byJsonPath(tableName: String, path: String, toRemove: Collection<String>, conn: Connection) {
|
||||||
val nameParams = Parameters.fieldNames(toRemove)
|
val nameParams = Parameters.fieldNames(toRemove)
|
||||||
conn.customNonQuery(
|
conn.customNonQuery(
|
||||||
RemoveFields.byJsonPath(tableName, nameParams),
|
RemoveFieldsQuery.byJsonPath(tableName, nameParams),
|
||||||
listOf(Parameter(":path", ParameterType.STRING, path), *nameParams.toTypedArray())
|
listOf(Parameter(":path", ParameterType.STRING, path), *nameParams.toTypedArray())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
package solutions.bitbadger.documents.query
|
package solutions.bitbadger.documents.query
|
||||||
|
|
||||||
|
import solutions.bitbadger.documents.DocumentException
|
||||||
import solutions.bitbadger.documents.Field
|
import solutions.bitbadger.documents.Field
|
||||||
import solutions.bitbadger.documents.FieldMatch
|
import solutions.bitbadger.documents.FieldMatch
|
||||||
import solutions.bitbadger.documents.query.byFields as byFieldsBase;
|
import kotlin.jvm.Throws
|
||||||
|
import solutions.bitbadger.documents.query.byFields as byFieldsBase
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Functions to count documents
|
* Functions to count documents
|
||||||
*/
|
*/
|
||||||
object Count {
|
object CountQuery {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query to count all documents in a table
|
* Query to count all documents in a table
|
||||||
@ -15,6 +17,7 @@ object Count {
|
|||||||
* @param tableName The table in which to count documents (may include schema)
|
* @param tableName The table in which to count documents (may include schema)
|
||||||
* @return A query to count documents
|
* @return A query to count documents
|
||||||
*/
|
*/
|
||||||
|
@JvmStatic
|
||||||
fun all(tableName: String) =
|
fun all(tableName: String) =
|
||||||
"SELECT COUNT(*) AS it FROM $tableName"
|
"SELECT COUNT(*) AS it FROM $tableName"
|
||||||
|
|
||||||
@ -26,6 +29,8 @@ object Count {
|
|||||||
* @param howMatched How fields should be compared (optional, defaults to ALL)
|
* @param howMatched How fields should be compared (optional, defaults to ALL)
|
||||||
* @return A query to count documents matching the given fields
|
* @return A query to count documents matching the given fields
|
||||||
*/
|
*/
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
fun byFields(tableName: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
fun byFields(tableName: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
||||||
byFieldsBase(all(tableName), fields, howMatched)
|
byFieldsBase(all(tableName), fields, howMatched)
|
||||||
|
|
||||||
@ -34,7 +39,10 @@ object Count {
|
|||||||
*
|
*
|
||||||
* @param tableName The table in which to count documents (may include schema)
|
* @param tableName The table in which to count documents (may include schema)
|
||||||
* @return A query to count documents via JSON containment
|
* @return A query to count documents via JSON containment
|
||||||
|
* @throws DocumentException If the database dialect is not PostgreSQL
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
|
@JvmStatic
|
||||||
fun byContains(tableName: String) =
|
fun byContains(tableName: String) =
|
||||||
statementWhere(all(tableName), Where.jsonContains())
|
statementWhere(all(tableName), Where.jsonContains())
|
||||||
|
|
||||||
@ -43,7 +51,10 @@ object Count {
|
|||||||
*
|
*
|
||||||
* @param tableName The table in which to count documents (may include schema)
|
* @param tableName The table in which to count documents (may include schema)
|
||||||
* @return A query to count documents via a JSON path match
|
* @return A query to count documents via a JSON path match
|
||||||
|
* @throws DocumentException If the database dialect is not PostgreSQL
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
|
@JvmStatic
|
||||||
fun byJsonPath(tableName: String) =
|
fun byJsonPath(tableName: String) =
|
||||||
statementWhere(all(tableName), Where.jsonPathMatches())
|
statementWhere(all(tableName), Where.jsonPathMatches())
|
||||||
}
|
}
|
@ -1,11 +1,12 @@
|
|||||||
package solutions.bitbadger.documents.query
|
package solutions.bitbadger.documents.query
|
||||||
|
|
||||||
import solutions.bitbadger.documents.*
|
import solutions.bitbadger.documents.*
|
||||||
|
import kotlin.jvm.Throws
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Functions to create queries to define tables and indexes
|
* Functions to create queries to define tables and indexes
|
||||||
*/
|
*/
|
||||||
object Definition {
|
object DefinitionQuery {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SQL statement to create a document table
|
* SQL statement to create a document table
|
||||||
@ -14,6 +15,7 @@ object Definition {
|
|||||||
* @param dataType The type of data for the column (`JSON`, `JSONB`, etc.)
|
* @param dataType The type of data for the column (`JSON`, `JSONB`, etc.)
|
||||||
* @return A query to create a document table
|
* @return A query to create a document table
|
||||||
*/
|
*/
|
||||||
|
@JvmStatic
|
||||||
fun ensureTableFor(tableName: String, dataType: String) =
|
fun ensureTableFor(tableName: String, dataType: String) =
|
||||||
"CREATE TABLE IF NOT EXISTS $tableName (data $dataType NOT NULL)"
|
"CREATE TABLE IF NOT EXISTS $tableName (data $dataType NOT NULL)"
|
||||||
|
|
||||||
@ -23,7 +25,11 @@ object Definition {
|
|||||||
* @param tableName The name of the table to create (may include schema)
|
* @param tableName The name of the table to create (may include schema)
|
||||||
* @param dialect The dialect to generate (optional, used in place of current)
|
* @param dialect The dialect to generate (optional, used in place of current)
|
||||||
* @return A query to create a document table
|
* @return A query to create a document table
|
||||||
|
* @throws DocumentException If the dialect is neither provided nor configured
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
fun ensureTable(tableName: String, dialect: Dialect? = null) =
|
fun ensureTable(tableName: String, dialect: Dialect? = null) =
|
||||||
when (dialect ?: Configuration.dialect("create table creation query")) {
|
when (dialect ?: Configuration.dialect("create table creation query")) {
|
||||||
Dialect.POSTGRESQL -> ensureTableFor(tableName, "JSONB")
|
Dialect.POSTGRESQL -> ensureTableFor(tableName, "JSONB")
|
||||||
@ -47,7 +53,11 @@ object Definition {
|
|||||||
* @param fields One or more fields to include in the index
|
* @param fields One or more fields to include in the index
|
||||||
* @param dialect The SQL dialect to use when creating this index (optional, used in place of current)
|
* @param dialect The SQL dialect to use when creating this index (optional, used in place of current)
|
||||||
* @return A query to create the field index
|
* @return A query to create the field index
|
||||||
|
* @throws DocumentException If the dialect is neither provided nor configured
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
fun ensureIndexOn(
|
fun ensureIndexOn(
|
||||||
tableName: String,
|
tableName: String,
|
||||||
indexName: String,
|
indexName: String,
|
||||||
@ -70,7 +80,11 @@ object Definition {
|
|||||||
* @param tableName The table on which a key index should be created (may include schema)
|
* @param tableName The table on which a key index should be created (may include schema)
|
||||||
* @param dialect The SQL dialect to use when creating this index (optional, used in place of current)
|
* @param dialect The SQL dialect to use when creating this index (optional, used in place of current)
|
||||||
* @return A query to create the key index
|
* @return A query to create the key index
|
||||||
|
* @throws DocumentException If the dialect is neither provided nor configured
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
fun ensureKey(tableName: String, dialect: Dialect? = null) =
|
fun ensureKey(tableName: String, dialect: Dialect? = null) =
|
||||||
ensureIndexOn(tableName, "key", listOf(Configuration.idField), dialect).replace("INDEX", "UNIQUE INDEX")
|
ensureIndexOn(tableName, "key", listOf(Configuration.idField), dialect).replace("INDEX", "UNIQUE INDEX")
|
||||||
|
|
||||||
@ -82,6 +96,8 @@ object Definition {
|
|||||||
* @return The SQL statement to create an index on JSON documents in the specified table
|
* @return The SQL statement to create an index on JSON documents in the specified table
|
||||||
* @throws DocumentException If the database mode is not PostgreSQL
|
* @throws DocumentException If the database mode is not PostgreSQL
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
|
@JvmStatic
|
||||||
fun ensureDocumentIndexOn(tableName: String, indexType: DocumentIndex): String {
|
fun ensureDocumentIndexOn(tableName: String, indexType: DocumentIndex): String {
|
||||||
if (Configuration.dialect("create document index query") != Dialect.POSTGRESQL) {
|
if (Configuration.dialect("create document index query") != Dialect.POSTGRESQL) {
|
||||||
throw DocumentException("'Document indexes are only supported on PostgreSQL")
|
throw DocumentException("'Document indexes are only supported on PostgreSQL")
|
@ -1,14 +1,16 @@
|
|||||||
package solutions.bitbadger.documents.query
|
package solutions.bitbadger.documents.query
|
||||||
|
|
||||||
|
import solutions.bitbadger.documents.DocumentException
|
||||||
import solutions.bitbadger.documents.Field
|
import solutions.bitbadger.documents.Field
|
||||||
import solutions.bitbadger.documents.FieldMatch
|
import solutions.bitbadger.documents.FieldMatch
|
||||||
|
import kotlin.jvm.Throws
|
||||||
import solutions.bitbadger.documents.query.byFields as byFieldsBase
|
import solutions.bitbadger.documents.query.byFields as byFieldsBase
|
||||||
import solutions.bitbadger.documents.query.byId as byIdBase
|
import solutions.bitbadger.documents.query.byId as byIdBase
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Functions to delete documents
|
* Functions to delete documents
|
||||||
*/
|
*/
|
||||||
object Delete {
|
object DeleteQuery {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query to delete documents from a table
|
* Query to delete documents from a table
|
||||||
@ -26,6 +28,8 @@ object Delete {
|
|||||||
* @param docId The ID of the document (optional, used for type checking)
|
* @param docId The ID of the document (optional, used for type checking)
|
||||||
* @return A query to delete a document by its ID
|
* @return A query to delete a document by its ID
|
||||||
*/
|
*/
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
fun <TKey> byId(tableName: String, docId: TKey? = null) =
|
fun <TKey> byId(tableName: String, docId: TKey? = null) =
|
||||||
byIdBase(delete(tableName), docId)
|
byIdBase(delete(tableName), docId)
|
||||||
|
|
||||||
@ -37,6 +41,8 @@ object Delete {
|
|||||||
* @param howMatched How fields should be compared (optional, defaults to ALL)
|
* @param howMatched How fields should be compared (optional, defaults to ALL)
|
||||||
* @return A query to delete documents matching for the given fields
|
* @return A query to delete documents matching for the given fields
|
||||||
*/
|
*/
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
fun byFields(tableName: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
fun byFields(tableName: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
||||||
byFieldsBase(delete(tableName), fields, howMatched)
|
byFieldsBase(delete(tableName), fields, howMatched)
|
||||||
|
|
||||||
@ -45,7 +51,10 @@ object Delete {
|
|||||||
*
|
*
|
||||||
* @param tableName The table from which documents should be deleted (may include schema)
|
* @param tableName The table from which documents should be deleted (may include schema)
|
||||||
* @return A query to delete documents via JSON containment
|
* @return A query to delete documents via JSON containment
|
||||||
|
* @throws DocumentException If the database dialect is not PostgreSQL
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
|
@JvmStatic
|
||||||
fun byContains(tableName: String) =
|
fun byContains(tableName: String) =
|
||||||
statementWhere(delete(tableName), Where.jsonContains())
|
statementWhere(delete(tableName), Where.jsonContains())
|
||||||
|
|
||||||
@ -54,7 +63,10 @@ object Delete {
|
|||||||
*
|
*
|
||||||
* @param tableName The table from which documents should be deleted (may include schema)
|
* @param tableName The table from which documents should be deleted (may include schema)
|
||||||
* @return A query to delete documents via a JSON path match
|
* @return A query to delete documents via a JSON path match
|
||||||
|
* @throws DocumentException If the database dialect is not PostgreSQL
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
|
@JvmStatic
|
||||||
fun byJsonPath(tableName: String) =
|
fun byJsonPath(tableName: String) =
|
||||||
statementWhere(delete(tableName), Where.jsonPathMatches())
|
statementWhere(delete(tableName), Where.jsonPathMatches())
|
||||||
}
|
}
|
@ -3,20 +3,26 @@ package solutions.bitbadger.documents.query
|
|||||||
import solutions.bitbadger.documents.AutoId
|
import solutions.bitbadger.documents.AutoId
|
||||||
import solutions.bitbadger.documents.Configuration
|
import solutions.bitbadger.documents.Configuration
|
||||||
import solutions.bitbadger.documents.Dialect
|
import solutions.bitbadger.documents.Dialect
|
||||||
|
import solutions.bitbadger.documents.DocumentException
|
||||||
|
import kotlin.jvm.Throws
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Functions for document-level operations
|
* Functions for document-level operations
|
||||||
*/
|
*/
|
||||||
object Document {
|
object DocumentQuery {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query to insert a document
|
* Query to insert a document
|
||||||
*
|
*
|
||||||
* @param tableName The table into which to insert (may include schema)
|
* @param tableName The table into which to insert (may include schema)
|
||||||
* @return A query to insert a document
|
* @return A query to insert a document
|
||||||
|
* @throws DocumentException If the dialect is not configured
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
fun insert(tableName: String, autoId: AutoId? = null): String {
|
fun insert(tableName: String, autoId: AutoId? = null): String {
|
||||||
val id = Configuration.idField
|
val id = Configuration.idField
|
||||||
val values = when (Configuration.dialect("create INSERT statement")) {
|
val values = when (Configuration.dialect("create INSERT statement")) {
|
||||||
Dialect.POSTGRESQL -> when (autoId ?: AutoId.DISABLED) {
|
Dialect.POSTGRESQL -> when (autoId ?: AutoId.DISABLED) {
|
||||||
AutoId.DISABLED -> ":data"
|
AutoId.DISABLED -> ":data"
|
||||||
@ -42,7 +48,10 @@ object Document {
|
|||||||
*
|
*
|
||||||
* @param tableName The table into which to save (may include schema)
|
* @param tableName The table into which to save (may include schema)
|
||||||
* @return A query to save a document
|
* @return A query to save a document
|
||||||
|
* @throws DocumentException If the dialect is not configured
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
|
@JvmStatic
|
||||||
fun save(tableName: String) =
|
fun save(tableName: String) =
|
||||||
insert(tableName, AutoId.DISABLED) +
|
insert(tableName, AutoId.DISABLED) +
|
||||||
" ON CONFLICT ((data->>'${Configuration.idField}')) DO UPDATE SET data = EXCLUDED.data"
|
" ON CONFLICT ((data->>'${Configuration.idField}')) DO UPDATE SET data = EXCLUDED.data"
|
||||||
@ -53,6 +62,7 @@ object Document {
|
|||||||
* @param tableName The table in which documents should be replaced (may include schema)
|
* @param tableName The table in which documents should be replaced (may include schema)
|
||||||
* @return A query to update documents
|
* @return A query to update documents
|
||||||
*/
|
*/
|
||||||
|
@JvmStatic
|
||||||
fun update(tableName: String) =
|
fun update(tableName: String) =
|
||||||
"UPDATE $tableName SET data = :data"
|
"UPDATE $tableName SET data = :data"
|
||||||
}
|
}
|
@ -1,12 +1,14 @@
|
|||||||
package solutions.bitbadger.documents.query
|
package solutions.bitbadger.documents.query
|
||||||
|
|
||||||
|
import solutions.bitbadger.documents.DocumentException
|
||||||
import solutions.bitbadger.documents.Field
|
import solutions.bitbadger.documents.Field
|
||||||
import solutions.bitbadger.documents.FieldMatch
|
import solutions.bitbadger.documents.FieldMatch
|
||||||
|
import kotlin.jvm.Throws
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Functions to check for document existence
|
* Functions to check for document existence
|
||||||
*/
|
*/
|
||||||
object Exists {
|
object ExistsQuery {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query to check for document existence in a table
|
* Query to check for document existence in a table
|
||||||
@ -25,6 +27,8 @@ object Exists {
|
|||||||
* @param docId The ID of the document (optional, used for type checking)
|
* @param docId The ID of the document (optional, used for type checking)
|
||||||
* @return A query to determine document existence by ID
|
* @return A query to determine document existence by ID
|
||||||
*/
|
*/
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
fun <TKey> byId(tableName: String, docId: TKey? = null) =
|
fun <TKey> byId(tableName: String, docId: TKey? = null) =
|
||||||
exists(tableName, Where.byId(docId = docId))
|
exists(tableName, Where.byId(docId = docId))
|
||||||
|
|
||||||
@ -36,6 +40,8 @@ object Exists {
|
|||||||
* @param howMatched How fields should be compared (optional, defaults to ALL)
|
* @param howMatched How fields should be compared (optional, defaults to ALL)
|
||||||
* @return A query to determine document existence for the given fields
|
* @return A query to determine document existence for the given fields
|
||||||
*/
|
*/
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
fun byFields(tableName: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
fun byFields(tableName: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
||||||
exists(tableName, Where.byFields(fields, howMatched))
|
exists(tableName, Where.byFields(fields, howMatched))
|
||||||
|
|
||||||
@ -44,7 +50,10 @@ object Exists {
|
|||||||
*
|
*
|
||||||
* @param tableName The table in which existence should be checked (may include schema)
|
* @param tableName The table in which existence should be checked (may include schema)
|
||||||
* @return A query to determine document existence via JSON containment
|
* @return A query to determine document existence via JSON containment
|
||||||
|
* @throws DocumentException If the database dialect is not PostgreSQL
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
|
@JvmStatic
|
||||||
fun byContains(tableName: String) =
|
fun byContains(tableName: String) =
|
||||||
exists(tableName, Where.jsonContains())
|
exists(tableName, Where.jsonContains())
|
||||||
|
|
||||||
@ -53,7 +62,10 @@ object Exists {
|
|||||||
*
|
*
|
||||||
* @param tableName The table in which existence should be checked (may include schema)
|
* @param tableName The table in which existence should be checked (may include schema)
|
||||||
* @return A query to determine document existence via a JSON path match
|
* @return A query to determine document existence via a JSON path match
|
||||||
|
* @throws DocumentException If the database dialect is not PostgreSQL
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
|
@JvmStatic
|
||||||
fun byJsonPath(tableName: String) =
|
fun byJsonPath(tableName: String) =
|
||||||
exists(tableName, Where.jsonPathMatches())
|
exists(tableName, Where.jsonPathMatches())
|
||||||
}
|
}
|
@ -1,14 +1,16 @@
|
|||||||
package solutions.bitbadger.documents.query
|
package solutions.bitbadger.documents.query
|
||||||
|
|
||||||
|
import solutions.bitbadger.documents.DocumentException
|
||||||
import solutions.bitbadger.documents.Field
|
import solutions.bitbadger.documents.Field
|
||||||
import solutions.bitbadger.documents.FieldMatch
|
import solutions.bitbadger.documents.FieldMatch
|
||||||
|
import kotlin.jvm.Throws
|
||||||
import solutions.bitbadger.documents.query.byId as byIdBase
|
import solutions.bitbadger.documents.query.byId as byIdBase
|
||||||
import solutions.bitbadger.documents.query.byFields as byFieldsBase
|
import solutions.bitbadger.documents.query.byFields as byFieldsBase
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Functions to retrieve documents
|
* Functions to retrieve documents
|
||||||
*/
|
*/
|
||||||
object Find {
|
object FindQuery {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query to retrieve all documents from a table
|
* Query to retrieve all documents from a table
|
||||||
@ -16,6 +18,7 @@ object Find {
|
|||||||
* @param tableName The table from which documents should be retrieved (may include schema)
|
* @param tableName The table from which documents should be retrieved (may include schema)
|
||||||
* @return A query to retrieve documents
|
* @return A query to retrieve documents
|
||||||
*/
|
*/
|
||||||
|
@JvmStatic
|
||||||
fun all(tableName: String) =
|
fun all(tableName: String) =
|
||||||
"SELECT data FROM $tableName"
|
"SELECT data FROM $tableName"
|
||||||
|
|
||||||
@ -26,6 +29,8 @@ object Find {
|
|||||||
* @param docId The ID of the document (optional, used for type checking)
|
* @param docId The ID of the document (optional, used for type checking)
|
||||||
* @return A query to retrieve a document by its ID
|
* @return A query to retrieve a document by its ID
|
||||||
*/
|
*/
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
fun <TKey> byId(tableName: String, docId: TKey? = null) =
|
fun <TKey> byId(tableName: String, docId: TKey? = null) =
|
||||||
byIdBase(all(tableName), docId)
|
byIdBase(all(tableName), docId)
|
||||||
|
|
||||||
@ -37,6 +42,8 @@ object Find {
|
|||||||
* @param howMatched How fields should be compared (optional, defaults to ALL)
|
* @param howMatched How fields should be compared (optional, defaults to ALL)
|
||||||
* @return A query to retrieve documents matching the given fields
|
* @return A query to retrieve documents matching the given fields
|
||||||
*/
|
*/
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
fun byFields(tableName: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
fun byFields(tableName: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
||||||
byFieldsBase(all(tableName), fields, howMatched)
|
byFieldsBase(all(tableName), fields, howMatched)
|
||||||
|
|
||||||
@ -45,7 +52,10 @@ object Find {
|
|||||||
*
|
*
|
||||||
* @param tableName The table from which documents should be retrieved (may include schema)
|
* @param tableName The table from which documents should be retrieved (may include schema)
|
||||||
* @return A query to retrieve documents via JSON containment
|
* @return A query to retrieve documents via JSON containment
|
||||||
|
* @throws DocumentException If the database dialect is not PostgreSQL
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
|
@JvmStatic
|
||||||
fun byContains(tableName: String) =
|
fun byContains(tableName: String) =
|
||||||
statementWhere(all(tableName), Where.jsonContains())
|
statementWhere(all(tableName), Where.jsonContains())
|
||||||
|
|
||||||
@ -54,7 +64,10 @@ object Find {
|
|||||||
*
|
*
|
||||||
* @param tableName The table from which documents should be retrieved (may include schema)
|
* @param tableName The table from which documents should be retrieved (may include schema)
|
||||||
* @return A query to retrieve documents via a JSON path match
|
* @return A query to retrieve documents via a JSON path match
|
||||||
|
* @throws DocumentException If the database dialect is not PostgreSQL
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
|
@JvmStatic
|
||||||
fun byJsonPath(tableName: String) =
|
fun byJsonPath(tableName: String) =
|
||||||
statementWhere(all(tableName), Where.jsonPathMatches())
|
statementWhere(all(tableName), Where.jsonPathMatches())
|
||||||
}
|
}
|
@ -1,16 +1,14 @@
|
|||||||
package solutions.bitbadger.documents.query
|
package solutions.bitbadger.documents.query
|
||||||
|
|
||||||
import solutions.bitbadger.documents.Configuration
|
import solutions.bitbadger.documents.*
|
||||||
import solutions.bitbadger.documents.Dialect
|
import kotlin.jvm.Throws
|
||||||
import solutions.bitbadger.documents.Field
|
|
||||||
import solutions.bitbadger.documents.FieldMatch
|
|
||||||
import solutions.bitbadger.documents.query.byFields as byFieldsBase
|
import solutions.bitbadger.documents.query.byFields as byFieldsBase
|
||||||
import solutions.bitbadger.documents.query.byId as byIdBase
|
import solutions.bitbadger.documents.query.byId as byIdBase
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Functions to create queries to patch (partially update) JSON documents
|
* Functions to create queries to patch (partially update) JSON documents
|
||||||
*/
|
*/
|
||||||
object Patch {
|
object PatchQuery {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an `UPDATE` statement to patch documents
|
* Create an `UPDATE` statement to patch documents
|
||||||
@ -30,7 +28,11 @@ object Patch {
|
|||||||
* @param tableName The name of the table where the document is stored
|
* @param tableName The name of the table where the document is stored
|
||||||
* @param docId The ID of the document to be updated (optional, used for type checking)
|
* @param docId The ID of the document to be updated (optional, used for type checking)
|
||||||
* @return A query to patch a JSON document by its ID
|
* @return A query to patch a JSON document by its ID
|
||||||
|
* @throws DocumentException If the dialect is not configured
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
fun <TKey> byId(tableName: String, docId: TKey? = null) =
|
fun <TKey> byId(tableName: String, docId: TKey? = null) =
|
||||||
byIdBase(patch(tableName), docId)
|
byIdBase(patch(tableName), docId)
|
||||||
|
|
||||||
@ -41,7 +43,11 @@ object Patch {
|
|||||||
* @param fields The field criteria
|
* @param fields The field criteria
|
||||||
* @param howMatched How the fields should be matched (optional, defaults to `ALL`)
|
* @param howMatched How the fields should be matched (optional, defaults to `ALL`)
|
||||||
* @return A query to patch JSON documents by field match criteria
|
* @return A query to patch JSON documents by field match criteria
|
||||||
|
* @throws DocumentException If the dialect is not configured
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
fun byFields(tableName: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
fun byFields(tableName: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
||||||
byFieldsBase(patch(tableName), fields, howMatched)
|
byFieldsBase(patch(tableName), fields, howMatched)
|
||||||
|
|
||||||
@ -50,7 +56,10 @@ object Patch {
|
|||||||
*
|
*
|
||||||
* @param tableName The name of the table where the document is stored
|
* @param tableName The name of the table where the document is stored
|
||||||
* @return A query to patch JSON documents by JSON containment
|
* @return A query to patch JSON documents by JSON containment
|
||||||
|
* @throws DocumentException If the database dialect is not PostgreSQL
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
|
@JvmStatic
|
||||||
fun byContains(tableName: String) =
|
fun byContains(tableName: String) =
|
||||||
statementWhere(patch(tableName), Where.jsonContains())
|
statementWhere(patch(tableName), Where.jsonContains())
|
||||||
|
|
||||||
@ -59,7 +68,10 @@ object Patch {
|
|||||||
*
|
*
|
||||||
* @param tableName The name of the table where the document is stored
|
* @param tableName The name of the table where the document is stored
|
||||||
* @return A query to patch JSON documents by JSON path match
|
* @return A query to patch JSON documents by JSON path match
|
||||||
|
* @throws DocumentException If the database dialect is not PostgreSQL
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
|
@JvmStatic
|
||||||
fun byJsonPath(tableName: String) =
|
fun byJsonPath(tableName: String) =
|
||||||
statementWhere(patch(tableName), Where.jsonPathMatches())
|
statementWhere(patch(tableName), Where.jsonPathMatches())
|
||||||
}
|
}
|
@ -1,3 +1,4 @@
|
|||||||
|
@file:JvmName("QueryUtils")
|
||||||
package solutions.bitbadger.documents.query
|
package solutions.bitbadger.documents.query
|
||||||
|
|
||||||
import solutions.bitbadger.documents.Configuration
|
import solutions.bitbadger.documents.Configuration
|
||||||
@ -35,6 +36,7 @@ fun <TKey> byId(statement: String, docId: TKey) =
|
|||||||
* @param howMatched Whether to match any or all of the field conditions (optional; default ALL)
|
* @param howMatched Whether to match any or all of the field conditions (optional; default ALL)
|
||||||
* @return A query addressing documents by field matching conditions
|
* @return A query addressing documents by field matching conditions
|
||||||
*/
|
*/
|
||||||
|
@JvmOverloads
|
||||||
fun byFields(statement: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
fun byFields(statement: String, fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
||||||
statementWhere(statement, Where.byFields(fields, howMatched))
|
statementWhere(statement, Where.byFields(fields, howMatched))
|
||||||
|
|
||||||
@ -45,6 +47,7 @@ fun byFields(statement: String, fields: Collection<Field<*>>, howMatched: FieldM
|
|||||||
* @param dialect The SQL dialect for the generated clause
|
* @param dialect The SQL dialect for the generated clause
|
||||||
* @return An `ORDER BY` clause for the given fields
|
* @return An `ORDER BY` clause for the given fields
|
||||||
*/
|
*/
|
||||||
|
@JvmOverloads
|
||||||
fun orderBy(fields: Collection<Field<*>>, dialect: Dialect? = null): String {
|
fun orderBy(fields: Collection<Field<*>>, dialect: Dialect? = null): String {
|
||||||
val mode = dialect ?: Configuration.dialect("generate ORDER BY clause")
|
val mode = dialect ?: Configuration.dialect("generate ORDER BY clause")
|
||||||
if (fields.isEmpty()) return ""
|
if (fields.isEmpty()) return ""
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
package solutions.bitbadger.documents.query
|
package solutions.bitbadger.documents.query
|
||||||
|
|
||||||
import solutions.bitbadger.documents.*
|
import solutions.bitbadger.documents.*
|
||||||
|
import kotlin.jvm.Throws
|
||||||
import solutions.bitbadger.documents.query.byFields as byFieldsBase
|
import solutions.bitbadger.documents.query.byFields as byFieldsBase
|
||||||
import solutions.bitbadger.documents.query.byId as byIdBase
|
import solutions.bitbadger.documents.query.byId as byIdBase
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Functions to create queries to remove fields from documents
|
* Functions to create queries to remove fields from documents
|
||||||
*/
|
*/
|
||||||
object RemoveFields {
|
object RemoveFieldsQuery {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a query to remove fields based on the given parameters
|
* Create a query to remove fields based on the given parameters
|
||||||
@ -31,7 +32,11 @@ object RemoveFields {
|
|||||||
* @param toRemove The parameters for the fields to be removed
|
* @param toRemove The parameters for the fields to be removed
|
||||||
* @param docId The ID of the document to be updated (optional, used for type checking)
|
* @param docId The ID of the document to be updated (optional, used for type checking)
|
||||||
* @return A query to patch a JSON document by its ID
|
* @return A query to patch a JSON document by its ID
|
||||||
|
* @throws DocumentException If the dialect is not configured
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
fun <TKey> byId(tableName: String, toRemove: Collection<Parameter<*>>, docId: TKey? = null) =
|
fun <TKey> byId(tableName: String, toRemove: Collection<Parameter<*>>, docId: TKey? = null) =
|
||||||
byIdBase(removeFields(tableName, toRemove), docId)
|
byIdBase(removeFields(tableName, toRemove), docId)
|
||||||
|
|
||||||
@ -43,7 +48,11 @@ object RemoveFields {
|
|||||||
* @param fields The field criteria
|
* @param fields The field criteria
|
||||||
* @param howMatched How the fields should be matched (optional, defaults to `ALL`)
|
* @param howMatched How the fields should be matched (optional, defaults to `ALL`)
|
||||||
* @return A query to patch JSON documents by field match criteria
|
* @return A query to patch JSON documents by field match criteria
|
||||||
|
* @throws DocumentException If the dialect is not configured
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
fun byFields(
|
fun byFields(
|
||||||
tableName: String,
|
tableName: String,
|
||||||
toRemove: Collection<Parameter<*>>,
|
toRemove: Collection<Parameter<*>>,
|
||||||
@ -58,7 +67,10 @@ object RemoveFields {
|
|||||||
* @param tableName The name of the table where the document is stored
|
* @param tableName The name of the table where the document is stored
|
||||||
* @param toRemove The parameters for the fields to be removed
|
* @param toRemove The parameters for the fields to be removed
|
||||||
* @return A query to patch JSON documents by JSON containment
|
* @return A query to patch JSON documents by JSON containment
|
||||||
|
* @throws DocumentException If the database dialect is not PostgreSQL
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
|
@JvmStatic
|
||||||
fun byContains(tableName: String, toRemove: Collection<Parameter<*>>) =
|
fun byContains(tableName: String, toRemove: Collection<Parameter<*>>) =
|
||||||
statementWhere(removeFields(tableName, toRemove), Where.jsonContains())
|
statementWhere(removeFields(tableName, toRemove), Where.jsonContains())
|
||||||
|
|
||||||
@ -68,7 +80,10 @@ object RemoveFields {
|
|||||||
* @param tableName The name of the table where the document is stored
|
* @param tableName The name of the table where the document is stored
|
||||||
* @param toRemove The parameters for the fields to be removed
|
* @param toRemove The parameters for the fields to be removed
|
||||||
* @return A query to patch JSON documents by JSON path match
|
* @return A query to patch JSON documents by JSON path match
|
||||||
|
* @throws DocumentException If the database dialect is not PostgreSQL
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
|
@JvmStatic
|
||||||
fun byJsonPath(tableName: String, toRemove: Collection<Parameter<*>>) =
|
fun byJsonPath(tableName: String, toRemove: Collection<Parameter<*>>) =
|
||||||
statementWhere(removeFields(tableName, toRemove), Where.jsonPathMatches())
|
statementWhere(removeFields(tableName, toRemove), Where.jsonPathMatches())
|
||||||
}
|
}
|
@ -5,6 +5,7 @@ import solutions.bitbadger.documents.Dialect
|
|||||||
import solutions.bitbadger.documents.DocumentException
|
import solutions.bitbadger.documents.DocumentException
|
||||||
import solutions.bitbadger.documents.Field
|
import solutions.bitbadger.documents.Field
|
||||||
import solutions.bitbadger.documents.FieldMatch
|
import solutions.bitbadger.documents.FieldMatch
|
||||||
|
import kotlin.jvm.Throws
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Functions to create `WHERE` clause fragments
|
* Functions to create `WHERE` clause fragments
|
||||||
@ -18,6 +19,8 @@ object Where {
|
|||||||
* @param howMatched How the fields should be matched (optional, defaults to `ALL`)
|
* @param howMatched How the fields should be matched (optional, defaults to `ALL`)
|
||||||
* @return A `WHERE` clause fragment to match the given fields
|
* @return A `WHERE` clause fragment to match the given fields
|
||||||
*/
|
*/
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
fun byFields(fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
fun byFields(fields: Collection<Field<*>>, howMatched: FieldMatch? = null) =
|
||||||
fields.joinToString(" ${(howMatched ?: FieldMatch.ALL).sql} ") { it.toWhere() }
|
fields.joinToString(" ${(howMatched ?: FieldMatch.ALL).sql} ") { it.toWhere() }
|
||||||
|
|
||||||
@ -27,6 +30,8 @@ object Where {
|
|||||||
* @param parameterName The parameter name to use for the ID placeholder (optional, defaults to ":id")
|
* @param parameterName The parameter name to use for the ID placeholder (optional, defaults to ":id")
|
||||||
* @param docId The ID value (optional; used for type determinations, string assumed if not provided)
|
* @param docId The ID value (optional; used for type determinations, string assumed if not provided)
|
||||||
*/
|
*/
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
fun <TKey> byId(parameterName: String = ":id", docId: TKey? = null) =
|
fun <TKey> byId(parameterName: String = ":id", docId: TKey? = null) =
|
||||||
byFields(listOf(Field.equal(Configuration.idField, docId ?: "", parameterName)))
|
byFields(listOf(Field.equal(Configuration.idField, docId ?: "", parameterName)))
|
||||||
|
|
||||||
@ -37,6 +42,9 @@ object Where {
|
|||||||
* @return A `WHERE` clause fragment to implement a JSON containment criterion
|
* @return A `WHERE` clause fragment to implement a JSON containment criterion
|
||||||
* @throws DocumentException If called against a SQLite database
|
* @throws DocumentException If called against a SQLite database
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
fun jsonContains(parameterName: String = ":criteria") =
|
fun jsonContains(parameterName: String = ":criteria") =
|
||||||
when (Configuration.dialect("create containment WHERE clause")) {
|
when (Configuration.dialect("create containment WHERE clause")) {
|
||||||
Dialect.POSTGRESQL -> "data @> $parameterName"
|
Dialect.POSTGRESQL -> "data @> $parameterName"
|
||||||
@ -50,6 +58,9 @@ object Where {
|
|||||||
* @return A `WHERE` clause fragment to implement a JSON path match criterion
|
* @return A `WHERE` clause fragment to implement a JSON path match criterion
|
||||||
* @throws DocumentException If called against a SQLite database
|
* @throws DocumentException If called against a SQLite database
|
||||||
*/
|
*/
|
||||||
|
@Throws(DocumentException::class)
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
fun jsonPathMatches(parameterName: String = ":path") =
|
fun jsonPathMatches(parameterName: String = ":path") =
|
||||||
when (Configuration.dialect("create JSON path match WHERE clause")) {
|
when (Configuration.dialect("create JSON path match WHERE clause")) {
|
||||||
Dialect.POSTGRESQL -> "jsonb_path_exists(data, $parameterName::jsonpath)"
|
Dialect.POSTGRESQL -> "jsonb_path_exists(data, $parameterName::jsonpath)"
|
||||||
|
@ -11,7 +11,7 @@ import static org.junit.jupiter.api.Assertions.*;
|
|||||||
/**
|
/**
|
||||||
* Unit tests for the `AutoId` enum
|
* Unit tests for the `AutoId` enum
|
||||||
*/
|
*/
|
||||||
@DisplayName("Java | Common | AutoId")
|
@DisplayName("JVM | Java | AutoId")
|
||||||
final public class AutoIdTest {
|
final public class AutoIdTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -9,7 +9,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
|||||||
/**
|
/**
|
||||||
* Unit tests for the `DocumentIndex` enum
|
* Unit tests for the `DocumentIndex` enum
|
||||||
*/
|
*/
|
||||||
@DisplayName("Java | Common | DocumentIndex")
|
@DisplayName("JVM | Java | DocumentIndex")
|
||||||
final public class DocumentIndexTest {
|
final public class DocumentIndexTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -9,7 +9,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
|||||||
/**
|
/**
|
||||||
* Unit tests for the `FieldMatch` enum
|
* Unit tests for the `FieldMatch` enum
|
||||||
*/
|
*/
|
||||||
@DisplayName("Java | Common | FieldMatch")
|
@DisplayName("JVM | Java | FieldMatch")
|
||||||
final public class FieldMatchTest {
|
final public class FieldMatchTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -14,7 +14,7 @@ import static org.junit.jupiter.api.Assertions.*;
|
|||||||
/**
|
/**
|
||||||
* Unit tests for the `Field` class
|
* Unit tests for the `Field` class
|
||||||
*/
|
*/
|
||||||
@DisplayName("Java | Common | Field")
|
@DisplayName("JVM | Java | Field")
|
||||||
final public class FieldTest {
|
final public class FieldTest {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -9,7 +9,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
|||||||
/**
|
/**
|
||||||
* Unit tests for the `Op` enum
|
* Unit tests for the `Op` enum
|
||||||
*/
|
*/
|
||||||
@DisplayName("Java | Common | Op")
|
@DisplayName("JVM | Java | Op")
|
||||||
final public class OpTest {
|
final public class OpTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -9,7 +9,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
|||||||
/**
|
/**
|
||||||
* Unit tests for the `ParameterName` class
|
* Unit tests for the `ParameterName` class
|
||||||
*/
|
*/
|
||||||
@DisplayName("Java | Common | ParameterName")
|
@DisplayName("JVM | Java | ParameterName")
|
||||||
final public class ParameterNameTest {
|
final public class ParameterNameTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -11,7 +11,7 @@ import static org.junit.jupiter.api.Assertions.*;
|
|||||||
/**
|
/**
|
||||||
* Unit tests for the `Parameter` class
|
* Unit tests for the `Parameter` class
|
||||||
*/
|
*/
|
||||||
@DisplayName("Java | Common | Parameter")
|
@DisplayName("JVM | Java | Parameter")
|
||||||
final public class ParameterTest {
|
final public class ParameterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -13,7 +13,7 @@ import static org.junit.jupiter.api.Assertions.*;
|
|||||||
/**
|
/**
|
||||||
* Unit tests for the `Parameters` object
|
* Unit tests for the `Parameters` object
|
||||||
*/
|
*/
|
||||||
@DisplayName("Java | Java | Parameters")
|
@DisplayName("JVM | Java | Parameters")
|
||||||
final public class ParametersTest {
|
final public class ParametersTest {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
package solutions.bitbadger.documents.java.jvm.integration.common;
|
package solutions.bitbadger.documents.java.jvm.integration.common;
|
||||||
|
|
||||||
|
import solutions.bitbadger.documents.DocumentException;
|
||||||
import solutions.bitbadger.documents.Field;
|
import solutions.bitbadger.documents.Field;
|
||||||
import solutions.bitbadger.documents.jvm.Count;
|
|
||||||
import solutions.bitbadger.documents.support.ThrowawayDatabase;
|
|
||||||
import solutions.bitbadger.documents.java.support.JsonDocument;
|
import solutions.bitbadger.documents.java.support.JsonDocument;
|
||||||
|
import solutions.bitbadger.documents.support.ThrowawayDatabase;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static solutions.bitbadger.documents.extensions.ConnExt.*;
|
||||||
import static solutions.bitbadger.documents.support.TypesKt.TEST_TABLE;
|
import static solutions.bitbadger.documents.support.TypesKt.TEST_TABLE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -18,42 +19,42 @@ final public class CountFunctions {
|
|||||||
|
|
||||||
public static void all(ThrowawayDatabase db) {
|
public static void all(ThrowawayDatabase db) {
|
||||||
JsonDocument.load(db);
|
JsonDocument.load(db);
|
||||||
assertEquals(5L, Count.all(TEST_TABLE, db.getConn()), "There should have been 5 documents in the table");
|
assertEquals(5L, countAll(db.getConn(), TEST_TABLE), "There should have been 5 documents in the table");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void byFieldsNumeric(ThrowawayDatabase db) {
|
public static void byFieldsNumeric(ThrowawayDatabase db) {
|
||||||
JsonDocument.load(db);
|
JsonDocument.load(db);
|
||||||
assertEquals(3L, Count.byFields(TEST_TABLE, List.of(Field.between("numValue", 10, 20)), db.getConn()),
|
assertEquals(3L, countByFields(db.getConn(), TEST_TABLE, List.of(Field.between("numValue", 10, 20))),
|
||||||
"There should have been 3 matching documents");
|
"There should have been 3 matching documents");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void byFieldsAlpha(ThrowawayDatabase db) {
|
public static void byFieldsAlpha(ThrowawayDatabase db) {
|
||||||
JsonDocument.load(db);
|
JsonDocument.load(db);
|
||||||
assertEquals(1L, Count.byFields(TEST_TABLE, List.of(Field.between("value", "aardvark", "apple")), db.getConn()),
|
assertEquals(1L, countByFields(db.getConn(), TEST_TABLE, List.of(Field.between("value", "aardvark", "apple"))),
|
||||||
"There should have been 1 matching document");
|
"There should have been 1 matching document");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void byContainsMatch(ThrowawayDatabase db) {
|
public static void byContainsMatch(ThrowawayDatabase db) throws DocumentException {
|
||||||
JsonDocument.load(db);
|
JsonDocument.load(db);
|
||||||
assertEquals(2L, Count.byContains(TEST_TABLE, Map.of("value", "purple"), db.getConn()),
|
assertEquals(2L, countByContains(db.getConn(), TEST_TABLE, Map.of("value", "purple")),
|
||||||
"There should have been 2 matching documents");
|
"There should have been 2 matching documents");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void byContainsNoMatch(ThrowawayDatabase db) {
|
public static void byContainsNoMatch(ThrowawayDatabase db) throws DocumentException {
|
||||||
JsonDocument.load(db);
|
JsonDocument.load(db);
|
||||||
assertEquals(0L, Count.byContains(TEST_TABLE, Map.of("value", "magenta"), db.getConn()),
|
assertEquals(0L, countByContains(db.getConn(), TEST_TABLE, Map.of("value", "magenta")),
|
||||||
"There should have been no matching documents");
|
"There should have been no matching documents");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void byJsonPathMatch(ThrowawayDatabase db) {
|
public static void byJsonPathMatch(ThrowawayDatabase db) throws DocumentException {
|
||||||
JsonDocument.load(db);
|
JsonDocument.load(db);
|
||||||
assertEquals(2L, Count.byJsonPath(TEST_TABLE, "$.numValue ? (@ < 5)", db.getConn()),
|
assertEquals(2L, countByJsonPath(db.getConn(), TEST_TABLE, "$.numValue ? (@ < 5)"),
|
||||||
"There should have been 2 matching documents");
|
"There should have been 2 matching documents");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void byJsonPathNoMatch(ThrowawayDatabase db) {
|
public static void byJsonPathNoMatch(ThrowawayDatabase db) throws DocumentException {
|
||||||
JsonDocument.load(db);
|
JsonDocument.load(db);
|
||||||
assertEquals(0L, Count.byJsonPath(TEST_TABLE, "$.numValue ? (@ > 100)", db.getConn()),
|
assertEquals(0L, countByJsonPath(db.getConn(), TEST_TABLE, "$.numValue ? (@ > 100)"),
|
||||||
"There should have been no matching documents");
|
"There should have been no matching documents");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,13 +2,14 @@ package solutions.bitbadger.documents.java.jvm.integration.postgresql;
|
|||||||
|
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import solutions.bitbadger.documents.DocumentException;
|
||||||
import solutions.bitbadger.documents.java.jvm.integration.common.CountFunctions;
|
import solutions.bitbadger.documents.java.jvm.integration.common.CountFunctions;
|
||||||
import solutions.bitbadger.documents.jvm.integration.postgresql.PgDB;
|
import solutions.bitbadger.documents.jvm.integration.postgresql.PgDB;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PostgreSQL integration tests for the `Count` object / `count*` connection extension functions
|
* PostgreSQL integration tests for the `Count` object / `count*` connection extension functions
|
||||||
*/
|
*/
|
||||||
@DisplayName("Java | Java | PostgreSQL: Count")
|
@DisplayName("JVM | Java | PostgreSQL: Count")
|
||||||
public class CountIT {
|
public class CountIT {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -37,7 +38,7 @@ public class CountIT {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byContains counts documents when matches are found")
|
@DisplayName("byContains counts documents when matches are found")
|
||||||
public void byContainsMatch() {
|
public void byContainsMatch() throws DocumentException {
|
||||||
try (PgDB db = new PgDB()) {
|
try (PgDB db = new PgDB()) {
|
||||||
CountFunctions.byContainsMatch(db);
|
CountFunctions.byContainsMatch(db);
|
||||||
}
|
}
|
||||||
@ -45,7 +46,7 @@ public class CountIT {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byContains counts documents when no matches are found")
|
@DisplayName("byContains counts documents when no matches are found")
|
||||||
public void byContainsNoMatch() {
|
public void byContainsNoMatch() throws DocumentException {
|
||||||
try (PgDB db = new PgDB()) {
|
try (PgDB db = new PgDB()) {
|
||||||
CountFunctions.byContainsNoMatch(db);
|
CountFunctions.byContainsNoMatch(db);
|
||||||
}
|
}
|
||||||
@ -53,7 +54,7 @@ public class CountIT {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byJsonPath counts documents when matches are found")
|
@DisplayName("byJsonPath counts documents when matches are found")
|
||||||
public void byJsonPathMatch() {
|
public void byJsonPathMatch() throws DocumentException {
|
||||||
try (PgDB db = new PgDB()) {
|
try (PgDB db = new PgDB()) {
|
||||||
CountFunctions.byJsonPathMatch(db);
|
CountFunctions.byJsonPathMatch(db);
|
||||||
}
|
}
|
||||||
@ -61,7 +62,7 @@ public class CountIT {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byJsonPath counts documents when no matches are found")
|
@DisplayName("byJsonPath counts documents when no matches are found")
|
||||||
public void byJsonPathNoMatch() {
|
public void byJsonPathNoMatch() throws DocumentException {
|
||||||
try (PgDB db = new PgDB()) {
|
try (PgDB db = new PgDB()) {
|
||||||
CountFunctions.byJsonPathNoMatch(db);
|
CountFunctions.byJsonPathNoMatch(db);
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
|
|||||||
/**
|
/**
|
||||||
* SQLite integration tests for the `Count` object / `count*` connection extension functions
|
* SQLite integration tests for the `Count` object / `count*` connection extension functions
|
||||||
*/
|
*/
|
||||||
@DisplayName("Java | Java | SQLite: Count")
|
@DisplayName("JVM | Java | SQLite: Count")
|
||||||
public class CountIT {
|
public class CountIT {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package solutions.bitbadger.documents.java.support;
|
package solutions.bitbadger.documents.java.support;
|
||||||
|
|
||||||
import kotlinx.serialization.Serializable;
|
|
||||||
import solutions.bitbadger.documents.jvm.Document;
|
import solutions.bitbadger.documents.jvm.Document;
|
||||||
import solutions.bitbadger.documents.support.ThrowawayDatabase;
|
import solutions.bitbadger.documents.support.ThrowawayDatabase;
|
||||||
|
|
||||||
@ -8,7 +7,6 @@ import java.util.List;
|
|||||||
|
|
||||||
import static solutions.bitbadger.documents.support.TypesKt.TEST_TABLE;
|
import static solutions.bitbadger.documents.support.TypesKt.TEST_TABLE;
|
||||||
|
|
||||||
@Serializable
|
|
||||||
public class JsonDocument {
|
public class JsonDocument {
|
||||||
|
|
||||||
private String id;
|
private String id;
|
||||||
|
@ -3,6 +3,7 @@ package solutions.bitbadger.documents
|
|||||||
import org.junit.jupiter.api.DisplayName
|
import org.junit.jupiter.api.DisplayName
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.junit.jupiter.api.assertThrows
|
import org.junit.jupiter.api.assertThrows
|
||||||
|
import solutions.bitbadger.documents.support.*
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertFalse
|
import kotlin.test.assertFalse
|
||||||
import kotlin.test.assertNotEquals
|
import kotlin.test.assertNotEquals
|
||||||
@ -11,7 +12,7 @@ import kotlin.test.assertTrue
|
|||||||
/**
|
/**
|
||||||
* Unit tests for the `AutoId` enum
|
* Unit tests for the `AutoId` enum
|
||||||
*/
|
*/
|
||||||
@DisplayName("Kotlin | Common | AutoId")
|
@DisplayName("JVM | Kotlin | AutoId")
|
||||||
class AutoIdTest {
|
class AutoIdTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -157,9 +158,3 @@ class AutoIdTest {
|
|||||||
assertThrows<DocumentException> { AutoId.needsAutoId(AutoId.RANDOM_STRING, ShortIdClass(55), "id") }
|
assertThrows<DocumentException> { AutoId.needsAutoId(AutoId.RANDOM_STRING, ShortIdClass(55), "id") }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class ByteIdClass(val id: Byte)
|
|
||||||
data class ShortIdClass(val id: Short)
|
|
||||||
data class IntIdClass(val id: Int)
|
|
||||||
data class LongIdClass(val id: Long)
|
|
||||||
data class StringIdClass(val id: String)
|
|
||||||
|
@ -9,7 +9,7 @@ import kotlin.test.assertTrue
|
|||||||
/**
|
/**
|
||||||
* Unit tests for the `ComparisonBetween` class
|
* Unit tests for the `ComparisonBetween` class
|
||||||
*/
|
*/
|
||||||
@DisplayName("ComparisonBetween")
|
@DisplayName("JVM | Kotlin | ComparisonBetween")
|
||||||
class ComparisonBetweenTest {
|
class ComparisonBetweenTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -50,7 +50,7 @@ class ComparisonBetweenTest {
|
|||||||
/**
|
/**
|
||||||
* Unit tests for the `ComparisonIn` class
|
* Unit tests for the `ComparisonIn` class
|
||||||
*/
|
*/
|
||||||
@DisplayName("ComparisonIn")
|
@DisplayName("JVM | Kotlin | ComparisonIn")
|
||||||
class ComparisonInTest {
|
class ComparisonInTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -92,7 +92,7 @@ class ComparisonInTest {
|
|||||||
/**
|
/**
|
||||||
* Unit tests for the `ComparisonInArray` class
|
* Unit tests for the `ComparisonInArray` class
|
||||||
*/
|
*/
|
||||||
@DisplayName("ComparisonInArray")
|
@DisplayName("JVM | Kotlin | ComparisonInArray")
|
||||||
class ComparisonInArrayTest {
|
class ComparisonInArrayTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -138,7 +138,7 @@ class ComparisonInArrayTest {
|
|||||||
/**
|
/**
|
||||||
* Unit tests for the `ComparisonSingle` class
|
* Unit tests for the `ComparisonSingle` class
|
||||||
*/
|
*/
|
||||||
@DisplayName("ComparisonSingle")
|
@DisplayName("JVM | Kotlin | ComparisonSingle")
|
||||||
class ComparisonSingleTest {
|
class ComparisonSingleTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -8,7 +8,7 @@ import kotlin.test.assertEquals
|
|||||||
/**
|
/**
|
||||||
* Unit tests for the `Configuration` object
|
* Unit tests for the `Configuration` object
|
||||||
*/
|
*/
|
||||||
@DisplayName("Kotlin | Common | Configuration")
|
@DisplayName("JVM | Kotlin | Configuration")
|
||||||
class ConfigurationTest {
|
class ConfigurationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -9,7 +9,7 @@ import kotlin.test.assertTrue
|
|||||||
/**
|
/**
|
||||||
* Unit tests for the `Dialect` enum
|
* Unit tests for the `Dialect` enum
|
||||||
*/
|
*/
|
||||||
@DisplayName("Kotlin | Common | Dialect")
|
@DisplayName("JVM | Kotlin | Dialect")
|
||||||
class DialectTest {
|
class DialectTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -7,7 +7,7 @@ import kotlin.test.assertEquals
|
|||||||
/**
|
/**
|
||||||
* Unit tests for the `DocumentIndex` enum
|
* Unit tests for the `DocumentIndex` enum
|
||||||
*/
|
*/
|
||||||
@DisplayName("Kotlin | Common | DocumentIndex")
|
@DisplayName("JVM | Kotlin | DocumentIndex")
|
||||||
class DocumentIndexTest {
|
class DocumentIndexTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -7,7 +7,7 @@ import kotlin.test.assertEquals
|
|||||||
/**
|
/**
|
||||||
* Unit tests for the `FieldMatch` enum
|
* Unit tests for the `FieldMatch` enum
|
||||||
*/
|
*/
|
||||||
@DisplayName("Kotlin | Common | FieldMatch")
|
@DisplayName("JVM | Kotlin | FieldMatch")
|
||||||
class FieldMatchTest {
|
class FieldMatchTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -11,7 +11,7 @@ import kotlin.test.assertNull
|
|||||||
/**
|
/**
|
||||||
* Unit tests for the `Field` class
|
* Unit tests for the `Field` class
|
||||||
*/
|
*/
|
||||||
@DisplayName("Kotlin | Common | Field")
|
@DisplayName("JVM | Kotlin | Field")
|
||||||
class FieldTest {
|
class FieldTest {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -7,7 +7,7 @@ import kotlin.test.assertEquals
|
|||||||
/**
|
/**
|
||||||
* Unit tests for the `Op` enum
|
* Unit tests for the `Op` enum
|
||||||
*/
|
*/
|
||||||
@DisplayName("Kotlin | Common | Op")
|
@DisplayName("JVM | Kotlin | Op")
|
||||||
class OpTest {
|
class OpTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -7,7 +7,7 @@ import kotlin.test.assertEquals
|
|||||||
/**
|
/**
|
||||||
* Unit tests for the `ParameterName` class
|
* Unit tests for the `ParameterName` class
|
||||||
*/
|
*/
|
||||||
@DisplayName("Kotlin | Common | ParameterName")
|
@DisplayName("JVM | Kotlin | ParameterName")
|
||||||
class ParameterNameTest {
|
class ParameterNameTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -9,7 +9,7 @@ import kotlin.test.assertNull
|
|||||||
/**
|
/**
|
||||||
* Unit tests for the `Parameter` class
|
* Unit tests for the `Parameter` class
|
||||||
*/
|
*/
|
||||||
@DisplayName("Kotlin | Common | Parameter")
|
@DisplayName("JVM | Kotlin | Parameter")
|
||||||
class ParameterTest {
|
class ParameterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -12,7 +12,7 @@ import kotlin.test.assertSame
|
|||||||
/**
|
/**
|
||||||
* Unit tests for the `Parameters` object
|
* Unit tests for the `Parameters` object
|
||||||
*/
|
*/
|
||||||
@DisplayName("Kotlin | Java | Parameters")
|
@DisplayName("JVM | Kotlin | Parameters")
|
||||||
class ParametersTest {
|
class ParametersTest {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3,9 +3,9 @@ package solutions.bitbadger.documents.jvm.integration.common
|
|||||||
import solutions.bitbadger.documents.*
|
import solutions.bitbadger.documents.*
|
||||||
import solutions.bitbadger.documents.extensions.*
|
import solutions.bitbadger.documents.extensions.*
|
||||||
import solutions.bitbadger.documents.jvm.Results
|
import solutions.bitbadger.documents.jvm.Results
|
||||||
import solutions.bitbadger.documents.query.Count
|
import solutions.bitbadger.documents.query.CountQuery
|
||||||
import solutions.bitbadger.documents.query.Delete
|
import solutions.bitbadger.documents.query.DeleteQuery
|
||||||
import solutions.bitbadger.documents.query.Find
|
import solutions.bitbadger.documents.query.FindQuery
|
||||||
import solutions.bitbadger.documents.support.*
|
import solutions.bitbadger.documents.support.*
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertNotNull
|
import kotlin.test.assertNotNull
|
||||||
@ -19,26 +19,26 @@ object Custom {
|
|||||||
fun listEmpty(db: ThrowawayDatabase) {
|
fun listEmpty(db: ThrowawayDatabase) {
|
||||||
JsonDocument.load(db)
|
JsonDocument.load(db)
|
||||||
db.conn.deleteByFields(TEST_TABLE, listOf(Field.exists(Configuration.idField)))
|
db.conn.deleteByFields(TEST_TABLE, listOf(Field.exists(Configuration.idField)))
|
||||||
val result = db.conn.customList(Find.all(TEST_TABLE), listOf(), JsonDocument::class.java, Results::fromData)
|
val result = db.conn.customList(FindQuery.all(TEST_TABLE), listOf(), JsonDocument::class.java, Results::fromData)
|
||||||
assertEquals(0, result.size, "There should have been no results")
|
assertEquals(0, result.size, "There should have been no results")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun listAll(db: ThrowawayDatabase) {
|
fun listAll(db: ThrowawayDatabase) {
|
||||||
JsonDocument.load(db)
|
JsonDocument.load(db)
|
||||||
val result = db.conn.customList(Find.all(TEST_TABLE), listOf(), JsonDocument::class.java, Results::fromData)
|
val result = db.conn.customList(FindQuery.all(TEST_TABLE), listOf(), JsonDocument::class.java, Results::fromData)
|
||||||
assertEquals(5, result.size, "There should have been 5 results")
|
assertEquals(5, result.size, "There should have been 5 results")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun singleNone(db: ThrowawayDatabase) =
|
fun singleNone(db: ThrowawayDatabase) =
|
||||||
assertNull(
|
assertNull(
|
||||||
db.conn.customSingle(Find.all(TEST_TABLE), listOf(), JsonDocument::class.java, Results::fromData),
|
db.conn.customSingle(FindQuery.all(TEST_TABLE), listOf(), JsonDocument::class.java, Results::fromData),
|
||||||
"There should not have been a document returned"
|
"There should not have been a document returned"
|
||||||
)
|
)
|
||||||
|
|
||||||
fun singleOne(db: ThrowawayDatabase) {
|
fun singleOne(db: ThrowawayDatabase) {
|
||||||
JsonDocument.load(db)
|
JsonDocument.load(db)
|
||||||
assertNotNull(
|
assertNotNull(
|
||||||
db.conn.customSingle(Find.all(TEST_TABLE), listOf(), JsonDocument::class.java, Results::fromData),
|
db.conn.customSingle(FindQuery.all(TEST_TABLE), listOf(), JsonDocument::class.java, Results::fromData),
|
||||||
"There should not have been a document returned"
|
"There should not have been a document returned"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -46,12 +46,12 @@ object Custom {
|
|||||||
fun nonQueryChanges(db: ThrowawayDatabase) {
|
fun nonQueryChanges(db: ThrowawayDatabase) {
|
||||||
JsonDocument.load(db)
|
JsonDocument.load(db)
|
||||||
assertEquals(
|
assertEquals(
|
||||||
5L, db.conn.customScalar(Count.all(TEST_TABLE), listOf(), Long::class.java, Results::toCount),
|
5L, db.conn.customScalar(CountQuery.all(TEST_TABLE), listOf(), Long::class.java, Results::toCount),
|
||||||
"There should have been 5 documents in the table"
|
"There should have been 5 documents in the table"
|
||||||
)
|
)
|
||||||
db.conn.customNonQuery("DELETE FROM $TEST_TABLE")
|
db.conn.customNonQuery("DELETE FROM $TEST_TABLE")
|
||||||
assertEquals(
|
assertEquals(
|
||||||
0L, db.conn.customScalar(Count.all(TEST_TABLE), listOf(), Long::class.java, Results::toCount),
|
0L, db.conn.customScalar(CountQuery.all(TEST_TABLE), listOf(), Long::class.java, Results::toCount),
|
||||||
"There should have been no documents in the table"
|
"There should have been no documents in the table"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -59,15 +59,15 @@ object Custom {
|
|||||||
fun nonQueryNoChanges(db: ThrowawayDatabase) {
|
fun nonQueryNoChanges(db: ThrowawayDatabase) {
|
||||||
JsonDocument.load(db)
|
JsonDocument.load(db)
|
||||||
assertEquals(
|
assertEquals(
|
||||||
5L, db.conn.customScalar(Count.all(TEST_TABLE), listOf(), Long::class.java, Results::toCount),
|
5L, db.conn.customScalar(CountQuery.all(TEST_TABLE), listOf(), Long::class.java, Results::toCount),
|
||||||
"There should have been 5 documents in the table"
|
"There should have been 5 documents in the table"
|
||||||
)
|
)
|
||||||
db.conn.customNonQuery(
|
db.conn.customNonQuery(
|
||||||
Delete.byId(TEST_TABLE, "eighty-two"),
|
DeleteQuery.byId(TEST_TABLE, "eighty-two"),
|
||||||
listOf(Parameter(":id", ParameterType.STRING, "eighty-two"))
|
listOf(Parameter(":id", ParameterType.STRING, "eighty-two"))
|
||||||
)
|
)
|
||||||
assertEquals(
|
assertEquals(
|
||||||
5L, db.conn.customScalar(Count.all(TEST_TABLE), listOf(), Long::class.java, Results::toCount),
|
5L, db.conn.customScalar(CountQuery.all(TEST_TABLE), listOf(), Long::class.java, Results::toCount),
|
||||||
"There should still have been 5 documents in the table"
|
"There should still have been 5 documents in the table"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import kotlin.test.Test
|
|||||||
/**
|
/**
|
||||||
* PostgreSQL integration tests for the `Definition` object / `ensure*` connection extension functions
|
* PostgreSQL integration tests for the `Definition` object / `ensure*` connection extension functions
|
||||||
*/
|
*/
|
||||||
@DisplayName("Java | Kotlin | PostgreSQL: Definition")
|
@DisplayName("JVM | Kotlin | PostgreSQL: Definition")
|
||||||
class DefinitionIT {
|
class DefinitionIT {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -7,7 +7,7 @@ import kotlin.test.Test
|
|||||||
/**
|
/**
|
||||||
* PostgreSQL integration tests for the `Delete` object / `deleteBy*` connection extension functions
|
* PostgreSQL integration tests for the `Delete` object / `deleteBy*` connection extension functions
|
||||||
*/
|
*/
|
||||||
@DisplayName("Java | Kotlin | PostgreSQL: Delete")
|
@DisplayName("JVM | Kotlin | PostgreSQL: Delete")
|
||||||
class DeleteIT {
|
class DeleteIT {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -7,7 +7,7 @@ import kotlin.test.Test
|
|||||||
/**
|
/**
|
||||||
* PostgreSQL integration tests for the `Document` object / `insert`, `save`, `update` connection extension functions
|
* PostgreSQL integration tests for the `Document` object / `insert`, `save`, `update` connection extension functions
|
||||||
*/
|
*/
|
||||||
@DisplayName("Java | Kotlin | PostgreSQL: Document")
|
@DisplayName("JVM | Kotlin | PostgreSQL: Document")
|
||||||
class DocumentIT {
|
class DocumentIT {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -7,7 +7,7 @@ import kotlin.test.Test
|
|||||||
/**
|
/**
|
||||||
* PostgreSQL integration tests for the `Exists` object / `existsBy*` connection extension functions
|
* PostgreSQL integration tests for the `Exists` object / `existsBy*` connection extension functions
|
||||||
*/
|
*/
|
||||||
@DisplayName("Java | Kotlin | PostgreSQL: Exists")
|
@DisplayName("JVM | Kotlin | PostgreSQL: Exists")
|
||||||
class ExistsIT {
|
class ExistsIT {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -7,7 +7,7 @@ import kotlin.test.Test
|
|||||||
/**
|
/**
|
||||||
* PostgreSQL integration tests for the `Find` object / `find*` connection extension functions
|
* PostgreSQL integration tests for the `Find` object / `find*` connection extension functions
|
||||||
*/
|
*/
|
||||||
@DisplayName("Java | Kotlin | PostgreSQL: Find")
|
@DisplayName("JVM | Kotlin | PostgreSQL: Find")
|
||||||
class FindIT {
|
class FindIT {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -7,7 +7,7 @@ import kotlin.test.Test
|
|||||||
/**
|
/**
|
||||||
* PostgreSQL integration tests for the `Patch` object / `patchBy*` connection extension functions
|
* PostgreSQL integration tests for the `Patch` object / `patchBy*` connection extension functions
|
||||||
*/
|
*/
|
||||||
@DisplayName("Java | Kotlin | PostgreSQL: Patch")
|
@DisplayName("JVM | Kotlin | PostgreSQL: Patch")
|
||||||
class PatchIT {
|
class PatchIT {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -7,7 +7,7 @@ import kotlin.test.Test
|
|||||||
/**
|
/**
|
||||||
* PostgreSQL integration tests for the `RemoveFields` object / `removeFieldsBy*` connection extension functions
|
* PostgreSQL integration tests for the `RemoveFields` object / `removeFieldsBy*` connection extension functions
|
||||||
*/
|
*/
|
||||||
@DisplayName("Java | Kotlin | PostgreSQL: RemoveFields")
|
@DisplayName("JVM | Kotlin | PostgreSQL: RemoveFields")
|
||||||
class RemoveFieldsIT {
|
class RemoveFieldsIT {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -9,7 +9,7 @@ import kotlin.test.Test
|
|||||||
/**
|
/**
|
||||||
* SQLite integration tests for the `Definition` object / `ensure*` connection extension functions
|
* SQLite integration tests for the `Definition` object / `ensure*` connection extension functions
|
||||||
*/
|
*/
|
||||||
@DisplayName("Java | Kotlin | SQLite: Definition")
|
@DisplayName("JVM | Kotlin | SQLite: Definition")
|
||||||
class DefinitionIT {
|
class DefinitionIT {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -9,7 +9,7 @@ import kotlin.test.Test
|
|||||||
/**
|
/**
|
||||||
* SQLite integration tests for the `Delete` object / `deleteBy*` connection extension functions
|
* SQLite integration tests for the `Delete` object / `deleteBy*` connection extension functions
|
||||||
*/
|
*/
|
||||||
@DisplayName("Java | Kotlin | SQLite: Delete")
|
@DisplayName("JVM | Kotlin | SQLite: Delete")
|
||||||
class DeleteIT {
|
class DeleteIT {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -7,7 +7,7 @@ import kotlin.test.Test
|
|||||||
/**
|
/**
|
||||||
* SQLite integration tests for the `Document` object / `insert`, `save`, `update` connection extension functions
|
* SQLite integration tests for the `Document` object / `insert`, `save`, `update` connection extension functions
|
||||||
*/
|
*/
|
||||||
@DisplayName("Java | Kotlin | SQLite: Document")
|
@DisplayName("JVM | Kotlin | SQLite: Document")
|
||||||
class DocumentIT {
|
class DocumentIT {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -9,7 +9,7 @@ import kotlin.test.Test
|
|||||||
/**
|
/**
|
||||||
* SQLite integration tests for the `Exists` object / `existsBy*` connection extension functions
|
* SQLite integration tests for the `Exists` object / `existsBy*` connection extension functions
|
||||||
*/
|
*/
|
||||||
@DisplayName("Java | Kotlin | SQLite: Exists")
|
@DisplayName("JVM | Kotlin | SQLite: Exists")
|
||||||
class ExistsIT {
|
class ExistsIT {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -9,7 +9,7 @@ import kotlin.test.Test
|
|||||||
/**
|
/**
|
||||||
* SQLite integration tests for the `Find` object / `find*` connection extension functions
|
* SQLite integration tests for the `Find` object / `find*` connection extension functions
|
||||||
*/
|
*/
|
||||||
@DisplayName("Java | Kotlin | SQLite: Find")
|
@DisplayName("JVM | Kotlin | SQLite: Find")
|
||||||
class FindIT {
|
class FindIT {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -9,7 +9,7 @@ import kotlin.test.Test
|
|||||||
/**
|
/**
|
||||||
* SQLite integration tests for the `Patch` object / `patchBy*` connection extension functions
|
* SQLite integration tests for the `Patch` object / `patchBy*` connection extension functions
|
||||||
*/
|
*/
|
||||||
@DisplayName("Java | Kotlin | SQLite: Patch")
|
@DisplayName("JVM | Kotlin | SQLite: Patch")
|
||||||
class PatchIT {
|
class PatchIT {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -9,7 +9,7 @@ import kotlin.test.Test
|
|||||||
/**
|
/**
|
||||||
* SQLite integration tests for the `RemoveFields` object / `removeFieldsBy*` connection extension functions
|
* SQLite integration tests for the `RemoveFields` object / `removeFieldsBy*` connection extension functions
|
||||||
*/
|
*/
|
||||||
@DisplayName("Java | Kotlin | SQLite: RemoveFields")
|
@DisplayName("JVM | Kotlin | SQLite: RemoveFields")
|
||||||
class RemoveFieldsIT {
|
class RemoveFieldsIT {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -13,8 +13,8 @@ import kotlin.test.assertEquals
|
|||||||
/**
|
/**
|
||||||
* Unit tests for the `Count` object
|
* Unit tests for the `Count` object
|
||||||
*/
|
*/
|
||||||
@DisplayName("Kotlin | Common | Query: Count")
|
@DisplayName("JVM | Kotlin | Query | CountQuery")
|
||||||
class CountTest {
|
class CountQueryTest {
|
||||||
|
|
||||||
/** Test table name */
|
/** Test table name */
|
||||||
private val tbl = "test_table"
|
private val tbl = "test_table"
|
||||||
@ -30,7 +30,7 @@ class CountTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("all generates correctly")
|
@DisplayName("all generates correctly")
|
||||||
fun all() =
|
fun all() =
|
||||||
assertEquals("SELECT COUNT(*) AS it FROM $tbl", Count.all(tbl), "Count query not constructed correctly")
|
assertEquals("SELECT COUNT(*) AS it FROM $tbl", CountQuery.all(tbl), "Count query not constructed correctly")
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byFields generates correctly (PostgreSQL)")
|
@DisplayName("byFields generates correctly (PostgreSQL)")
|
||||||
@ -38,7 +38,7 @@ class CountTest {
|
|||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"SELECT COUNT(*) AS it FROM $tbl WHERE data->>'test' = :field0",
|
"SELECT COUNT(*) AS it FROM $tbl WHERE data->>'test' = :field0",
|
||||||
Count.byFields(tbl, listOf(Field.equal("test", "", ":field0"))),
|
CountQuery.byFields(tbl, listOf(Field.equal("test", "", ":field0"))),
|
||||||
"Count query not constructed correctly"
|
"Count query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -49,7 +49,7 @@ class CountTest {
|
|||||||
Configuration.dialectValue = Dialect.SQLITE
|
Configuration.dialectValue = Dialect.SQLITE
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"SELECT COUNT(*) AS it FROM $tbl WHERE data->>'test' = :field0",
|
"SELECT COUNT(*) AS it FROM $tbl WHERE data->>'test' = :field0",
|
||||||
Count.byFields(tbl, listOf(Field.equal("test", "", ":field0"))),
|
CountQuery.byFields(tbl, listOf(Field.equal("test", "", ":field0"))),
|
||||||
"Count query not constructed correctly"
|
"Count query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -59,7 +59,7 @@ class CountTest {
|
|||||||
fun byContainsPostgres() {
|
fun byContainsPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"SELECT COUNT(*) AS it FROM $tbl WHERE data @> :criteria", Count.byContains(tbl),
|
"SELECT COUNT(*) AS it FROM $tbl WHERE data @> :criteria", CountQuery.byContains(tbl),
|
||||||
"Count query not constructed correctly"
|
"Count query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -68,7 +68,7 @@ class CountTest {
|
|||||||
@DisplayName("byContains fails (SQLite)")
|
@DisplayName("byContains fails (SQLite)")
|
||||||
fun byContainsSQLite() {
|
fun byContainsSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
Configuration.dialectValue = Dialect.SQLITE
|
||||||
assertThrows<DocumentException> { Count.byContains(tbl) }
|
assertThrows<DocumentException> { CountQuery.byContains(tbl) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -77,7 +77,7 @@ class CountTest {
|
|||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"SELECT COUNT(*) AS it FROM $tbl WHERE jsonb_path_exists(data, :path::jsonpath)",
|
"SELECT COUNT(*) AS it FROM $tbl WHERE jsonb_path_exists(data, :path::jsonpath)",
|
||||||
Count.byJsonPath(tbl), "Count query not constructed correctly"
|
CountQuery.byJsonPath(tbl), "Count query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,6 +85,6 @@ class CountTest {
|
|||||||
@DisplayName("byJsonPath fails (SQLite)")
|
@DisplayName("byJsonPath fails (SQLite)")
|
||||||
fun byJsonPathSQLite() {
|
fun byJsonPathSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
Configuration.dialectValue = Dialect.SQLITE
|
||||||
assertThrows<DocumentException> { Count.byJsonPath(tbl) }
|
assertThrows<DocumentException> { CountQuery.byJsonPath(tbl) }
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -13,8 +13,8 @@ import kotlin.test.assertEquals
|
|||||||
/**
|
/**
|
||||||
* Unit tests for the `Definition` object
|
* Unit tests for the `Definition` object
|
||||||
*/
|
*/
|
||||||
@DisplayName("Kotlin | Common | Query: Definition")
|
@DisplayName("JVM | Kotlin | Query | DefinitionQuery")
|
||||||
class DefinitionTest {
|
class DefinitionQueryTest {
|
||||||
|
|
||||||
/** Test table name */
|
/** Test table name */
|
||||||
private val tbl = "test_table"
|
private val tbl = "test_table"
|
||||||
@ -32,27 +32,27 @@ class DefinitionTest {
|
|||||||
fun ensureTableFor() =
|
fun ensureTableFor() =
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"CREATE TABLE IF NOT EXISTS my.table (data JSONB NOT NULL)",
|
"CREATE TABLE IF NOT EXISTS my.table (data JSONB NOT NULL)",
|
||||||
Definition.ensureTableFor("my.table", "JSONB"), "CREATE TABLE statement not constructed correctly"
|
DefinitionQuery.ensureTableFor("my.table", "JSONB"), "CREATE TABLE statement not constructed correctly"
|
||||||
)
|
)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("ensureTable generates correctly (PostgreSQL)")
|
@DisplayName("ensureTable generates correctly (PostgreSQL)")
|
||||||
fun ensureTablePostgres() {
|
fun ensureTablePostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||||
assertEquals("CREATE TABLE IF NOT EXISTS $tbl (data JSONB NOT NULL)", Definition.ensureTable(tbl))
|
assertEquals("CREATE TABLE IF NOT EXISTS $tbl (data JSONB NOT NULL)", DefinitionQuery.ensureTable(tbl))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("ensureTable generates correctly (SQLite)")
|
@DisplayName("ensureTable generates correctly (SQLite)")
|
||||||
fun ensureTableSQLite() {
|
fun ensureTableSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
Configuration.dialectValue = Dialect.SQLITE
|
||||||
assertEquals("CREATE TABLE IF NOT EXISTS $tbl (data TEXT NOT NULL)", Definition.ensureTable(tbl))
|
assertEquals("CREATE TABLE IF NOT EXISTS $tbl (data TEXT NOT NULL)", DefinitionQuery.ensureTable(tbl))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("ensureTable fails when no dialect is set")
|
@DisplayName("ensureTable fails when no dialect is set")
|
||||||
fun ensureTableFailsUnknown() {
|
fun ensureTableFailsUnknown() {
|
||||||
assertThrows<DocumentException> { Definition.ensureTable(tbl) }
|
assertThrows<DocumentException> { DefinitionQuery.ensureTable(tbl) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -60,7 +60,7 @@ class DefinitionTest {
|
|||||||
fun ensureKeyWithSchema() =
|
fun ensureKeyWithSchema() =
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"CREATE UNIQUE INDEX IF NOT EXISTS idx_table_key ON test.table ((data->>'id'))",
|
"CREATE UNIQUE INDEX IF NOT EXISTS idx_table_key ON test.table ((data->>'id'))",
|
||||||
Definition.ensureKey("test.table", Dialect.POSTGRESQL),
|
DefinitionQuery.ensureKey("test.table", Dialect.POSTGRESQL),
|
||||||
"CREATE INDEX for key statement with schema not constructed correctly"
|
"CREATE INDEX for key statement with schema not constructed correctly"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ class DefinitionTest {
|
|||||||
fun ensureKeyWithoutSchema() =
|
fun ensureKeyWithoutSchema() =
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"CREATE UNIQUE INDEX IF NOT EXISTS idx_${tbl}_key ON $tbl ((data->>'id'))",
|
"CREATE UNIQUE INDEX IF NOT EXISTS idx_${tbl}_key ON $tbl ((data->>'id'))",
|
||||||
Definition.ensureKey(tbl, Dialect.SQLITE),
|
DefinitionQuery.ensureKey(tbl, Dialect.SQLITE),
|
||||||
"CREATE INDEX for key statement without schema not constructed correctly"
|
"CREATE INDEX for key statement without schema not constructed correctly"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -78,7 +78,7 @@ class DefinitionTest {
|
|||||||
fun ensureIndexOnMultipleFields() =
|
fun ensureIndexOnMultipleFields() =
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"CREATE INDEX IF NOT EXISTS idx_table_gibberish ON test.table ((data->>'taco'), (data->>'guac') DESC, (data->>'salsa') ASC)",
|
"CREATE INDEX IF NOT EXISTS idx_table_gibberish ON test.table ((data->>'taco'), (data->>'guac') DESC, (data->>'salsa') ASC)",
|
||||||
Definition.ensureIndexOn(
|
DefinitionQuery.ensureIndexOn(
|
||||||
"test.table", "gibberish", listOf("taco", "guac DESC", "salsa ASC"),
|
"test.table", "gibberish", listOf("taco", "guac DESC", "salsa ASC"),
|
||||||
Dialect.POSTGRESQL
|
Dialect.POSTGRESQL
|
||||||
),
|
),
|
||||||
@ -90,7 +90,7 @@ class DefinitionTest {
|
|||||||
fun ensureIndexOnNestedPostgres() =
|
fun ensureIndexOnNestedPostgres() =
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"CREATE INDEX IF NOT EXISTS idx_${tbl}_nest ON $tbl ((data#>>'{a,b,c}'))",
|
"CREATE INDEX IF NOT EXISTS idx_${tbl}_nest ON $tbl ((data#>>'{a,b,c}'))",
|
||||||
Definition.ensureIndexOn(tbl, "nest", listOf("a.b.c"), Dialect.POSTGRESQL),
|
DefinitionQuery.ensureIndexOn(tbl, "nest", listOf("a.b.c"), Dialect.POSTGRESQL),
|
||||||
"CREATE INDEX for nested PostgreSQL field incorrect"
|
"CREATE INDEX for nested PostgreSQL field incorrect"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -99,7 +99,7 @@ class DefinitionTest {
|
|||||||
fun ensureIndexOnNestedSQLite() =
|
fun ensureIndexOnNestedSQLite() =
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"CREATE INDEX IF NOT EXISTS idx_${tbl}_nest ON $tbl ((data->'a'->'b'->>'c'))",
|
"CREATE INDEX IF NOT EXISTS idx_${tbl}_nest ON $tbl ((data->'a'->'b'->>'c'))",
|
||||||
Definition.ensureIndexOn(tbl, "nest", listOf("a.b.c"), Dialect.SQLITE),
|
DefinitionQuery.ensureIndexOn(tbl, "nest", listOf("a.b.c"), Dialect.SQLITE),
|
||||||
"CREATE INDEX for nested SQLite field incorrect"
|
"CREATE INDEX for nested SQLite field incorrect"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -109,7 +109,7 @@ class DefinitionTest {
|
|||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"CREATE INDEX IF NOT EXISTS idx_${tbl}_document ON $tbl USING GIN (data)",
|
"CREATE INDEX IF NOT EXISTS idx_${tbl}_document ON $tbl USING GIN (data)",
|
||||||
Definition.ensureDocumentIndexOn(tbl, DocumentIndex.FULL),
|
DefinitionQuery.ensureDocumentIndexOn(tbl, DocumentIndex.FULL),
|
||||||
"CREATE INDEX for full document index incorrect"
|
"CREATE INDEX for full document index incorrect"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -120,7 +120,7 @@ class DefinitionTest {
|
|||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"CREATE INDEX IF NOT EXISTS idx_${tbl}_document ON $tbl USING GIN (data jsonb_path_ops)",
|
"CREATE INDEX IF NOT EXISTS idx_${tbl}_document ON $tbl USING GIN (data jsonb_path_ops)",
|
||||||
Definition.ensureDocumentIndexOn(tbl, DocumentIndex.OPTIMIZED),
|
DefinitionQuery.ensureDocumentIndexOn(tbl, DocumentIndex.OPTIMIZED),
|
||||||
"CREATE INDEX for optimized document index incorrect"
|
"CREATE INDEX for optimized document index incorrect"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -129,6 +129,6 @@ class DefinitionTest {
|
|||||||
@DisplayName("ensureDocumentIndexOn fails for SQLite")
|
@DisplayName("ensureDocumentIndexOn fails for SQLite")
|
||||||
fun ensureDocumentIndexOnFailsSQLite() {
|
fun ensureDocumentIndexOnFailsSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
Configuration.dialectValue = Dialect.SQLITE
|
||||||
assertThrows<DocumentException> { Definition.ensureDocumentIndexOn(tbl, DocumentIndex.FULL) }
|
assertThrows<DocumentException> { DefinitionQuery.ensureDocumentIndexOn(tbl, DocumentIndex.FULL) }
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -13,8 +13,8 @@ import kotlin.test.assertEquals
|
|||||||
/**
|
/**
|
||||||
* Unit tests for the `Delete` object
|
* Unit tests for the `Delete` object
|
||||||
*/
|
*/
|
||||||
@DisplayName("Kotlin | Common | Query: Delete")
|
@DisplayName("JVM | Kotlin | Query | DeleteQuery")
|
||||||
class DeleteTest {
|
class DeleteQueryTest {
|
||||||
|
|
||||||
/** Test table name */
|
/** Test table name */
|
||||||
private val tbl = "test_table"
|
private val tbl = "test_table"
|
||||||
@ -33,7 +33,7 @@ class DeleteTest {
|
|||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"DELETE FROM $tbl WHERE data->>'id' = :id",
|
"DELETE FROM $tbl WHERE data->>'id' = :id",
|
||||||
Delete.byId<String>(tbl), "Delete query not constructed correctly"
|
DeleteQuery.byId<String>(tbl), "Delete query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ class DeleteTest {
|
|||||||
Configuration.dialectValue = Dialect.SQLITE
|
Configuration.dialectValue = Dialect.SQLITE
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"DELETE FROM $tbl WHERE data->>'id' = :id",
|
"DELETE FROM $tbl WHERE data->>'id' = :id",
|
||||||
Delete.byId<String>(tbl), "Delete query not constructed correctly"
|
DeleteQuery.byId<String>(tbl), "Delete query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ class DeleteTest {
|
|||||||
fun byFieldsPostgres() {
|
fun byFieldsPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"DELETE FROM $tbl WHERE data->>'a' = :b", Delete.byFields(tbl, listOf(Field.equal("a", "", ":b"))),
|
"DELETE FROM $tbl WHERE data->>'a' = :b", DeleteQuery.byFields(tbl, listOf(Field.equal("a", "", ":b"))),
|
||||||
"Delete query not constructed correctly"
|
"Delete query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -62,7 +62,7 @@ class DeleteTest {
|
|||||||
fun byFieldsSQLite() {
|
fun byFieldsSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
Configuration.dialectValue = Dialect.SQLITE
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"DELETE FROM $tbl WHERE data->>'a' = :b", Delete.byFields(tbl, listOf(Field.equal("a", "", ":b"))),
|
"DELETE FROM $tbl WHERE data->>'a' = :b", DeleteQuery.byFields(tbl, listOf(Field.equal("a", "", ":b"))),
|
||||||
"Delete query not constructed correctly"
|
"Delete query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -72,7 +72,7 @@ class DeleteTest {
|
|||||||
fun byContainsPostgres() {
|
fun byContainsPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"DELETE FROM $tbl WHERE data @> :criteria", Delete.byContains(tbl), "Delete query not constructed correctly"
|
"DELETE FROM $tbl WHERE data @> :criteria", DeleteQuery.byContains(tbl), "Delete query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,7 +80,7 @@ class DeleteTest {
|
|||||||
@DisplayName("byContains fails (SQLite)")
|
@DisplayName("byContains fails (SQLite)")
|
||||||
fun byContainsSQLite() {
|
fun byContainsSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
Configuration.dialectValue = Dialect.SQLITE
|
||||||
assertThrows<DocumentException> { Delete.byContains(tbl) }
|
assertThrows<DocumentException> { DeleteQuery.byContains(tbl) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -88,7 +88,7 @@ class DeleteTest {
|
|||||||
fun byJsonPathPostgres() {
|
fun byJsonPathPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"DELETE FROM $tbl WHERE jsonb_path_exists(data, :path::jsonpath)", Delete.byJsonPath(tbl),
|
"DELETE FROM $tbl WHERE jsonb_path_exists(data, :path::jsonpath)", DeleteQuery.byJsonPath(tbl),
|
||||||
"Delete query not constructed correctly"
|
"Delete query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -97,6 +97,6 @@ class DeleteTest {
|
|||||||
@DisplayName("byJsonPath fails (SQLite)")
|
@DisplayName("byJsonPath fails (SQLite)")
|
||||||
fun byJsonPathSQLite() {
|
fun byJsonPathSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
Configuration.dialectValue = Dialect.SQLITE
|
||||||
assertThrows<DocumentException> { Delete.byJsonPath(tbl) }
|
assertThrows<DocumentException> { DeleteQuery.byJsonPath(tbl) }
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -14,8 +14,8 @@ import kotlin.test.assertTrue
|
|||||||
/**
|
/**
|
||||||
* Unit tests for the `Document` object
|
* Unit tests for the `Document` object
|
||||||
*/
|
*/
|
||||||
@DisplayName("Kotlin | Common | Query: Document")
|
@DisplayName("JVM | Kotlin | Query | DocumentQuery")
|
||||||
class DocumentTest {
|
class DocumentQueryTest {
|
||||||
|
|
||||||
/** Test table name */
|
/** Test table name */
|
||||||
private val tbl = "test_table"
|
private val tbl = "test_table"
|
||||||
@ -32,14 +32,14 @@ class DocumentTest {
|
|||||||
@DisplayName("insert generates no auto ID (PostgreSQL)")
|
@DisplayName("insert generates no auto ID (PostgreSQL)")
|
||||||
fun insertNoAutoPostgres() {
|
fun insertNoAutoPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||||
assertEquals("INSERT INTO $tbl VALUES (:data)", Document.insert(tbl))
|
assertEquals("INSERT INTO $tbl VALUES (:data)", DocumentQuery.insert(tbl))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("insert generates no auto ID (SQLite)")
|
@DisplayName("insert generates no auto ID (SQLite)")
|
||||||
fun insertNoAutoSQLite() {
|
fun insertNoAutoSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
Configuration.dialectValue = Dialect.SQLITE
|
||||||
assertEquals("INSERT INTO $tbl VALUES (:data)", Document.insert(tbl))
|
assertEquals("INSERT INTO $tbl VALUES (:data)", DocumentQuery.insert(tbl))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -49,7 +49,7 @@ class DocumentTest {
|
|||||||
assertEquals(
|
assertEquals(
|
||||||
"INSERT INTO $tbl VALUES (:data::jsonb || ('{\"id\":' " +
|
"INSERT INTO $tbl VALUES (:data::jsonb || ('{\"id\":' " +
|
||||||
"|| (SELECT COALESCE(MAX((data->>'id')::numeric), 0) + 1 FROM $tbl) || '}')::jsonb)",
|
"|| (SELECT COALESCE(MAX((data->>'id')::numeric), 0) + 1 FROM $tbl) || '}')::jsonb)",
|
||||||
Document.insert(tbl, AutoId.NUMBER)
|
DocumentQuery.insert(tbl, AutoId.NUMBER)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ class DocumentTest {
|
|||||||
assertEquals(
|
assertEquals(
|
||||||
"INSERT INTO $tbl VALUES (json_set(:data, '$.id', " +
|
"INSERT INTO $tbl VALUES (json_set(:data, '$.id', " +
|
||||||
"(SELECT coalesce(max(data->>'id'), 0) + 1 FROM $tbl)))",
|
"(SELECT coalesce(max(data->>'id'), 0) + 1 FROM $tbl)))",
|
||||||
Document.insert(tbl, AutoId.NUMBER)
|
DocumentQuery.insert(tbl, AutoId.NUMBER)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ class DocumentTest {
|
|||||||
@DisplayName("insert generates auto UUID (PostgreSQL)")
|
@DisplayName("insert generates auto UUID (PostgreSQL)")
|
||||||
fun insertAutoUUIDPostgres() {
|
fun insertAutoUUIDPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||||
val query = Document.insert(tbl, AutoId.UUID)
|
val query = DocumentQuery.insert(tbl, AutoId.UUID)
|
||||||
assertTrue(
|
assertTrue(
|
||||||
query.startsWith("INSERT INTO $tbl VALUES (:data::jsonb || '{\"id\":\""),
|
query.startsWith("INSERT INTO $tbl VALUES (:data::jsonb || '{\"id\":\""),
|
||||||
"Query start not correct (actual: $query)"
|
"Query start not correct (actual: $query)"
|
||||||
@ -80,7 +80,7 @@ class DocumentTest {
|
|||||||
@DisplayName("insert generates auto UUID (SQLite)")
|
@DisplayName("insert generates auto UUID (SQLite)")
|
||||||
fun insertAutoUUIDSQLite() {
|
fun insertAutoUUIDSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
Configuration.dialectValue = Dialect.SQLITE
|
||||||
val query = Document.insert(tbl, AutoId.UUID)
|
val query = DocumentQuery.insert(tbl, AutoId.UUID)
|
||||||
assertTrue(
|
assertTrue(
|
||||||
query.startsWith("INSERT INTO $tbl VALUES (json_set(:data, '$.id', '"),
|
query.startsWith("INSERT INTO $tbl VALUES (json_set(:data, '$.id', '"),
|
||||||
"Query start not correct (actual: $query)"
|
"Query start not correct (actual: $query)"
|
||||||
@ -94,7 +94,7 @@ class DocumentTest {
|
|||||||
try {
|
try {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||||
Configuration.idStringLength = 8
|
Configuration.idStringLength = 8
|
||||||
val query = Document.insert(tbl, AutoId.RANDOM_STRING)
|
val query = DocumentQuery.insert(tbl, AutoId.RANDOM_STRING)
|
||||||
assertTrue(
|
assertTrue(
|
||||||
query.startsWith("INSERT INTO $tbl VALUES (:data::jsonb || '{\"id\":\""),
|
query.startsWith("INSERT INTO $tbl VALUES (:data::jsonb || '{\"id\":\""),
|
||||||
"Query start not correct (actual: $query)"
|
"Query start not correct (actual: $query)"
|
||||||
@ -114,7 +114,7 @@ class DocumentTest {
|
|||||||
@DisplayName("insert generates auto random string (SQLite)")
|
@DisplayName("insert generates auto random string (SQLite)")
|
||||||
fun insertAutoRandomSQLite() {
|
fun insertAutoRandomSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
Configuration.dialectValue = Dialect.SQLITE
|
||||||
val query = Document.insert(tbl, AutoId.RANDOM_STRING)
|
val query = DocumentQuery.insert(tbl, AutoId.RANDOM_STRING)
|
||||||
assertTrue(
|
assertTrue(
|
||||||
query.startsWith("INSERT INTO $tbl VALUES (json_set(:data, '$.id', '"),
|
query.startsWith("INSERT INTO $tbl VALUES (json_set(:data, '$.id', '"),
|
||||||
"Query start not correct (actual: $query)"
|
"Query start not correct (actual: $query)"
|
||||||
@ -130,7 +130,7 @@ class DocumentTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("insert fails when no dialect is set")
|
@DisplayName("insert fails when no dialect is set")
|
||||||
fun insertFailsUnknown() {
|
fun insertFailsUnknown() {
|
||||||
assertThrows<DocumentException> { Document.insert(tbl) }
|
assertThrows<DocumentException> { DocumentQuery.insert(tbl) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -139,12 +139,12 @@ class DocumentTest {
|
|||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"INSERT INTO $tbl VALUES (:data) ON CONFLICT ((data->>'id')) DO UPDATE SET data = EXCLUDED.data",
|
"INSERT INTO $tbl VALUES (:data) ON CONFLICT ((data->>'id')) DO UPDATE SET data = EXCLUDED.data",
|
||||||
Document.save(tbl), "INSERT ON CONFLICT UPDATE statement not constructed correctly"
|
DocumentQuery.save(tbl), "INSERT ON CONFLICT UPDATE statement not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("update generates successfully")
|
@DisplayName("update generates successfully")
|
||||||
fun update() =
|
fun update() =
|
||||||
assertEquals("UPDATE $tbl SET data = :data", Document.update(tbl), "Update query not constructed correctly")
|
assertEquals("UPDATE $tbl SET data = :data", DocumentQuery.update(tbl), "Update query not constructed correctly")
|
||||||
}
|
}
|
@ -14,7 +14,7 @@ import kotlin.test.assertEquals
|
|||||||
* Unit tests for the `Exists` object
|
* Unit tests for the `Exists` object
|
||||||
*/
|
*/
|
||||||
@DisplayName("Kotlin | Common | Query: Exists")
|
@DisplayName("Kotlin | Common | Query: Exists")
|
||||||
class ExistsTest {
|
class ExistsQueryTest {
|
||||||
|
|
||||||
/** Test table name */
|
/** Test table name */
|
||||||
private val tbl = "test_table"
|
private val tbl = "test_table"
|
||||||
@ -33,7 +33,7 @@ class ExistsTest {
|
|||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"SELECT EXISTS (SELECT 1 FROM $tbl WHERE data->>'id' = :id) AS it",
|
"SELECT EXISTS (SELECT 1 FROM $tbl WHERE data->>'id' = :id) AS it",
|
||||||
Exists.byId<String>(tbl), "Exists query not constructed correctly"
|
ExistsQuery.byId<String>(tbl), "Exists query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ class ExistsTest {
|
|||||||
Configuration.dialectValue = Dialect.SQLITE
|
Configuration.dialectValue = Dialect.SQLITE
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"SELECT EXISTS (SELECT 1 FROM $tbl WHERE data->>'id' = :id) AS it",
|
"SELECT EXISTS (SELECT 1 FROM $tbl WHERE data->>'id' = :id) AS it",
|
||||||
Exists.byId<String>(tbl), "Exists query not constructed correctly"
|
ExistsQuery.byId<String>(tbl), "Exists query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ class ExistsTest {
|
|||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"SELECT EXISTS (SELECT 1 FROM $tbl WHERE (data->>'it')::numeric = :test) AS it",
|
"SELECT EXISTS (SELECT 1 FROM $tbl WHERE (data->>'it')::numeric = :test) AS it",
|
||||||
Exists.byFields(tbl, listOf(Field.equal("it", 7, ":test"))),
|
ExistsQuery.byFields(tbl, listOf(Field.equal("it", 7, ":test"))),
|
||||||
"Exists query not constructed correctly"
|
"Exists query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -64,7 +64,7 @@ class ExistsTest {
|
|||||||
Configuration.dialectValue = Dialect.SQLITE
|
Configuration.dialectValue = Dialect.SQLITE
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"SELECT EXISTS (SELECT 1 FROM $tbl WHERE data->>'it' = :test) AS it",
|
"SELECT EXISTS (SELECT 1 FROM $tbl WHERE data->>'it' = :test) AS it",
|
||||||
Exists.byFields(tbl, listOf(Field.equal("it", 7, ":test"))),
|
ExistsQuery.byFields(tbl, listOf(Field.equal("it", 7, ":test"))),
|
||||||
"Exists query not constructed correctly"
|
"Exists query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -74,7 +74,7 @@ class ExistsTest {
|
|||||||
fun byContainsPostgres() {
|
fun byContainsPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"SELECT EXISTS (SELECT 1 FROM $tbl WHERE data @> :criteria) AS it", Exists.byContains(tbl),
|
"SELECT EXISTS (SELECT 1 FROM $tbl WHERE data @> :criteria) AS it", ExistsQuery.byContains(tbl),
|
||||||
"Exists query not constructed correctly"
|
"Exists query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -83,7 +83,7 @@ class ExistsTest {
|
|||||||
@DisplayName("byContains fails (SQLite)")
|
@DisplayName("byContains fails (SQLite)")
|
||||||
fun byContainsSQLite() {
|
fun byContainsSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
Configuration.dialectValue = Dialect.SQLITE
|
||||||
assertThrows<DocumentException> { Exists.byContains(tbl) }
|
assertThrows<DocumentException> { ExistsQuery.byContains(tbl) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -92,7 +92,7 @@ class ExistsTest {
|
|||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"SELECT EXISTS (SELECT 1 FROM $tbl WHERE jsonb_path_exists(data, :path::jsonpath)) AS it",
|
"SELECT EXISTS (SELECT 1 FROM $tbl WHERE jsonb_path_exists(data, :path::jsonpath)) AS it",
|
||||||
Exists.byJsonPath(tbl), "Exists query not constructed correctly"
|
ExistsQuery.byJsonPath(tbl), "Exists query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,6 +100,6 @@ class ExistsTest {
|
|||||||
@DisplayName("byJsonPath fails (SQLite)")
|
@DisplayName("byJsonPath fails (SQLite)")
|
||||||
fun byJsonPathSQLite() {
|
fun byJsonPathSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
Configuration.dialectValue = Dialect.SQLITE
|
||||||
assertThrows<DocumentException> { Exists.byJsonPath(tbl) }
|
assertThrows<DocumentException> { ExistsQuery.byJsonPath(tbl) }
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -8,16 +8,14 @@ import solutions.bitbadger.documents.Configuration
|
|||||||
import solutions.bitbadger.documents.Dialect
|
import solutions.bitbadger.documents.Dialect
|
||||||
import solutions.bitbadger.documents.DocumentException
|
import solutions.bitbadger.documents.DocumentException
|
||||||
import solutions.bitbadger.documents.Field
|
import solutions.bitbadger.documents.Field
|
||||||
|
import solutions.bitbadger.documents.support.TEST_TABLE
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for the `Find` object
|
* Unit tests for the `Find` object
|
||||||
*/
|
*/
|
||||||
@DisplayName("Kotlin | Common | Query: Find")
|
@DisplayName("JVM | Kotlin | Query | FindQuery")
|
||||||
class FindTest {
|
class FindQueryTest {
|
||||||
|
|
||||||
/** Test table name */
|
|
||||||
private val tbl = "test_table"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear the connection string (resets Dialect)
|
* Clear the connection string (resets Dialect)
|
||||||
@ -30,15 +28,15 @@ class FindTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("all generates correctly")
|
@DisplayName("all generates correctly")
|
||||||
fun all() =
|
fun all() =
|
||||||
assertEquals("SELECT data FROM $tbl", Find.all(tbl), "Find query not constructed correctly")
|
assertEquals("SELECT data FROM $TEST_TABLE", FindQuery.all(TEST_TABLE), "Find query not constructed correctly")
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("byId generates correctly (PostgreSQL)")
|
@DisplayName("byId generates correctly (PostgreSQL)")
|
||||||
fun byIdPostgres() {
|
fun byIdPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"SELECT data FROM $tbl WHERE data->>'id' = :id",
|
"SELECT data FROM $TEST_TABLE WHERE data->>'id' = :id",
|
||||||
Find.byId<String>(tbl), "Find query not constructed correctly"
|
FindQuery.byId<String>(TEST_TABLE), "Find query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,8 +45,8 @@ class FindTest {
|
|||||||
fun byIdSQLite() {
|
fun byIdSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
Configuration.dialectValue = Dialect.SQLITE
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"SELECT data FROM $tbl WHERE data->>'id' = :id",
|
"SELECT data FROM $TEST_TABLE WHERE data->>'id' = :id",
|
||||||
Find.byId<String>(tbl), "Find query not constructed correctly"
|
FindQuery.byId<String>(TEST_TABLE), "Find query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,8 +55,8 @@ class FindTest {
|
|||||||
fun byFieldsPostgres() {
|
fun byFieldsPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"SELECT data FROM $tbl WHERE data->>'a' = :b AND (data->>'c')::numeric < :d",
|
"SELECT data FROM $TEST_TABLE WHERE data->>'a' = :b AND (data->>'c')::numeric < :d",
|
||||||
Find.byFields(tbl, listOf(Field.equal("a", "", ":b"), Field.less("c", 14, ":d"))),
|
FindQuery.byFields(TEST_TABLE, listOf(Field.equal("a", "", ":b"), Field.less("c", 14, ":d"))),
|
||||||
"Find query not constructed correctly"
|
"Find query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -68,8 +66,8 @@ class FindTest {
|
|||||||
fun byFieldsSQLite() {
|
fun byFieldsSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
Configuration.dialectValue = Dialect.SQLITE
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"SELECT data FROM $tbl WHERE data->>'a' = :b AND data->>'c' < :d",
|
"SELECT data FROM $TEST_TABLE WHERE data->>'a' = :b AND data->>'c' < :d",
|
||||||
Find.byFields(tbl, listOf(Field.equal("a", "", ":b"), Field.less("c", 14, ":d"))),
|
FindQuery.byFields(TEST_TABLE, listOf(Field.equal("a", "", ":b"), Field.less("c", 14, ":d"))),
|
||||||
"Find query not constructed correctly"
|
"Find query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -79,7 +77,7 @@ class FindTest {
|
|||||||
fun byContainsPostgres() {
|
fun byContainsPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"SELECT data FROM $tbl WHERE data @> :criteria", Find.byContains(tbl),
|
"SELECT data FROM $TEST_TABLE WHERE data @> :criteria", FindQuery.byContains(TEST_TABLE),
|
||||||
"Find query not constructed correctly"
|
"Find query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -88,7 +86,7 @@ class FindTest {
|
|||||||
@DisplayName("byContains fails (SQLite)")
|
@DisplayName("byContains fails (SQLite)")
|
||||||
fun byContainsSQLite() {
|
fun byContainsSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
Configuration.dialectValue = Dialect.SQLITE
|
||||||
assertThrows<DocumentException> { Find.byContains(tbl) }
|
assertThrows<DocumentException> { FindQuery.byContains(TEST_TABLE) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -96,7 +94,8 @@ class FindTest {
|
|||||||
fun byJsonPathPostgres() {
|
fun byJsonPathPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"SELECT data FROM $tbl WHERE jsonb_path_exists(data, :path::jsonpath)", Find.byJsonPath(tbl),
|
"SELECT data FROM $TEST_TABLE WHERE jsonb_path_exists(data, :path::jsonpath)",
|
||||||
|
FindQuery.byJsonPath(TEST_TABLE),
|
||||||
"Find query not constructed correctly"
|
"Find query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -105,6 +104,6 @@ class FindTest {
|
|||||||
@DisplayName("byJsonPath fails (SQLite)")
|
@DisplayName("byJsonPath fails (SQLite)")
|
||||||
fun byJsonPathSQLite() {
|
fun byJsonPathSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
Configuration.dialectValue = Dialect.SQLITE
|
||||||
assertThrows<DocumentException> { Find.byJsonPath(tbl) }
|
assertThrows<DocumentException> { FindQuery.byJsonPath(TEST_TABLE) }
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -13,8 +13,8 @@ import kotlin.test.assertEquals
|
|||||||
/**
|
/**
|
||||||
* Unit tests for the `Patch` object
|
* Unit tests for the `Patch` object
|
||||||
*/
|
*/
|
||||||
@DisplayName("Kotlin | Common | Query: Patch")
|
@DisplayName("JVM | Kotlin | Query | PatchQuery")
|
||||||
class PatchTest {
|
class PatchQueryTest {
|
||||||
|
|
||||||
/** Test table name */
|
/** Test table name */
|
||||||
private val tbl = "test_table"
|
private val tbl = "test_table"
|
||||||
@ -33,7 +33,7 @@ class PatchTest {
|
|||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"UPDATE $tbl SET data = data || :data WHERE data->>'id' = :id",
|
"UPDATE $tbl SET data = data || :data WHERE data->>'id' = :id",
|
||||||
Patch.byId<String>(tbl), "Patch query not constructed correctly"
|
PatchQuery.byId<String>(tbl), "Patch query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ class PatchTest {
|
|||||||
Configuration.dialectValue = Dialect.SQLITE
|
Configuration.dialectValue = Dialect.SQLITE
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"UPDATE $tbl SET data = json_patch(data, json(:data)) WHERE data->>'id' = :id",
|
"UPDATE $tbl SET data = json_patch(data, json(:data)) WHERE data->>'id' = :id",
|
||||||
Patch.byId<String>(tbl), "Patch query not constructed correctly"
|
PatchQuery.byId<String>(tbl), "Patch query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ class PatchTest {
|
|||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"UPDATE $tbl SET data = data || :data WHERE data->>'z' = :y",
|
"UPDATE $tbl SET data = data || :data WHERE data->>'z' = :y",
|
||||||
Patch.byFields(tbl, listOf(Field.equal("z", "", ":y"))),
|
PatchQuery.byFields(tbl, listOf(Field.equal("z", "", ":y"))),
|
||||||
"Patch query not constructed correctly"
|
"Patch query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -64,7 +64,7 @@ class PatchTest {
|
|||||||
Configuration.dialectValue = Dialect.SQLITE
|
Configuration.dialectValue = Dialect.SQLITE
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"UPDATE $tbl SET data = json_patch(data, json(:data)) WHERE data->>'z' = :y",
|
"UPDATE $tbl SET data = json_patch(data, json(:data)) WHERE data->>'z' = :y",
|
||||||
Patch.byFields(tbl, listOf(Field.equal("z", "", ":y"))),
|
PatchQuery.byFields(tbl, listOf(Field.equal("z", "", ":y"))),
|
||||||
"Patch query not constructed correctly"
|
"Patch query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -74,7 +74,7 @@ class PatchTest {
|
|||||||
fun byContainsPostgres() {
|
fun byContainsPostgres() {
|
||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"UPDATE $tbl SET data = data || :data WHERE data @> :criteria", Patch.byContains(tbl),
|
"UPDATE $tbl SET data = data || :data WHERE data @> :criteria", PatchQuery.byContains(tbl),
|
||||||
"Patch query not constructed correctly"
|
"Patch query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -83,7 +83,7 @@ class PatchTest {
|
|||||||
@DisplayName("byContains fails (SQLite)")
|
@DisplayName("byContains fails (SQLite)")
|
||||||
fun byContainsSQLite() {
|
fun byContainsSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
Configuration.dialectValue = Dialect.SQLITE
|
||||||
assertThrows<DocumentException> { Patch.byContains(tbl) }
|
assertThrows<DocumentException> { PatchQuery.byContains(tbl) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -92,7 +92,7 @@ class PatchTest {
|
|||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"UPDATE $tbl SET data = data || :data WHERE jsonb_path_exists(data, :path::jsonpath)",
|
"UPDATE $tbl SET data = data || :data WHERE jsonb_path_exists(data, :path::jsonpath)",
|
||||||
Patch.byJsonPath(tbl), "Patch query not constructed correctly"
|
PatchQuery.byJsonPath(tbl), "Patch query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,6 +100,6 @@ class PatchTest {
|
|||||||
@DisplayName("byJsonPath fails (SQLite)")
|
@DisplayName("byJsonPath fails (SQLite)")
|
||||||
fun byJsonPathSQLite() {
|
fun byJsonPathSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
Configuration.dialectValue = Dialect.SQLITE
|
||||||
assertThrows<DocumentException> { Patch.byJsonPath(tbl) }
|
assertThrows<DocumentException> { PatchQuery.byJsonPath(tbl) }
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -10,9 +10,9 @@ import solutions.bitbadger.documents.FieldMatch
|
|||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for the top-level query functions
|
* Unit tests for the package-level query functions
|
||||||
*/
|
*/
|
||||||
@DisplayName("Kotlin | Common | Query")
|
@DisplayName("JVM | Kotlin | Query | Package Functions")
|
||||||
class QueryTest {
|
class QueryTest {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -10,8 +10,8 @@ import kotlin.test.assertEquals
|
|||||||
/**
|
/**
|
||||||
* Unit tests for the `RemoveFields` object
|
* Unit tests for the `RemoveFields` object
|
||||||
*/
|
*/
|
||||||
@DisplayName("Kotlin | Common | Query: RemoveFields")
|
@DisplayName("JVM | Kotlin | Query | RemoveFieldsQuery")
|
||||||
class RemoveFieldsTest {
|
class RemoveFieldsQueryTest {
|
||||||
|
|
||||||
/** Test table name */
|
/** Test table name */
|
||||||
private val tbl = "test_table"
|
private val tbl = "test_table"
|
||||||
@ -30,7 +30,7 @@ class RemoveFieldsTest {
|
|||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"UPDATE $tbl SET data = data - :name::text[] WHERE data->>'id' = :id",
|
"UPDATE $tbl SET data = data - :name::text[] WHERE data->>'id' = :id",
|
||||||
RemoveFields.byId<String>(tbl, listOf(Parameter(":name", ParameterType.STRING, "{a,z}"))),
|
RemoveFieldsQuery.byId<String>(tbl, listOf(Parameter(":name", ParameterType.STRING, "{a,z}"))),
|
||||||
"Remove Fields query not constructed correctly"
|
"Remove Fields query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -41,7 +41,7 @@ class RemoveFieldsTest {
|
|||||||
Configuration.dialectValue = Dialect.SQLITE
|
Configuration.dialectValue = Dialect.SQLITE
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"UPDATE $tbl SET data = json_remove(data, :name0, :name1) WHERE data->>'id' = :id",
|
"UPDATE $tbl SET data = json_remove(data, :name0, :name1) WHERE data->>'id' = :id",
|
||||||
RemoveFields.byId<String>(
|
RemoveFieldsQuery.byId<String>(
|
||||||
tbl,
|
tbl,
|
||||||
listOf(
|
listOf(
|
||||||
Parameter(":name0", ParameterType.STRING, "a"),
|
Parameter(":name0", ParameterType.STRING, "a"),
|
||||||
@ -58,7 +58,7 @@ class RemoveFieldsTest {
|
|||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"UPDATE $tbl SET data = data - :name::text[] WHERE data->>'f' > :g",
|
"UPDATE $tbl SET data = data - :name::text[] WHERE data->>'f' > :g",
|
||||||
RemoveFields.byFields(
|
RemoveFieldsQuery.byFields(
|
||||||
tbl,
|
tbl,
|
||||||
listOf(Parameter(":name", ParameterType.STRING, "{b,c}")),
|
listOf(Parameter(":name", ParameterType.STRING, "{b,c}")),
|
||||||
listOf(Field.greater("f", "", ":g"))
|
listOf(Field.greater("f", "", ":g"))
|
||||||
@ -73,7 +73,7 @@ class RemoveFieldsTest {
|
|||||||
Configuration.dialectValue = Dialect.SQLITE
|
Configuration.dialectValue = Dialect.SQLITE
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"UPDATE $tbl SET data = json_remove(data, :name0, :name1) WHERE data->>'f' > :g",
|
"UPDATE $tbl SET data = json_remove(data, :name0, :name1) WHERE data->>'f' > :g",
|
||||||
RemoveFields.byFields(
|
RemoveFieldsQuery.byFields(
|
||||||
tbl,
|
tbl,
|
||||||
listOf(Parameter(":name0", ParameterType.STRING, "b"), Parameter(":name1", ParameterType.STRING, "c")),
|
listOf(Parameter(":name0", ParameterType.STRING, "b"), Parameter(":name1", ParameterType.STRING, "c")),
|
||||||
listOf(Field.greater("f", "", ":g"))
|
listOf(Field.greater("f", "", ":g"))
|
||||||
@ -88,7 +88,7 @@ class RemoveFieldsTest {
|
|||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"UPDATE $tbl SET data = data - :name::text[] WHERE data @> :criteria",
|
"UPDATE $tbl SET data = data - :name::text[] WHERE data @> :criteria",
|
||||||
RemoveFields.byContains(tbl, listOf(Parameter(":name", ParameterType.STRING, "{m,n}"))),
|
RemoveFieldsQuery.byContains(tbl, listOf(Parameter(":name", ParameterType.STRING, "{m,n}"))),
|
||||||
"Remove Field query not constructed correctly"
|
"Remove Field query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -97,7 +97,7 @@ class RemoveFieldsTest {
|
|||||||
@DisplayName("byContains fails (SQLite)")
|
@DisplayName("byContains fails (SQLite)")
|
||||||
fun byContainsSQLite() {
|
fun byContainsSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
Configuration.dialectValue = Dialect.SQLITE
|
||||||
assertThrows<DocumentException> { RemoveFields.byContains(tbl, listOf()) }
|
assertThrows<DocumentException> { RemoveFieldsQuery.byContains(tbl, listOf()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -106,7 +106,7 @@ class RemoveFieldsTest {
|
|||||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"UPDATE $tbl SET data = data - :name::text[] WHERE jsonb_path_exists(data, :path::jsonpath)",
|
"UPDATE $tbl SET data = data - :name::text[] WHERE jsonb_path_exists(data, :path::jsonpath)",
|
||||||
RemoveFields.byJsonPath(tbl, listOf(Parameter(":name", ParameterType.STRING, "{o,p}"))),
|
RemoveFieldsQuery.byJsonPath(tbl, listOf(Parameter(":name", ParameterType.STRING, "{o,p}"))),
|
||||||
"Remove Field query not constructed correctly"
|
"Remove Field query not constructed correctly"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -115,6 +115,6 @@ class RemoveFieldsTest {
|
|||||||
@DisplayName("byJsonPath fails (SQLite)")
|
@DisplayName("byJsonPath fails (SQLite)")
|
||||||
fun byJsonPathSQLite() {
|
fun byJsonPathSQLite() {
|
||||||
Configuration.dialectValue = Dialect.SQLITE
|
Configuration.dialectValue = Dialect.SQLITE
|
||||||
assertThrows<DocumentException> { RemoveFields.byJsonPath(tbl, listOf()) }
|
assertThrows<DocumentException> { RemoveFieldsQuery.byJsonPath(tbl, listOf()) }
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -10,7 +10,7 @@ import kotlin.test.assertEquals
|
|||||||
/**
|
/**
|
||||||
* Unit tests for the `Where` object
|
* Unit tests for the `Where` object
|
||||||
*/
|
*/
|
||||||
@DisplayName("Kotlin | Common | Query: Where")
|
@DisplayName("JVM | Kotlin | Query | Where")
|
||||||
class WhereTest {
|
class WhereTest {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,22 +1,18 @@
|
|||||||
package solutions.bitbadger.documents.support
|
package solutions.bitbadger.documents.support
|
||||||
|
|
||||||
import kotlinx.serialization.Serializable
|
|
||||||
import solutions.bitbadger.documents.extensions.insert
|
import solutions.bitbadger.documents.extensions.insert
|
||||||
|
|
||||||
/** The test table name to use for integration tests */
|
/** The test table name to use for integration tests */
|
||||||
const val TEST_TABLE = "test_table"
|
const val TEST_TABLE = "test_table"
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class NumIdDocument(val key: Int, val text: String) {
|
data class NumIdDocument(val key: Int, val text: String) {
|
||||||
constructor() : this(0, "")
|
constructor() : this(0, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class SubDocument(val foo: String, val bar: String) {
|
data class SubDocument(val foo: String, val bar: String) {
|
||||||
constructor() : this("", "")
|
constructor() : this("", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class ArrayDocument(val id: String, val values: List<String>) {
|
data class ArrayDocument(val id: String, val values: List<String>) {
|
||||||
|
|
||||||
constructor() : this("", listOf())
|
constructor() : this("", listOf())
|
||||||
@ -31,7 +27,6 @@ data class ArrayDocument(val id: String, val values: List<String>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class JsonDocument(val id: String, val value: String = "", val numValue: Int = 0, val sub: SubDocument? = null) {
|
data class JsonDocument(val id: String, val value: String = "", val numValue: Int = 0, val sub: SubDocument? = null) {
|
||||||
|
|
||||||
constructor() : this("")
|
constructor() : this("")
|
||||||
@ -50,3 +45,11 @@ data class JsonDocument(val id: String, val value: String = "", val numValue: In
|
|||||||
testDocuments.forEach { db.conn.insert(tableName, it) }
|
testDocuments.forEach { db.conn.insert(tableName, it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test classes for AutoId generation
|
||||||
|
|
||||||
|
data class ByteIdClass(val id: Byte)
|
||||||
|
data class ShortIdClass(val id: Short)
|
||||||
|
data class IntIdClass(val id: Int)
|
||||||
|
data class LongIdClass(val id: Long)
|
||||||
|
data class StringIdClass(val id: String)
|
||||||
|
@ -30,8 +30,6 @@
|
|||||||
<groupId>solutions.bitbadger.documents</groupId>
|
<groupId>solutions.bitbadger.documents</groupId>
|
||||||
<artifactId>jvm</artifactId>
|
<artifactId>jvm</artifactId>
|
||||||
<version>4.0.0-alpha1-SNAPSHOT</version>
|
<version>4.0.0-alpha1-SNAPSHOT</version>
|
||||||
<scope>system</scope>
|
|
||||||
<systemPath>${project.basedir}/../jvm/target/jvm-4.0.0-alpha1-SNAPSHOT.jar</systemPath>
|
|
||||||
<type>jar</type>
|
<type>jar</type>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
@ -2,7 +2,7 @@ package solutions.bitbadger.documents.kotlin
|
|||||||
|
|
||||||
import solutions.bitbadger.documents.*
|
import solutions.bitbadger.documents.*
|
||||||
import solutions.bitbadger.documents.kotlin.extensions.*
|
import solutions.bitbadger.documents.kotlin.extensions.*
|
||||||
import solutions.bitbadger.documents.query.Count
|
import solutions.bitbadger.documents.query.CountQuery
|
||||||
|
|
||||||
import java.sql.Connection
|
import java.sql.Connection
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ object Count {
|
|||||||
* @return A count of the documents in the table
|
* @return A count of the documents in the table
|
||||||
*/
|
*/
|
||||||
fun all(tableName: String, conn: Connection) =
|
fun all(tableName: String, conn: Connection) =
|
||||||
conn.customScalar(Count.all(tableName), mapFunc = Results::toCount)
|
conn.customScalar(CountQuery.all(tableName), mapFunc = Results::toCount)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Count all documents in the table
|
* Count all documents in the table
|
||||||
@ -47,7 +47,7 @@ object Count {
|
|||||||
): Long {
|
): Long {
|
||||||
val named = Parameters.nameFields(fields)
|
val named = Parameters.nameFields(fields)
|
||||||
return conn.customScalar(
|
return conn.customScalar(
|
||||||
Count.byFields(tableName, named, howMatched),
|
CountQuery.byFields(tableName, named, howMatched),
|
||||||
Parameters.addFields(named),
|
Parameters.addFields(named),
|
||||||
Results::toCount
|
Results::toCount
|
||||||
)
|
)
|
||||||
@ -74,7 +74,7 @@ object Count {
|
|||||||
* @throws DocumentException If called on a SQLite connection
|
* @throws DocumentException If called on a SQLite connection
|
||||||
*/
|
*/
|
||||||
inline fun <reified TContains> byContains(tableName: String, criteria: TContains, conn: Connection) =
|
inline fun <reified TContains> byContains(tableName: String, criteria: TContains, conn: Connection) =
|
||||||
conn.customScalar(Count.byContains(tableName), listOf(Parameters.json(":criteria", criteria)), Results::toCount)
|
conn.customScalar(CountQuery.byContains(tableName), listOf(Parameters.json(":criteria", criteria)), Results::toCount)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Count documents using a JSON containment query (PostgreSQL only)
|
* Count documents using a JSON containment query (PostgreSQL only)
|
||||||
@ -98,7 +98,7 @@ object Count {
|
|||||||
*/
|
*/
|
||||||
fun byJsonPath(tableName: String, path: String, conn: Connection) =
|
fun byJsonPath(tableName: String, path: String, conn: Connection) =
|
||||||
conn.customScalar(
|
conn.customScalar(
|
||||||
Count.byJsonPath(tableName),
|
CountQuery.byJsonPath(tableName),
|
||||||
listOf(Parameter(":path", ParameterType.STRING, path)),
|
listOf(Parameter(":path", ParameterType.STRING, path)),
|
||||||
Results::toCount
|
Results::toCount
|
||||||
)
|
)
|
||||||
|
@ -3,7 +3,7 @@ package solutions.bitbadger.documents.kotlin
|
|||||||
import solutions.bitbadger.documents.*
|
import solutions.bitbadger.documents.*
|
||||||
import solutions.bitbadger.documents.jvm.Delete as JvmDelete
|
import solutions.bitbadger.documents.jvm.Delete as JvmDelete
|
||||||
import solutions.bitbadger.documents.kotlin.extensions.*
|
import solutions.bitbadger.documents.kotlin.extensions.*
|
||||||
import solutions.bitbadger.documents.query.Delete
|
import solutions.bitbadger.documents.query.DeleteQuery
|
||||||
import java.sql.Connection
|
import java.sql.Connection
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -60,7 +60,7 @@ object Delete {
|
|||||||
* @throws DocumentException If called on a SQLite connection
|
* @throws DocumentException If called on a SQLite connection
|
||||||
*/
|
*/
|
||||||
inline fun <reified TContains> byContains(tableName: String, criteria: TContains, conn: Connection) =
|
inline fun <reified TContains> byContains(tableName: String, criteria: TContains, conn: Connection) =
|
||||||
conn.customNonQuery(Delete.byContains(tableName), listOf(Parameters.json(":criteria", criteria)))
|
conn.customNonQuery(DeleteQuery.byContains(tableName), listOf(Parameters.json(":criteria", criteria)))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete documents using a JSON containment query (PostgreSQL only)
|
* Delete documents using a JSON containment query (PostgreSQL only)
|
||||||
|
@ -5,7 +5,7 @@ import solutions.bitbadger.documents.Configuration
|
|||||||
import solutions.bitbadger.documents.Dialect
|
import solutions.bitbadger.documents.Dialect
|
||||||
import solutions.bitbadger.documents.Field
|
import solutions.bitbadger.documents.Field
|
||||||
import solutions.bitbadger.documents.extensions.customNonQuery
|
import solutions.bitbadger.documents.extensions.customNonQuery
|
||||||
import solutions.bitbadger.documents.query.Document
|
import solutions.bitbadger.documents.query.DocumentQuery
|
||||||
import solutions.bitbadger.documents.query.Where
|
import solutions.bitbadger.documents.query.Where
|
||||||
import solutions.bitbadger.documents.query.statementWhere
|
import solutions.bitbadger.documents.query.statementWhere
|
||||||
import java.sql.Connection
|
import java.sql.Connection
|
||||||
@ -25,7 +25,7 @@ object Document {
|
|||||||
inline fun <reified TDoc> insert(tableName: String, document: TDoc, conn: Connection) {
|
inline fun <reified TDoc> insert(tableName: String, document: TDoc, conn: Connection) {
|
||||||
val strategy = Configuration.autoIdStrategy
|
val strategy = Configuration.autoIdStrategy
|
||||||
val query = if (strategy == AutoId.DISABLED) {
|
val query = if (strategy == AutoId.DISABLED) {
|
||||||
Document.insert(tableName)
|
DocumentQuery.insert(tableName)
|
||||||
} else {
|
} else {
|
||||||
val idField = Configuration.idField
|
val idField = Configuration.idField
|
||||||
val dialect = Configuration.dialect("Create auto-ID insert query")
|
val dialect = Configuration.dialect("Create auto-ID insert query")
|
||||||
@ -52,7 +52,7 @@ object Document {
|
|||||||
":data"
|
":data"
|
||||||
}
|
}
|
||||||
|
|
||||||
Document.insert(tableName).replace(":data", dataParam)
|
DocumentQuery.insert(tableName).replace(":data", dataParam)
|
||||||
}
|
}
|
||||||
conn.customNonQuery(query, listOf(Parameters.json(":data", document)))
|
conn.customNonQuery(query, listOf(Parameters.json(":data", document)))
|
||||||
}
|
}
|
||||||
@ -74,7 +74,7 @@ object Document {
|
|||||||
* @param conn The connection on which the query should be executed
|
* @param conn The connection on which the query should be executed
|
||||||
*/
|
*/
|
||||||
inline fun <reified TDoc> save(tableName: String, document: TDoc, conn: Connection) =
|
inline fun <reified TDoc> save(tableName: String, document: TDoc, conn: Connection) =
|
||||||
conn.customNonQuery(Document.save(tableName), listOf(Parameters.json(":data", document)))
|
conn.customNonQuery(DocumentQuery.save(tableName), listOf(Parameters.json(":data", document)))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save a document, inserting it if it does not exist and updating it if it does (AKA "upsert")
|
* Save a document, inserting it if it does not exist and updating it if it does (AKA "upsert")
|
||||||
@ -95,7 +95,7 @@ object Document {
|
|||||||
*/
|
*/
|
||||||
inline fun <TKey, reified TDoc> update(tableName: String, docId: TKey, document: TDoc, conn: Connection) =
|
inline fun <TKey, reified TDoc> update(tableName: String, docId: TKey, document: TDoc, conn: Connection) =
|
||||||
conn.customNonQuery(
|
conn.customNonQuery(
|
||||||
statementWhere(Document.update(tableName), Where.byId(":id", docId)),
|
statementWhere(DocumentQuery.update(tableName), Where.byId(":id", docId)),
|
||||||
Parameters.addFields(
|
Parameters.addFields(
|
||||||
listOf(Field.equal(Configuration.idField, docId, ":id")),
|
listOf(Field.equal(Configuration.idField, docId, ":id")),
|
||||||
mutableListOf(Parameters.json(":data", document))
|
mutableListOf(Parameters.json(":data", document))
|
||||||
|
@ -3,7 +3,7 @@ package solutions.bitbadger.documents.kotlin
|
|||||||
import solutions.bitbadger.documents.*
|
import solutions.bitbadger.documents.*
|
||||||
import solutions.bitbadger.documents.jvm.Exists as JvmExists
|
import solutions.bitbadger.documents.jvm.Exists as JvmExists
|
||||||
import solutions.bitbadger.documents.kotlin.extensions.*
|
import solutions.bitbadger.documents.kotlin.extensions.*
|
||||||
import solutions.bitbadger.documents.query.Exists
|
import solutions.bitbadger.documents.query.ExistsQuery
|
||||||
import java.sql.Connection
|
import java.sql.Connection
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -66,7 +66,7 @@ object Exists {
|
|||||||
*/
|
*/
|
||||||
inline fun <reified TContains> byContains(tableName: String, criteria: TContains, conn: Connection) =
|
inline fun <reified TContains> byContains(tableName: String, criteria: TContains, conn: Connection) =
|
||||||
conn.customScalar(
|
conn.customScalar(
|
||||||
Exists.byContains(tableName),
|
ExistsQuery.byContains(tableName),
|
||||||
listOf(Parameters.json(":criteria", criteria)),
|
listOf(Parameters.json(":criteria", criteria)),
|
||||||
Results::toExists
|
Results::toExists
|
||||||
)
|
)
|
||||||
|
@ -2,7 +2,7 @@ package solutions.bitbadger.documents.kotlin
|
|||||||
|
|
||||||
import solutions.bitbadger.documents.*
|
import solutions.bitbadger.documents.*
|
||||||
import solutions.bitbadger.documents.kotlin.extensions.*
|
import solutions.bitbadger.documents.kotlin.extensions.*
|
||||||
import solutions.bitbadger.documents.query.Find
|
import solutions.bitbadger.documents.query.FindQuery
|
||||||
import solutions.bitbadger.documents.query.orderBy
|
import solutions.bitbadger.documents.query.orderBy
|
||||||
import java.sql.Connection
|
import java.sql.Connection
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ object Find {
|
|||||||
* @return A list of documents from the given table
|
* @return A list of documents from the given table
|
||||||
*/
|
*/
|
||||||
inline fun <reified TDoc : Any> all(tableName: String, orderBy: Collection<Field<*>>? = null, conn: Connection) =
|
inline fun <reified TDoc : Any> all(tableName: String, orderBy: Collection<Field<*>>? = null, conn: Connection) =
|
||||||
conn.customList<TDoc>(Find.all(tableName) + (orderBy?.let(::orderBy) ?: ""), mapFunc = Results::fromData)
|
conn.customList<TDoc>(FindQuery.all(tableName) + (orderBy?.let(::orderBy) ?: ""), mapFunc = Results::fromData)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve all documents in the given table
|
* Retrieve all documents in the given table
|
||||||
@ -52,7 +52,7 @@ object Find {
|
|||||||
*/
|
*/
|
||||||
inline fun <TKey, reified TDoc : Any> byId(tableName: String, docId: TKey, conn: Connection) =
|
inline fun <TKey, reified TDoc : Any> byId(tableName: String, docId: TKey, conn: Connection) =
|
||||||
conn.customSingle<TDoc>(
|
conn.customSingle<TDoc>(
|
||||||
Find.byId(tableName, docId),
|
FindQuery.byId(tableName, docId),
|
||||||
Parameters.addFields(listOf(Field.equal(Configuration.idField, docId, ":id"))),
|
Parameters.addFields(listOf(Field.equal(Configuration.idField, docId, ":id"))),
|
||||||
Results::fromData
|
Results::fromData
|
||||||
)
|
)
|
||||||
@ -86,7 +86,7 @@ object Find {
|
|||||||
): List<TDoc> {
|
): List<TDoc> {
|
||||||
val named = Parameters.nameFields(fields)
|
val named = Parameters.nameFields(fields)
|
||||||
return conn.customList<TDoc>(
|
return conn.customList<TDoc>(
|
||||||
Find.byFields(tableName, named, howMatched) + (orderBy?.let(::orderBy) ?: ""),
|
FindQuery.byFields(tableName, named, howMatched) + (orderBy?.let(::orderBy) ?: ""),
|
||||||
Parameters.addFields(named),
|
Parameters.addFields(named),
|
||||||
Results::fromData
|
Results::fromData
|
||||||
)
|
)
|
||||||
@ -158,7 +158,7 @@ object Find {
|
|||||||
conn: Connection
|
conn: Connection
|
||||||
) =
|
) =
|
||||||
conn.customList<TDoc>(
|
conn.customList<TDoc>(
|
||||||
Find.byContains(tableName) + (orderBy?.let(::orderBy) ?: ""),
|
FindQuery.byContains(tableName) + (orderBy?.let(::orderBy) ?: ""),
|
||||||
listOf(Parameters.json(":criteria", criteria)),
|
listOf(Parameters.json(":criteria", criteria)),
|
||||||
Results::fromData
|
Results::fromData
|
||||||
)
|
)
|
||||||
@ -223,7 +223,7 @@ object Find {
|
|||||||
conn: Connection
|
conn: Connection
|
||||||
) =
|
) =
|
||||||
conn.customList<TDoc>(
|
conn.customList<TDoc>(
|
||||||
Find.byJsonPath(tableName) + (orderBy?.let(::orderBy) ?: ""),
|
FindQuery.byJsonPath(tableName) + (orderBy?.let(::orderBy) ?: ""),
|
||||||
listOf(Parameter(":path", ParameterType.STRING, path)),
|
listOf(Parameter(":path", ParameterType.STRING, path)),
|
||||||
Results::fromData
|
Results::fromData
|
||||||
)
|
)
|
||||||
@ -271,7 +271,7 @@ object Find {
|
|||||||
): TDoc? {
|
): TDoc? {
|
||||||
val named = Parameters.nameFields(fields)
|
val named = Parameters.nameFields(fields)
|
||||||
return conn.customSingle<TDoc>(
|
return conn.customSingle<TDoc>(
|
||||||
Find.byFields(tableName, named, howMatched) + (orderBy?.let(::orderBy) ?: ""),
|
FindQuery.byFields(tableName, named, howMatched) + (orderBy?.let(::orderBy) ?: ""),
|
||||||
Parameters.addFields(named),
|
Parameters.addFields(named),
|
||||||
Results::fromData
|
Results::fromData
|
||||||
)
|
)
|
||||||
@ -328,7 +328,7 @@ object Find {
|
|||||||
conn: Connection
|
conn: Connection
|
||||||
) =
|
) =
|
||||||
conn.customSingle<TDoc>(
|
conn.customSingle<TDoc>(
|
||||||
Find.byContains(tableName) + (orderBy?.let(::orderBy) ?: ""),
|
FindQuery.byContains(tableName) + (orderBy?.let(::orderBy) ?: ""),
|
||||||
listOf(Parameters.json(":criteria", criteria)),
|
listOf(Parameters.json(":criteria", criteria)),
|
||||||
Results::fromData
|
Results::fromData
|
||||||
)
|
)
|
||||||
@ -382,7 +382,7 @@ object Find {
|
|||||||
conn: Connection
|
conn: Connection
|
||||||
) =
|
) =
|
||||||
conn.customSingle<TDoc>(
|
conn.customSingle<TDoc>(
|
||||||
Find.byJsonPath(tableName) + (orderBy?.let(::orderBy) ?: ""),
|
FindQuery.byJsonPath(tableName) + (orderBy?.let(::orderBy) ?: ""),
|
||||||
listOf(Parameter(":path", ParameterType.STRING, path)),
|
listOf(Parameter(":path", ParameterType.STRING, path)),
|
||||||
Results::fromData
|
Results::fromData
|
||||||
)
|
)
|
||||||
|
@ -2,7 +2,7 @@ package solutions.bitbadger.documents.kotlin
|
|||||||
|
|
||||||
import solutions.bitbadger.documents.*
|
import solutions.bitbadger.documents.*
|
||||||
import solutions.bitbadger.documents.kotlin.extensions.*
|
import solutions.bitbadger.documents.kotlin.extensions.*
|
||||||
import solutions.bitbadger.documents.query.Patch
|
import solutions.bitbadger.documents.query.PatchQuery
|
||||||
import java.sql.Connection
|
import java.sql.Connection
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -20,7 +20,7 @@ object Patch {
|
|||||||
*/
|
*/
|
||||||
inline fun <TKey, reified TPatch> byId(tableName: String, docId: TKey, patch: TPatch, conn: Connection) =
|
inline fun <TKey, reified TPatch> byId(tableName: String, docId: TKey, patch: TPatch, conn: Connection) =
|
||||||
conn.customNonQuery(
|
conn.customNonQuery(
|
||||||
Patch.byId(tableName, docId),
|
PatchQuery.byId(tableName, docId),
|
||||||
Parameters.addFields(
|
Parameters.addFields(
|
||||||
listOf(Field.equal(Configuration.idField, docId, ":id")),
|
listOf(Field.equal(Configuration.idField, docId, ":id")),
|
||||||
mutableListOf(Parameters.json(":data", patch))
|
mutableListOf(Parameters.json(":data", patch))
|
||||||
@ -55,7 +55,7 @@ object Patch {
|
|||||||
) {
|
) {
|
||||||
val named = Parameters.nameFields(fields)
|
val named = Parameters.nameFields(fields)
|
||||||
conn.customNonQuery(
|
conn.customNonQuery(
|
||||||
Patch.byFields(tableName, named, howMatched), Parameters.addFields(
|
PatchQuery.byFields(tableName, named, howMatched), Parameters.addFields(
|
||||||
named,
|
named,
|
||||||
mutableListOf(Parameters.json(":data", patch))
|
mutableListOf(Parameters.json(":data", patch))
|
||||||
)
|
)
|
||||||
@ -94,7 +94,7 @@ object Patch {
|
|||||||
conn: Connection
|
conn: Connection
|
||||||
) =
|
) =
|
||||||
conn.customNonQuery(
|
conn.customNonQuery(
|
||||||
Patch.byContains(tableName),
|
PatchQuery.byContains(tableName),
|
||||||
listOf(Parameters.json(":criteria", criteria), Parameters.json(":data", patch))
|
listOf(Parameters.json(":criteria", criteria), Parameters.json(":data", patch))
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -120,7 +120,7 @@ object Patch {
|
|||||||
*/
|
*/
|
||||||
inline fun <reified TPatch> byJsonPath(tableName: String, path: String, patch: TPatch, conn: Connection) =
|
inline fun <reified TPatch> byJsonPath(tableName: String, path: String, patch: TPatch, conn: Connection) =
|
||||||
conn.customNonQuery(
|
conn.customNonQuery(
|
||||||
Patch.byJsonPath(tableName),
|
PatchQuery.byJsonPath(tableName),
|
||||||
listOf(Parameter(":path", ParameterType.STRING, path), Parameters.json(":data", patch))
|
listOf(Parameter(":path", ParameterType.STRING, path), Parameters.json(":data", patch))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ package solutions.bitbadger.documents.kotlin
|
|||||||
import solutions.bitbadger.documents.*
|
import solutions.bitbadger.documents.*
|
||||||
import solutions.bitbadger.documents.jvm.RemoveFields as JvmRemoveFields
|
import solutions.bitbadger.documents.jvm.RemoveFields as JvmRemoveFields
|
||||||
import solutions.bitbadger.documents.kotlin.extensions.*
|
import solutions.bitbadger.documents.kotlin.extensions.*
|
||||||
import solutions.bitbadger.documents.query.RemoveFields
|
import solutions.bitbadger.documents.query.RemoveFieldsQuery
|
||||||
import java.sql.Connection
|
import java.sql.Connection
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -83,7 +83,7 @@ object RemoveFields {
|
|||||||
) {
|
) {
|
||||||
val nameParams = Parameters.fieldNames(toRemove)
|
val nameParams = Parameters.fieldNames(toRemove)
|
||||||
conn.customNonQuery(
|
conn.customNonQuery(
|
||||||
RemoveFields.byContains(tableName, nameParams),
|
RemoveFieldsQuery.byContains(tableName, nameParams),
|
||||||
listOf(Parameters.json(":criteria", criteria), *nameParams.toTypedArray())
|
listOf(Parameters.json(":criteria", criteria), *nameParams.toTypedArray())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
52
src/kotlin/src/test/kotlin/Types.kt
Normal file
52
src/kotlin/src/test/kotlin/Types.kt
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package solutions.bitbadger.documents.kotlin
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import solutions.bitbadger.documents.extensions.insert
|
||||||
|
|
||||||
|
/** The test table name to use for integration tests */
|
||||||
|
const val TEST_TABLE = "test_table"
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class NumIdDocument(val key: Int, val text: String) {
|
||||||
|
constructor() : this(0, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class SubDocument(val foo: String, val bar: String) {
|
||||||
|
constructor() : this("", "")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class ArrayDocument(val id: String, val values: List<String>) {
|
||||||
|
|
||||||
|
constructor() : this("", listOf())
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
/** A set of documents used for integration tests */
|
||||||
|
val testDocuments = listOf(
|
||||||
|
ArrayDocument("first", listOf("a", "b", "c")),
|
||||||
|
ArrayDocument("second", listOf("c", "d", "e")),
|
||||||
|
ArrayDocument("third", listOf("x", "y", "z"))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class JsonDocument(val id: String, val value: String = "", val numValue: Int = 0, val sub: SubDocument? = null) {
|
||||||
|
|
||||||
|
constructor() : this("")
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
/** Documents to use for testing */
|
||||||
|
private val testDocuments = listOf(
|
||||||
|
JsonDocument("one", "FIRST!", 0, null),
|
||||||
|
JsonDocument("two", "another", 10, SubDocument("green", "blue")),
|
||||||
|
JsonDocument("three", "", 4, null),
|
||||||
|
JsonDocument("four", "purple", 17, SubDocument("green", "red")),
|
||||||
|
JsonDocument("five", "purple", 18, null)
|
||||||
|
)
|
||||||
|
|
||||||
|
// fun load(db: ThrowawayDatabase, tableName: String = TEST_TABLE) =
|
||||||
|
// testDocuments.forEach { db.conn.insert(tableName, it) }
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user