Initial Development #1
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
14
.idea/compiler.xml
generated
Normal file
14
.idea/compiler.xml
generated
Normal file
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<annotationProcessing>
|
||||
<profile name="Maven default annotation processors profile" enabled="true">
|
||||
<sourceOutputDir name="target/generated-sources/annotations" />
|
||||
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
||||
<outputRelativeToContentRoot value="true" />
|
||||
<module name="common" />
|
||||
<module name="sqlite" />
|
||||
</profile>
|
||||
</annotationProcessing>
|
||||
</component>
|
||||
</project>
|
9
.idea/encodings.xml
generated
Normal file
9
.idea/encodings.xml
generated
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding">
|
||||
<file url="file://$PROJECT_DIR$/src/common/src/main/kotlin" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/src/common/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/resources" charset="UTF-8" />
|
||||
</component>
|
||||
</project>
|
25
.idea/jarRepositories.xml
generated
Normal file
25
.idea/jarRepositories.xml
generated
Normal file
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RemoteRepositoriesConfiguration">
|
||||
<remote-repository>
|
||||
<option name="id" value="mavenCentral" />
|
||||
<option name="name" value="mavenCentral" />
|
||||
<option name="url" value="https://repo1.maven.org/maven2/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="central" />
|
||||
<option name="name" value="Central Repository" />
|
||||
<option name="url" value="https://repo.maven.apache.org/maven2" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="central" />
|
||||
<option name="name" value="Maven Central repository" />
|
||||
<option name="url" value="https://repo1.maven.org/maven2" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="jboss.community" />
|
||||
<option name="name" value="JBoss Community repository" />
|
||||
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
|
||||
</remote-repository>
|
||||
</component>
|
||||
</project>
|
6
.idea/kotlinc.xml
generated
Normal file
6
.idea/kotlinc.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="KotlinJpsPluginSettings">
|
||||
<option name="version" value="2.1.10" />
|
||||
</component>
|
||||
</project>
|
23
.idea/libraries/KotlinJavaRuntime.xml
generated
Normal file
23
.idea/libraries/KotlinJavaRuntime.xml
generated
Normal file
@ -0,0 +1,23 @@
|
||||
<component name="libraryTable">
|
||||
<library name="KotlinJavaRuntime" type="repository">
|
||||
<properties maven-id="org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.0.21" />
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk8/2.0.21/kotlin-stdlib-jdk8-2.0.21.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib/2.0.21/kotlin-stdlib-2.0.21.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/annotations/13.0/annotations-13.0.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk7/2.0.21/kotlin-stdlib-jdk7-2.0.21.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk8/2.0.21/kotlin-stdlib-jdk8-2.0.21-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib/2.0.21/kotlin-stdlib-2.0.21-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/annotations/13.0/annotations-13.0-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk7/2.0.21/kotlin-stdlib-jdk7-2.0.21-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk8/2.0.21/kotlin-stdlib-jdk8-2.0.21-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib/2.0.21/kotlin-stdlib-2.0.21-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/annotations/13.0/annotations-13.0-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk7/2.0.21/kotlin-stdlib-jdk7-2.0.21-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
15
.idea/misc.xml
generated
Normal file
15
.idea/misc.xml
generated
Normal file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="MavenProjectsManager">
|
||||
<option name="originalFiles">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/src/common/pom.xml" />
|
||||
<option value="$PROJECT_DIR$/src/sqlite/pom.xml" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="corretto-21" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/solutions.bitbadger.documents.iml" filepath="$PROJECT_DIR$/.idea/solutions.bitbadger.documents.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
10
.idea/solutions.bitbadger.documents.iml
generated
Normal file
10
.idea/solutions.bitbadger.documents.iml
generated
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" scope="TEST" name="KotlinJavaRuntime" level="project" />
|
||||
</component>
|
||||
</module>
|
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
99
src/sqlite/pom.xml
Normal file
99
src/sqlite/pom.xml
Normal file
@ -0,0 +1,99 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>solutions.bitbadger.documents</groupId>
|
||||
<artifactId>sqlite</artifactId>
|
||||
<version>4.0-ALPHA</version>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<kotlin.code.style>official</kotlin.code.style>
|
||||
<kotlin.compiler.jvmTarget>1.8</kotlin.compiler.jvmTarget>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>mavenCentral</id>
|
||||
<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>2.1.10</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>compile</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>test-compile</id>
|
||||
<phase>test-compile</phase>
|
||||
<goals>
|
||||
<goal>test-compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.22.2</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<version>2.22.2</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<configuration>
|
||||
<mainClass>MainKt</mainClass>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-test-junit5</artifactId>
|
||||
<version>2.1.10</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<version>5.10.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib</artifactId>
|
||||
<version>2.1.10</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.xerial</groupId>
|
||||
<artifactId>sqlite-jdbc</artifactId>
|
||||
<version>3.46.1.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>solutions.bitbadger.documents</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>4.0-ALPHA</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
26
src/sqlite/src/main/kotlin/Configuration.kt
Normal file
26
src/sqlite/src/main/kotlin/Configuration.kt
Normal file
@ -0,0 +1,26 @@
|
||||
package solutions.bitbadger.documents.sqlite
|
||||
|
||||
import java.sql.Connection
|
||||
import java.sql.DriverManager
|
||||
|
||||
/**
|
||||
* Configuration for SQLite
|
||||
*/
|
||||
object Configuration {
|
||||
|
||||
/** The connection string for the SQLite database */
|
||||
var connectionString: String? = null
|
||||
|
||||
/**
|
||||
* Retrieve a new connection to the SQLite database
|
||||
*
|
||||
* @return A new connection to the SQLite database
|
||||
* @throws IllegalArgumentException If the connection string is not set before calling this
|
||||
*/
|
||||
fun dbConn(): Connection {
|
||||
if (connectionString == null) {
|
||||
throw IllegalArgumentException("Please provide a connection string before attempting data access")
|
||||
}
|
||||
return DriverManager.getConnection(connectionString)
|
||||
}
|
||||
}
|
102
src/sqlite/src/main/kotlin/Query.kt
Normal file
102
src/sqlite/src/main/kotlin/Query.kt
Normal file
@ -0,0 +1,102 @@
|
||||
package solutions.bitbadger.documents.sqlite
|
||||
|
||||
import solutions.bitbadger.documents.common.*
|
||||
import solutions.bitbadger.documents.common.Configuration
|
||||
import solutions.bitbadger.documents.common.Query
|
||||
|
||||
/**
|
||||
* Queries with specific syntax in SQLite
|
||||
*/
|
||||
object Query {
|
||||
|
||||
/**
|
||||
* Create a `WHERE` clause fragment to implement a comparison on fields in a JSON document
|
||||
*
|
||||
* @param howMatched How the fields should be matched
|
||||
* @param fields The fields for the comparisons
|
||||
* @return A `WHERE` clause implementing the comparisons for the given fields
|
||||
*/
|
||||
fun whereByFields(howMatched: FieldMatch, fields: Collection<Field<*>>): String {
|
||||
val name = ParameterName()
|
||||
return fields.joinToString(" ${howMatched.sql} ") {
|
||||
val comp = it.comparison
|
||||
when (comp.op) {
|
||||
Op.EXISTS, Op.NOT_EXISTS -> {
|
||||
"${it.path(Dialect.SQLITE, FieldFormat.SQL)} ${it.comparison.op.sql}"
|
||||
}
|
||||
Op.BETWEEN -> {
|
||||
val p = name.derive(it.parameterName)
|
||||
"${it.path(Dialect.SQLITE, FieldFormat.SQL)} ${comp.op.sql} ${p}min AND ${p}max"
|
||||
}
|
||||
Op.IN -> {
|
||||
val p = name.derive(it.parameterName)
|
||||
val values = comp.value as List<*>
|
||||
val paramNames = values.indices.joinToString(", ") { idx -> "${p}_$idx" }
|
||||
"${it.path(Dialect.SQLITE, FieldFormat.SQL)} ${comp.op.sql} ($paramNames)"
|
||||
}
|
||||
Op.IN_ARRAY -> {
|
||||
val p = name.derive(it.parameterName)
|
||||
val (table, values) = comp.value as Pair<String, List<*>>
|
||||
val paramNames = values.indices.joinToString(", ") { idx -> "${p}_$idx" }
|
||||
"EXISTS (SELECT 1 FROM json_each($table.data, '$.${it.name}') WHERE value IN ($paramNames)"
|
||||
}
|
||||
else -> {
|
||||
"${it.path(Dialect.SQLITE, FieldFormat.SQL)} ${comp.op.sql} ${name.derive(it.parameterName)}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a `WHERE` clause fragment to implement an ID-based query
|
||||
*
|
||||
* @param docId The ID of the document
|
||||
* @return A `WHERE` clause fragment identifying a document by its ID
|
||||
*/
|
||||
fun <TKey> whereById(docId: TKey): String =
|
||||
whereByFields(FieldMatch.ANY, listOf(Field.equal(Configuration.idField, docId).withParameterName(":id")))
|
||||
|
||||
/**
|
||||
* Create an `UPDATE` statement to patch documents
|
||||
*
|
||||
* @param tableName The table to be updated
|
||||
* @return A query to patch documents
|
||||
*/
|
||||
fun patch(tableName: String): String =
|
||||
"UPDATE $tableName SET data = json_patch(data, json(:data))"
|
||||
|
||||
// TODO: fun removeFields(tableName: String, fields: Collection<String>): String
|
||||
|
||||
/**
|
||||
* Create a query by a document's ID
|
||||
*
|
||||
* @param statement The SQL statement to be run against a document by its ID
|
||||
* @param docId The ID of the document targeted
|
||||
* @returns A query addressing a document by its ID
|
||||
*/
|
||||
fun <TKey> byId(statement: String, docId: TKey): String =
|
||||
Query.statementWhere(statement, whereById(docId))
|
||||
|
||||
/**
|
||||
* Create a query on JSON fields
|
||||
*
|
||||
* @param statement The SQL statement to be run against matching fields
|
||||
* @param howMatched Whether to match any or all of the field conditions
|
||||
* @param fields The field conditions to be matched
|
||||
* @return A query addressing documents by field matching conditions
|
||||
*/
|
||||
fun byFields(statement: String, howMatched: FieldMatch, fields: Collection<Field<*>>): String =
|
||||
Query.statementWhere(statement, whereByFields(howMatched, fields))
|
||||
|
||||
object Definition {
|
||||
|
||||
/**
|
||||
* SQL statement to create a document table
|
||||
*
|
||||
* @param tableName The name of the table (may include schema)
|
||||
* @return A query to create the table if it does not exist
|
||||
*/
|
||||
fun ensureTable(tableName: String): String =
|
||||
Query.Definition.ensureTableFor(tableName, "TEXT")
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user