From c9740642777cfcd471967a5814143de9f295d073 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Tue, 6 Dec 2022 20:06:06 +0100 Subject: [PATCH 01/35] Added action for deploying to nexus --- .github/workflows/smeup.yml | 44 +++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 .github/workflows/smeup.yml diff --git a/.github/workflows/smeup.yml b/.github/workflows/smeup.yml new file mode 100644 index 0000000..f5f2ac9 --- /dev/null +++ b/.github/workflows/smeup.yml @@ -0,0 +1,44 @@ +name: Deploy to nexus +on: + workflow_dispatch: + push: + branches: [master, develop] +env: + DISTRIBUTION: zulu + JAVA_VERSION: 8 + +jobs: + deploy-jardis-server: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: Set smeup nexus settings for snapshots + if: ${{ github.ref == 'refs/heads/develop' }} + uses: actions/setup-java@v3 + with: + distribution: ${{ env.DISTRIBUTION }} + java-version: ${{ env.JAVA_VERSION }} + server-id: snapshots + server-username: NEXUS_USER + server-password: NEXUS_PASSWORD + + - name: Set smeup nexus settings for releases + if: ${{ github.ref == 'refs/heads/master' }} + uses: actions/setup-java@v3 + with: + distribution: ${{ env.DISTRIBUTION }} + java-version: ${{ env.JAVA_VERSION }} + server-id: releases + server-username: NEXUS_USER + server-password: NEXUS_PASSWORD + + + - name: Publish to smeup nexus + run: mvn deploy + env: + NEXUS_USER: ${{ secrets.NEXUS_USER }} + NEXUS_PASSWORD: ${{ secrets.NEXUS_PASSWORD }} + + \ No newline at end of file From 8a11fc26cb7293b3cacb33734f10c1f672984ed7 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Wed, 7 Dec 2022 15:20:31 +0100 Subject: [PATCH 02/35] Created profile reload-nexus-profile containing reference to releases and snapshots nexus repository, defined in order to differentiate the deploying to sonatype from the one towards nexus. Disabled all tests and set the new maven profile in the GitHub action. --- .github/workflows/smeup.yml | 2 +- .gitignore | 2 +- pom.xml | 17 +++++++++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/.github/workflows/smeup.yml b/.github/workflows/smeup.yml index f5f2ac9..0f2a65e 100644 --- a/.github/workflows/smeup.yml +++ b/.github/workflows/smeup.yml @@ -36,7 +36,7 @@ jobs: - name: Publish to smeup nexus - run: mvn deploy + run: mvn deploy -DskipTests -Preload-nexus-deploy env: NEXUS_USER: ${{ secrets.NEXUS_USER }} NEXUS_PASSWORD: ${{ secrets.NEXUS_PASSWORD }} diff --git a/.gitignore b/.gitignore index 553945e..47bb38e 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,4 @@ bin/ *.iml /docker/mongodb/data/ /base/src/test/resources/dds/properties/out/ -.gradle/ +.vscode diff --git a/pom.xml b/pom.xml index 63d4b1f..3a8c6f6 100644 --- a/pom.xml +++ b/pom.xml @@ -219,6 +219,23 @@ + + + reload-nexus-deploy + + + releases + Internal Releases + https://repo.smeup.cloud/nexus/content/repositories/releases + + + + snapshots + Internal Snapshots + https://repo.smeup.cloud/nexus/content/repositories/snapshots + + + From 6b90e001f4182445abfb9db05a57e56c5b74bae4 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Wed, 7 Dec 2022 15:42:15 +0100 Subject: [PATCH 03/35] Changed action settings for test --- .github/workflows/smeup.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/smeup.yml b/.github/workflows/smeup.yml index 0f2a65e..8a723ab 100644 --- a/.github/workflows/smeup.yml +++ b/.github/workflows/smeup.yml @@ -2,7 +2,8 @@ name: Deploy to nexus on: workflow_dispatch: push: - branches: [master, develop] +# branches: [master, develop] + branches: [nexus-deploy-action] env: DISTRIBUTION: zulu JAVA_VERSION: 8 @@ -15,7 +16,8 @@ jobs: - uses: actions/checkout@v3 - name: Set smeup nexus settings for snapshots - if: ${{ github.ref == 'refs/heads/develop' }} +# if: ${{ github.ref == 'refs/heads/develop' }} + if: ${{ github.ref == 'refs/heads/nexus-deploy-action' }} uses: actions/setup-java@v3 with: distribution: ${{ env.DISTRIBUTION }} From 315dc3634f2ea172dcec47a59cf8f14e749ad01b Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Wed, 7 Dec 2022 18:05:37 +0100 Subject: [PATCH 04/35] Set right triggered branches and enabled cache feature in setup-java@v3 action --- .github/workflows/smeup.yml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/.github/workflows/smeup.yml b/.github/workflows/smeup.yml index 8a723ab..4b7afbf 100644 --- a/.github/workflows/smeup.yml +++ b/.github/workflows/smeup.yml @@ -1,9 +1,7 @@ name: Deploy to nexus -on: - workflow_dispatch: +on: push: -# branches: [master, develop] - branches: [nexus-deploy-action] + branches: [master, develop] env: DISTRIBUTION: zulu JAVA_VERSION: 8 @@ -16,13 +14,13 @@ jobs: - uses: actions/checkout@v3 - name: Set smeup nexus settings for snapshots -# if: ${{ github.ref == 'refs/heads/develop' }} - if: ${{ github.ref == 'refs/heads/nexus-deploy-action' }} + if: ${{ github.ref == 'refs/heads/develop' }} uses: actions/setup-java@v3 with: distribution: ${{ env.DISTRIBUTION }} java-version: ${{ env.JAVA_VERSION }} server-id: snapshots + cache: 'maven' server-username: NEXUS_USER server-password: NEXUS_PASSWORD @@ -33,10 +31,10 @@ jobs: distribution: ${{ env.DISTRIBUTION }} java-version: ${{ env.JAVA_VERSION }} server-id: releases + cache: 'maven' server-username: NEXUS_USER server-password: NEXUS_PASSWORD - - name: Publish to smeup nexus run: mvn deploy -DskipTests -Preload-nexus-deploy env: From adce95fff3e7b419144a61f33ef2c49d1017b6b5 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Sat, 10 Dec 2022 15:13:29 +0100 Subject: [PATCH 05/35] Made the deploying to internal nexus more smeup compliant, now is no longer necessary setting the profile reload-nexus-deploy when you want to deploy. --- .github/workflows/maven.yml | 2 +- .github/workflows/smeup.yml | 2 +- pom.xml | 42 +++++++++++++++++-------------------- 3 files changed, 21 insertions(+), 25 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 2d269b8..b2780b9 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -1,7 +1,7 @@ name: Deploy to maven central on: push: - branches: [master, develop] + branches: [master, develop, nexus-deploy-action] jobs: build: runs-on: ubuntu-latest diff --git a/.github/workflows/smeup.yml b/.github/workflows/smeup.yml index 4b7afbf..b1c14fc 100644 --- a/.github/workflows/smeup.yml +++ b/.github/workflows/smeup.yml @@ -36,7 +36,7 @@ jobs: server-password: NEXUS_PASSWORD - name: Publish to smeup nexus - run: mvn deploy -DskipTests -Preload-nexus-deploy + run: mvn deploy -DskipTests env: NEXUS_USER: ${{ secrets.NEXUS_USER }} NEXUS_PASSWORD: ${{ secrets.NEXUS_PASSWORD }} diff --git a/pom.xml b/pom.xml index 3a8c6f6..9a6cb21 100644 --- a/pom.xml +++ b/pom.xml @@ -184,6 +184,16 @@ ci-cd + + + ossrh + https://s01.oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://s01.oss.sonatype.org/service/local/staging/deploy/maven2 + + @@ -219,34 +229,20 @@ - - - reload-nexus-deploy - - - releases - Internal Releases - https://repo.smeup.cloud/nexus/content/repositories/releases - - - - snapshots - Internal Snapshots - https://repo.smeup.cloud/nexus/content/repositories/snapshots - - - - - ossrh - https://s01.oss.sonatype.org/content/repositories/snapshots - - ossrh - https://s01.oss.sonatype.org/service/local/staging/deploy/maven2 + releases + Internal Releases + https://repo.smeup.cloud/nexus/content/repositories/releases + + + snapshots + Internal Snapshots + https://repo.smeup.cloud/nexus/content/repositories/snapshots + \ No newline at end of file From a7bfa60347b32a252f057e8e1b1d5616a5f6f5c8 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Sat, 10 Dec 2022 15:19:16 +0100 Subject: [PATCH 06/35] Removed in "Deploy to maven central" the triggering of test branch --- .github/workflows/maven.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index b2780b9..2d269b8 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -1,7 +1,7 @@ name: Deploy to maven central on: push: - branches: [master, develop, nexus-deploy-action] + branches: [master, develop] jobs: build: runs-on: ubuntu-latest From 85a4adea772371309525768bd9ba39b02c1d630b Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Sat, 10 Dec 2022 15:33:28 +0100 Subject: [PATCH 07/35] Fixed documentation related the inclusion of reload in own projects --- README.md | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 8594ea6..d556755 100644 --- a/README.md +++ b/README.md @@ -54,20 +54,38 @@ We use [Maven Central](https://repo1.maven.org/maven2/.) to publish the [project See more details [here](docs/central.md). ### Maven -If you use Maven, add the following dependencies for the core library: - - - com.github.smeup.reload - reload - development-SNAPSHOT - +If you use Maven and if you want to work with sql and no-sql, add the following dependencies: + + + io.github.smeup.reload + base + vx.y.z + + + io.github.smeup.reload + manager + vx.y.z + + + io.github.smeup.reload + sql + vx.y.z + + + io.github.smeup.reload + nosql + vx.y.z + ### Gradle -Here are the configurationd to add to your build.gradle: +The gradle configuration could be like this: ``` dependencies { ... - implementation 'com.github.smeup:reload:-SNAPSHOT' + implementation "io.github.smeup.reload:base:vx.y.z" + implementation "io.github.smeup.reload:manager:vx.y.z" + implementation "io.github.smeup.reload:sql:vx.y.z" + implementation "io.github.smeup.reload:nosql:vx.y.z" } ``` From 059a95f2078ebb896356ed9d57ca71b445d1c395 Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Thu, 12 Jan 2023 15:38:03 +0100 Subject: [PATCH 08/35] Added fields name list in sql statements select (instead of *) --- .../smeup/dbnative/sql/Native2SQLAdapter.kt | 38 ++++++++++++------- .../com/smeup/dbnative/sql/SQLDBFile.kt | 2 +- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt b/sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt index cb03a30..d1d7a38 100644 --- a/sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt +++ b/sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt @@ -1,6 +1,8 @@ package com.smeup.dbnative.sql import com.smeup.dbnative.file.Record +import com.smeup.dbnative.model.FileMetadata +import com.smeup.dbnative.model.Field import java.lang.Exception enum class PositioningMethod { @@ -33,7 +35,7 @@ class ReadInstruction(var method: ReadMethod, var keys: List){ fun admitEmptyKeys() = method == ReadMethod.READ || method == ReadMethod.READP } -class Native2SQL(val fileKeys: List, val tableName: String) { +class Native2SQL(val fileMetadata: FileMetadata) { private var lastPositioningInstruction: PositioningInstruction? = null private var lastReadInstruction: ReadInstruction? = null @@ -44,11 +46,11 @@ class Native2SQL(val fileKeys: List, val tableName: String) { } private fun checkKeys(keys: List){ - require(fileKeys.size > 0){ + require(fileMetadata.fileKeys.size > 0){ "No keys specified in metadata" } - require(keys.size <= fileKeys.size){ - "Number of metadata keys $fileKeys less than number of positioning/read keys $keys" + require(keys.size <= fileMetadata.fileKeys.size){ + "Number of metadata keys $fileMetadata.fileKeys less than number of positioning/read keys $keys" } } @@ -120,7 +122,7 @@ class Native2SQL(val fileKeys: List, val tableName: String) { return true } lastReadInstruction!!.keys.mapIndexed { index, value -> - val keyname = fileKeys.get(index) + val keyname = fileMetadata.fileKeys.get(index) if(record[keyname]?.trim() != value.trim()){ return false } @@ -168,19 +170,19 @@ class Native2SQL(val fileKeys: List, val tableName: String) { private fun getSQLOrderByClause(): String{ val sortOrder = getSortOrder() - return " ORDER BY " + fileKeys.joinToString(separator = " " + sortOrder.symbol + ", ", postfix = " " + sortOrder.symbol ) + return " ORDER BY " + fileMetadata.fileKeys.joinToString(separator = " " + sortOrder.symbol + ", ", postfix = " " + sortOrder.symbol ) } fun getReadSqlStatement(): Pair>{ checkPositioning() - return Pair(getSQL(fileKeys.subList(0, lastPositioningInstruction!!.keys.size), Comparison.EQ, tableName), lastPositioningInstruction!!.keys) + return Pair(getSQL(fileMetadata.fields, fileMetadata.fileKeys.subList(0, lastPositioningInstruction!!.keys.size), Comparison.EQ, fileMetadata.tableName), lastPositioningInstruction!!.keys) } fun getSQLSatement(): Pair>{ when(lastReadInstruction!!.method){ ReadMethod.CHAIN ->{ checkReadKeys() - return Pair(getSQL(fileKeys.subList(0, lastReadInstruction!!.keys.size), Comparison.EQ, tableName), lastReadInstruction!!.keys) + return Pair(getSQL(fileMetadata.fields, fileMetadata.fileKeys.subList(0, lastReadInstruction!!.keys.size), Comparison.EQ, fileMetadata.tableName), lastReadInstruction!!.keys) } ReadMethod.READ,ReadMethod.READP -> { checkRead() @@ -203,13 +205,13 @@ class Native2SQL(val fileKeys: List, val tableName: String) { "Empty positioning keys" } if(lastPositioningInstruction!!.keys.size == 1){ - queries.add(getSQL(fileKeys.subList(0, 1), comparison.first, tableName)) + queries.add(getSQL(fileMetadata.fields, fileMetadata.fileKeys.subList(0, 1), comparison.first, fileMetadata.tableName)) replacements.addAll(lastPositioningInstruction!!.keys) } else { val limit = if(fullUnion)1 else 2 for (i in lastPositioningInstruction!!.keys.size downTo limit) { - queries.add(getSQL(fileKeys.subList(0, i), if(i == lastPositioningInstruction!!.keys.size) comparison.first else comparison.second, tableName)) + queries.add(getSQL(fileMetadata.fields, fileMetadata.fileKeys.subList(0, i), if(i == lastPositioningInstruction!!.keys.size) comparison.first else comparison.second, fileMetadata.tableName)) replacements.addAll(lastPositioningInstruction!!.keys.subList(0, i)) } } @@ -217,18 +219,28 @@ class Native2SQL(val fileKeys: List, val tableName: String) { } } -private fun getSQL(keys: List, comparison: Comparison, tableName: String): String{ +private fun getSQL(fields: List, keys: List, comparison: Comparison, tableName: String): String{ + var columns = "" + fields.forEachIndexed { index, k -> + run { + columns += k.name + ", " + } + } + var value = "" keys.forEachIndexed { index, k -> run { value += k + " " + (if (index < keys.size - 1) Comparison.EQ.symbol else comparison.symbol) + " ? AND " } } - return "(SELECT * FROM $tableName WHERE " + value.removeSuffix("AND ") + ")" + return "(SELECT " + columns.removeSuffix(", ")+ " FROM $tableName WHERE " + value.removeSuffix("AND ") + ")" } fun main(){ - val adapter = Native2SQL(listOf("Regione", "Provincia", "Comune"), "rld_comuni").apply{ + var fields = listOf(Field("Regione", ""), Field("Provincia", ""), Field("Comune", "")) + var fieldsKeys = listOf("Regione", "Provincia", "Comune") + var metadata = FileMetadata("test", "rld_comuni", fields, fieldsKeys) + val adapter = Native2SQL(metadata).apply{ setPositioning(PositioningMethod.SETLL, listOf("Lombardia", "Brescia", "Erbusco")) println(isCoherent(listOf("Lombardia", "Brescia", "Erbusco"))) setRead(ReadMethod.READE, listOf("Lombardia", "Brescia", "Erbusco")) diff --git a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFile.kt b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFile.kt index 225dc11..45d48ae 100644 --- a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFile.kt +++ b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFile.kt @@ -56,7 +56,7 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada // if (indexes.isEmpty()) connection.orderingFields(fileMetadata.name) else indexes //} - private var adapter: Native2SQL = Native2SQL(this.fileMetadata.fileKeys, fileMetadata.tableName) + private var adapter: Native2SQL = Native2SQL(this.fileMetadata) private var eof:Boolean = false private fun logEvent(loggingKey: LoggingKey, message: String, elapsedTime: Long? = null) = From b36077aadd150c6def9ae966c8ad29779540bf83 Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Mon, 6 Feb 2023 17:49:52 +0100 Subject: [PATCH 09/35] Insert double quote in columns names --- sql/pom.xml | 12 +++++++++++- .../com/smeup/dbnative/sql/Native2SQLAdapter.kt | 4 ++-- .../kotlin/com/smeup/dbnative/sql/SQLDBMManager.kt | 13 ++++++++++++- .../main/kotlin/com/smeup/dbnative/sql/SQLUtils.kt | 14 +++++++------- 4 files changed, 32 insertions(+), 11 deletions(-) diff --git a/sql/pom.xml b/sql/pom.xml index 397e5d5..b99fcba 100644 --- a/sql/pom.xml +++ b/sql/pom.xml @@ -70,6 +70,16 @@ ${project.basedir}/src/main/kotlin ${project.basedir}/src/test/kotlin - + + + org.apache.maven.plugins + maven-compiler-plugin + + 8 + 8 + + + + diff --git a/sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt b/sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt index d1d7a38..f137c80 100644 --- a/sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt +++ b/sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt @@ -223,14 +223,14 @@ private fun getSQL(fields: List, keys: List, comparison: Comparis var columns = "" fields.forEachIndexed { index, k -> run { - columns += k.name + ", " + columns += "\"" + k.name + "\", " } } var value = "" keys.forEachIndexed { index, k -> run { - value += k + " " + (if (index < keys.size - 1) Comparison.EQ.symbol else comparison.symbol) + " ? AND " + value += "\"" + k + "\" " + (if (index < keys.size - 1) Comparison.EQ.symbol else comparison.symbol) + " ? AND " } } return "(SELECT " + columns.removeSuffix(", ")+ " FROM $tableName WHERE " + value.removeSuffix("AND ") + ")" diff --git a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBMManager.kt b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBMManager.kt index 76e87db..9ac0a1a 100644 --- a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBMManager.kt +++ b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBMManager.kt @@ -22,6 +22,7 @@ import com.smeup.dbnative.DBManagerBaseImpl import com.smeup.dbnative.log.LoggingKey import java.sql.Connection import java.sql.DriverManager +import java.util.* import kotlin.system.measureTimeMillis open class SQLDBMManager(override val connectionConfig: ConnectionConfig) : DBManagerBaseImpl() { @@ -37,7 +38,17 @@ open class SQLDBMManager(override val connectionConfig: ConnectionConfig) : DBMa connectionConfig.driver?.let { Class.forName(connectionConfig.driver) } - conn = DriverManager.getConnection(connectionConfig.url, connectionConfig.user, connectionConfig.password) + + val connectionProps = Properties(); + connectionProps.put("user", connectionConfig.user); + connectionProps.put("password", connectionConfig.password); + + connectionConfig.properties.forEach() { + if (!it.key.equals("user") && !it.key.equals("password")) { + connectionProps.put(it.key, it.value); + } + } + conn = DriverManager.getConnection(connectionConfig.url, connectionProps) }.apply { logger?.logEvent(LoggingKey.connection, "SQL connection successfully opened", this) } diff --git a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLUtils.kt b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLUtils.kt index 960dc4f..49f22c5 100644 --- a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLUtils.kt +++ b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLUtils.kt @@ -22,13 +22,13 @@ import com.smeup.dbnative.file.RecordField fun String.insertSQL(record: Record): String { - val names = record.keys.joinToString { it } + val names = record.keys.joinToString { "\"" + it + "\"" } val questionMarks = record.keys.joinToString { "?" } return "INSERT INTO $this ($names) VALUES($questionMarks)" } fun String.updateSQL(record: Record): String { - val namesAndQuestionMarks = record.keys.joinToString { "$it = ?" } + val namesAndQuestionMarks = record.keys.joinToString { "\"$it\" = ?" } val wheres = record.keys.toList() val comparations = List(record.size) { Comparison.EQ } return "UPDATE $this SET $namesAndQuestionMarks ${whereSQL(wheres, comparations)}" @@ -45,9 +45,9 @@ fun orderBySQL(keysNames: List, reverse: Boolean = false): String = "" } else { if (reverse) { - "ORDER BY " + keysNames.joinToString(separator = " DESC, ", postfix = " DESC") + "ORDER BY " + keysNames.joinToString(separator = " DESC, ", postfix = " DESC") {"\"$it\""} } else { - "ORDER BY " + keysNames.joinToString() + "ORDER BY " + keysNames.joinToString {"\"$it\""} } } @@ -56,7 +56,7 @@ fun whereSQL(wheres: List, comparations: List): String { "" } else { var result = "WHERE " - wheres.forEachIndexed { index, _ -> result += wheres[index] + " " + comparations[index].symbol + " ? AND " } + wheres.forEachIndexed { index, _ -> result += "\"" + wheres[index] + "\" " + comparations[index].symbol + " ? AND " } return result.removeSuffix("AND ") } } @@ -133,9 +133,9 @@ fun createMarkerSQL(keysNames: List): String = } else { // in HSQLDB CONCAT needs at least two params! if (keysNames.size == 1) { - "CONCAT( " + keysNames.joinToString() + ", '') AS NATIVE_ACCESS_MARKER" + "CONCAT( " + keysNames.joinToString{"\"$it\""} + ", '') AS NATIVE_ACCESS_MARKER" } else { - "CONCAT( " + keysNames.joinToString() + ") AS NATIVE_ACCESS_MARKER" + "CONCAT( " + keysNames.joinToString{"\"$it\""} + ") AS NATIVE_ACCESS_MARKER" } } From 73d88f4c07fa387fb609b9f692f5eff77cde1374 Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Mon, 3 Jul 2023 15:22:20 +0200 Subject: [PATCH 10/35] Patch for develop version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4988b2a..9a6cb21 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.github.smeup.reload reload - v1.3.2 + develop-SNAPSHOT pom reload From b3e52b34f7f26ba43b92956f6d92cd57c9bc9bf1 Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Mon, 3 Jul 2023 16:04:43 +0200 Subject: [PATCH 11/35] Patch for submodules snapshot version --- base/pom.xml | 2 +- distribution/pom.xml | 2 +- jt400/pom.xml | 2 +- manager/pom.xml | 2 +- nosql/pom.xml | 2 +- sql/pom.xml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/base/pom.xml b/base/pom.xml index ec5fae0..4865923 100644 --- a/base/pom.xml +++ b/base/pom.xml @@ -33,7 +33,7 @@ io.github.smeup.reload reload - v1.3.2 + develop-SNAPSHOT base diff --git a/distribution/pom.xml b/distribution/pom.xml index 7f9c7d9..fa21773 100644 --- a/distribution/pom.xml +++ b/distribution/pom.xml @@ -25,7 +25,7 @@ reload io.github.smeup.reload - v1.3.2 + develop-SNAPSHOT distribution diff --git a/jt400/pom.xml b/jt400/pom.xml index 3625a82..bb3c562 100644 --- a/jt400/pom.xml +++ b/jt400/pom.xml @@ -31,7 +31,7 @@ io.github.smeup.reload reload - v1.3.2 + develop-SNAPSHOT jt400 diff --git a/manager/pom.xml b/manager/pom.xml index 67f264e..fe6f95b 100644 --- a/manager/pom.xml +++ b/manager/pom.xml @@ -25,7 +25,7 @@ io.github.smeup.reload reload - v1.3.2 + develop-SNAPSHOT manager diff --git a/nosql/pom.xml b/nosql/pom.xml index 55989a4..68cc3b8 100644 --- a/nosql/pom.xml +++ b/nosql/pom.xml @@ -26,7 +26,7 @@ io.github.smeup.reload reload - v1.3.2 + develop-SNAPSHOT nosql diff --git a/sql/pom.xml b/sql/pom.xml index 815206c..b99fcba 100644 --- a/sql/pom.xml +++ b/sql/pom.xml @@ -25,7 +25,7 @@ io.github.smeup.reload reload - v1.3.2 + develop-SNAPSHOT sql From 1320252d7c1c3a14072da7da04c62e92d9ce82c4 Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Thu, 16 Nov 2023 15:21:55 +0100 Subject: [PATCH 12/35] Fix for chain failure after read operation --- pom.xml | 3 + .../smeup/dbnative/sql/Native2SQLAdapter.kt | 4 +- .../dbnative/sql/SQLMunicipalityPerfTest.kt | 85 +++++++++++++++++++ 3 files changed, 90 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 9a6cb21..3b540f4 100644 --- a/pom.xml +++ b/pom.xml @@ -110,6 +110,9 @@ src/main/kotlin src/main/resources + 11 + 1.6 + 1.6 diff --git a/sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt b/sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt index f137c80..1254fe5 100644 --- a/sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt +++ b/sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt @@ -98,8 +98,8 @@ class Native2SQL(val fileMetadata: FileMetadata) { executeQuery = true } } - require(lastReadInstruction == null || method == lastReadInstruction!!.method) { - "read operations are only allowed immediatly after positioning or after a same method read instruction" + require(lastReadInstruction == null || method == ReadMethod.CHAIN || method == lastReadInstruction!!.method) { + "read operation " + method + " is allowed immediatly after positioning or after a same method read instruction" } if(lastReadInstruction == null){ executeQuery = true diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLMunicipalityPerfTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLMunicipalityPerfTest.kt index 9d8d6a0..be563c1 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLMunicipalityPerfTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLMunicipalityPerfTest.kt @@ -17,6 +17,8 @@ package com.smeup.dbnative.sql +import com.smeup.dbnative.file.Record +import com.smeup.dbnative.file.RecordField import com.smeup.dbnative.sql.utils.* import org.junit.AfterClass import org.junit.BeforeClass @@ -145,6 +147,89 @@ class SQLMunicipalityPerfTest { dbManager.closeFile(MUNICIPALITY_TABLE_NAME) } + @Test + fun write() { + val dbFile = dbManager.openFile(MUNICIPALITY_TABLE_NAME) + + // Write new record + val recordFields = emptyList().toMutableList() + recordFields.add(RecordField("NAZ", "IT")) + recordFields.add(RecordField("REG", "LOM")) + recordFields.add(RecordField("PROV", "BG")) + recordFields.add(RecordField("CITTA", "TOPOLINIA")) + recordFields.add(RecordField("PREF", "1234")) + recordFields.add(RecordField("COMUNE", "A99")) + recordFields.add(RecordField("ISTAT", "999999")) + dbFile.write(Record(*recordFields.toTypedArray())); + + // Read new record for control + var chainResult = dbFile.chain(buildMunicipalityKey("IT", "LOM", "BG", "TOPOLINIA")) + assertEquals("TOPOLINIA", getMunicipalityName(chainResult.record)) + } + + @Test + fun update() { + val dbFile = dbManager.openFile(MUNICIPALITY_TABLE_NAME) + + // Chain to record to modify + var chainResult = dbFile.chain(buildMunicipalityKey("IT", "LOM", "BG", "DALMINE")) + assertEquals("DALMINE", getMunicipalityName(chainResult.record)) + assertEquals("BG", getMunicipalityProv(chainResult.record)) + + // Update + val record = chainResult.record + record.set("PROV", "BS") + dbFile.update(record) + + // Verify changes + chainResult = dbFile.chain(buildMunicipalityKey("IT", "LOM", "BS", "DALMINE")) + assertEquals("BS", getMunicipalityProv(chainResult.record)) + + // Verify that old record is missing + chainResult = dbFile.chain(buildMunicipalityKey("IT", "LOM", "BG", "DALMINE")) + assertTrue(dbFile.eof()) + } + + @Test + fun readAndChain() { + val dbFile = dbManager.openFile(MUNICIPALITY_TABLE_NAME) + + dbFile.setll(buildMunicipalityKey("IT", "LOM", "BS", "ERBUSCO")) + val readResult = dbFile.read() + assertEquals("ERBUSCO", getMunicipalityName(readResult.record)) + + // Chain to another record + var chainResult = dbFile.chain(buildMunicipalityKey("IT", "LOM", "BS", "ADRO")) + assertEquals("ADRO", getMunicipalityName(chainResult.record)) + } + + @Test + fun writeAndDelete() { + val dbFile = dbManager.openFile(MUNICIPALITY_TABLE_NAME) + + // Write new record + val recordFields = emptyList().toMutableList() + recordFields.add(RecordField("NAZ", "IT")) + recordFields.add(RecordField("REG", "LOM")) + recordFields.add(RecordField("PROV", "BG")) + recordFields.add(RecordField("CITTA", "PAPEROPOLI")) + recordFields.add(RecordField("PREF", "4321")) + recordFields.add(RecordField("COMUNE", "A99")) + recordFields.add(RecordField("ISTAT", "999999")) + dbFile.write(Record(*recordFields.toTypedArray())); + + // Read new record + dbFile.setll(buildMunicipalityKey("IT", "LOM", "BG", "PAPEROPOLI")) + val readResult = dbFile.read() + assertEquals("PAPEROPOLI", getMunicipalityName(readResult.record)) + + // Delete added record + var chainResult= dbFile.chain(buildMunicipalityKey("IT", "LOM", "BG", "PAPEROPOLI")) + dbFile.delete(chainResult.record) + chainResult = dbFile.chain(buildMunicipalityKey("IT", "LOM", "BG", "PAPEROPOLI")) + assertTrue(dbFile.eof()) + } + @Test fun fullTest() { eofAfterRead() From 00c5ec64f9393d361da5544464666ad7cf1995f8 Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Thu, 16 Nov 2023 15:31:20 +0100 Subject: [PATCH 13/35] Update maven.yml --- .github/workflows/maven.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 2d269b8..2d2861c 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -10,7 +10,7 @@ jobs: - name: Set up Maven Central Repository uses: actions/setup-java@v1 with: - java-version: 1.8 + java-version: 11 server-id: ossrh server-username: MAVEN_USERNAME server-password: MAVEN_PASSWORD From 4335f6ca7e2791337c8061f759e3add3571e6ca9 Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Thu, 16 Nov 2023 15:33:27 +0100 Subject: [PATCH 14/35] Update smeup.yml --- .github/workflows/smeup.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/smeup.yml b/.github/workflows/smeup.yml index b1c14fc..08ec2f2 100644 --- a/.github/workflows/smeup.yml +++ b/.github/workflows/smeup.yml @@ -4,7 +4,7 @@ on: branches: [master, develop] env: DISTRIBUTION: zulu - JAVA_VERSION: 8 + JAVA_VERSION: 11 jobs: deploy-jardis-server: @@ -41,4 +41,4 @@ jobs: NEXUS_USER: ${{ secrets.NEXUS_USER }} NEXUS_PASSWORD: ${{ secrets.NEXUS_PASSWORD }} - \ No newline at end of file + From 8af26d7f754ae53208b87748e7b949945f399d45 Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Thu, 16 Nov 2023 15:38:44 +0100 Subject: [PATCH 15/35] Fix for chain failure after read operation - patch for maven setup --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3b540f4..139fa96 100644 --- a/pom.xml +++ b/pom.xml @@ -40,7 +40,7 @@ UTF-8 - 1.4.10 + 1.8.20 official [4.13.1,) 1.0.0-RC From 1e191327c211a6a5055f51259adb3da0a43afdd3 Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Tue, 28 Nov 2023 17:57:46 +0100 Subject: [PATCH 16/35] Fix for chain failure after read operation - patch for maven setup --- .mvn/jvm.config | 1 + .../kotlin/com/smeup/dbnative/DBMManager.kt | 16 +- .../com/smeup/dbnative/DBManagerBaseImpl.kt | 32 ++- .../smeup/dbnative/DBNativeAccessConfig.kt | 10 +- .../kotlin/com/smeup/dbnative/file/DBFile.kt | 15 +- .../kotlin/com/smeup/dbnative/file/Record.kt | 16 +- .../kotlin/com/smeup/dbnative/file/Result.kt | 2 +- .../kotlin/com/smeup/dbnative/log/Logging.kt | 100 ++++--- .../dbnative/metadata/MetadataRegister.kt | 15 +- .../metadata/file/FSMetadataRegisterImpl.kt | 20 +- .../metadata/file/PropertiesSerializer.kt | 40 +-- .../kotlin/com/smeup/dbnative/model/Field.kt | 2 +- .../com/smeup/dbnative/model/FileMetadata.kt | 2 +- .../com/smeup/dbnative/utils/Comparison.kt | 2 +- .../com/smeup/dbnative/utils/FileUtilities.kt | 12 +- .../dbnative/PropertiesSerializationTest.kt | 3 +- .../com/smeup/dbnative/utils/FieldType.kt | 251 ++++++++---------- .../kotlin/com/smeup/dbnative/utils/Types.kt | 94 ++++--- pom.xml | 14 + 19 files changed, 358 insertions(+), 289 deletions(-) create mode 100644 .mvn/jvm.config diff --git a/.mvn/jvm.config b/.mvn/jvm.config new file mode 100644 index 0000000..45d7a1d --- /dev/null +++ b/.mvn/jvm.config @@ -0,0 +1 @@ +--add-opens java.base/java.lang=ALL-UNNAMED \ No newline at end of file diff --git a/base/src/main/kotlin/com/smeup/dbnative/DBMManager.kt b/base/src/main/kotlin/com/smeup/dbnative/DBMManager.kt index e8b2dc7..31e24a0 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/DBMManager.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/DBMManager.kt @@ -26,16 +26,24 @@ import com.smeup.dbnative.model.FileMetadata * A datasource can contains either only tables(views) or only documents. * File is an abstraction of table, view or document. * */ -interface DBMManager : AutoCloseable{ - val connectionConfig : ConnectionConfig - +interface DBMManager : AutoCloseable { + val connectionConfig: ConnectionConfig fun existFile(name: String): Boolean - fun registerMetadata(metadata: FileMetadata, overwrite: Boolean) + + fun registerMetadata( + metadata: FileMetadata, + overwrite: Boolean, + ) + fun metadataOf(name: String): FileMetadata + fun openFile(name: String): DBFile + fun closeFile(name: String) + fun unregisterMetadata(name: String) + /** * Validate connectionConfig. If validation fails, implementation has to throw an IllegalArgumentException * */ diff --git a/base/src/main/kotlin/com/smeup/dbnative/DBManagerBaseImpl.kt b/base/src/main/kotlin/com/smeup/dbnative/DBManagerBaseImpl.kt index 395d642..82fc982 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/DBManagerBaseImpl.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/DBManagerBaseImpl.kt @@ -15,7 +15,6 @@ * */ - package com.smeup.dbnative import com.smeup.dbnative.log.Logger @@ -37,11 +36,17 @@ abstract class DBManagerBaseImpl : DBMManager { return getMetadataRegister().getMetadata(name.toUpperCase()) } - override fun registerMetadata(metadata: FileMetadata, overwrite: Boolean) { + override fun registerMetadata( + metadata: FileMetadata, + overwrite: Boolean, + ) { if (getMetadataRegister().contains(metadata.name)) { - if (overwrite) getMetadataRegister().remove(metadata.name) - else return - //TODO: send exception (existent metadata and no overwrite) + if (overwrite) { + getMetadataRegister().remove(metadata.name) + } else { + return + } + // TODO: send exception (existent metadata and no overwrite) } getMetadataRegister().registerMetadata(metadata, overwrite) @@ -58,7 +63,6 @@ abstract class DBManagerBaseImpl : DBMManager { } companion object { - val register: MetadataRegister get() { return FSMetadataRegisterImpl @@ -68,11 +72,17 @@ abstract class DBManagerBaseImpl : DBMManager { return register } - fun staticRegisterMetadata(metadata: FileMetadata, overwrite: Boolean) { + fun staticRegisterMetadata( + metadata: FileMetadata, + overwrite: Boolean, + ) { if (getMetadataRegister().contains(metadata.name)) { - if (overwrite) getMetadataRegister().remove(metadata.name) - else return - //TODO: send exception (existent metadata and no overwrite) + if (overwrite) { + getMetadataRegister().remove(metadata.name) + } else { + return + } + // TODO: send exception (existent metadata and no overwrite) } getMetadataRegister().registerMetadata(metadata, overwrite) @@ -85,7 +95,7 @@ abstract class DBManagerBaseImpl : DBMManager { } fun staticGetMetadata(name: String): FileMetadata { - return getMetadataRegister().getMetadata(name); + return getMetadataRegister().getMetadata(name) } } } diff --git a/base/src/main/kotlin/com/smeup/dbnative/DBNativeAccessConfig.kt b/base/src/main/kotlin/com/smeup/dbnative/DBNativeAccessConfig.kt index beec4c5..387d5d7 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/DBNativeAccessConfig.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/DBNativeAccessConfig.kt @@ -19,8 +19,8 @@ package com.smeup.dbnative import com.smeup.dbnative.log.Logger -data class DBNativeAccessConfig (val connectionsConfig: List, val logger: Logger? = null){ - constructor(connectionsConfig: List):this(connectionsConfig, null) +data class DBNativeAccessConfig(val connectionsConfig: List, val logger: Logger? = null) { + constructor(connectionsConfig: List) : this(connectionsConfig, null) } /** @@ -34,12 +34,12 @@ data class DBNativeAccessConfig (val connectionsConfig: List, * @param impl DBMManager implementation. If doesn't specified is assumed by url * @param properties Others connection properties * */ -data class ConnectionConfig ( +data class ConnectionConfig( val fileName: String, val url: String, val user: String, val password: String, val driver: String? = null, val impl: String? = null, - val properties : Map = mutableMapOf()) - + val properties: Map = mutableMapOf(), +) diff --git a/base/src/main/kotlin/com/smeup/dbnative/file/DBFile.kt b/base/src/main/kotlin/com/smeup/dbnative/file/DBFile.kt index 0ccba2a..722051c 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/file/DBFile.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/file/DBFile.kt @@ -23,35 +23,44 @@ import com.smeup.dbnative.model.FileMetadata /** * DBFile is an abstraction of table or view (in sql database) or document (in nosql database). * */ -interface DBFile: AutoCloseable { +interface DBFile : AutoCloseable { var name: String var fileMetadata: FileMetadata var logger: Logger? // Control functions fun eof(): Boolean + fun equal(): Boolean // Pointing functions fun setll(key: String): Boolean + fun setll(keys: List): Boolean + fun setgt(key: String): Boolean - fun setgt(keys: List): Boolean + fun setgt(keys: List): Boolean // Read functions fun chain(key: String): Result + fun chain(keys: List): Result fun read(): Result + fun readPrevious(): Result fun readEqual(): Result + fun readEqual(key: String): Result + fun readEqual(keys: List): Result fun readPreviousEqual(): Result + fun readPreviousEqual(key: String): Result + fun readPreviousEqual(keys: List): Result // Write functions @@ -64,4 +73,4 @@ interface DBFile: AutoCloseable { fun delete(record: Record): Result override fun close() {} -} \ No newline at end of file +} diff --git a/base/src/main/kotlin/com/smeup/dbnative/file/Record.kt b/base/src/main/kotlin/com/smeup/dbnative/file/Record.kt index bf99ace..7be4df9 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/file/Record.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/file/Record.kt @@ -24,20 +24,20 @@ class Record(vararg fields: RecordField) : LinkedHashMap() { } } - fun matches(keyFields: List) = keyFields.all { + fun matches(keyFields: List) = + keyFields.all { + var value1 = this[it.name]?.trim() + var value2 = it.value.trim() - var value1 = this[it.name]?.trim() - var value2 = it.value.trim(); - - value1.equals(value2.trim()) - } + value1.equals(value2.trim()) + } fun add(field: RecordField) { put(field.name, field.value) } - fun duplicate(): Record{ + fun duplicate(): Record { val thisMap = this return Record().apply { this.putAll(thisMap) } } -} \ No newline at end of file +} diff --git a/base/src/main/kotlin/com/smeup/dbnative/file/Result.kt b/base/src/main/kotlin/com/smeup/dbnative/file/Result.kt index d6f2e84..f41dc00 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/file/Result.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/file/Result.kt @@ -17,4 +17,4 @@ package com.smeup.dbnative.file -data class Result(var record: Record = Record(), var indicatorHI: Boolean = false, var indicatorLO: Boolean = false, var indicatorEQ: Boolean = false, var errorMsg: String = "") \ No newline at end of file +data class Result(var record: Record = Record(), var indicatorHI: Boolean = false, var indicatorLO: Boolean = false, var indicatorEQ: Boolean = false, var errorMsg: String = "") diff --git a/base/src/main/kotlin/com/smeup/dbnative/log/Logging.kt b/base/src/main/kotlin/com/smeup/dbnative/log/Logging.kt index 528de58..f1485e1 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/log/Logging.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/log/Logging.kt @@ -3,71 +3,95 @@ package com.smeup.dbnative.log import java.text.SimpleDateFormat import java.util.* -enum class LoggingLevel{ - OFF, ERROR, WARN, INFO, DEBUG, TRACE, ALL +enum class LoggingLevel { + OFF, + ERROR, + WARN, + INFO, + DEBUG, + TRACE, + ALL, } -enum class LoggingKey(val level: LoggingLevel){ +enum class LoggingKey(val level: LoggingLevel) { native_access_method(LoggingLevel.TRACE), read_data(LoggingLevel.TRACE), execute_inquiry(LoggingLevel.DEBUG), search_data(LoggingLevel.DEBUG), - connection(LoggingLevel.DEBUG) + connection(LoggingLevel.DEBUG), } -enum class NativeMethod(){ - equal, setll, setgt, chain, read, readPrevious, readEqual, readPreviousEqual, write, update, delete; +enum class NativeMethod() { + equal, + setll, + setgt, + chain, + read, + readPrevious, + readEqual, + readPreviousEqual, + write, + update, + delete, } -data class LoggingEvent(val eventKey: LoggingKey, - val message: String, - val callerMethod: String? = null, - val elapsedTime: Long? = null, - val nativeMethodCall: NativeMethod? = null, - val fileName: String? = null){ +data class LoggingEvent( + val eventKey: LoggingKey, + val message: String, + val callerMethod: String? = null, + val elapsedTime: Long? = null, + val nativeMethodCall: NativeMethod? = null, + val fileName: String? = null, +) { val issueTime: Date = Date() + fun isMeasuredEvent() = elapsedTime != null } -open class Logger(val level:LoggingLevel = LoggingLevel.OFF, - var loggingFunction: ((LoggingEvent) -> Unit)?) -{ - companion object{ +open class Logger( + val level: LoggingLevel = LoggingLevel.OFF, + var loggingFunction: ((LoggingEvent) -> Unit)?, +) { + companion object { @JvmStatic - fun getSimpleInstance(level:LoggingLevel = LoggingLevel.DEBUG): Logger{ + fun getSimpleInstance(level: LoggingLevel = LoggingLevel.DEBUG): Logger { return Logger(level, loggingFunction = { val logged = "[%s][%s][%s][%s][%s] * %s %s" - println(logged.format(SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS").format(it.issueTime), - it.eventKey.level, - it.eventKey.name, - it.nativeMethodCall?:"", - it.fileName?:"", - it.message, - if(it.isMeasuredEvent()) "(${it.elapsedTime} ms)" else "") - ) + println( + logged.format( + SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS").format(it.issueTime), + it.eventKey.level, + it.eventKey.name, + it.nativeMethodCall ?: "", + it.fileName ?: "", + it.message, + if (it.isMeasuredEvent()) "(${it.elapsedTime} ms)" else "", + ), + ) }) } } - fun logEvent(eventKey: LoggingKey, - message: String, - elapsedTime: Long? = null, - nativeMethodCall: NativeMethod? = null, - fileName: String? = null): LoggingEvent?{ - return if(eventKey.level.ordinal <= level.ordinal) { - val caller = Thread.currentThread().getStackTrace().getOrNull(2)?.let { - "${it.className} ${it.methodName}:${it.lineNumber}" - }?:"" + fun logEvent( + eventKey: LoggingKey, + message: String, + elapsedTime: Long? = null, + nativeMethodCall: NativeMethod? = null, + fileName: String? = null, + ): LoggingEvent? { + return if (eventKey.level.ordinal <= level.ordinal) { + val caller = + Thread.currentThread().getStackTrace().getOrNull(2)?.let { + "${it.className} ${it.methodName}:${it.lineNumber}" + } ?: "" logEvent(LoggingEvent(eventKey, message, caller, elapsedTime, nativeMethodCall, fileName)) - } - else{ + } else { null } } - internal fun logEvent(ev: LoggingEvent): LoggingEvent{ + internal fun logEvent(ev: LoggingEvent): LoggingEvent { loggingFunction?.invoke(ev) return ev } } - diff --git a/base/src/main/kotlin/com/smeup/dbnative/metadata/MetadataRegister.kt b/base/src/main/kotlin/com/smeup/dbnative/metadata/MetadataRegister.kt index af52dd8..2ea8769 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/metadata/MetadataRegister.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/metadata/MetadataRegister.kt @@ -20,9 +20,14 @@ package com.smeup.dbnative.metadata import com.smeup.dbnative.model.FileMetadata interface MetadataRegister { + fun registerMetadata( + metadata: FileMetadata, + overwrite: Boolean, + ) - fun registerMetadata(metadata: FileMetadata, overwrite: Boolean) - fun getMetadata(filename:String): FileMetadata - fun contains(fileName:String): Boolean - fun remove(fileName:String) -} \ No newline at end of file + fun getMetadata(filename: String): FileMetadata + + fun contains(fileName: String): Boolean + + fun remove(fileName: String) +} diff --git a/base/src/main/kotlin/com/smeup/dbnative/metadata/file/FSMetadataRegisterImpl.kt b/base/src/main/kotlin/com/smeup/dbnative/metadata/file/FSMetadataRegisterImpl.kt index e3884dc..ad8a280 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/metadata/file/FSMetadataRegisterImpl.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/metadata/file/FSMetadataRegisterImpl.kt @@ -21,22 +21,24 @@ import com.smeup.dbnative.metadata.MetadataRegister import com.smeup.dbnative.model.FileMetadata import java.io.File -object FSMetadataRegisterImpl: MetadataRegister{ - +object FSMetadataRegisterImpl : MetadataRegister { var propertiesDirPath: String init { - propertiesDirPath = System.getenv("DBNATIVE_DDS_DIR") ?:"${System.getProperty("user.home")}${File.separatorChar}" + - "etc${File.separatorChar}" + - "dbnativeaccess${File.separatorChar}dds" + propertiesDirPath = System.getenv("DBNATIVE_DDS_DIR") ?: "${System.getProperty("user.home")}${File.separatorChar}" + + "etc${File.separatorChar}" + + "dbnativeaccess${File.separatorChar}dds" if (File(propertiesDirPath).exists() == false) { File(propertiesDirPath).mkdirs() } } - override fun registerMetadata(metadata: FileMetadata, overwrite: Boolean) { + override fun registerMetadata( + metadata: FileMetadata, + overwrite: Boolean, + ) { PropertiesSerializer.metadataToProperties(propertiesDirPath, metadata, true) } @@ -45,11 +47,11 @@ object FSMetadataRegisterImpl: MetadataRegister{ } override fun contains(fileName: String): Boolean { - return File("${propertiesDirPath}${File.separatorChar}${fileName}.properties").exists() + return File("${propertiesDirPath}${File.separatorChar}$fileName.properties").exists() } override fun remove(fileName: String) { - var propertiesFile = File("${propertiesDirPath}${File.separatorChar}${fileName}.properties") + var propertiesFile = File("${propertiesDirPath}${File.separatorChar}$fileName.properties") if (propertiesFile.exists()) propertiesFile.delete() } -} \ No newline at end of file +} diff --git a/base/src/main/kotlin/com/smeup/dbnative/metadata/file/PropertiesSerializer.kt b/base/src/main/kotlin/com/smeup/dbnative/metadata/file/PropertiesSerializer.kt index 2218ca3..8df8111 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/metadata/file/PropertiesSerializer.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/metadata/file/PropertiesSerializer.kt @@ -27,18 +27,22 @@ import java.nio.charset.Charset import java.util.* import kotlin.collections.ArrayList - object PropertiesSerializer { - - fun propertiesToMetadata(propertiesDirPath: String, fileName: String): FileMetadata{ + fun propertiesToMetadata( + propertiesDirPath: String, + fileName: String, + ): FileMetadata { val propertiesFile = FileInputStream(File("$propertiesDirPath${File.separatorChar}${fileName.toUpperCase()}.properties")) - //val properties = Properties() - //properties.load(InputStreamReader(propertiesFile, Charset.forName("UTF-8"))) + // val properties = Properties() + // properties.load(InputStreamReader(propertiesFile, Charset.forName("UTF-8"))) val mp: MutableMap = LinkedHashMap() object : Properties() { @Synchronized - override fun put(key: Any, value: Any): Any? { + override fun put( + key: Any, + value: Any, + ): Any? { return mp.put(key as String, value as String) } }.load(InputStreamReader(propertiesFile, Charset.forName("UTF-8"))) @@ -63,7 +67,7 @@ object PropertiesSerializer { // FieldKeys val fieldsKeys: MutableList = ArrayList() - if(!(mp["filekeys"]).isNullOrEmpty()){ + if (!(mp["filekeys"]).isNullOrEmpty()) { fieldsKeys.addAll((mp["filekeys"]?.split(",")!!)) } @@ -71,27 +75,30 @@ object PropertiesSerializer { return FileMetadata(fileName, tableName, fields, fieldsKeys) } - - fun metadataToProperties(propertiesDirPath: String, fileMetadata: FileMetadata, overwrite: Boolean){ + fun metadataToProperties( + propertiesDirPath: String, + fileMetadata: FileMetadata, + overwrite: Boolean, + ) { metadataToPropertiesImpl(propertiesDirPath, fileMetadata, fileMetadata.fieldsToProperties(), overwrite) } - - private fun metadataToPropertiesImpl(propertiesDirPath: String, - fileMetadata: FileMetadata, - properties: MutableList>, - overwrite: Boolean){ + private fun metadataToPropertiesImpl( + propertiesDirPath: String, + fileMetadata: FileMetadata, + properties: MutableList>, + overwrite: Boolean, + ) { properties.add(Pair("tablename", fileMetadata.tableName)) val keys = fileMetadata.fileKeys.joinToString(",") properties.add(Pair("filekeys", keys)) - val propertiesFilePath = "${propertiesDirPath}${File.separatorChar}${fileMetadata.name.toUpperCase()}.properties" val propertiesFile = File(propertiesFilePath) - if (overwrite && propertiesFile.exists()) { + if (overwrite && propertiesFile.exists()) { propertiesFile.delete() } @@ -103,6 +110,5 @@ object PropertiesSerializer { } writer.flush() writer.close() - } } diff --git a/base/src/main/kotlin/com/smeup/dbnative/model/Field.kt b/base/src/main/kotlin/com/smeup/dbnative/model/Field.kt index f266536..94e803d 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/model/Field.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/model/Field.kt @@ -17,4 +17,4 @@ package com.smeup.dbnative.model -data class Field(val name: String, val text:String = "") \ No newline at end of file +data class Field(val name: String, val text: String = "") diff --git a/base/src/main/kotlin/com/smeup/dbnative/model/FileMetadata.kt b/base/src/main/kotlin/com/smeup/dbnative/model/FileMetadata.kt index 9aa1f00..3ae9f33 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/model/FileMetadata.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/model/FileMetadata.kt @@ -17,4 +17,4 @@ package com.smeup.dbnative.model -data class FileMetadata(var name: String, var tableName:String, var fields: List, var fileKeys:List) \ No newline at end of file +data class FileMetadata(var name: String, var tableName: String, var fields: List, var fileKeys: List) diff --git a/base/src/main/kotlin/com/smeup/dbnative/utils/Comparison.kt b/base/src/main/kotlin/com/smeup/dbnative/utils/Comparison.kt index 7995e1d..52563d9 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/utils/Comparison.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/utils/Comparison.kt @@ -23,5 +23,5 @@ enum class Comparison(val symbol: String) { GT(">"), GE(">="), LT("<"), - LE("<="); + LE("<="), } diff --git a/base/src/main/kotlin/com/smeup/dbnative/utils/FileUtilities.kt b/base/src/main/kotlin/com/smeup/dbnative/utils/FileUtilities.kt index 8176280..1dedf4b 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/utils/FileUtilities.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/utils/FileUtilities.kt @@ -21,12 +21,10 @@ import com.smeup.dbnative.file.RecordField import com.smeup.dbnative.model.Field import com.smeup.dbnative.model.FileMetadata - /* Return true if passed keys are all primary fields in metadata - */ + */ fun FileMetadata.matchFileKeys(keys: List): Boolean { - val keysAsString = mutableListOf() keys.forEach { @@ -51,16 +49,16 @@ fun FileMetadata.getField(name: String): Field? { } } -fun FileMetadata.fieldsToProperties(): MutableList>{ +fun FileMetadata.fieldsToProperties(): MutableList> { val properties = mutableListOf>() for (field in fields.iterator()) { properties.add( Pair( "field.${field.name}", - "${field.text}" - ) + "${field.text}", + ), ) } - return properties; + return properties } diff --git a/base/src/test/kotlin/com/smeup/dbnative/PropertiesSerializationTest.kt b/base/src/test/kotlin/com/smeup/dbnative/PropertiesSerializationTest.kt index c3a44e9..735a9e6 100644 --- a/base/src/test/kotlin/com/smeup/dbnative/PropertiesSerializationTest.kt +++ b/base/src/test/kotlin/com/smeup/dbnative/PropertiesSerializationTest.kt @@ -22,7 +22,6 @@ import org.junit.Test import java.io.File class DBFileFactoryTest { - @Test fun loadAndSaveTest() { // Delete tmp file @@ -43,4 +42,4 @@ class DBFileFactoryTest { // Compare metadatas class assert(metadata2.equals(metadata1)) } -} \ No newline at end of file +} diff --git a/base/src/test/kotlin/com/smeup/dbnative/utils/FieldType.kt b/base/src/test/kotlin/com/smeup/dbnative/utils/FieldType.kt index b11b610..fe099f3 100644 --- a/base/src/test/kotlin/com/smeup/dbnative/utils/FieldType.kt +++ b/base/src/test/kotlin/com/smeup/dbnative/utils/FieldType.kt @@ -31,190 +31,173 @@ enum class Type { TIME, DATE, BINARY, - VARBINARY + VARBINARY, } sealed class FieldType { - - abstract val type: Type - abstract val size: Int - abstract val digits: Int - } + abstract val type: Type + abstract val size: Int + abstract val digits: Int +} // Fixed length string - data class CharacterType(val length: Int) : FieldType() { +data class CharacterType(val length: Int) : FieldType() { + override val type: Type + get() = Type.CHARACTER - override val type: Type - get() = Type.CHARACTER + override val size: Int + get() = length - override val size: Int - get() = length - - override val digits: Int - get() = 0 - } + override val digits: Int + get() = 0 +} // Varying length string (with max length) - data class VarcharType(val length: Int) : FieldType() { - - override val type: Type - get() = Type.VARCHAR - - override val size: Int - get() = length - - override val digits: Int - get() = 0 - } - - object IntegerType : FieldType() { +data class VarcharType(val length: Int) : FieldType() { + override val type: Type + get() = Type.VARCHAR - override val type: Type - get() = Type.INTEGER + override val size: Int + get() = length - override val size: Int - get() = 10 - - override val digits: Int - get() = 0 - } - - object SmallintType : FieldType() { + override val digits: Int + get() = 0 +} - override val type: Type - get() = Type.SMALLINT +object IntegerType : FieldType() { + override val type: Type + get() = Type.INTEGER - override val size: Int - get() = 5 + override val size: Int + get() = 10 - override val digits: Int - get() = 0 - } + override val digits: Int + get() = 0 +} - object BigintType : FieldType() { +object SmallintType : FieldType() { + override val type: Type + get() = Type.SMALLINT - override val type: Type - get() = Type.BIGINT + override val size: Int + get() = 5 - override val size: Int - get() = 19 + override val digits: Int + get() = 0 +} - override val digits: Int - get() = 0 - } +object BigintType : FieldType() { + override val type: Type + get() = Type.BIGINT - object BooleanType : FieldType() { + override val size: Int + get() = 19 - override val type: Type - get() = Type.BOOLEAN + override val digits: Int + get() = 0 +} - override val size: Int - get() = 1 +object BooleanType : FieldType() { + override val type: Type + get() = Type.BOOLEAN - override val digits: Int - get() = 0 - } + override val size: Int + get() = 1 + override val digits: Int + get() = 0 +} // Numeric with total length and number of digits (a.k.a. NUMERIC) - data class DecimalType(val length: Int, val precision: Int) : FieldType() { - - override val type: Type - get() = Type.DECIMAL +data class DecimalType(val length: Int, val precision: Int) : FieldType() { + override val type: Type + get() = Type.DECIMAL - override val size: Int - get() = length + override val size: Int + get() = length - override val digits: Int - get() = precision - } - - object FloatType : FieldType() { - - override val type: Type - get() = Type.FLOAT + override val digits: Int + get() = precision +} - override val size: Int - get() = 19 +object FloatType : FieldType() { + override val type: Type + get() = Type.FLOAT - override val digits: Int - get() = 0 - } + override val size: Int + get() = 19 - object DoubleType : FieldType() { + override val digits: Int + get() = 0 +} - override val type: Type - get() = Type.DOUBLE +object DoubleType : FieldType() { + override val type: Type + get() = Type.DOUBLE - override val size: Int - get() = 19 + override val size: Int + get() = 19 - override val digits: Int - get() = 0 - } + override val digits: Int + get() = 0 +} // Year, month, day, hour, minutes, seconds - object TimeStampType : FieldType() { - - override val type: Type - get() = Type.TIMESTAMP +object TimeStampType : FieldType() { + override val type: Type + get() = Type.TIMESTAMP - override val size: Int - get() = 14 + override val size: Int + get() = 14 - override val digits: Int - get() = 0 - } + override val digits: Int + get() = 0 +} // Year, month, day - object DateType : FieldType() { - - override val type: Type - get() = Type.DATE +object DateType : FieldType() { + override val type: Type + get() = Type.DATE - override val size: Int - get() = 8 + override val size: Int + get() = 8 - override val digits: Int - get() = 0 - - } + override val digits: Int + get() = 0 +} // hour, minutes, seconds - object TimeType : FieldType() { +object TimeType : FieldType() { + override val type: Type + get() = Type.TIME - override val type: Type - get() = Type.TIME + override val size: Int + get() = 6 - override val size: Int - get() = 6 - - override val digits: Int - get() = 0 - } + override val digits: Int + get() = 0 +} // Binary with fixed length - data class BinaryType(val length: Int) : FieldType() { +data class BinaryType(val length: Int) : FieldType() { + override val type: Type + get() = Type.BINARY - override val type: Type - get() = Type.BINARY + override val size: Int + get() = length - override val size: Int - get() = length - - override val digits: Int - get() = 0 - } + override val digits: Int + get() = 0 +} // Binary with varying length - data class VarbinaryType(val length: Int) : FieldType() { +data class VarbinaryType(val length: Int) : FieldType() { + override val type: Type + get() = Type.VARBINARY - override val type: Type - get() = Type.VARBINARY + override val size: Int + get() = length - override val size: Int - get() = length - - override val digits: Int - get() = 0 - } + override val digits: Int + get() = 0 +} diff --git a/base/src/test/kotlin/com/smeup/dbnative/utils/Types.kt b/base/src/test/kotlin/com/smeup/dbnative/utils/Types.kt index e1ca8b8..d1aee14 100644 --- a/base/src/test/kotlin/com/smeup/dbnative/utils/Types.kt +++ b/base/src/test/kotlin/com/smeup/dbnative/utils/Types.kt @@ -8,35 +8,36 @@ import java.nio.charset.Charset import java.util.* import kotlin.collections.ArrayList -data class TypedField(val field: Field, val type: FieldType){ -} +data class TypedField(val field: Field, val type: FieldType) -fun Collection.fieldList():List{ - return map({tf -> tf.field}) +fun Collection.fieldList(): List { + return map({ tf -> tf.field }) } -fun Collection.fieldTypeList():List{ - return map({tf -> tf.type}) +fun Collection.fieldTypeList(): List { + return map({ tf -> tf.type }) } -data class TypedMetadata(var name: String, - var tableName: String, - var fields: List, - var fileKeys:List){ - fun fileMetadata(): FileMetadata = FileMetadata(name, tableName, fields.fieldList(), fileKeys); +data class TypedMetadata( + var name: String, + var tableName: String, + var fields: List, + var fileKeys: List, +) { + fun fileMetadata(): FileMetadata = FileMetadata(name, tableName, fields.fieldList(), fileKeys) - fun fieldsToProperties(): MutableList>{ + fun fieldsToProperties(): MutableList> { val properties = mutableListOf>() for ((index, field) in fields.iterator().withIndex()) { properties.add( Pair( "field.${field.field.name}", - "${field.field.text},${fields[index].type.type},${fields[index].type.size},${fields[index].type.digits}" - ) + "${field.field.text},${fields[index].type.type},${fields[index].type.size},${fields[index].type.digits}", + ), ) } - return properties; + return properties } fun getField(name: String): TypedField? { @@ -50,38 +51,47 @@ data class TypedMetadata(var name: String, infix fun String.fieldByType(type: FieldType): TypedField = TypedField(Field(this), type) -fun String.getFieldTypeInstance(columnSize: Int, decimalDigits: Int): FieldType { - - val fieldTypeObject = when (this.toUpperCase()) { - "CHAR","CHARACTER" -> CharacterType(columnSize) - "VARCHAR" -> VarcharType(columnSize) - "INT", "INTEGER" -> IntegerType - "SMALLINT" -> SmallintType - "BIGINT" -> BigintType - "BOOLEAN", "BOOL" -> BooleanType - "DECIMAL" -> DecimalType(columnSize, decimalDigits) - "DOUBLE" -> DoubleType - "FLOAT" -> FloatType - "TIMESTAMP" -> TimeStampType - "TIME" -> TimeType - "DATE" -> DateType - "BINARY" -> BinaryType(columnSize) - "VARBINARY" -> VarbinaryType(columnSize) - else -> throw IllegalArgumentException("Wrong type of FieldType") - } +fun String.getFieldTypeInstance( + columnSize: Int, + decimalDigits: Int, +): FieldType { + val fieldTypeObject = + when (this.toUpperCase()) { + "CHAR", "CHARACTER" -> CharacterType(columnSize) + "VARCHAR" -> VarcharType(columnSize) + "INT", "INTEGER" -> IntegerType + "SMALLINT" -> SmallintType + "BIGINT" -> BigintType + "BOOLEAN", "BOOL" -> BooleanType + "DECIMAL" -> DecimalType(columnSize, decimalDigits) + "DOUBLE" -> DoubleType + "FLOAT" -> FloatType + "TIMESTAMP" -> TimeStampType + "TIME" -> TimeType + "DATE" -> DateType + "BINARY" -> BinaryType(columnSize) + "VARBINARY" -> VarbinaryType(columnSize) + else -> throw IllegalArgumentException("Wrong type of FieldType") + } return fieldTypeObject } -fun propertiesToTypedMetadata(propertiesDirPath: String, fileName: String): TypedMetadata { +fun propertiesToTypedMetadata( + propertiesDirPath: String, + fileName: String, +): TypedMetadata { val propertiesFile = FileInputStream(File("$propertiesDirPath${File.separatorChar}${fileName.toUpperCase()}.properties")) - //val properties = Properties() - //properties.load(InputStreamReader(propertiesFile, Charset.forName("UTF-8"))) + // val properties = Properties() + // properties.load(InputStreamReader(propertiesFile, Charset.forName("UTF-8"))) val mp: MutableMap = LinkedHashMap() object : Properties() { @Synchronized - override fun put(key: Any, value: Any): Any? { + override fun put( + key: Any, + value: Any, + ): Any? { return mp.put(key as String, value as String) } }.load(InputStreamReader(propertiesFile, Charset.forName("UTF-8"))) @@ -99,17 +109,17 @@ fun propertiesToTypedMetadata(propertiesDirPath: String, fileName: String): Type val datatype = fldAttributes[1].trim() val fieldType = datatype.getFieldTypeInstance(length, decimal) - fields.add(TypedField(Field(name, description), fieldType)) + fields.add(TypedField(Field(name, description), fieldType)) } // FormatName - val tablename = mp.get("tablename")?:"" + val tablename = mp.get("tablename") ?: "" // FieldKeys val fieldsKeys: MutableList = ArrayList() - if(!(mp.get("filekeys")).isNullOrEmpty()){ + if (!(mp.get("filekeys")).isNullOrEmpty()) { fieldsKeys.addAll((mp.get("filekeys")?.split(",")!!)) } return TypedMetadata(fileName, tablename, fields, fieldsKeys) -} \ No newline at end of file +} diff --git a/pom.xml b/pom.xml index 139fa96..9e95b8c 100644 --- a/pom.xml +++ b/pom.xml @@ -181,6 +181,20 @@ + + com.github.gantsign.maven + ktlint-maven-plugin + 3.0.0 + + + format-and-check + + format + check + + + + From 70b58a48180fc1176a68d5888a48d2f37757bbc0 Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Tue, 28 Nov 2023 18:00:59 +0100 Subject: [PATCH 17/35] Fix for chain failure after read operation - patch for maven setup --- base/src/test/kotlin/com/smeup/dbnative/utils/Types.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/base/src/test/kotlin/com/smeup/dbnative/utils/Types.kt b/base/src/test/kotlin/com/smeup/dbnative/utils/Types.kt index d1aee14..163e3a7 100644 --- a/base/src/test/kotlin/com/smeup/dbnative/utils/Types.kt +++ b/base/src/test/kotlin/com/smeup/dbnative/utils/Types.kt @@ -56,7 +56,7 @@ fun String.getFieldTypeInstance( decimalDigits: Int, ): FieldType { val fieldTypeObject = - when (this.toUpperCase()) { + when (this.uppercase()) { "CHAR", "CHARACTER" -> CharacterType(columnSize) "VARCHAR" -> VarcharType(columnSize) "INT", "INTEGER" -> IntegerType @@ -81,7 +81,7 @@ fun propertiesToTypedMetadata( propertiesDirPath: String, fileName: String, ): TypedMetadata { - val propertiesFile = FileInputStream(File("$propertiesDirPath${File.separatorChar}${fileName.toUpperCase()}.properties")) + val propertiesFile = FileInputStream(File("$propertiesDirPath${File.separatorChar}${fileName.uppercase()}.properties")) // val properties = Properties() // properties.load(InputStreamReader(propertiesFile, Charset.forName("UTF-8"))) From 92c0e93624163f46e0418c3fafd674f93125d6c5 Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Tue, 28 Nov 2023 18:04:43 +0100 Subject: [PATCH 18/35] Fix for chain failure after read operation - patch for maven setup --- base/src/main/kotlin/com/smeup/dbnative/DBManagerBaseImpl.kt | 2 +- .../com/smeup/dbnative/metadata/file/PropertiesSerializer.kt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/base/src/main/kotlin/com/smeup/dbnative/DBManagerBaseImpl.kt b/base/src/main/kotlin/com/smeup/dbnative/DBManagerBaseImpl.kt index 82fc982..a9b8e40 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/DBManagerBaseImpl.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/DBManagerBaseImpl.kt @@ -59,7 +59,7 @@ abstract class DBManagerBaseImpl : DBMManager { } override fun existFile(name: String): Boolean { - return getMetadataRegister().contains(name.toUpperCase()) + return getMetadataRegister().contains(name.uppercase()) } companion object { diff --git a/base/src/main/kotlin/com/smeup/dbnative/metadata/file/PropertiesSerializer.kt b/base/src/main/kotlin/com/smeup/dbnative/metadata/file/PropertiesSerializer.kt index 8df8111..4c3d254 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/metadata/file/PropertiesSerializer.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/metadata/file/PropertiesSerializer.kt @@ -32,7 +32,7 @@ object PropertiesSerializer { propertiesDirPath: String, fileName: String, ): FileMetadata { - val propertiesFile = FileInputStream(File("$propertiesDirPath${File.separatorChar}${fileName.toUpperCase()}.properties")) + val propertiesFile = FileInputStream(File("$propertiesDirPath${File.separatorChar}${fileName.uppercase()}.properties")) // val properties = Properties() // properties.load(InputStreamReader(propertiesFile, Charset.forName("UTF-8"))) @@ -94,7 +94,7 @@ object PropertiesSerializer { val keys = fileMetadata.fileKeys.joinToString(",") properties.add(Pair("filekeys", keys)) - val propertiesFilePath = "${propertiesDirPath}${File.separatorChar}${fileMetadata.name.toUpperCase()}.properties" + val propertiesFilePath = "${propertiesDirPath}${File.separatorChar}${fileMetadata.name.uppercase(Locale.getDefault())}.properties" val propertiesFile = File(propertiesFilePath) From ee27f3375072f7a6d3dbbed4c74c995c1294316b Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Tue, 28 Nov 2023 18:13:57 +0100 Subject: [PATCH 19/35] Fix for chain failure after read operation - patch for maven setup --- .../kotlin/com/smeup/dbnative/DBManagerBaseImpl.kt | 3 ++- .../src/main/kotlin/com/smeup/dbnative/file/Record.kt | 4 ++-- .../dbnative/metadata/file/FSMetadataRegisterImpl.kt | 11 +++++++---- .../kotlin/com/smeup/dbnative/utils/FileUtilities.kt | 2 +- .../com/smeup/dbnative/PropertiesSerializationTest.kt | 6 +++--- 5 files changed, 15 insertions(+), 11 deletions(-) diff --git a/base/src/main/kotlin/com/smeup/dbnative/DBManagerBaseImpl.kt b/base/src/main/kotlin/com/smeup/dbnative/DBManagerBaseImpl.kt index a9b8e40..93d4e1a 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/DBManagerBaseImpl.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/DBManagerBaseImpl.kt @@ -21,6 +21,7 @@ import com.smeup.dbnative.log.Logger import com.smeup.dbnative.metadata.MetadataRegister import com.smeup.dbnative.metadata.file.FSMetadataRegisterImpl import com.smeup.dbnative.model.FileMetadata +import java.util.* abstract class DBManagerBaseImpl : DBMManager { var logger: Logger? = null @@ -33,7 +34,7 @@ abstract class DBManagerBaseImpl : DBMManager { */ override fun metadataOf(name: String): FileMetadata { - return getMetadataRegister().getMetadata(name.toUpperCase()) + return getMetadataRegister().getMetadata(name.uppercase(Locale.getDefault())) } override fun registerMetadata( diff --git a/base/src/main/kotlin/com/smeup/dbnative/file/Record.kt b/base/src/main/kotlin/com/smeup/dbnative/file/Record.kt index 7be4df9..33aa86d 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/file/Record.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/file/Record.kt @@ -26,8 +26,8 @@ class Record(vararg fields: RecordField) : LinkedHashMap() { fun matches(keyFields: List) = keyFields.all { - var value1 = this[it.name]?.trim() - var value2 = it.value.trim() + val value1 = this[it.name]?.trim() + val value2 = it.value.trim() value1.equals(value2.trim()) } diff --git a/base/src/main/kotlin/com/smeup/dbnative/metadata/file/FSMetadataRegisterImpl.kt b/base/src/main/kotlin/com/smeup/dbnative/metadata/file/FSMetadataRegisterImpl.kt index ad8a280..be99aea 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/metadata/file/FSMetadataRegisterImpl.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/metadata/file/FSMetadataRegisterImpl.kt @@ -26,9 +26,12 @@ object FSMetadataRegisterImpl : MetadataRegister { init { - propertiesDirPath = System.getenv("DBNATIVE_DDS_DIR") ?: "${System.getProperty("user.home")}${File.separatorChar}" + - "etc${File.separatorChar}" + - "dbnativeaccess${File.separatorChar}dds" + propertiesDirPath = + System.getenv("DBNATIVE_DDS_DIR") ?: ( + "${System.getProperty("user.home")}${File.separatorChar}" + + "etc${File.separatorChar}" + + "dbnativeaccess${File.separatorChar}dds" + ) if (File(propertiesDirPath).exists() == false) { File(propertiesDirPath).mkdirs() @@ -51,7 +54,7 @@ object FSMetadataRegisterImpl : MetadataRegister { } override fun remove(fileName: String) { - var propertiesFile = File("${propertiesDirPath}${File.separatorChar}$fileName.properties") + val propertiesFile = File("${propertiesDirPath}${File.separatorChar}$fileName.properties") if (propertiesFile.exists()) propertiesFile.delete() } } diff --git a/base/src/main/kotlin/com/smeup/dbnative/utils/FileUtilities.kt b/base/src/main/kotlin/com/smeup/dbnative/utils/FileUtilities.kt index 1dedf4b..97d546b 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/utils/FileUtilities.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/utils/FileUtilities.kt @@ -56,7 +56,7 @@ fun FileMetadata.fieldsToProperties(): MutableList> { properties.add( Pair( "field.${field.name}", - "${field.text}", + field.text, ), ) } diff --git a/base/src/test/kotlin/com/smeup/dbnative/PropertiesSerializationTest.kt b/base/src/test/kotlin/com/smeup/dbnative/PropertiesSerializationTest.kt index 735a9e6..ecc0baf 100644 --- a/base/src/test/kotlin/com/smeup/dbnative/PropertiesSerializationTest.kt +++ b/base/src/test/kotlin/com/smeup/dbnative/PropertiesSerializationTest.kt @@ -25,19 +25,19 @@ class DBFileFactoryTest { @Test fun loadAndSaveTest() { // Delete tmp file - var tmpFile = File("src/test/resources/dds/properties/out/BRARTI0F.properties") + val tmpFile = File("src/test/resources/dds/properties/out/BRARTI0F.properties") if (tmpFile.exists()) tmpFile.delete() tmpFile.parentFile.mkdirs() // Read metadata1 from properties - var metadata1 = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "BRARTI0F") + val metadata1 = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "BRARTI0F") println(metadata1) // Save metadata1 to tmp properties file PropertiesSerializer.metadataToProperties("src/test/resources/dds/properties/out", metadata1, true) // Read metadata2 from tmp properties file - var metadata2 = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/out/", "BRARTI0F") + val metadata2 = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/out/", "BRARTI0F") // Compare metadatas class assert(metadata2.equals(metadata1)) From 6c8b74a27a20cbc998bc9e1ed97fffc2d362132d Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Wed, 29 Nov 2023 15:03:46 +0100 Subject: [PATCH 20/35] Fix source formattation and klint integration --- .../com/smeup/dbnative/jt400/JT400DBFile.kt | 91 +++--- .../smeup/dbnative/jt400/JT400DBMManager.kt | 23 +- .../dbnative/jt400/JT400Chain1KeyTest.kt | 3 - .../dbnative/jt400/JT400Chain2KeysTest.kt | 22 +- .../dbnative/jt400/JT400MunicipalityTest.kt | 11 +- .../dbnative/jt400/JT400OperationsOnFile.kt | 48 ++- .../dbnative/jt400/JT400ReadPreviousTest.kt | 3 - .../dbnative/jt400/utils/JT400DBTestUtils.kt | 181 ++++++------ .../smeup/dbnative/manager/DBFileFactory.kt | 54 ++-- .../smeup/dbnative/manager/DBFileWrapper.kt | 9 +- .../dbnative/manager/DBFileFactoryTest.kt | 92 +++--- .../com/smeup/dbnative/nosql/NoSQLDBFile.kt | 208 +++++++------ .../smeup/dbnative/nosql/NoSQLDBMManager.kt | 21 +- .../dbnative/nosql/utils/MongoDbUtils.kt | 23 +- .../smeup/dbnative/nosql/NoSQLDBFileTest.kt | 6 +- .../dbnative/nosql/NoSQLMunicipalityTest.kt | 12 +- .../dbnative/nosql/utils/NoSQLDBTestUtils.kt | 87 +++--- .../com/smeup/dbnative/sql/JDBCUtils.kt | 21 +- .../smeup/dbnative/sql/Native2SQLAdapter.kt | 200 ++++++++----- .../com/smeup/dbnative/sql/SQLDBFile.kt | 74 ++--- .../com/smeup/dbnative/sql/SQLDBFileNoPerf.kt | 133 +++++---- .../com/smeup/dbnative/sql/SQLDBMManager.kt | 34 +-- .../kotlin/com/smeup/dbnative/sql/SQLUtils.kt | 94 +++--- .../dbnative/sql/DB2400OperationsOnFile.kt | 49 ++-- .../sql/DB2400OperationsOnFilePerfTest.kt | 48 +-- .../com/smeup/dbnative/sql/JDBCUtilsTest.kt | 11 +- .../smeup/dbnative/sql/SQLChain1KeyTest.kt | 4 - .../smeup/dbnative/sql/SQLChain2KeysTest.kt | 24 +- .../dbnative/sql/SQLMunicipalityPerfTest.kt | 28 +- .../smeup/dbnative/sql/SQLMunicipalityTest.kt | 10 +- .../smeup/dbnative/sql/SQLReadEqualTest.kt | 17 +- .../smeup/dbnative/sql/SQLReadPreviousTest.kt | 5 +- .../com/smeup/dbnative/sql/SQLUtilsTest.kt | 60 ++-- .../dbnative/sql/utils/SQLDBTestUtils.kt | 276 ++++++++++-------- 34 files changed, 1032 insertions(+), 950 deletions(-) diff --git a/jt400/src/main/kotlin/com/smeup/dbnative/jt400/JT400DBFile.kt b/jt400/src/main/kotlin/com/smeup/dbnative/jt400/JT400DBFile.kt index aa8f24b..1ac67c3 100644 --- a/jt400/src/main/kotlin/com/smeup/dbnative/jt400/JT400DBFile.kt +++ b/jt400/src/main/kotlin/com/smeup/dbnative/jt400/JT400DBFile.kt @@ -29,14 +29,17 @@ import com.smeup.dbnative.model.FileMetadata import java.math.BigDecimal private enum class CursorAction { - NONE, SETLL, SETGT + NONE, + SETLL, + SETGT, } -class JT400DBFile(override var name: String, - override var fileMetadata: FileMetadata, - var file: KeyedFile, - override var logger: Logger? = null) : DBFile { - +class JT400DBFile( + override var name: String, + override var fileMetadata: FileMetadata, + var file: KeyedFile, + override var logger: Logger? = null, +) : DBFile { private var equalFlag: Boolean = false private var eofReached: Boolean = false private var previousAction: CursorAction = CursorAction.NONE @@ -96,9 +99,9 @@ class JT400DBFile(override var name: String, } catch (e: AS400Exception) { } try { - //file.positionCursorBefore(keys2Array(keys)) + // file.positionCursorBefore(keys2Array(keys)) file.positionCursor(keys2Array(keys), KeyedFile.KEY_LT) - //file.positionCursor(keys2Array(keys), KeyedFile.KEY_LT) + // file.positionCursor(keys2Array(keys), KeyedFile.KEY_LT) return true } catch (e: AS400Exception) { handleAS400Error(e) @@ -142,14 +145,14 @@ class JT400DBFile(override var name: String, override fun chain(keys: List): Result { this.previousAction = CursorAction.NONE resetStatus() - //TODO("Attenzione alla gestione del lock") + // TODO("Attenzione alla gestione del lock") try { /* file.positionCursor(keys2Array(keys), KeyedFile.KEY_EQ) var r : Result? = Result(as400RecordToSmeUPRecord(file.read())) //file.positionCursorToNext(); return r ?: fail("Read failed"); - */ + */ return Result(as400RecordToSmeUPRecord(file.read(keys2Array(keys)))) } catch (e: AS400Exception) { handleAS400Error(e) @@ -161,13 +164,13 @@ class JT400DBFile(override var name: String, * The READ operation reads the record, currently pointed to, from a full procedural file. */ override fun read(): Result { - //https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_74/rzasd/zzread.htm - var r : Result + // https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_74/rzasd/zzread.htm + var r: Result try { - if (this.previousAction==CursorAction.SETLL) { + if (this.previousAction == CursorAction.SETLL) { file.positionCursorToNext() } - r = Result(as400RecordToSmeUPRecord(file.read())) + r = Result(as400RecordToSmeUPRecord(file.read())) } catch (e: AS400Exception) { handleAS400Error(e) r = Result(Record()) @@ -186,12 +189,12 @@ class JT400DBFile(override var name: String, */ override fun readPrevious(): Result { resetStatus() - var r : Result + var r: Result try { - if (this.previousAction!=CursorAction.SETLL) { + if (this.previousAction != CursorAction.SETLL) { file.positionCursorToPrevious() } - r = Result(as400RecordToSmeUPRecord(file.read())) + r = Result(as400RecordToSmeUPRecord(file.read())) } catch (e: AS400Exception) { handleAS400Error(e) r = Result(Record()) @@ -223,10 +226,10 @@ class JT400DBFile(override var name: String, override fun readEqual(keys: List): Result { resetStatus() - //https://code400.com/forum/forum/iseries-programming-languages/java/8386-noobie-question + // https://code400.com/forum/forum/iseries-programming-languages/java/8386-noobie-question return try { - //val r = if (this.previousAction==CursorAction.SETGT) file.read(keys2Array(keys)) else file.readNextEqual(keys2Array(keys)) - if (this.previousAction==CursorAction.SETGT) { + // val r = if (this.previousAction==CursorAction.SETGT) file.read(keys2Array(keys)) else file.readNextEqual(keys2Array(keys)) + if (this.previousAction == CursorAction.SETGT) { file.positionCursorToPrevious() } val r = file.readNextEqual(keys2Array(keys)) @@ -274,7 +277,7 @@ class JT400DBFile(override var name: String, override fun readPreviousEqual(keys: List): Result { resetStatus() return try { - if (this.previousAction==CursorAction.SETLL) { + if (this.previousAction == CursorAction.SETLL) { file.positionCursorToNext() } val r = file.readPreviousEqual(keys2Array(keys)) @@ -324,8 +327,8 @@ class JT400DBFile(override var name: String, * After a conversion mapping message on a read operation, the file is positioned to the record containing the data that caused the message. */ private fun handleAS400Error(e: AS400Exception) { - //CPF5001 End of file reached - //CPF5006 Record not found + // CPF5001 End of file reached + // CPF5006 Record not found val eid = as400ErrorID(e).toUpperCase() if (eid.startsWith("CPF5001")) { this.eofReached = true @@ -335,20 +338,22 @@ class JT400DBFile(override var name: String, } throw RuntimeException() } - private fun as400ErrorID(e: AS400Exception) : String { - //CPF5001 End of file reached - //CPF5006 Record not found - if (e.aS400Message != null - && e.aS400Message.id != null) { + + private fun as400ErrorID(e: AS400Exception): String { + // CPF5001 End of file reached + // CPF5006 Record not found + if (e.aS400Message != null && + e.aS400Message.id != null + ) { return e.aS400Message.id } return "" } private fun keys2Array(keys: List): Array { - //return keys.map { it.value }.toTypedArray() + // return keys.map { it.value }.toTypedArray() val keysValues = mutableListOf() - //for (key in fileMetadata.fileKeys) { + // for (key in fileMetadata.fileKeys) { for (i in keys.indices) { val keyName = fileMetadata.fileKeys[i] val keyValue = keys.get(i) @@ -373,7 +378,7 @@ class JT400DBFile(override var name: String, private fun as400RecordToSmeUPRecord(r: com.ibm.as400.access.Record?): Record { // TODO create a unit test for the isAfterLast condition - if (r == null) { //TODO || this.isAfterLast + if (r == null) { // TODO || this.isAfterLast return Record() } val result = Record() @@ -385,10 +390,10 @@ class JT400DBFile(override var name: String, return result } - //fun com.ibm.as400.access.Record?.currentRecordToValues(): Record { + // fun com.ibm.as400.access.Record?.currentRecordToValues(): Record { private fun smeUPRecordToAS400Record(r: Record?): com.ibm.as400.access.Record? { if (r == null) { - return null //com.ibm.as400.access.Record() + return null // com.ibm.as400.access.Record() } val result = com.ibm.as400.access.Record() result.recordFormat = file.recordFormat @@ -396,20 +401,20 @@ class JT400DBFile(override var name: String, if (numericField(name)) { result.setField(name, BigDecimal(value)) } else { - //try { - result.setField(name, value.trimEnd()) - //} catch (ex : Exception) { + // try { + result.setField(name, value.trimEnd()) + // } catch (ex : Exception) { // println(ex.message) - //} + // } } } return result } - private fun numericField(name : String) : Boolean { + private fun numericField(name: String): Boolean { val dataType = file.recordFormat.getFieldDescription(name).dataType.instanceType - //val field : Field? = this.fileMetadata.getField(name) - //val type : FieldType? = field?.type + // val field : Field? = this.fileMetadata.getField(name) + // val type : FieldType? = field?.type return when (dataType) { AS400DataType.TYPE_ZONED, AS400DataType.TYPE_PACKED, @@ -423,11 +428,11 @@ class JT400DBFile(override var name: String, AS400DataType.TYPE_UBIN4, AS400DataType.TYPE_UBIN8, AS400DataType.TYPE_FLOAT4, - AS400DataType.TYPE_FLOAT8 -> + AS400DataType.TYPE_FLOAT8, + -> true else -> false } } - -} \ No newline at end of file +} diff --git a/jt400/src/main/kotlin/com/smeup/dbnative/jt400/JT400DBMManager.kt b/jt400/src/main/kotlin/com/smeup/dbnative/jt400/JT400DBMManager.kt index ca53bae..98da145 100644 --- a/jt400/src/main/kotlin/com/smeup/dbnative/jt400/JT400DBMManager.kt +++ b/jt400/src/main/kotlin/com/smeup/dbnative/jt400/JT400DBMManager.kt @@ -25,29 +25,28 @@ import com.smeup.dbnative.ConnectionConfig import com.smeup.dbnative.DBManagerBaseImpl import com.smeup.dbnative.file.DBFile -open class JT400DBMManager(final override val connectionConfig: ConnectionConfig) : DBManagerBaseImpl() { - +open class JT400DBMManager(final override val connectionConfig: ConnectionConfig) : DBManagerBaseImpl() { private var openedFile = mutableMapOf() // as400://SRVLAB01.SMEUP.COM/W_SCAARM private val match = Regex("as400://((?:\\w|\\.)+)/(\\w+)").find(connectionConfig.url) - private val host : String by lazy { + private val host: String by lazy { match!!.destructured.component1() } - private val library : String by lazy { + private val library: String by lazy { match!!.destructured.component2() } - private val connection : AS400 by lazy { + private val connection: AS400 by lazy { val as400 = AS400(host, connectionConfig.user, connectionConfig.password) as400.isGuiAvailable = false - //as400.addConnectionListener + // as400.addConnectionListener as400.connectService(AS400.RECORDACCESS) as400 } - override fun openFile(name: String) : DBFile { + override fun openFile(name: String): DBFile { require(existFile(name)) { "Cannot open unregistered file $name" } @@ -58,16 +57,15 @@ open class JT400DBMManager(final override val connectionConfig: ConnectionConfig // val fileName = QSYSObjectPathName(library, name, "*FILE", "MBR") val path = fileName.path - //println("Path: $path") + // println("Path: $path") val file = KeyedFile(connection, path) - //val rf = AS400FileRecordDescription(system, path).retrieveRecordFormat() - //file.recordFormat = rf[0] + // val rf = AS400FileRecordDescription(system, path).retrieveRecordFormat() + // file.recordFormat = rf[0] file.setRecordFormat() // Loads the record format directly from the server. file.open(AS400File.READ_WRITE, 0, AS400File.COMMIT_LOCK_LEVEL_NONE) val jt400File = JT400DBFile(name, metadataOf(name), file, logger) openedFile.putIfAbsent(name, jt400File) return jt400File - } override fun closeFile(name: String) { @@ -84,5 +82,4 @@ open class JT400DBMManager(final override val connectionConfig: ConnectionConfig override fun close() { connection.disconnectAllServices() } - -} \ No newline at end of file +} diff --git a/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400Chain1KeyTest.kt b/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400Chain1KeyTest.kt index cc11c72..73bf549 100644 --- a/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400Chain1KeyTest.kt +++ b/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400Chain1KeyTest.kt @@ -28,7 +28,6 @@ import kotlin.test.assertEquals import kotlin.test.assertTrue class JT400Chain1KeyTest { - private lateinit var dbManager: JT400DBMManager @Before @@ -60,6 +59,4 @@ class JT400Chain1KeyTest { assertTrue(dbFile.chain("XYZ").record.isEmpty()) dbManager.closeFile(TSTTAB_TABLE_NAME) } - } - diff --git a/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400Chain2KeysTest.kt b/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400Chain2KeysTest.kt index 1b5972d..002611a 100644 --- a/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400Chain2KeysTest.kt +++ b/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400Chain2KeysTest.kt @@ -28,7 +28,6 @@ import kotlin.test.assertEquals import kotlin.test.assertTrue class JT400Chain2KeysTest { - private lateinit var dbManager: JT400DBMManager @Before @@ -48,10 +47,11 @@ class JT400Chain2KeysTest { @Test fun findRecordsIfChainWithExistingKey() { val dbFile = dbManager.openFile(TST2TAB_TABLE_NAME) - val key2 = listOf( - "ABC", - "12.00" - ) + val key2 = + listOf( + "ABC", + "12.00", + ) val chainResult = dbFile.chain(key2) assertEquals("ABC", chainResult.record["TSTFLDCHR"]) assertEquals("12.00", chainResult.record["TSTFLDNBR"]) @@ -62,14 +62,12 @@ class JT400Chain2KeysTest { @Test fun doesNotFindRecordsIfChainWithNotExistingKey() { val dbFile = dbManager.openFile(TST2TAB_TABLE_NAME) - val key2 = listOf( - "ZZZ", - "12" - ) + val key2 = + listOf( + "ZZZ", + "12", + ) assertTrue(dbFile.chain(key2).record.isEmpty()) dbManager.closeFile(TST2TAB_TABLE_NAME) } - - } - diff --git a/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400MunicipalityTest.kt b/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400MunicipalityTest.kt index ab27a90..c1a95ae 100644 --- a/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400MunicipalityTest.kt +++ b/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400MunicipalityTest.kt @@ -25,9 +25,7 @@ import org.junit.Test import kotlin.test.assertEquals import kotlin.test.assertTrue - class JT400MunicipalityTest { - private lateinit var dbManager: JT400DBMManager @Before @@ -80,11 +78,11 @@ class JT400MunicipalityTest { assertTrue(dbFile.setll(buildMunicipalityKey("IT", "LOM", "BS", "ERBUSCO"))) assertEquals( "EDOLO", - getMunicipalityName(dbFile.readPreviousEqual(buildMunicipalityKey("IT", "LOM", "BS")).record) + getMunicipalityName(dbFile.readPreviousEqual(buildMunicipalityKey("IT", "LOM", "BS")).record), ) assertEquals( "DESENZANO DEL GARDA", - getMunicipalityName(dbFile.readPreviousEqual(buildMunicipalityKey("IT", "LOM", "BS")).record) + getMunicipalityName(dbFile.readPreviousEqual(buildMunicipalityKey("IT", "LOM", "BS")).record), ) dbManager.closeFile(MUNICIPALITY_TABLE_NAME) } @@ -404,7 +402,7 @@ class JT400MunicipalityTest { fun t15_eof() { val dbFile = dbManager.openFile(MUNICIPALITY_TABLE_NAME) val key3A = buildMunicipalityKey("IT", "BAS", "MT") - //val key3A = buildMunicipalityKey("IT", "LOM", "PV", "PALESTRO") + // val key3A = buildMunicipalityKey("IT", "LOM", "PV", "PALESTRO") assertTrue(dbFile.setll(key3A)) var count = 0 while (!dbFile.eof()) { @@ -414,7 +412,4 @@ class JT400MunicipalityTest { assertEquals(32, count) dbManager.closeFile(MUNICIPALITY_TABLE_NAME) } - - } - diff --git a/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400OperationsOnFile.kt b/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400OperationsOnFile.kt index 5b50436..600477d 100644 --- a/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400OperationsOnFile.kt +++ b/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400OperationsOnFile.kt @@ -32,7 +32,6 @@ import kotlin.test.assertEquals import kotlin.test.assertTrue class JT400OperationsOnFile { - private lateinit var dbManager: JT400DBMManager @Before @@ -194,7 +193,7 @@ class JT400OperationsOnFile { var chainResult = dbFile.chain(keyList) assertEquals(0, chainResult.record.size) - //Set field values and write record + // Set field values and write record chainResult.record["A§ARTI"] = key chainResult.record["A§DEAR"] = "Kotlin DBNativeAccess Write " chainResult.record["A§TIAR"] = "ART " @@ -202,17 +201,17 @@ class JT400OperationsOnFile { dbFile.write(chainResult.record) - //Must exists correct write + // Must exists correct write chainResult = dbFile.chain(keyList) assertEquals(key, chainResult.record["A§ARTI"]) assertEquals("ART ", chainResult.record["A§TIAR"]) assertEquals("Kotlin DBNativeAccess Write ", chainResult.record["A§DEAR"]) assertEquals("0 ", chainResult.record["A§TPAR"]) - //Delete record + // Delete record dbFile.delete(chainResult.record) - //Check delete success + // Check delete success chainResult = dbFile.chain(keyList) assertEquals(0, chainResult.record.size) @@ -220,7 +219,7 @@ class JT400OperationsOnFile { } @Test - fun multipleUpdateOnReadE(){ + fun multipleUpdateOnReadE() { // TEST FLOW // Step1: write 100 records with "currentTimeMillis" as unique key // Step2: read above written records and update A§DEA2 field @@ -235,7 +234,7 @@ class JT400OperationsOnFile { // Create list of items to write into A§ARTI field val items = mutableListOf() - repeat(numberOfRecordsToHandle){ + repeat(numberOfRecordsToHandle) { items.add(System.currentTimeMillis().toString() + " ") Thread.sleep(5) } @@ -246,19 +245,21 @@ class JT400OperationsOnFile { val dea2Key = "Kotlin DBNativeAccess TEST-UPDATED " // WRITE - repeat(numberOfRecordsToHandle){ + repeat(numberOfRecordsToHandle) { val record = Record() - repeat(fieldsNumber){ index -> + repeat(fieldsNumber) { index -> val name: String = dbFile.fileMetadata.fields[index].name - //print(dbFile.fileMetadata.getField(name)?.type) - val value = when(name){ - "A§ARTI" -> items[it] - "A§DEAR" -> dearKey - else -> when(tMetadata.getField(name)?.type){ - is DecimalType -> "0" - else -> "" + // print(dbFile.fileMetadata.getField(name)?.type) + val value = + when (name) { + "A§ARTI" -> items[it] + "A§DEAR" -> dearKey + else -> + when (tMetadata.getField(name)?.type) { + is DecimalType -> "0" + else -> "" + } } - } val recordField = RecordField(name, value) record.add(recordField) @@ -270,7 +271,7 @@ class JT400OperationsOnFile { // Read records with same description (A§DEAR) and update field named 'secondary description' (A§DEA2) val keyList = listOf(dearKey) assertTrue(dbFile.setll(keyList)) - //dbFile.positionCursorBefore(keyList) //TODO rivedere + // dbFile.positionCursorBefore(keyList) //TODO rivedere // Update repeat(numberOfRecordsToHandle) { val readEResult = dbFile.readEqual(keyList) @@ -283,7 +284,7 @@ class JT400OperationsOnFile { // READ AND CHECK // Check all records are updated as expected assertTrue(dbFile.setll(keyList)) - //dbFile.positionCursorBefore(keyList) //TODO rivedere + // dbFile.positionCursorBefore(keyList) //TODO rivedere repeat(numberOfRecordsToHandle) { val readEResult = dbFile.readEqual(keyList) println("[READ AND CHECK]: " + readEResult.record["A§ARTI"]) @@ -292,14 +293,13 @@ class JT400OperationsOnFile { // DELETE assertTrue(dbFile.setll(keyList)) - //dbFile.positionCursorBefore(keyList) //TODO rivedere + // dbFile.positionCursorBefore(keyList) //TODO rivedere repeat(numberOfRecordsToHandle) { val readEResult = dbFile.readEqual(keyList) assertEquals(dea2Key, readEResult.record["A§DEA2"]) - //Delete record + // Delete record dbFile.delete(readEResult.record) } - } @Test @@ -345,7 +345,7 @@ class JT400OperationsOnFile { dbManager.registerMetadata(fileMetadata, false) val dbFile = dbManager.openFile("VERAPG1L") - //keys: V£DATA, V£NOME, V£IDOJ + // keys: V£DATA, V£NOME, V£IDOJ val data = "20200901" val nome = "BNUNCA " val idoj = "0002003070" @@ -449,6 +449,4 @@ class JT400OperationsOnFile { dbManager.closeFile("BRARTI0L") } */ - } - diff --git a/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400ReadPreviousTest.kt b/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400ReadPreviousTest.kt index ad69ad5..a1a8953 100644 --- a/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400ReadPreviousTest.kt +++ b/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400ReadPreviousTest.kt @@ -25,7 +25,6 @@ import kotlin.test.assertEquals import kotlin.test.assertTrue class JT400ReadPreviousTest { - private lateinit var dbManager: JT400DBMManager @Before @@ -80,6 +79,4 @@ class JT400ReadPreviousTest { assertEquals("SALLY KWAN", getEmployeeName(dbFile.read().record)) dbManager.closeFile(EMPLOYEE_TABLE_NAME) } - - } diff --git a/jt400/src/test/kotlin/com/smeup/dbnative/jt400/utils/JT400DBTestUtils.kt b/jt400/src/test/kotlin/com/smeup/dbnative/jt400/utils/JT400DBTestUtils.kt index 96de888..1ae3ad1 100644 --- a/jt400/src/test/kotlin/com/smeup/dbnative/jt400/utils/JT400DBTestUtils.kt +++ b/jt400/src/test/kotlin/com/smeup/dbnative/jt400/utils/JT400DBTestUtils.kt @@ -35,8 +35,9 @@ const val TSTTAB_TABLE_NAME = "TSTTAB" const val TST2TAB_TABLE_NAME = "TST2TAB" const val MUNICIPALITY_TABLE_NAME = "MUNIC0000B" const val TEST_LOG = false -//do not change defaultValue -//if you want to create sqlconnection against another db use function: dbManagerForTest(testSQLDBType: TestSQLDBType) + +// do not change defaultValue +// if you want to create sqlconnection against another db use function: dbManagerForTest(testSQLDBType: TestSQLDBType) private var defaultDbType = TestSQLDBType.DB2_400 const val DB2_400_HOST = "SRVLAB01.SMEUP.COM" const val DB2_400_LIBRARY_NAME = "W_PARFRA" @@ -46,32 +47,34 @@ const val CONVENTIONAL_INDEX_SUFFIX = "_INDEX" enum class TestSQLDBType( val connectionConfig: ConnectionConfig, val dbaConnectionConfig: ConnectionConfig? = connectionConfig, - val createDatabase : (dbaConnection: AS400) -> Unit = {}, - val destroyDatabase: (dbaConnection: AS400) -> Unit = {}) { - DB2_400(ConnectionConfig( - fileName= "*", + val createDatabase: (dbaConnection: AS400) -> Unit = {}, + val destroyDatabase: (dbaConnection: AS400) -> Unit = {}, +) { + DB2_400( + ConnectionConfig( + fileName = "*", driver = "com.ibm.as400.access.AS400JDBCDriver", url = "jdbc:as400://$DB2_400_HOST/$DB2_400_LIBRARY_NAME;", user = "USER", - password = "*********"), - //force no create connection for dba operations - dbaConnectionConfig = null - ) - + password = "*********", + ), + // force no create connection for dba operations + dbaConnectionConfig = null, + ), } fun dbManagerForTest() = dbManagerForTest(defaultDbType) -fun dbManagerForTest(testSQLDBType: TestSQLDBType) : JT400DBMManager { +fun dbManagerForTest(testSQLDBType: TestSQLDBType): JT400DBMManager { testLog("Creating SQLDBManager with db type = $testSQLDBType") val dbManager = JT400DBMManager(testSQLDBType.connectionConfig) if (testSQLDBType.dbaConnectionConfig != null) { - //JT400DBMMAnager(testSQLDBType.dbaConnectionConfig).connection.use { + // JT400DBMMAnager(testSQLDBType.dbaConnectionConfig).connection.use { // testSQLDBType.createDatabase(it) - //} + // } } - //dbManager.setSQLLog(TEST_LOG) + // dbManager.setSQLLog(TEST_LOG) return dbManager } @@ -81,117 +84,121 @@ fun destroyDatabase() { fun destroyDatabase(testSQLDBType: TestSQLDBType) { if (testSQLDBType.dbaConnectionConfig != null) { - //JT400DBMMAnager(testSQLDBType.dbaConnectionConfig).connection.use { + // JT400DBMMAnager(testSQLDBType.dbaConnectionConfig).connection.use { // testSQLDBType.destroyDatabase(it) - //} + // } } } fun createAndPopulateMunicipalityTable(dbManager: JT400DBMManager?) { - val fields = listOf( - "NAZ" fieldByType CharacterType(2), - "REG" fieldByType CharacterType(3), - "PROV" fieldByType CharacterType(2), - "CITTA" fieldByType VarcharType(35), - "CAP" fieldByType CharacterType(5), - "PREF" fieldByType CharacterType(4), - "COMUNE" fieldByType CharacterType(4), - "ISTAT" fieldByType CharacterType(6) - ) - - val keys = listOf( - "NAZ", - "REG", - "PROV", - "CITTA" - ) - - - //createAndPopulateTable( /* ci mette tantissimo >20min, la teniamo fissa già creata */ + val fields = + listOf( + "NAZ" fieldByType CharacterType(2), + "REG" fieldByType CharacterType(3), + "PROV" fieldByType CharacterType(2), + "CITTA" fieldByType VarcharType(35), + "CAP" fieldByType CharacterType(5), + "PREF" fieldByType CharacterType(4), + "COMUNE" fieldByType CharacterType(4), + "ISTAT" fieldByType CharacterType(6), + ) + + val keys = + listOf( + "NAZ", + "REG", + "PROV", + "CITTA", + ) + + // createAndPopulateTable( /* ci mette tantissimo >20min, la teniamo fissa già creata */ registerTable( dbManager, MUNICIPALITY_TABLE_NAME, "TSTREC", fields, keys, - "src/test/resources/csv/Municipality.csv" + "src/test/resources/csv/Municipality.csv", ) - /**/ + // } fun createAndPopulateTestTable(dbManager: JT400DBMManager?) { - val fields = listOf( - "TSTFLDCHR" fieldByType CharacterType(3), - "TSTFLDNBR" fieldByType DecimalType(5, 2) - ) - - val keys = listOf( - "TSTFLDCHR", - "TSTFLDNBR" - ) - - - //createAndPopulateTable( /* ci mette tantissimo >20min, la teniamo fissa già creata */ + val fields = + listOf( + "TSTFLDCHR" fieldByType CharacterType(3), + "TSTFLDNBR" fieldByType DecimalType(5, 2), + ) + + val keys = + listOf( + "TSTFLDCHR", + "TSTFLDNBR", + ) + + // createAndPopulateTable( /* ci mette tantissimo >20min, la teniamo fissa già creata */ registerTable( dbManager, TSTTAB_TABLE_NAME, "TSTREC", fields, keys, - "src/test/resources/csv/TstTab.csv" + "src/test/resources/csv/TstTab.csv", ) - /**/ + // } fun createAndPopulateTest2Table(dbManager: JT400DBMManager?) { - val fields = listOf( - "TSTFLDCHR" fieldByType CharacterType(3), - "TSTFLDNBR" fieldByType DecimalType(5, 2), - "DESTST" fieldByType CharacterType(10), - ) - - val keys = listOf( - "TSTFLDCHR", - "TSTFLDNBR" - ) - - - //createAndPopulateTable( /* ci mette tantissimo >20min, la teniamo fissa già creata */ + val fields = + listOf( + "TSTFLDCHR" fieldByType CharacterType(3), + "TSTFLDNBR" fieldByType DecimalType(5, 2), + "DESTST" fieldByType CharacterType(10), + ) + + val keys = + listOf( + "TSTFLDCHR", + "TSTFLDNBR", + ) + + // createAndPopulateTable( /* ci mette tantissimo >20min, la teniamo fissa già creata */ registerTable( dbManager, TST2TAB_TABLE_NAME, "TSTREC", fields, keys, - "src/test/resources/csv/TstTab.csv" + "src/test/resources/csv/TstTab.csv", ) - /**/ + // } fun createAndPopulateEmployeeTable(dbManager: JT400DBMManager?) { - val fields = listOf( - "EMPNO" fieldByType CharacterType(6), - "FIRSTNME" fieldByType CharacterType(20), - "MIDINIT" fieldByType CharacterType(1), - "LASTNAME" fieldByType CharacterType(20), - "WORKDEPT" fieldByType CharacterType(3), - ) - - val keys = listOf( - "EMPNO" - ) - - - //createAndPopulateTable( /* ci mette tantissimo >20min, la teniamo fissa già creata */ + val fields = + listOf( + "EMPNO" fieldByType CharacterType(6), + "FIRSTNME" fieldByType CharacterType(20), + "MIDINIT" fieldByType CharacterType(1), + "LASTNAME" fieldByType CharacterType(20), + "WORKDEPT" fieldByType CharacterType(3), + ) + + val keys = + listOf( + "EMPNO", + ) + + // createAndPopulateTable( /* ci mette tantissimo >20min, la teniamo fissa già creata */ registerTable( dbManager, EMPLOYEE_TABLE_NAME, "TSTREC", fields, keys, - "src/test/resources/csv/Employee.csv" + "src/test/resources/csv/Employee.csv", ) - /**/ + // } fun getEmployeeName(record: Record): String { @@ -214,7 +221,7 @@ private fun registerTable( formatName: String, fields: List, keys: List, - dataFilePath: String + dataFilePath: String, ) { val metadata = TypedMetadata(tableName, formatName, fields, keys).fileMetadata() dbManager!!.registerMetadata(metadata, true) @@ -261,7 +268,7 @@ fun buildMunicipalityKey(vararg values: String): List { val recordFields = mutableListOf() val keys = arrayOf("NAZ", "REG", "PROV", "CITTA") for ((index, value) in values.withIndex()) { - if (keys.size> index) { + if (keys.size > index) { recordFields.add(value) } } @@ -290,5 +297,3 @@ fun connectJDBC() : Connection { return DriverManager.getConnection(connectionConfig.url, connectionConfig.user, connectionConfig.password) } */ - - diff --git a/manager/src/main/kotlin/com/smeup/dbnative/manager/DBFileFactory.kt b/manager/src/main/kotlin/com/smeup/dbnative/manager/DBFileFactory.kt index 6b17deb..a909a28 100644 --- a/manager/src/main/kotlin/com/smeup/dbnative/manager/DBFileFactory.kt +++ b/manager/src/main/kotlin/com/smeup/dbnative/manager/DBFileFactory.kt @@ -40,10 +40,9 @@ import com.smeup.dbnative.model.FileMetadata * */ class DBFileFactory( private val config: DBNativeAccessConfig, - private val fileNameNormalizer: (String) -> String = {it} + private val fileNameNormalizer: (String) -> String = { it }, ) : AutoCloseable { - - private val managers = mutableMapOf () + private val managers = mutableMapOf() /** * Open the file named fileName. A file can only be opened after registration of its metadata. @@ -54,10 +53,13 @@ class DBFileFactory( * @param fileName file to open * @param fileMetadata metadata to register. If passed, file metadata is registered before file opening * */ - fun open(fileName: String, fileMetadata: FileMetadata?) : DBFile { + fun open( + fileName: String, + fileMetadata: FileMetadata?, + ): DBFile { val fileNameNormalized = fileNameNormalizer(fileName) val configMatch = findConnectionConfigFor(fileNameNormalized, config.connectionsConfig) - val dbmManager = managers.getOrPut(configMatch) {createDBManager(configMatch, config.logger).apply { validateConfig() }} + val dbmManager = managers.getOrPut(configMatch) { createDBManager(configMatch, config.logger).apply { validateConfig() } } if (fileMetadata != null) { dbmManager.registerMetadata(fileMetadata, true) @@ -87,7 +89,7 @@ class DBFileFactory( } override fun close() { - managers.values.forEach {it.close()} + managers.values.forEach { it.close() } } } @@ -96,34 +98,42 @@ class DBFileFactory( * @param fileName file name * @param connectionsConfig ConnectionConfig entries * */ -fun findConnectionConfigFor(fileName: String, connectionsConfig: List) : ConnectionConfig { - val configList = connectionsConfig.filter { - it.fileName.toUpperCase() == fileName.toUpperCase() || it.fileName == "*" || +fun findConnectionConfigFor( + fileName: String, + connectionsConfig: List, +): ConnectionConfig { + val configList = + connectionsConfig.filter { + it.fileName.toUpperCase() == fileName.toUpperCase() || it.fileName == "*" || fileName.toUpperCase().matches(Regex(it.fileName.toUpperCase().replace("*", ".*"))) - } + } require(configList.isNotEmpty()) { "Wrong configuration. Not found a ConnectionConfig entry matching name: $fileName" } - //At the top of the list we have ConnectionConfig whose property file does not have wildcards + // At the top of the list we have ConnectionConfig whose property file does not have wildcards return configList.sortedWith(DBFileFactory.COMPARATOR)[0] } -private fun createDBManager(config: ConnectionConfig, logger: Logger? = null): DBMManager { +private fun createDBManager( + config: ConnectionConfig, + logger: Logger? = null, +): DBMManager { val impl = getImplByUrl(config) - val clazz :Class? = Class.forName(impl) as Class? + val clazz: Class? = Class.forName(impl) as Class? return clazz?.let { val constructor = it.getConstructor(ConnectionConfig::class.java) val dbmManager = constructor.newInstance(config) - if(dbmManager is DBManagerBaseImpl){ - dbmManager.logger = logger - } + if (dbmManager is DBManagerBaseImpl) + { + dbmManager.logger = logger + } return dbmManager }!! } -private fun getImplByUrl(config: ConnectionConfig) : String { +private fun getImplByUrl(config: ConnectionConfig): String { return when { config.impl != null && config.impl!!.trim().isEmpty() -> config.impl!! config.url.startsWith("jdbc:") -> "com.smeup.dbnative.sql.SQLDBMManager" @@ -133,10 +143,12 @@ private fun getImplByUrl(config: ConnectionConfig) : String { } } -//ConnectionConfig.file with wildcards at the bottom +// ConnectionConfig.file with wildcards at the bottom class ConnectionConfigComparator : Comparator { - - override fun compare(o1: ConnectionConfig?, o2: ConnectionConfig?): Int { + override fun compare( + o1: ConnectionConfig?, + o2: ConnectionConfig?, + ): Int { require(o1 != null) require(o2 != null) return when { @@ -148,4 +160,4 @@ class ConnectionConfigComparator : Comparator { else -> o1.fileName.compareTo(o2.fileName) } } -} \ No newline at end of file +} diff --git a/manager/src/main/kotlin/com/smeup/dbnative/manager/DBFileWrapper.kt b/manager/src/main/kotlin/com/smeup/dbnative/manager/DBFileWrapper.kt index 8b78eb4..0fd69ff 100644 --- a/manager/src/main/kotlin/com/smeup/dbnative/manager/DBFileWrapper.kt +++ b/manager/src/main/kotlin/com/smeup/dbnative/manager/DBFileWrapper.kt @@ -24,8 +24,7 @@ import com.smeup.dbnative.file.Result import com.smeup.dbnative.log.Logger import com.smeup.dbnative.model.FileMetadata -class DBFileWrapper (private val dbFile: DBFile, private val dbmManager: DBMManager): DBFile { - +class DBFileWrapper(private val dbFile: DBFile, private val dbmManager: DBMManager) : DBFile { private var closed = false override var name: String @@ -37,7 +36,9 @@ class DBFileWrapper (private val dbFile: DBFile, private val dbmManager: DBMMana set(value) {} override var logger: Logger? get() = dbFile.logger - set(value) {dbFile.logger = value} + set(value) { + dbFile.logger = value + } override fun eof(): Boolean { return dbFile.eof() @@ -142,4 +143,4 @@ class DBFileWrapper (private val dbFile: DBFile, private val dbmManager: DBMMana closed = true dbmManager.closeFile(fileMetadata.tableName) } -} \ No newline at end of file +} diff --git a/manager/src/test/kotlin/com/smeup/dbnative/manager/DBFileFactoryTest.kt b/manager/src/test/kotlin/com/smeup/dbnative/manager/DBFileFactoryTest.kt index acbb3a4..4c03040 100644 --- a/manager/src/test/kotlin/com/smeup/dbnative/manager/DBFileFactoryTest.kt +++ b/manager/src/test/kotlin/com/smeup/dbnative/manager/DBFileFactoryTest.kt @@ -32,51 +32,57 @@ import org.junit.Before import org.junit.Test import kotlin.test.assertEquals import kotlin.test.assertTrue + private val LOGGING_LEVEL = LoggingLevel.OFF private enum class TestConnectionConfig( - val connectionConfig: ConnectionConfig + val connectionConfig: ConnectionConfig, ) { DEFAULT( - connectionConfig = ConnectionConfig( - fileName= "*", - url = "jdbc:hsqldb:mem:TEST", - user = "", - password = "", - driver = "org.hsqldb.jdbcDriver" - ) + connectionConfig = + ConnectionConfig( + fileName = "*", + url = "jdbc:hsqldb:mem:TEST", + user = "", + password = "", + driver = "org.hsqldb.jdbcDriver", + ), ), STARTS_WITH_TEST( - connectionConfig = ConnectionConfig( - fileName= "TEST*", - url = "jdbc:hsqldb:mem:TEST", - user = "", - password = "", - driver = "org.hsqldb.jdbcDriver" - ) + connectionConfig = + ConnectionConfig( + fileName = "TEST*", + url = "jdbc:hsqldb:mem:TEST", + user = "", + password = "", + driver = "org.hsqldb.jdbcDriver", + ), ), MUNICIPALITY( ConnectionConfig( - fileName= "MUNICIPALITY", + fileName = "MUNICIPALITY", url = "mongodb://localhost:27017/W_TEST", user = "", - password = "") - ) + password = "", + ), + ), } class DBFileFactoryTest { - - private lateinit var config : DBNativeAccessConfig + private lateinit var config: DBNativeAccessConfig private lateinit var manager: SQLDBMManager @Before fun setUp() { - config = DBNativeAccessConfig(mutableListOf( - TestConnectionConfig.DEFAULT.connectionConfig, - TestConnectionConfig.STARTS_WITH_TEST.connectionConfig, - TestConnectionConfig.MUNICIPALITY.connectionConfig - ), - Logger.getSimpleInstance(LOGGING_LEVEL)) + config = + DBNativeAccessConfig( + mutableListOf( + TestConnectionConfig.DEFAULT.connectionConfig, + TestConnectionConfig.STARTS_WITH_TEST.connectionConfig, + TestConnectionConfig.MUNICIPALITY.connectionConfig, + ), + Logger.getSimpleInstance(LOGGING_LEVEL), + ) manager = SQLDBMManager(TestConnectionConfig.STARTS_WITH_TEST.connectionConfig) manager.connection.createStatement().use { it.executeUpdate("CREATE TABLE TEST1F (NAME CHAR(20))") @@ -94,31 +100,36 @@ class DBFileFactoryTest { testFields.add("NAME" fieldByType CharacterType(20)) val testTableMetadata = FileMetadata("TEST1L", "TEST1F", testFields.fieldList(), listOf("NAME")) manager.registerMetadata(testTableMetadata, true) - } @Test fun findConnectionForPIPPO() { - assertEquals(TestConnectionConfig.DEFAULT.connectionConfig, - findConnectionConfigFor("PIPPO/PLUTO", config.connectionsConfig)) + assertEquals( + TestConnectionConfig.DEFAULT.connectionConfig, + findConnectionConfigFor("PIPPO/PLUTO", config.connectionsConfig), + ) } @Test fun findConnectionForTESTXXX() { - assertEquals(TestConnectionConfig.STARTS_WITH_TEST.connectionConfig, - findConnectionConfigFor("TEST3L", config.connectionsConfig)) + assertEquals( + TestConnectionConfig.STARTS_WITH_TEST.connectionConfig, + findConnectionConfigFor("TEST3L", config.connectionsConfig), + ) } @Test fun findConnectionForMUNICIPALITY() { - assertEquals(TestConnectionConfig.MUNICIPALITY.connectionConfig, - findConnectionConfigFor("MUNICIPALITY", config.connectionsConfig)) + assertEquals( + TestConnectionConfig.MUNICIPALITY.connectionConfig, + findConnectionConfigFor("MUNICIPALITY", config.connectionsConfig), + ) } - //test ok if no throw exception + // test ok if no throw exception @Test fun openExistingTables() { - DBFileFactory(config).use {dbFileFactory -> + DBFileFactory(config).use { dbFileFactory -> // Open a file already registered dbFileFactory.open("TEST1L", null) @@ -143,9 +154,9 @@ class DBFileFactoryTest { DBFileFactory(config).use { dbFileFactory -> val dbFile = dbFileFactory.open("TEST1L", null) var result = dbFile.chain("MARCO") - assertTrue (result.record["NAME"]?.trim().equals("MARCO")) + assertTrue(result.record["NAME"]?.trim().equals("MARCO")) result = dbFile.chain("DARIO") - assertTrue (result.record["NAME"]?.trim().equals("DARIO")) + assertTrue(result.record["NAME"]?.trim().equals("DARIO")) dbFile.close() } @@ -160,12 +171,12 @@ class DBFileFactoryTest { @Test fun reopenClosedFile() { - DBFileFactory(config).use {dbFileFactory -> + DBFileFactory(config).use { dbFileFactory -> val dbFile = dbFileFactory.open("TEST1L", null) dbFile.setll("DARIO") dbFile.read() dbFile.close() - assertTrue (dbFile.runCatching { read() }.isFailure) + assertTrue(dbFile.runCatching { read() }.isFailure) } } @@ -184,5 +195,4 @@ class DBFileFactoryTest { manager.unregisterMetadata("TEST2L") manager.unregisterMetadata("TEST3L") } - -} \ No newline at end of file +} diff --git a/nosql/src/main/kotlin/com/smeup/dbnative/nosql/NoSQLDBFile.kt b/nosql/src/main/kotlin/com/smeup/dbnative/nosql/NoSQLDBFile.kt index be0bb2e..7e0e98e 100644 --- a/nosql/src/main/kotlin/com/smeup/dbnative/nosql/NoSQLDBFile.kt +++ b/nosql/src/main/kotlin/com/smeup/dbnative/nosql/NoSQLDBFile.kt @@ -35,11 +35,12 @@ import com.smeup.dbnative.utils.matchFileKeys import org.bson.Document import kotlin.system.measureTimeMillis -class NoSQLDBFile(override var name: String, - override var fileMetadata: FileMetadata, - private val database: MongoDatabase, - override var logger: Logger? = null): DBFile { - +class NoSQLDBFile( + override var name: String, + override var fileMetadata: FileMetadata, + private val database: MongoDatabase, + override var logger: Logger? = null, +) : DBFile { private var globalCursor: MongoCursor? = null private var up_direction: Boolean = true private var last_set_keys: List = emptyList() @@ -48,8 +49,11 @@ class NoSQLDBFile(override var name: String, private var eof: Boolean = false private var lastNativeMethod: NativeMethod? = null - private fun logEvent(loggingKey: LoggingKey, message: String, elapsedTime: Long? = null) = - logger?.logEvent(loggingKey, message, elapsedTime, lastNativeMethod, fileMetadata.name) + private fun logEvent( + loggingKey: LoggingKey, + message: String, + elapsedTime: Long? = null, + ) = logger?.logEvent(loggingKey, message, elapsedTime, lastNativeMethod, fileMetadata.name) override fun eof(): Boolean { return eof @@ -67,7 +71,6 @@ class NoSQLDBFile(override var name: String, } } - override fun setll(key: String): Boolean { return setll(mutableListOf(key)) } @@ -82,10 +85,11 @@ class NoSQLDBFile(override var name: String, measureTimeMillis { eof = false - var keyAsRecordField = keys.mapIndexed { index, value -> - val keyname = fileMetadata.fileKeys.get(index) - RecordField(keyname, value) - } + var keyAsRecordField = + keys.mapIndexed { index, value -> + val keyname = fileMetadata.fileKeys.get(index) + RecordField(keyname, value) + } /* Passed keys are not primary key for DBFile @@ -94,7 +98,6 @@ class NoSQLDBFile(override var name: String, return false } - /* Find syntax @@ -104,7 +107,7 @@ class NoSQLDBFile(override var name: String, {$and:[{ NAZ: { $eq: "IT" } }, { REG: { $eq: "LOM" } }, { PROV: { $eq: "BS" } }, { CITTA: { $gt: "ERBUSCO" } } ] } - */ + */ /* val filter = StringBuilder() @@ -152,7 +155,7 @@ class NoSQLDBFile(override var name: String, up_direction = true last_keys = keys - */ + */ val cursor = calculateCursor(keyAsRecordField, true, true) @@ -185,10 +188,11 @@ class NoSQLDBFile(override var name: String, measureTimeMillis { eof = false - var keyAsRecordField = keys.mapIndexed { index, value -> - val keyname = fileMetadata.fileKeys.get(index) - RecordField(keyname, value) - } + var keyAsRecordField = + keys.mapIndexed { index, value -> + val keyname = fileMetadata.fileKeys.get(index) + RecordField(keyname, value) + } /* Passed keys are not primary key for DBFile @@ -206,19 +210,19 @@ class NoSQLDBFile(override var name: String, {$and:[{ NAZ: { $gte: "IT" } }, { REG: { $gte: "LOM" } }, { PROV: { $gte: "BS" } }, { CITTA: { $gte: "ERBUSCO" } } ] } - *** SETGT forward: + *** SETGT forward: {$and:[{ NAZ: { $eq: "IT" } }, { REG: { $eq: "LOM" } }, { PROV: { $eq: "BS" } }, { CITTA: { $gt: "ERBUSCO" } } ] } with order {NAZ: 1, REG: 1, PROV: 1, CITTA: 1} - ***SETGT backward: + ***SETGT backward: {$and:[{ NAZ: { $eq: "IT" } }, { REG: { $eq: "LOM" } }, { PROV: { $eq: "BS" } }, { CITTA: { $gt: "ERBUSCO" } } ] } with order {NAZ: 1, REG: 1, PROV: 1, CITTA: -1} - */ + */ /* val filter = StringBuilder() @@ -231,8 +235,7 @@ class NoSQLDBFile(override var name: String, filter.append("{ ${dbField.name}: {\$gt: \"${keys.get(keys.indexOfFirst { recordField -> recordField.name == dbField.name }).value}\" } }") } } - */ - + */ /* Sort sintax: @@ -273,14 +276,13 @@ class NoSQLDBFile(override var name: String, last_set_keys = keyAsRecordField IncludeFirst = false }.apply { - logEvent(LoggingKey.native_access_method, "setgt executed", this) + logEvent(LoggingKey.native_access_method, "setgt executed", this) } lastNativeMethod = null return result } override fun chain(key: String): Result { - return chain(mutableListOf(key)) } @@ -291,37 +293,37 @@ class NoSQLDBFile(override var name: String, measureTimeMillis { eof = false - var keyAsRecordField = keys.mapIndexed { index, value -> - val keyname = fileMetadata.fileKeys.get(index) - RecordField(keyname, value) - } + var keyAsRecordField = + keys.mapIndexed { index, value -> + val keyname = fileMetadata.fileKeys.get(index) + RecordField(keyname, value) + } /* Passed keys are not primary key for DBFile */ if (fileMetadata.matchFileKeys(keyAsRecordField) == false) { - result = Result(record = Record(), indicatorLO = true) - } - else { - + result = Result(record = Record(), indicatorLO = true) + } else { val cursor = calculateCursor(keyAsRecordField, true, true) globalCursor = cursor.iterator() up_direction = true last_set_keys = keyAsRecordField - //when globalCursor is empty return result empty + // when globalCursor is empty return result empty val document = globalCursor!!.tryNext() - if(document == null){ - result = Result(Record()) - } - else - if (matchKeys(document, keyAsRecordField)) { - val record = documentToRecord(document) - updateLastKeys(record) - result = Result(record) - } else { - result = Result(Record()) + if (document == null) + { + result = Result(Record()) + } else { + if (matchKeys(document, keyAsRecordField)) { + val record = documentToRecord(document) + updateLastKeys(record) + result = Result(record) + } else { + result = Result(Record()) + } } } }.apply { @@ -341,7 +343,7 @@ class NoSQLDBFile(override var name: String, if (globalCursor == null) { return Result( indicatorLO = true, - errorMsg = "Cursor not defined. Call SETLL or SETGT before invoke READ command" + errorMsg = "Cursor not defined. Call SETLL or SETGT before invoke READ command", ) } @@ -356,7 +358,6 @@ class NoSQLDBFile(override var name: String, IncludeFirst = true if (globalCursor != null) { - if (globalCursor!!.hasNext()) { val record = documentToRecord(globalCursor!!.next()) if (globalCursor!!.hasNext()) { @@ -398,10 +399,11 @@ class NoSQLDBFile(override var name: String, lastNativeMethod = NativeMethod.readEqual logEvent(LoggingKey.native_access_method, "Executing readEqual on keys $keys") measureTimeMillis { - var keyAsRecordField = keys.mapIndexed { index, value -> - val keyname = fileMetadata.fileKeys.get(index) - RecordField(keyname, value) - } + var keyAsRecordField = + keys.mapIndexed { index, value -> + val keyname = fileMetadata.fileKeys.get(index) + RecordField(keyname, value) + } if (globalCursor == null) { globalCursor = calculateCursor(keyAsRecordField, true, true).iterator() @@ -426,7 +428,6 @@ class NoSQLDBFile(override var name: String, while (true) { if (globalCursor!!.hasNext()) { - val document = globalCursor!!.next() val record = documentToRecord(document) @@ -457,7 +458,7 @@ class NoSQLDBFile(override var name: String, if (globalCursor == null) { return Result( indicatorLO = true, - errorMsg = "Cursor not defined. Call SETLL or SETGT before invoke READ command" + errorMsg = "Cursor not defined. Call SETLL or SETGT before invoke READ command", ) } @@ -472,7 +473,6 @@ class NoSQLDBFile(override var name: String, IncludeFirst = true if (globalCursor != null) { - if (globalCursor!!.hasNext()) { val record = documentToRecord(globalCursor!!.next()) if (globalCursor!!.hasNext()) { @@ -506,15 +506,16 @@ class NoSQLDBFile(override var name: String, lastNativeMethod = NativeMethod.readPreviousEqual logEvent(LoggingKey.native_access_method, "Executing readPreviousEqual on keys $keys") measureTimeMillis { - var keyAsRecordField = keys.mapIndexed { index, value -> - val keyname = fileMetadata.fileKeys.get(index) - RecordField(keyname, value) - } + var keyAsRecordField = + keys.mapIndexed { index, value -> + val keyname = fileMetadata.fileKeys.get(index) + RecordField(keyname, value) + } if (globalCursor == null) { return Result( indicatorLO = true, - errorMsg = "Cursor not defined. Call SETLL or SETGT before invoke READ command" + errorMsg = "Cursor not defined. Call SETLL or SETGT before invoke READ command", ) } @@ -536,10 +537,8 @@ class NoSQLDBFile(override var name: String, IncludeFirst = true - while (true) { if (globalCursor!!.hasNext()) { - val document = globalCursor!!.next() val record = documentToRecord(document) @@ -563,7 +562,6 @@ class NoSQLDBFile(override var name: String, lastNativeMethod = null } - override fun write(record: Record): Result { lastNativeMethod = NativeMethod.write logEvent(LoggingKey.native_access_method, "Executing write for record $record") @@ -579,7 +577,7 @@ class NoSQLDBFile(override var name: String, } override fun update(record: Record): Result { - TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + TODO("not implemented") // To change body of created functions use File | Settings | File Templates. } override fun delete(record: Record): Result { @@ -591,8 +589,10 @@ class NoSQLDBFile(override var name: String, /* Evaluate matching between values of passed keys and relative values in document */ - private fun matchKeys(document: Document, keys: List): Boolean { - + private fun matchKeys( + document: Document, + keys: List, + ): Boolean { var match = true keys.forEach({ @@ -602,10 +602,8 @@ class NoSQLDBFile(override var name: String, }) return match - } - private fun documentToRecord(document: Document?): Record { val result = Record() @@ -617,7 +615,11 @@ class NoSQLDBFile(override var name: String, return result } - private fun calculateCursor(keys: List, up_direction: Boolean, includeFirst: Boolean): FindIterable { + private fun calculateCursor( + keys: List, + up_direction: Boolean, + includeFirst: Boolean, + ): FindIterable { /* Complete examples for filters in file filter_syntax_examples.txt @@ -650,7 +652,7 @@ class NoSQLDBFile(override var name: String, ] } - */ + */ var operator1: MongoOperator = MongoOperator.EQ var operator2: MongoOperator = MongoOperator.EQ @@ -692,25 +694,36 @@ class NoSQLDBFile(override var name: String, } } - val filter = StringBuilder() filter.append("{\$or:[") val orContent = StringBuilder() - // Add first line val line = StringBuilder() line.append("{\$and:[") - keyFields.forEachIndexed{index: Int, dbField: Field -> - if (index != keyFields.size-1) { - line.append("{ \"${dbField.name}\": {${operator3.symbol} \"${keys.get(keys.indexOfFirst { recordField -> recordField.name == dbField.name }).value}\" } }, ") - } - else { - line.append("{ \"${dbField.name}\": {${operator1.symbol} \"${keys.get(keys.indexOfFirst { recordField -> recordField.name == dbField.name }).value}\" } }") + keyFields.forEachIndexed { index: Int, dbField: Field -> + if (index != keyFields.size - 1) { + line.append( + "{ \"${dbField.name}\": {${operator3.symbol} \"${keys.get( + keys.indexOfFirst { + recordField -> + recordField.name == dbField.name + }, + ).value}\" } }, ", + ) + } else { + line.append( + "{ \"${dbField.name}\": {${operator1.symbol} \"${keys.get( + keys.indexOfFirst { + recordField -> + recordField.name == dbField.name + }, + ).value}\" } }", + ) } } @@ -720,23 +733,34 @@ class NoSQLDBFile(override var name: String, // Add other lines if (keyFields.size > 1) { - var while_index = keyFields.size while (while_index > 1) { - val tempLine = StringBuilder() tempLine.append(", {\$and:[") - val subList = keyFields.subList(0, while_index-1) - - subList.forEachIndexed{index: Int, dbField: Field -> - if (index != subList.size-1) { - tempLine.append("{ \"${dbField.name}\": {${operator3.symbol} \"${keys.get(keys.indexOfFirst { recordField -> recordField.name == dbField.name }).value}\" } }, ") - } - else { - tempLine.append("{ \"${dbField.name}\": {${operator2.symbol} \"${keys.get(keys.indexOfFirst { recordField -> recordField.name == dbField.name }).value}\" } }") + val subList = keyFields.subList(0, while_index - 1) + + subList.forEachIndexed { index: Int, dbField: Field -> + if (index != subList.size - 1) { + tempLine.append( + "{ \"${dbField.name}\": {${operator3.symbol} \"${keys.get( + keys.indexOfFirst { + recordField -> + recordField.name == dbField.name + }, + ).value}\" } }, ", + ) + } else { + tempLine.append( + "{ \"${dbField.name}\": {${operator2.symbol} \"${keys.get( + keys.indexOfFirst { + recordField -> + recordField.name == dbField.name + }, + ).value}\" } }", + ) } } @@ -752,7 +776,6 @@ class NoSQLDBFile(override var name: String, filter.append("] }") - /* Sort sintax: @@ -762,7 +785,7 @@ class NoSQLDBFile(override var name: String, val sort = StringBuilder() - keyFields.joinTo(sort, separator= ",", prefix= "{", postfix = "}") { + keyFields.joinTo(sort, separator = ",", prefix = "{", postfix = "}") { if (up_direction) { "\"${it.name}\": 1" } else { @@ -771,7 +794,7 @@ class NoSQLDBFile(override var name: String, } sort.append("}") logEvent(LoggingKey.execute_inquiry, "Building filter command $filter with sort $sort") - //println("$filter - $sort") + // println("$filter - $sort") val cursor = database.getCollection(fileMetadata.tableName).find(Document.parse(filter.toString())) @@ -779,7 +802,6 @@ class NoSQLDBFile(override var name: String, } private fun updateLastKeys(record: Record) { - val lastKeys = mutableListOf() fileMetadata.fileKeys.forEach { lastKeys.add(RecordField(it, record.getValue(it))) @@ -793,8 +815,6 @@ class NoSQLDBFile(override var name: String, GT("\$gt:"), GE("\$gte:"), LT("\$lt:"), - LE("\$lte:") + LE("\$lte:"), } - } - diff --git a/nosql/src/main/kotlin/com/smeup/dbnative/nosql/NoSQLDBMManager.kt b/nosql/src/main/kotlin/com/smeup/dbnative/nosql/NoSQLDBMManager.kt index 9d195cd..c84f690 100644 --- a/nosql/src/main/kotlin/com/smeup/dbnative/nosql/NoSQLDBMManager.kt +++ b/nosql/src/main/kotlin/com/smeup/dbnative/nosql/NoSQLDBMManager.kt @@ -17,14 +17,11 @@ package com.smeup.dbnative.nosql -import com.mongodb.BasicDBObject import com.mongodb.MongoClient -import com.mongodb.client.MongoCollection import com.mongodb.client.MongoDatabase import com.smeup.dbnative.ConnectionConfig import com.smeup.dbnative.DBManagerBaseImpl import com.smeup.dbnative.file.DBFile -import org.bson.Document /** * Assign table: @@ -34,24 +31,23 @@ import org.bson.Document * Record --> Object in collection */ -class NoSQLDBMManager (override val connectionConfig: ConnectionConfig) : DBManagerBaseImpl() { - +class NoSQLDBMManager(override val connectionConfig: ConnectionConfig) : DBManagerBaseImpl() { private val match = Regex("mongodb://((?:\\w|\\.)+):(\\d+)/(\\w+)").find(connectionConfig.url) - private val host : String by lazy { + private val host: String by lazy { match!!.destructured.component1() } - private val port : Int by lazy { + private val port: Int by lazy { match!!.destructured.component2().toInt() } - private val dataBase : String by lazy { + private val dataBase: String by lazy { match!!.destructured.component3() } - private val mongoClient : MongoClient by lazy { + private val mongoClient: MongoClient by lazy { MongoClient(host, port) } - val mongoDatabase : MongoDatabase by lazy { + val mongoDatabase: MongoDatabase by lazy { mongoClient.getDatabase(dataBase) } @@ -64,13 +60,12 @@ class NoSQLDBMManager (override val connectionConfig: ConnectionConfig) : DBMana } override fun close() { - openedFile.values.forEach { it.close()} + openedFile.values.forEach { it.close() } openedFile.clear() mongoClient.close() } override fun openFile(name: String): DBFile { - require(existFile(name)) { "Cannot open unregistered file $name" } @@ -93,4 +88,4 @@ class NoSQLDBMManager (override val connectionConfig: ConnectionConfig) : DBMana override fun closeFile(name: String) { openedFile.remove(name)!!.close() } -} \ No newline at end of file +} diff --git a/nosql/src/main/kotlin/com/smeup/dbnative/nosql/utils/MongoDbUtils.kt b/nosql/src/main/kotlin/com/smeup/dbnative/nosql/utils/MongoDbUtils.kt index ac0ed3a..3ab6b17 100644 --- a/nosql/src/main/kotlin/com/smeup/dbnative/nosql/utils/MongoDbUtils.kt +++ b/nosql/src/main/kotlin/com/smeup/dbnative/nosql/utils/MongoDbUtils.kt @@ -20,14 +20,16 @@ package com.smeup.dbnative.nosql.utils import com.smeup.dbnative.file.Record import com.smeup.dbnative.model.FileMetadata - -fun FileMetadata.buildInsertCommand(filename: String, record: Record): String { - //TODO: insert controls beetwen metadata and record format - println("Build insert command from ${filename} metadata") +fun FileMetadata.buildInsertCommand( + filename: String, + record: Record, +): String { + // TODO: insert controls beetwen metadata and record format + println("Build insert command from $filename metadata") val documents = StringBuilder() - record.toList().joinTo(documents, separator=",", prefix="{", postfix="}") { + record.toList().joinTo(documents, separator = ",", prefix = "{", postfix = "}") { "\"${it.first}\": \"${it.second}\"" } @@ -41,10 +43,8 @@ fun FileMetadata.buildInsertCommand(filename: String, record: Record): String { println(result) return result - } - /* Expected command format: @@ -74,11 +74,10 @@ Expected command format: */ -fun FileMetadata.buildIndexCommand(): String{ - +fun FileMetadata.buildIndexCommand(): String { val keys = StringBuilder() - this.fileKeys.joinTo(keys, separator=",", prefix="{", postfix="}") { + this.fileKeys.joinTo(keys, separator = ",", prefix = "{", postfix = "}") { "\"${it}\": 1" } @@ -87,7 +86,7 @@ fun FileMetadata.buildIndexCommand(): String{ createIndexes: "${this.tableName.toUpperCase()}", indexes: [ { - key: ${keys}, + key: $keys, name: "${this.tableName.toUpperCase()}_index", unique: false } @@ -98,6 +97,4 @@ fun FileMetadata.buildIndexCommand(): String{ println(result) return result - } - diff --git a/nosql/src/test/kotlin/com/smeup/dbnative/nosql/NoSQLDBFileTest.kt b/nosql/src/test/kotlin/com/smeup/dbnative/nosql/NoSQLDBFileTest.kt index 09a152d..7b42d4a 100644 --- a/nosql/src/test/kotlin/com/smeup/dbnative/nosql/NoSQLDBFileTest.kt +++ b/nosql/src/test/kotlin/com/smeup/dbnative/nosql/NoSQLDBFileTest.kt @@ -27,11 +27,10 @@ import kotlin.test.assertEquals import kotlin.test.assertFalse class NoSQLDBFileTest { - private val tableName = TSTAB_TABLE_NAME companion object { - private lateinit var dbManager : NoSQLDBMManager + private lateinit var dbManager: NoSQLDBMManager @BeforeClass @JvmStatic @@ -84,8 +83,5 @@ class NoSQLDBFileTest { @After fun destroyEnv() { - } - } - diff --git a/nosql/src/test/kotlin/com/smeup/dbnative/nosql/NoSQLMunicipalityTest.kt b/nosql/src/test/kotlin/com/smeup/dbnative/nosql/NoSQLMunicipalityTest.kt index 4275e2d..a5fd3db 100644 --- a/nosql/src/test/kotlin/com/smeup/dbnative/nosql/NoSQLMunicipalityTest.kt +++ b/nosql/src/test/kotlin/com/smeup/dbnative/nosql/NoSQLMunicipalityTest.kt @@ -29,7 +29,6 @@ import kotlin.test.assertEquals import kotlin.test.assertTrue class NoSQLMunicipalityTest { - private lateinit var dbManager: NoSQLDBMManager @Before @@ -74,11 +73,11 @@ class NoSQLMunicipalityTest { assertTrue(dbFile.setll(buildMunicipalityKey("IT", "LOM", "BS", "ERBUSCO"))) assertEquals( "EDOLO", - getMunicipalityName(dbFile.readPreviousEqual(buildMunicipalityKey("IT", "LOM", "BS")).record) + getMunicipalityName(dbFile.readPreviousEqual(buildMunicipalityKey("IT", "LOM", "BS")).record), ) assertEquals( "DESENZANO DEL GARDA", - getMunicipalityName(dbFile.readPreviousEqual(buildMunicipalityKey("IT", "LOM", "BS")).record) + getMunicipalityName(dbFile.readPreviousEqual(buildMunicipalityKey("IT", "LOM", "BS")).record), ) dbManager.closeFile(MUNICIPALITY_TABLE_NAME) } @@ -92,7 +91,6 @@ class NoSQLMunicipalityTest { dbManager.closeFile(MUNICIPALITY_TABLE_NAME) } - @Test fun t04_findLastOfBergamoWithSetll4AndReadPE2() { val dbFile = dbManager.openFile(MUNICIPALITY_TABLE_NAME) @@ -402,20 +400,16 @@ class NoSQLMunicipalityTest { @After fun destroyEnv() { - } - private fun buildMunicipalityKey(vararg values: String): List { val keyValues = mutableListOf() val keys = arrayOf("£NAZ", "§REG", "PROV", "CITTA") for ((index, value) in values.withIndex()) { - if (keys.size> index) { + if (keys.size > index) { keyValues.add(value) } } return keyValues } - } - diff --git a/nosql/src/test/kotlin/com/smeup/dbnative/nosql/utils/NoSQLDBTestUtils.kt b/nosql/src/test/kotlin/com/smeup/dbnative/nosql/utils/NoSQLDBTestUtils.kt index a307638..b121e6f 100644 --- a/nosql/src/test/kotlin/com/smeup/dbnative/nosql/utils/NoSQLDBTestUtils.kt +++ b/nosql/src/test/kotlin/com/smeup/dbnative/nosql/utils/NoSQLDBTestUtils.kt @@ -18,7 +18,6 @@ package com.smeup.dbnative.nosql.utils import com.github.doyaaaaaken.kotlincsv.dsl.csvReader -import com.mongodb.BasicDBObject import com.smeup.dbnative.ConnectionConfig import com.smeup.dbnative.file.DBFile import com.smeup.dbnative.file.Record @@ -30,7 +29,6 @@ import com.smeup.dbnative.nosql.NoSQLDBMManager import com.smeup.dbnative.utils.TypedField import com.smeup.dbnative.utils.TypedMetadata import com.smeup.dbnative.utils.fieldByType -import com.smeup.dbnative.utils.getFieldTypeInstance import org.bson.Document import org.junit.Assert import java.io.File @@ -42,19 +40,23 @@ private val LOGGING_LEVEL = LoggingLevel.OFF fun dbManagerForTest(): NoSQLDBMManager { testLog("Creating NOSQLDBManager with db type MONGO") - return NoSQLDBMManager(ConnectionConfig("*", "mongodb://localhost:27017/W_TEST", "", "")).apply { logger = Logger.getSimpleInstance(LOGGING_LEVEL) } + return NoSQLDBMManager(ConnectionConfig("*", "mongodb://localhost:27017/W_TEST", "", "")).apply { + logger = Logger.getSimpleInstance(LOGGING_LEVEL) + } } fun createAndPopulateTestTable(dbManager: NoSQLDBMManager) { // Create file - val fields = listOf( - "TSTFLDCHR" fieldByType CharacterType(3), - "TSTFLDNBR" fieldByType DecimalType(5, 2) - ) - - val keys = listOf( - "TSTFLDCHR" - ) + val fields = + listOf( + "TSTFLDCHR" fieldByType CharacterType(3), + "TSTFLDNBR" fieldByType DecimalType(5, 2), + ) + + val keys = + listOf( + "TSTFLDCHR", + ) val tMetadata = TypedMetadata(TSTAB_TABLE_NAME, "TSTREC", fields, keys) createFile(tMetadata, dbManager) @@ -67,33 +69,32 @@ fun createAndPopulateTestTable(dbManager: NoSQLDBMManager) { } fun createAndPopulateMunicipalityTable(dbManager: NoSQLDBMManager) { - if (!dbManager.existFile(MUNICIPALITY_TABLE_NAME)) { - - val fields = listOf( - "£NAZ" fieldByType CharacterType(2), - "§REG" fieldByType CharacterType(3), - "PROV" fieldByType CharacterType(2), - "CITTA" fieldByType VarcharType(35), - "CAP" fieldByType CharacterType(5), - "PREF" fieldByType CharacterType(4), - "COMUNE" fieldByType CharacterType(4), - "ISTAT" fieldByType CharacterType(6) - ) - - val keys = listOf( - "£NAZ", - "§REG", - "PROV", - "CITTA" - ) + val fields = + listOf( + "£NAZ" fieldByType CharacterType(2), + "§REG" fieldByType CharacterType(3), + "PROV" fieldByType CharacterType(2), + "CITTA" fieldByType VarcharType(35), + "CAP" fieldByType CharacterType(5), + "PREF" fieldByType CharacterType(4), + "COMUNE" fieldByType CharacterType(4), + "ISTAT" fieldByType CharacterType(6), + ) + + val keys = + listOf( + "£NAZ", + "§REG", + "PROV", + "CITTA", + ) createAndPopulateTable( - dbManager, MUNICIPALITY_TABLE_NAME, fields, keys, - "src/test/resources/csv/Municipality.csv" + "src/test/resources/csv/Municipality.csv", ) } } @@ -109,13 +110,17 @@ fun testLog(message: String) { } } -private fun createAndPopulateTable(dbManager: NoSQLDBMManager, tableName: String, fields: List, keys:List, dataFilePath: String) { - +private fun createAndPopulateTable( + dbManager: NoSQLDBMManager, + tableName: String, + fields: List, + keys: List, + dataFilePath: String, +) { val tMetadata = TypedMetadata(tableName, tableName, fields, keys) - //if not exist file on mongodb create and populate with data + // if not exist file on mongodb create and populate with data if (dbManager.existFile(tableName) == false) { - createFile(tMetadata, dbManager) Assert.assertTrue(dbManager.existFile(tableName)) var dbFile = dbManager.openFile(tableName) @@ -135,18 +140,18 @@ private fun createAndPopulateTable(dbManager: NoSQLDBMManager, tableName: String } dbManager.closeFile(tableName) - } -fun createFile(tMetadata: TypedMetadata, dbManager: NoSQLDBMManager) { +fun createFile( + tMetadata: TypedMetadata, + dbManager: NoSQLDBMManager, +) { // Find table registration in library metadata file - val metadata: FileMetadata = tMetadata.fileMetadata(); + val metadata: FileMetadata = tMetadata.fileMetadata() if (dbManager.existFile(metadata.name) == false) { - // Create file index dbManager.mongoDatabase.runCommand(Document.parse(metadata.buildIndexCommand())) } dbManager.registerMetadata(metadata, true) - } diff --git a/sql/src/main/kotlin/com/smeup/dbnative/sql/JDBCUtils.kt b/sql/src/main/kotlin/com/smeup/dbnative/sql/JDBCUtils.kt index 72c7821..9b256d9 100644 --- a/sql/src/main/kotlin/com/smeup/dbnative/sql/JDBCUtils.kt +++ b/sql/src/main/kotlin/com/smeup/dbnative/sql/JDBCUtils.kt @@ -40,7 +40,8 @@ fun ResultSet.joinToString(separator: String = " - "): String { fun PreparedStatement.bind(values: List) { values.forEachIndexed { - i, value -> this.setObject(i + 1, value) + i, value -> + this.setObject(i + 1, value) } } @@ -55,7 +56,8 @@ fun Connection.recordFormatName(tableName: String): String? = return@use tableName } -private fun ResultSet.indexId() = "${this.getString("TABLE_CAT")}." + +private fun ResultSet.indexId() = + "${this.getString("TABLE_CAT")}." + "${this.getString("TABLE_SCHEM")}.${this.getString("INDEX_NAME")}" private fun ResultSet.isUnique() = this.getInt("NON_UNIQUE") == 0 @@ -67,10 +69,10 @@ fun Connection.primaryKeys(tableName: String): List { result.add(it.getString("COLUMN_NAME")) } } - //if primary key is not defined i will get it by first unique index + // if primary key is not defined i will get it by first unique index if (result.isEmpty()) { var indexId: String? = null - //a row for every field in the indexes + // a row for every field in the indexes this.metaData.getIndexInfo(null, null, tableName, true, false).use { while (it.next()) { if (indexId == null) { @@ -78,8 +80,7 @@ fun Connection.primaryKeys(tableName: String): List { } if (it.indexId() != indexId) { break - } - else { + } else { result.add(it.getString("COLUMN_NAME")) } } @@ -98,7 +99,7 @@ fun Connection.orderingFields(tableName: String): List { if (it.next()) { // TODO handle DESC and ASC keywords val fields = it.getString(field).toUpperCase().substringAfter("ORDER BY").split(",") - result.addAll(fields.map { fl: String -> fl.substring(fl.lastIndexOf('.') + 1).trim('`', ' ') }) + result.addAll(fields.map { fl: String -> fl.substring(fl.lastIndexOf('.') + 1).trim('`', ' ') }) } } } @@ -110,7 +111,8 @@ fun ResultSet?.closeIfOpen() { if (this != null) { try { this.close() - } catch (t: Throwable) {} + } catch (t: Throwable) { + } } } @@ -136,6 +138,3 @@ fun ResultSet?.currentRecordToValues(): Record { } return result } - - - diff --git a/sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt b/sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt index 1254fe5..5ab8b7c 100644 --- a/sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt +++ b/sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt @@ -1,33 +1,39 @@ package com.smeup.dbnative.sql import com.smeup.dbnative.file.Record -import com.smeup.dbnative.model.FileMetadata import com.smeup.dbnative.model.Field +import com.smeup.dbnative.model.FileMetadata import java.lang.Exception enum class PositioningMethod { - SETLL, SETGT; + SETLL, + SETGT, } -enum class ReadMethod(val forward: Boolean){ - READE(true), READPE(false), READP(false), READ(true), CHAIN(true); +enum class ReadMethod(val forward: Boolean) { + READE(true), + READPE(false), + READP(false), + READ(true), + CHAIN(true), } -enum class SortOrder(val symbol: String){ - ASCEDING("ASC"), DESCENDING("DESC"); +enum class SortOrder(val symbol: String) { + ASCEDING("ASC"), + DESCENDING("DESC"), } -class PositioningInstruction(val method: PositioningMethod, val keys: List){ +class PositioningInstruction(val method: PositioningMethod, val keys: List) { init { - require(keys.isNotEmpty()){ + require(keys.isNotEmpty()) { "No keys specified for positioning instruction $method" } } } -class ReadInstruction(var method: ReadMethod, var keys: List){ - constructor(method: ReadMethod): this(method, emptyList()){ - require(admitEmptyKeys()){ +class ReadInstruction(var method: ReadMethod, var keys: List) { + constructor(method: ReadMethod) : this(method, emptyList()) { + require(admitEmptyKeys()) { "Keys are mandatory for read instruction $method " } } @@ -39,40 +45,43 @@ class Native2SQL(val fileMetadata: FileMetadata) { private var lastPositioningInstruction: PositioningInstruction? = null private var lastReadInstruction: ReadInstruction? = null - private fun checkPositioning(){ - requireNotNull(lastPositioningInstruction){ + private fun checkPositioning() { + requireNotNull(lastPositioningInstruction) { "No positioning instruction found" } } - private fun checkKeys(keys: List){ - require(fileMetadata.fileKeys.size > 0){ + private fun checkKeys(keys: List) { + require(fileMetadata.fileKeys.size > 0) { "No keys specified in metadata" } - require(keys.size <= fileMetadata.fileKeys.size){ + require(keys.size <= fileMetadata.fileKeys.size) { "Number of metadata keys $fileMetadata.fileKeys less than number of positioning/read keys $keys" } } - private fun checkRead(){ - requireNotNull(lastReadInstruction){ + private fun checkRead() { + requireNotNull(lastReadInstruction) { "No read instruction found" } } - private fun checkReadKeys(){ + private fun checkReadKeys() { checkRead() - require(!lastReadInstruction!!.keys.isNullOrEmpty()){ + require(!lastReadInstruction!!.keys.isNullOrEmpty()) { "No keys specified for read instruction ${lastReadInstruction!!.method}" } } - private fun checkInstructions(){ + private fun checkInstructions() { checkPositioning() checkRead() } - fun setPositioning(method: PositioningMethod, keys: List){ + fun setPositioning( + method: PositioningMethod, + keys: List, + ) { checkKeys(keys) lastPositioningInstruction = PositioningInstruction(method, keys) lastReadInstruction = null @@ -81,14 +90,17 @@ class Native2SQL(val fileMetadata: FileMetadata) { /* * @return true if read method need new query execution */ - fun setRead(method: ReadMethod, keys: List? = null): Boolean{ + fun setRead( + method: ReadMethod, + keys: List? = null, + ): Boolean { checkKeys(keys ?: emptyList()) var executeQuery = false - when(method){ - ReadMethod.READPE, ReadMethod.READE ->{ - val coherent = keys?.let{isCoherent(keys)} ?: true - //Test to remove on fully supported operations - require(coherent){ + when (method) { + ReadMethod.READPE, ReadMethod.READE -> { + val coherent = keys?.let { isCoherent(keys) } ?: true + // Test to remove on fully supported operations + require(coherent) { "Uncoherent read not yet managed" } } @@ -101,90 +113,105 @@ class Native2SQL(val fileMetadata: FileMetadata) { require(lastReadInstruction == null || method == ReadMethod.CHAIN || method == lastReadInstruction!!.method) { "read operation " + method + " is allowed immediatly after positioning or after a same method read instruction" } - if(lastReadInstruction == null){ + if (lastReadInstruction == null) { executeQuery = true } - lastReadInstruction = ReadInstruction(method, keys ?:emptyList()) + lastReadInstruction = ReadInstruction(method, keys ?: emptyList()) return executeQuery } - fun clear(){ + fun clear() { lastReadInstruction = null lastPositioningInstruction = null } - fun getLastKeys() = lastReadInstruction?.keys ?:lastPositioningInstruction?.keys ?: throw Exception("Keys not yet set") + fun getLastKeys() = lastReadInstruction?.keys ?: lastPositioningInstruction?.keys ?: throw Exception("Keys not yet set") - fun isLastOperationSet()=lastReadInstruction == null + fun isLastOperationSet() = lastReadInstruction == null fun lastReadMatchRecord(record: Record): Boolean { - if(lastReadInstruction!!.keys.isEmpty()){ + if (lastReadInstruction!!.keys.isEmpty()) { return true } lastReadInstruction!!.keys.mapIndexed { index, value -> val keyname = fileMetadata.fileKeys.get(index) - if(record[keyname]?.trim() != value.trim()){ + if (record[keyname]?.trim() != value.trim()) { return false } } return true } - - fun isCoherent(newKeys: List): Boolean{ + fun isCoherent(newKeys: List): Boolean { checkPositioning() return newKeys.isEmpty() || if (newKeys.size <= lastPositioningInstruction!!.keys.size && - newKeys.size <= lastReadInstruction?.keys?.size?:newKeys.size) { - newKeys.forEachIndexed() { index, value -> - if(lastPositioningInstruction!!.keys.get(index) != value){ - return false + newKeys.size <= lastReadInstruction?.keys?.size ?: newKeys.size + ) { + newKeys.forEachIndexed { index, value -> + if (lastPositioningInstruction!!.keys.get(index) != value) { + return false + } } + return true + } else { + false } - return true - } - else false } - private fun getSortOrder(): SortOrder { checkInstructions() - return if(lastReadInstruction!!.method.forward) SortOrder.ASCEDING else SortOrder.DESCENDING + return if (lastReadInstruction!!.method.forward) SortOrder.ASCEDING else SortOrder.DESCENDING } - private fun getComparison(): Pair{ + private fun getComparison(): Pair { checkInstructions() - return if(lastReadInstruction!!.method.forward){ - when(lastPositioningInstruction!!.method){ - PositioningMethod.SETLL -> return Pair(Comparison.GE, Comparison.GT) - PositioningMethod.SETGT -> return Pair(Comparison.GT, Comparison.GT) + return if (lastReadInstruction!!.method.forward) { + when (lastPositioningInstruction!!.method) { + PositioningMethod.SETLL -> return Pair(Comparison.GE, Comparison.GT) + PositioningMethod.SETGT -> return Pair(Comparison.GT, Comparison.GT) } - } - else{ - when(lastPositioningInstruction!!.method){ + } else { + when (lastPositioningInstruction!!.method) { PositioningMethod.SETLL -> return Pair(Comparison.LT, Comparison.LT) PositioningMethod.SETGT -> return Pair(Comparison.LE, Comparison.LT) } } } - private fun getSQLOrderByClause(): String{ + private fun getSQLOrderByClause(): String { val sortOrder = getSortOrder() - return " ORDER BY " + fileMetadata.fileKeys.joinToString(separator = " " + sortOrder.symbol + ", ", postfix = " " + sortOrder.symbol ) + return " ORDER BY " + fileMetadata.fileKeys.joinToString(separator = " " + sortOrder.symbol + ", ", postfix = " " + sortOrder.symbol) } - fun getReadSqlStatement(): Pair>{ + fun getReadSqlStatement(): Pair> { checkPositioning() - return Pair(getSQL(fileMetadata.fields, fileMetadata.fileKeys.subList(0, lastPositioningInstruction!!.keys.size), Comparison.EQ, fileMetadata.tableName), lastPositioningInstruction!!.keys) + return Pair( + getSQL( + fileMetadata.fields, + fileMetadata.fileKeys.subList(0, lastPositioningInstruction!!.keys.size), + Comparison.EQ, + fileMetadata.tableName, + ), + lastPositioningInstruction!!.keys, + ) } - fun getSQLSatement(): Pair>{ - when(lastReadInstruction!!.method){ - ReadMethod.CHAIN ->{ + fun getSQLSatement(): Pair> { + when (lastReadInstruction!!.method) { + ReadMethod.CHAIN -> { checkReadKeys() - return Pair(getSQL(fileMetadata.fields, fileMetadata.fileKeys.subList(0, lastReadInstruction!!.keys.size), Comparison.EQ, fileMetadata.tableName), lastReadInstruction!!.keys) + return Pair( + getSQL( + fileMetadata.fields, + fileMetadata.fileKeys.subList(0, lastReadInstruction!!.keys.size), + Comparison.EQ, + fileMetadata.tableName, + ), + lastReadInstruction!!.keys, + ) } - ReadMethod.READ,ReadMethod.READP -> { + ReadMethod.READ, ReadMethod.READP -> { checkRead() return getCoherentSql(true) } @@ -195,23 +222,28 @@ class Native2SQL(val fileMetadata: FileMetadata) { } } - - private fun getCoherentSql(fullUnion: Boolean = false):Pair>{ + private fun getCoherentSql(fullUnion: Boolean = false): Pair> { checkPositioning() val queries = mutableListOf() val replacements = mutableListOf() val comparison = getComparison() - require(!lastPositioningInstruction!!.keys.isEmpty()){ + require(!lastPositioningInstruction!!.keys.isEmpty()) { "Empty positioning keys" } - if(lastPositioningInstruction!!.keys.size == 1){ + if (lastPositioningInstruction!!.keys.size == 1) { queries.add(getSQL(fileMetadata.fields, fileMetadata.fileKeys.subList(0, 1), comparison.first, fileMetadata.tableName)) replacements.addAll(lastPositioningInstruction!!.keys) - } - else { - val limit = if(fullUnion)1 else 2 + } else { + val limit = if (fullUnion)1 else 2 for (i in lastPositioningInstruction!!.keys.size downTo limit) { - queries.add(getSQL(fileMetadata.fields, fileMetadata.fileKeys.subList(0, i), if(i == lastPositioningInstruction!!.keys.size) comparison.first else comparison.second, fileMetadata.tableName)) + queries.add( + getSQL( + fileMetadata.fields, + fileMetadata.fileKeys.subList(0, i), + if (i == lastPositioningInstruction!!.keys.size) comparison.first else comparison.second, + fileMetadata.tableName, + ), + ) replacements.addAll(lastPositioningInstruction!!.keys.subList(0, i)) } } @@ -219,7 +251,12 @@ class Native2SQL(val fileMetadata: FileMetadata) { } } -private fun getSQL(fields: List, keys: List, comparison: Comparison, tableName: String): String{ +private fun getSQL( + fields: List, + keys: List, + comparison: Comparison, + tableName: String, +): String { var columns = "" fields.forEachIndexed { index, k -> run { @@ -230,22 +267,23 @@ private fun getSQL(fields: List, keys: List, comparison: Comparis var value = "" keys.forEachIndexed { index, k -> run { - value += "\"" + k + "\" " + (if (index < keys.size - 1) Comparison.EQ.symbol else comparison.symbol) + " ? AND " + value += "\"" + k + "\" " + (if (index < keys.size - 1) Comparison.EQ.symbol else comparison.symbol) + " ? AND " } } - return "(SELECT " + columns.removeSuffix(", ")+ " FROM $tableName WHERE " + value.removeSuffix("AND ") + ")" + return "(SELECT " + columns.removeSuffix(", ") + " FROM $tableName WHERE " + value.removeSuffix("AND ") + ")" } -fun main(){ +fun main() { var fields = listOf(Field("Regione", ""), Field("Provincia", ""), Field("Comune", "")) var fieldsKeys = listOf("Regione", "Provincia", "Comune") var metadata = FileMetadata("test", "rld_comuni", fields, fieldsKeys) - val adapter = Native2SQL(metadata).apply{ - setPositioning(PositioningMethod.SETLL, listOf("Lombardia", "Brescia", "Erbusco")) - println(isCoherent(listOf("Lombardia", "Brescia", "Erbusco"))) - setRead(ReadMethod.READE, listOf("Lombardia", "Brescia", "Erbusco")) - } - adapter.getSQLSatement().let{ + val adapter = + Native2SQL(metadata).apply { + setPositioning(PositioningMethod.SETLL, listOf("Lombardia", "Brescia", "Erbusco")) + println(isCoherent(listOf("Lombardia", "Brescia", "Erbusco"))) + setRead(ReadMethod.READE, listOf("Lombardia", "Brescia", "Erbusco")) + } + adapter.getSQLSatement().let { println(it.first) println(it.second) } diff --git a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFile.kt b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFile.kt index 45d48ae..903797e 100644 --- a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFile.kt +++ b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFile.kt @@ -17,7 +17,6 @@ package com.smeup.dbnative.sql - import com.smeup.dbnative.file.DBFile import com.smeup.dbnative.file.Record import com.smeup.dbnative.file.Result @@ -30,14 +29,17 @@ import java.sql.PreparedStatement import java.sql.ResultSet import kotlin.system.measureTimeMillis -class SQLDBFile(override var name: String, override var fileMetadata: FileMetadata, - var connection: Connection, - override var logger: Logger? = null) : DBFile { - +class SQLDBFile( + override var name: String, + override var fileMetadata: FileMetadata, + var connection: Connection, + override var logger: Logger? = null, +) : DBFile { constructor( name: String, fileMetadata: FileMetadata, - connection: Connection): this(name, fileMetadata, connection, null) + connection: Connection, + ) : this(name, fileMetadata, connection, null) private var preparedStatements: MutableMap = mutableMapOf() private var resultSet: ResultSet? = null @@ -45,8 +47,8 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada private var lastNativeMethod: NativeMethod? = null - //Search from: metadata, primary key, unique index, view ordering fields - //private val thisFileKeys: List by lazy { + // Search from: metadata, primary key, unique index, view ordering fields + // private val thisFileKeys: List by lazy { // // TODO: think about a right way (local file maybe?) to retrieve keylist // var indexes = this.fileMetadata.fileKeys // if(indexes.isEmpty()){ @@ -54,14 +56,16 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada // } // } // if (indexes.isEmpty()) connection.orderingFields(fileMetadata.name) else indexes - //} + // } private var adapter: Native2SQL = Native2SQL(this.fileMetadata) - private var eof:Boolean = false - - private fun logEvent(loggingKey: LoggingKey, message: String, elapsedTime: Long? = null) = - logger?.logEvent(loggingKey, message, elapsedTime, lastNativeMethod, fileMetadata.name) + private var eof: Boolean = false + private fun logEvent( + loggingKey: LoggingKey, + message: String, + elapsedTime: Long? = null, + ) = logger?.logEvent(loggingKey, message, elapsedTime, lastNativeMethod, fileMetadata.name) override fun setll(key: String): Boolean { return setll(mutableListOf(key)) @@ -85,7 +89,6 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada adapter.setPositioning(PositioningMethod.SETGT, keys) return true - } override fun chain(key: String): Result { @@ -98,7 +101,6 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada adapter.setRead(ReadMethod.CHAIN, keys) val read: Result measureTimeMillis { - executeQuery(adapter.getSQLSatement()) read = readNextFromResultSet() }.apply { @@ -113,7 +115,7 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada logEvent(LoggingKey.native_access_method, "Executing read") val read: Result measureTimeMillis { - if (adapter.setRead(ReadMethod.READ) ) { + if (adapter.setRead(ReadMethod.READ)) { executeQuery(adapter.getSQLSatement()) } read = readNextFromResultSet() @@ -153,7 +155,6 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada logEvent(LoggingKey.native_access_method, "Executing readEqual on keys $keys") val read: Result measureTimeMillis { - if (adapter.setRead(ReadMethod.READE, keys)) { executeQuery(adapter.getSQLSatement()) } @@ -165,7 +166,6 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada return read } - override fun readPreviousEqual(): Result { return readPreviousEqual(adapter.getLastKeys()) } @@ -179,7 +179,6 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada logEvent(LoggingKey.native_access_method, "Executing readPreviousEqual on keys $keys") val read: Result measureTimeMillis { - if (adapter.setRead(ReadMethod.READPE, keys)) { executeQuery(adapter.getSQLSatement()) } @@ -210,19 +209,22 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada override fun update(record: Record): Result { lastNativeMethod = NativeMethod.update - logEvent(LoggingKey.native_access_method, "Executing update record $actualRecord to $record with autocommit=${connection.autoCommit}") + logEvent( + LoggingKey.native_access_method, + "Executing update record $actualRecord to $record with autocommit=${connection.autoCommit}", + ) measureTimeMillis { // record before update is "actualRecord" // record post update will be "record" var atLeastOneFieldChanged = false actualRecord?.forEach { val fieldValue = record.getValue(it.key) - if(fieldValue != it.value){ + if (fieldValue != it.value) { atLeastOneFieldChanged = true this.getResultSet()?.updateObject(it.key, fieldValue) } - }?:logEvent(LoggingKey.native_access_method, "No previous read executed, nothing to update") - if(atLeastOneFieldChanged){ + } ?: logEvent(LoggingKey.native_access_method, "No previous read executed, nothing to update") + if (atLeastOneFieldChanged) { this.getResultSet()?.updateRow() } }.apply { @@ -234,12 +236,14 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada override fun delete(record: Record): Result { lastNativeMethod = NativeMethod.delete - logEvent(LoggingKey.native_access_method, "Executing delete for current record $actualRecord with autocommit=${connection.autoCommit}") + logEvent( + LoggingKey.native_access_method, + "Executing delete for current record $actualRecord with autocommit=${connection.autoCommit}", + ) measureTimeMillis { - if(actualRecord != null) { + if (actualRecord != null) { this.getResultSet()?.deleteRow() - } - else{ + } else { logEvent(LoggingKey.native_access_method, "No previous read executed, nothing to delete") } }.apply { @@ -253,14 +257,17 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada executeQuery(sqlAndValues.first, sqlAndValues.second) } - private fun executeQuery(sql: String, values: List) { + private fun executeQuery( + sql: String, + values: List, + ) { eof = false resultSet.closeIfOpen() logEvent(LoggingKey.execute_inquiry, "Preparing statement for query: $sql with bingings: $values") val stm: PreparedStatement measureTimeMillis { - stm = preparedStatements.get(sql)?:connection.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE) - preparedStatements.putIfAbsent(sql, stm); + stm = preparedStatements.get(sql) ?: connection.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE) + preparedStatements.putIfAbsent(sql, stm) stm.bind(values) }.apply { logEvent(LoggingKey.execute_inquiry, "Statement prepared, executing query for statement", this) @@ -272,7 +279,6 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada } } - private fun readNextFromResultSet(): Result { val result = Result(resultSet.toValues()) if (!eof() && adapter.lastReadMatchRecord(result.record)) { @@ -288,14 +294,13 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada } } - private fun closeResultSet(){ + private fun closeResultSet() { resultSet.closeIfOpen() resultSet = null } override fun eof() = eof - override fun equal(): Boolean { logEvent(LoggingKey.read_data, "Read current record for equal") lastNativeMethod = NativeMethod.equal @@ -303,7 +308,6 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada if (!adapter.isLastOperationSet()) { result = false } else { - measureTimeMillis { executeQuery(adapter.getReadSqlStatement()) result = resultSet?.next() ?: false @@ -323,4 +327,4 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada resultSet.closeIfOpen() preparedStatements.values.forEach { it.close() } } -} \ No newline at end of file +} diff --git a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFileNoPerf.kt b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFileNoPerf.kt index 5618b85..5491987 100644 --- a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFileNoPerf.kt +++ b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFileNoPerf.kt @@ -17,7 +17,6 @@ package com.smeup.dbnative.sql - import com.smeup.dbnative.file.DBFile import com.smeup.dbnative.file.Record import com.smeup.dbnative.file.RecordField @@ -31,15 +30,17 @@ import java.sql.PreparedStatement import java.sql.ResultSet import kotlin.system.measureTimeMillis -class SQLDBFileNoPerf(override var name: String, - override var fileMetadata: FileMetadata, - var connection: Connection, - override var logger: Logger? = null) : DBFile { - +class SQLDBFileNoPerf( + override var name: String, + override var fileMetadata: FileMetadata, + var connection: Connection, + override var logger: Logger? = null, +) : DBFile { constructor( name: String, fileMetadata: FileMetadata, - connection: Connection): this(name, fileMetadata, connection, null) + connection: Connection, + ) : this(name, fileMetadata, connection, null) private var resultSet: ResultSet? = null private var movingForward = true @@ -48,21 +49,22 @@ class SQLDBFileNoPerf(override var name: String, private var actualRecordToPop: Record? = null private var eof: Boolean = false private var lastOperationSet: Boolean = false - private var lastNativeMethod: NativeMethod? = null; - - + private var lastNativeMethod: NativeMethod? = null private val thisFileKeys: List by lazy { // TODO: think about a right way (local file maybe?) to retrieve keylist var indexes = this.fileMetadata.fileKeys - if(indexes.isEmpty()){ + if (indexes.isEmpty()) { indexes = connection.primaryKeys(fileMetadata.name) } if (indexes.isEmpty()) connection.orderingFields(fileMetadata.name) else indexes } - private fun logEvent(loggingKey: LoggingKey, message: String, elapsedTime: Long? = null) = - logger?.logEvent(loggingKey, message, elapsedTime, lastNativeMethod, fileMetadata.tableName) + private fun logEvent( + loggingKey: LoggingKey, + message: String, + elapsedTime: Long? = null, + ) = logger?.logEvent(loggingKey, message, elapsedTime, lastNativeMethod, fileMetadata.tableName) override fun setll(key: String): Boolean { return setll(mutableListOf(key)) @@ -75,14 +77,15 @@ class SQLDBFileNoPerf(override var name: String, measureTimeMillis { lastOperationSet = true - var keyAsRecordField = keys.mapIndexed { index, value -> - val keyname = thisFileKeys.get(index) - RecordField(keyname, value) - } + var keyAsRecordField = + keys.mapIndexed { index, value -> + val keyname = thisFileKeys.get(index) + RecordField(keyname, value) + } checkAndStoreLastKeys(keyAsRecordField) movingForward = true - point = point(keyAsRecordField); + point = point(keyAsRecordField) }.apply { logEvent(LoggingKey.native_access_method, "setll executed", this) } @@ -91,7 +94,6 @@ class SQLDBFileNoPerf(override var name: String, } override fun setgt(key: String): Boolean { - return setgt(mutableListOf(key)) } @@ -102,10 +104,11 @@ class SQLDBFileNoPerf(override var name: String, measureTimeMillis { lastOperationSet = true - var keyAsRecordField = keys.mapIndexed { index, value -> - val keyname = thisFileKeys.get(index) - RecordField(keyname, value) - } + var keyAsRecordField = + keys.mapIndexed { index, value -> + val keyname = thisFileKeys.get(index) + RecordField(keyname, value) + } checkAndStoreLastKeys(keyAsRecordField) movingForward = false @@ -128,10 +131,11 @@ class SQLDBFileNoPerf(override var name: String, measureTimeMillis { lastOperationSet = false - var keyAsRecordField = keys.mapIndexed { index, value -> - val keyname = thisFileKeys.get(index) - RecordField(keyname, value) - } + var keyAsRecordField = + keys.mapIndexed { index, value -> + val keyname = thisFileKeys.get(index) + RecordField(keyname, value) + } checkAndStoreLastKeys(keyAsRecordField) movingForward = true @@ -151,7 +155,6 @@ class SQLDBFileNoPerf(override var name: String, measureTimeMillis { lastOperationSet = false - if (resultSet == null) { pointAtUpperLL() } @@ -190,15 +193,14 @@ class SQLDBFileNoPerf(override var name: String, } override fun readEqual(): Result { - val lastKeysAsList = lastKeys.map { - it.value - } + val lastKeysAsList = + lastKeys.map { + it.value + } return readEqual(lastKeysAsList) } override fun readEqual(key: String): Result { - - return readEqual(mutableListOf(key)) } @@ -209,10 +211,11 @@ class SQLDBFileNoPerf(override var name: String, measureTimeMillis { lastOperationSet = false - var keysAsRecordField = keys.mapIndexed { index, value -> - val keyname = thisFileKeys.get(index) - RecordField(keyname, value) - } + var keysAsRecordField = + keys.mapIndexed { index, value -> + val keyname = thisFileKeys.get(index) + RecordField(keyname, value) + } checkAndStoreLastKeys(keysAsRecordField) if (resultSet == null) { @@ -231,10 +234,10 @@ class SQLDBFileNoPerf(override var name: String, } override fun readPreviousEqual(): Result { - - val lastKeysAsList = lastKeys.map { - it.value - } + val lastKeysAsList = + lastKeys.map { + it.value + } return readPreviousEqual(lastKeysAsList) } @@ -245,15 +248,16 @@ class SQLDBFileNoPerf(override var name: String, override fun readPreviousEqual(keys: List): Result { lastNativeMethod = NativeMethod.readPreviousEqual - logEvent(LoggingKey.native_access_method, "Executing readPreviousEqual on keys ${keys}") + logEvent(LoggingKey.native_access_method, "Executing readPreviousEqual on keys $keys") val read: Result measureTimeMillis { lastOperationSet = false - var keyAsRecordField = keys.mapIndexed { index, value -> - val keyname = thisFileKeys.get(index) - RecordField(keyname, value) - } + var keyAsRecordField = + keys.mapIndexed { index, value -> + val keyname = thisFileKeys.get(index) + RecordField(keyname, value) + } checkAndStoreLastKeys(keyAsRecordField) if (resultSet == null) { @@ -276,7 +280,7 @@ class SQLDBFileNoPerf(override var name: String, override fun write(record: Record): Result { lastNativeMethod = NativeMethod.write - logEvent(LoggingKey.native_access_method, "Executing write for record ${record}") + logEvent(LoggingKey.native_access_method, "Executing write for record $record") lastOperationSet = false measureTimeMillis { // TODO: manage errors @@ -294,7 +298,7 @@ class SQLDBFileNoPerf(override var name: String, override fun update(record: Record): Result { lastNativeMethod = NativeMethod.update - logEvent(LoggingKey.native_access_method, "Executing update for record ${record}") + logEvent(LoggingKey.native_access_method, "Executing update for record $record") lastOperationSet = false measureTimeMillis { // record before update is "actualRecord" @@ -302,12 +306,12 @@ class SQLDBFileNoPerf(override var name: String, var atLeastOneFieldChanged = false actualRecord?.forEach { var fieldValue = record.getValue(it.key) - if(fieldValue != it.value){ + if (fieldValue != it.value) { atLeastOneFieldChanged = true this.getResultSet()?.updateObject(it.key, fieldValue) } } - if(atLeastOneFieldChanged){ + if (atLeastOneFieldChanged) { this.getResultSet()?.updateRow() } }.apply { @@ -319,7 +323,7 @@ class SQLDBFileNoPerf(override var name: String, override fun delete(record: Record): Result { lastNativeMethod = NativeMethod.delete - logEvent(LoggingKey.native_access_method, "Executing delete for record ${record}") + logEvent(LoggingKey.native_access_method, "Executing delete for record $record") lastOperationSet = false measureTimeMillis { this.getResultSet()?.deleteRow() @@ -330,8 +334,10 @@ class SQLDBFileNoPerf(override var name: String, return Result(record) } - - private fun executeQuery(sql: String, values: List) { + private fun executeQuery( + sql: String, + values: List, + ) { resultSet.closeIfOpen() logEvent(LoggingKey.execute_inquiry, "Preparing statement for query: $sql with bingings: $values") val stm: PreparedStatement @@ -370,7 +376,10 @@ class SQLDBFileNoPerf(override var name: String, } // calculate the upper or the lower part of the ordered table given the input keys using an sql query (composed of selects in union if primary keys size > 1) - private fun calculateResultSet(keys: List, withEquals: Boolean = true) { + private fun calculateResultSet( + keys: List, + withEquals: Boolean = true, + ) { actualRecordToPop = null val sqlAndValues = filePartSQLAndValues(fileMetadata.tableName, movingForward, thisFileKeys, keys, withEquals) val values = sqlAndValues.first @@ -382,7 +391,10 @@ class SQLDBFileNoPerf(override var name: String, calculateResultSet(calculateRecordKeys(actualRecord, thisFileKeys), false) } - private fun calculateRecordKeys(record: Record?, keysNames: List): List { + private fun calculateRecordKeys( + record: Record?, + keysNames: List, + ): List { val result = mutableListOf() keysNames.forEach { result.add(RecordField(it, record!![it].toString())) @@ -410,7 +422,7 @@ class SQLDBFileNoPerf(override var name: String, } private fun readFromResultSetFilteringBy(keys: List): Result { - logEvent(LoggingKey.search_data, "Searching record for keys: ${keys}") + logEvent(LoggingKey.search_data, "Searching record for keys: $keys") var result: Result var counter = 0 measureTimeMillis { @@ -419,7 +431,11 @@ class SQLDBFileNoPerf(override var name: String, counter++ } while (!result.record.matches(keys) && resultSet.hasRecords() && !eof()) }.apply { - logEvent(LoggingKey.search_data, "Search stops after $counter ResultSet iterations. Is eof: ${eof()}. Current row number is ${resultSet?.row?:" undefined"}}", this) + logEvent( + LoggingKey.search_data, + "Search stops after $counter ResultSet iterations. Is eof: ${eof()}. Current row number is ${resultSet?.row ?: " undefined"}}", + this, + ) } return result } @@ -431,7 +447,6 @@ class SQLDBFileNoPerf(override var name: String, override fun eof(): Boolean = resultSet?.isAfterLast ?: true - override fun equal(): Boolean { lastNativeMethod = NativeMethod.equal if (lastOperationSet == false) { @@ -457,4 +472,4 @@ class SQLDBFileNoPerf(override var name: String, fun getResultSet(): ResultSet? { return this.resultSet } -} \ No newline at end of file +} diff --git a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBMManager.kt b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBMManager.kt index 9ac0a1a..ccbfc0a 100644 --- a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBMManager.kt +++ b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBMManager.kt @@ -25,13 +25,12 @@ import java.sql.DriverManager import java.util.* import kotlin.system.measureTimeMillis -open class SQLDBMManager(override val connectionConfig: ConnectionConfig) : DBManagerBaseImpl() { - +open class SQLDBMManager(override val connectionConfig: ConnectionConfig) : DBManagerBaseImpl() { private var sqlLog: Boolean = false private var openedFile = mutableMapOf() - val connection : Connection by lazy { + val connection: Connection by lazy { logger?.logEvent(LoggingKey.connection, "Opening SQL connection on url ${connectionConfig.url}") val conn: Connection measureTimeMillis { @@ -39,13 +38,13 @@ open class SQLDBMManager(override val connectionConfig: ConnectionConfig) : DBMa Class.forName(connectionConfig.driver) } - val connectionProps = Properties(); - connectionProps.put("user", connectionConfig.user); - connectionProps.put("password", connectionConfig.password); + val connectionProps = Properties() + connectionProps.put("user", connectionConfig.user) + connectionProps.put("password", connectionConfig.password) - connectionConfig.properties.forEach() { - if (!it.key.equals("user") && !it.key.equals("password")) { - connectionProps.put(it.key, it.value); + connectionConfig.properties.forEach { + if (!it.key.equals("user") && !it.key.equals("password")) { + connectionProps.put(it.key, it.value) } } conn = DriverManager.getConnection(connectionConfig.url, connectionProps) @@ -59,18 +58,18 @@ open class SQLDBMManager(override val connectionConfig: ConnectionConfig) : DBMa } override fun close() { - openedFile.values.forEach { it.close()} + openedFile.values.forEach { it.close() } openedFile.clear() connection.close() } - override fun openFile(name: String) = openedFile.getOrPut(name) { - require(existFile(name)) { - "Cannot open a unregistered file $name" + override fun openFile(name: String) = + openedFile.getOrPut(name) { + require(existFile(name)) { + "Cannot open a unregistered file $name" + } + SQLDBFile(name = name, fileMetadata = metadataOf(name), connection = connection, logger) } - SQLDBFile(name = name, fileMetadata = metadataOf(name), connection = connection, logger) - } - override fun closeFile(name: String) { openedFile.remove(name)?.close() @@ -90,5 +89,4 @@ open class SQLDBMManager(override val connectionConfig: ConnectionConfig) : DBMa fun setSQLLog(on: Boolean) { sqlLog = on } - -} \ No newline at end of file +} diff --git a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLUtils.kt b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLUtils.kt index 49f22c5..16217a1 100644 --- a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLUtils.kt +++ b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLUtils.kt @@ -20,7 +20,6 @@ package com.smeup.dbnative.sql import com.smeup.dbnative.file.Record import com.smeup.dbnative.file.RecordField - fun String.insertSQL(record: Record): String { val names = record.keys.joinToString { "\"" + it + "\"" } val questionMarks = record.keys.joinToString { "?" } @@ -40,18 +39,24 @@ fun String.deleteSQL(record: Record): String { return "DELETE FROM $this ${whereSQL(wheres, comparations)}" } -fun orderBySQL(keysNames: List, reverse: Boolean = false): String = +fun orderBySQL( + keysNames: List, + reverse: Boolean = false, +): String = if (keysNames.isEmpty()) { "" } else { if (reverse) { - "ORDER BY " + keysNames.joinToString(separator = " DESC, ", postfix = " DESC") {"\"$it\""} + "ORDER BY " + keysNames.joinToString(separator = " DESC, ", postfix = " DESC") { "\"$it\"" } } else { - "ORDER BY " + keysNames.joinToString {"\"$it\""} + "ORDER BY " + keysNames.joinToString { "\"$it\"" } } } -fun whereSQL(wheres: List, comparations: List): String { +fun whereSQL( + wheres: List, + comparations: List, +): String { return if (wheres.isEmpty()) { "" } else { @@ -66,9 +71,8 @@ fun filePartSQLAndValues( movingForward: Boolean, fileKeys: List, keys: List, - withEquals: Boolean + withEquals: Boolean, ): Pair, String> { - val queries = mutableListOf() val values = mutableListOf() @@ -76,12 +80,12 @@ fun filePartSQLAndValues( val keys2Size = keys2.size do { - - var lastComparison = if (movingForward) { - Comparison.GT - } else { - Comparison.LT - } + var lastComparison = + if (movingForward) { + Comparison.GT + } else { + Comparison.LT + } val comparisons = mutableListOf() keys2.forEachIndexed { index, _ -> @@ -101,19 +105,20 @@ fun filePartSQLAndValues( val sql = "(SELECT * FROM $tableName ${whereSQL( keys2.map { it.name }, - comparisons + comparisons, )})" values.addAll(keys2.map { it.value.toString() }) queries.add(sql) keys2 = keys2.subList(0, keys2.size - 1) - } while (keys2.isNotEmpty()) - val sql = queries.joinToString(" UNION ") + " " + orderBySQL( - fileKeys, - reverse = !movingForward - ) + val sql = + queries.joinToString(" UNION ") + " " + + orderBySQL( + fileKeys, + reverse = !movingForward, + ) return Pair(values, sql) } @@ -124,7 +129,7 @@ enum class Comparison(val symbol: String) { GT(">"), GE(">="), LT("<"), - LE("<="); + LE("<="), } fun createMarkerSQL(keysNames: List): String = @@ -133,50 +138,47 @@ fun createMarkerSQL(keysNames: List): String = } else { // in HSQLDB CONCAT needs at least two params! if (keysNames.size == 1) { - "CONCAT( " + keysNames.joinToString{"\"$it\""} + ", '') AS NATIVE_ACCESS_MARKER" + "CONCAT( " + keysNames.joinToString { "\"$it\"" } + ", '') AS NATIVE_ACCESS_MARKER" } else { - "CONCAT( " + keysNames.joinToString{"\"$it\""} + ") AS NATIVE_ACCESS_MARKER" + "CONCAT( " + keysNames.joinToString { "\"$it\"" } + ") AS NATIVE_ACCESS_MARKER" } - } fun calculateMarkerValue( keys: List, movingForward: Boolean = true, - withEquals: Boolean = true + withEquals: Boolean = true, ): String = if (keys.isEmpty()) { "" } else { - val padChar = if (movingForward) { - ' ' - } else { - 'Z' - } + val padChar = + if (movingForward) { + ' ' + } else { + 'Z' + } // NOTE: calculate max length of marker using primary fields max length (temp 100 but incorrect) if (withEquals) { keys.joinToString("") { it.value }.padEnd(100, padChar) } else { keys.joinToString("") { it.value } - } } -fun markerWhereSQL(movingForward: Boolean, withEquals: Boolean): String { - val comparison = if (movingForward && !withEquals) { - Comparison.GT - } else if (movingForward && withEquals) { - Comparison.GE - } else if (!movingForward && !withEquals) { - Comparison.LT - } else { - Comparison.LE - } +fun markerWhereSQL( + movingForward: Boolean, + withEquals: Boolean, +): String { + val comparison = + if (movingForward && !withEquals) { + Comparison.GT + } else if (movingForward && withEquals) { + Comparison.GE + } else if (!movingForward && !withEquals) { + Comparison.LT + } else { + Comparison.LE + } return " WHERE NATIVE_ACCESS_MARKER ${comparison.symbol} ? " } - - - - - - diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400OperationsOnFile.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400OperationsOnFile.kt index 2001976..5c8588c 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400OperationsOnFile.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400OperationsOnFile.kt @@ -31,11 +31,9 @@ import org.junit.Test import kotlin.test.assertEquals import kotlin.test.assertTrue -//@Ignore +// @Ignore class DB2400OperationsOnFile { - companion object { - private var dbManager: SQLDBMManager? = null @BeforeClass @@ -49,7 +47,7 @@ class DB2400OperationsOnFile { } } - //Ignored fields in metadata not necessary + // Ignored fields in metadata not necessary @Ignore @Test fun open() { @@ -203,7 +201,7 @@ class DB2400OperationsOnFile { var chainResult = dbFile.chain(key) assertEquals(0, chainResult.record.size) - //Set field values and write record + // Set field values and write record chainResult.record["A§ARTI"] = key chainResult.record["A§DEAR"] = "Kotlin DBNativeAccess Write " chainResult.record["A§TIAR"] = "ART " @@ -211,17 +209,17 @@ class DB2400OperationsOnFile { dbFile.write(chainResult.record) - //Must exists correct write + // Must exists correct write chainResult = dbFile.chain(key) assertEquals(key, chainResult.record["A§ARTI"]) assertEquals("ART ", chainResult.record["A§TIAR"]) assertEquals("Kotlin DBNativeAccess Write ", chainResult.record["A§DEAR"]) assertEquals("0 ", chainResult.record["A§TPAR"]) - //Delete record + // Delete record dbFile.delete(chainResult.record) - //Check delete success + // Check delete success chainResult = dbFile.chain(key) assertEquals(0, chainResult.record.size) @@ -231,7 +229,7 @@ class DB2400OperationsOnFile { // Ignore, fields in metadata non necessary @Ignore @Test - fun multipleUpdateOnReadE(){ + fun multipleUpdateOnReadE() { // TEST FLOW // Step1: write 100 records with "currentTimeMillis" as unique key // Step2: read above written records and update A§DEA2 field @@ -246,7 +244,7 @@ class DB2400OperationsOnFile { // Create list of items to write into A§ARTI field val items = mutableListOf() - repeat(numberOfRecordsToHandle){ + repeat(numberOfRecordsToHandle) { items.add(System.currentTimeMillis().toString() + " ") Thread.sleep(5) } @@ -257,19 +255,21 @@ class DB2400OperationsOnFile { val dea2Key = "Kotlin DBNativeAccess TEST-UPDATED " // WRITE - repeat(numberOfRecordsToHandle){ + repeat(numberOfRecordsToHandle) { var record = Record() - repeat(fieldsNumber){ index -> + repeat(fieldsNumber) { index -> var name: String = dbFile.fileMetadata.fields[index].name print(tMetadata.getField(name)?.type) - var value = when(name){ - "A§ARTI" -> items[it] - "A§DEAR" -> dearKey - else -> when(tMetadata.getField(name)?.type){ - is DecimalType -> "0" - else -> "" + var value = + when (name) { + "A§ARTI" -> items[it] + "A§DEAR" -> dearKey + else -> + when (tMetadata.getField(name)?.type) { + is DecimalType -> "0" + else -> "" + } } - } var recordField: RecordField = RecordField(name, value) record.add(recordField) @@ -303,10 +303,9 @@ class DB2400OperationsOnFile { repeat(numberOfRecordsToHandle) { var readEResult = dbFile.readEqual(dearKey) assertEquals(dea2Key, readEResult.record["A§DEA2"]) - //Delete record + // Delete record dbFile.delete(readEResult.record) } - } @Test @@ -352,7 +351,7 @@ class DB2400OperationsOnFile { dbManager!!.registerMetadata(fileMetadata, false) var dbFile = dbManager!!.openFile("VERAPG1L") - //keys: V£DATA, V£NOME, V£IDOJ + // keys: V£DATA, V£NOME, V£IDOJ val data = "20200901" val nome = "BNUNCA " val idoj = "0002003070" @@ -378,7 +377,7 @@ class DB2400OperationsOnFile { } @Test - fun resultSetCursorMovements(){ + fun resultSetCursorMovements() { val fileMetadata = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "BRARTI0L") dbManager!!.registerMetadata(fileMetadata, false) var dbFile = dbManager!!.openFile("BRARTI0L") @@ -402,7 +401,7 @@ class DB2400OperationsOnFile { } @Test - fun resultSetCursorUpdate(){ + fun resultSetCursorUpdate() { val fileMetadata = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "BRARTI0L") dbManager!!.registerMetadata(fileMetadata, false) var dbFile = dbManager!!.openFile("BRARTI0L") @@ -439,6 +438,4 @@ class DB2400OperationsOnFile { dbManager!!.closeFile("BRARTI0L") } - } - diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400OperationsOnFilePerfTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400OperationsOnFilePerfTest.kt index 6bbe4fc..13c2861 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400OperationsOnFilePerfTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400OperationsOnFilePerfTest.kt @@ -22,21 +22,18 @@ import com.smeup.dbnative.file.Record import com.smeup.dbnative.file.RecordField import com.smeup.dbnative.metadata.file.PropertiesSerializer import com.smeup.dbnative.sql.utils.* -import org.junit.AfterClass -import org.junit.BeforeClass import org.junit.Ignore import org.junit.Test import kotlin.test.assertEquals import kotlin.test.assertFalse -import kotlin.test.assertTrue - class DB2400OperationsOnFilePerfTest { - - private var dbManager: SQLDBMManager? = null - fun initDbManager(host: String = DB2_400_HOST, library: String = DB2_400_LIBRARY_NAME) { + fun initDbManager( + host: String = DB2_400_HOST, + library: String = DB2_400_LIBRARY_NAME, + ) { dbManager = dbManagerDB2400ForTest(host, library) } @@ -48,12 +45,15 @@ class DB2400OperationsOnFilePerfTest { PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "VERAPG0L") it!!.registerMetadata(fileMetadata, false) val dbFile = it!!.openFile("VERAPG0L") - for(i in 1..10) { - var record = Record(RecordField("V£IDOJ", "A3L00000X1"), - RecordField("V£DATA", "20210117"), - RecordField("V£NOME", "BUSFIO2 "), - RecordField("V£CDC", "SMEGL.001 "), - RecordField("V£COD1", "ERB ")) + for (i in 1..10) { + var record = + Record( + RecordField("V£IDOJ", "A3L00000X1"), + RecordField("V£DATA", "20210117"), + RecordField("V£NOME", "BUSFIO2 "), + RecordField("V£CDC", "SMEGL.001 "), + RecordField("V£COD1", "ERB "), + ) dbFile.write(record) record = dbFile.chain(arrayListOf("A3L00000X1")).record if (!dbFile.eof()) { @@ -93,11 +93,14 @@ class DB2400OperationsOnFilePerfTest { var record = dbFile.chain(arrayListOf("A3L0000001")).record if (dbFile.eof()) { - record = Record(RecordField("V£IDOJ", "A3L0000001"), - RecordField("V£DATA", "20210117"), - RecordField("V£NOME", "BUSFIO "), - RecordField("V£CDC", "SMEGL.001 "), - RecordField("V£COD1", "ERB ")) + record = + Record( + RecordField("V£IDOJ", "A3L0000001"), + RecordField("V£DATA", "20210117"), + RecordField("V£NOME", "BUSFIO "), + RecordField("V£CDC", "SMEGL.001 "), + RecordField("V£COD1", "ERB "), + ) dbFile.write(record) record = dbFile.chain(arrayListOf("A3L0000001")).record assertFalse { dbFile.eof() } @@ -110,7 +113,6 @@ class DB2400OperationsOnFilePerfTest { record = dbFile.chain(arrayListOf("A3L0000001")).record assertEquals(record["V£ATV0"], "2") dbFile.delete(record) - } } @@ -155,11 +157,11 @@ class DB2400OperationsOnFilePerfTest { } } - private fun doChain(keys: List, dbFile: DBFile){ + private fun doChain( + keys: List, + dbFile: DBFile, + ) { val chainResult = dbFile.chain(keys) assertEquals(keys[0], chainResult.record["A§ARTI"]?.trim()) } - - } - diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/JDBCUtilsTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/JDBCUtilsTest.kt index e6b3ca3..6d2e022 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/JDBCUtilsTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/JDBCUtilsTest.kt @@ -25,7 +25,6 @@ import org.junit.Test import kotlin.test.assertEquals class JDBCUtilsTest { - private lateinit var dbManager: SQLDBMManager @Before @@ -37,7 +36,9 @@ class JDBCUtilsTest { fun primaryKeysTest() { dbManager.connection.use { it.createStatement() - .execute("CREATE TABLE TSTTAB00 (TSTFLDCHR CHAR (5) NOT NULL, TSTFLDNBR DECIMAL (7, 2) NOT NULL, TSTFLDNB2 DECIMAL (2, 0) NOT NULL, PRIMARY KEY(TSTFLDCHR, TSTFLDNBR))") + .execute( + "CREATE TABLE TSTTAB00 (TSTFLDCHR CHAR (5) NOT NULL, TSTFLDNBR DECIMAL (7, 2) NOT NULL, TSTFLDNB2 DECIMAL (2, 0) NOT NULL, PRIMARY KEY(TSTFLDCHR, TSTFLDNBR))", + ) assertEquals(listOf("TSTFLDCHR", "TSTFLDNBR"), it.primaryKeys("TSTTAB00")) } } @@ -46,7 +47,9 @@ class JDBCUtilsTest { fun orderingFieldsTest() { dbManager.connection.use { it.createStatement() - .execute("CREATE TABLE TSTTAB00 (TSTFLDCHR CHAR (5) NOT NULL, TSTFLDNBR DECIMAL (7, 2) NOT NULL, TSTFLDNB2 DECIMAL (2, 0) NOT NULL, PRIMARY KEY(TSTFLDCHR, TSTFLDNBR))") + .execute( + "CREATE TABLE TSTTAB00 (TSTFLDCHR CHAR (5) NOT NULL, TSTFLDNBR DECIMAL (7, 2) NOT NULL, TSTFLDNB2 DECIMAL (2, 0) NOT NULL, PRIMARY KEY(TSTFLDCHR, TSTFLDNBR))", + ) it.createStatement().execute("CREATE VIEW TSTVIEW AS SELECT * FROM TSTTAB00 ORDER BY TSTFLDNB2, TSTFLDNBR") it.createStatement() .execute("CREATE INDEX TSTVIEW$CONVENTIONAL_INDEX_SUFFIX ON TSTTAB00 (TSTFLDNB2, TSTFLDNBR)") @@ -58,4 +61,4 @@ class JDBCUtilsTest { fun tearDownEach() { destroyDatabase() } -} \ No newline at end of file +} diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLChain1KeyTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLChain1KeyTest.kt index 1fb9bcd..7229cd4 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLChain1KeyTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLChain1KeyTest.kt @@ -28,9 +28,7 @@ import kotlin.test.assertEquals import kotlin.test.assertTrue class SQLChain1KeyTest { - companion object { - private var dbManager: SQLDBMManager? = null private var libName: String? = null @@ -63,6 +61,4 @@ class SQLChain1KeyTest { assertTrue(dbFile.chain("XYZ").record.isEmpty()) dbManager!!.closeFile(TSTTAB_TABLE_NAME) } - } - diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLChain2KeysTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLChain2KeysTest.kt index bcbeaf9..6daae14 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLChain2KeysTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLChain2KeysTest.kt @@ -28,12 +28,9 @@ import kotlin.test.assertEquals import kotlin.test.assertTrue class SQLChain2KeysTest { - companion object { - private lateinit var dbManager: SQLDBMManager - @BeforeClass @JvmStatic fun setUp() { @@ -51,10 +48,11 @@ class SQLChain2KeysTest { @Test fun findRecordsIfChainWithExistingKey() { val dbFile = dbManager.openFile(TST2TAB_TABLE_NAME) - val key2 = listOf( - "ABC", - "12.00" - ) + val key2 = + listOf( + "ABC", + "12.00", + ) val chainResult = dbFile.chain(key2) assertEquals("ABC", chainResult.record["TSTFLDCHR"]) assertEquals("12.00", chainResult.record["TSTFLDNBR"]) @@ -65,14 +63,12 @@ class SQLChain2KeysTest { @Test fun doesNotFindRecordsIfChainWithNotExistingKey() { val dbFile = dbManager.openFile(TST2TAB_TABLE_NAME) - val key2 = listOf( - "ZZZ", - "12" - ) + val key2 = + listOf( + "ZZZ", + "12", + ) assertTrue(dbFile.chain(key2).record.isEmpty()) dbManager.closeFile(TST2TAB_TABLE_NAME) } - - } - diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLMunicipalityPerfTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLMunicipalityPerfTest.kt index be563c1..1ad5b89 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLMunicipalityPerfTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLMunicipalityPerfTest.kt @@ -27,11 +27,8 @@ import kotlin.test.assertEquals import kotlin.test.assertFails import kotlin.test.assertTrue - class SQLMunicipalityPerfTest { - companion object { - private lateinit var dbManager: SQLDBMManager @BeforeClass @@ -52,11 +49,11 @@ class SQLMunicipalityPerfTest { fun read() { val dbFile = dbManager.openFile(MUNICIPALITY_TABLE_NAME) assertTrue(dbFile.setll(buildMunicipalityKey("IT", "LOM", "BS", "ERBUSCO"))) - for(index in 0..138){ - var result = dbFile.read(); - assertTrue{!dbFile.eof()} - if(index == 138) { - assertEquals("CO" , getMunicipalityProv(result.record)) + for (index in 0..138) { + var result = dbFile.read() + assertTrue { !dbFile.eof() } + if (index == 138) { + assertEquals("CO", getMunicipalityProv(result.record)) } } dbManager.closeFile(MUNICIPALITY_TABLE_NAME) @@ -160,7 +157,7 @@ class SQLMunicipalityPerfTest { recordFields.add(RecordField("PREF", "1234")) recordFields.add(RecordField("COMUNE", "A99")) recordFields.add(RecordField("ISTAT", "999999")) - dbFile.write(Record(*recordFields.toTypedArray())); + dbFile.write(Record(*recordFields.toTypedArray())) // Read new record for control var chainResult = dbFile.chain(buildMunicipalityKey("IT", "LOM", "BG", "TOPOLINIA")) @@ -216,7 +213,7 @@ class SQLMunicipalityPerfTest { recordFields.add(RecordField("PREF", "4321")) recordFields.add(RecordField("COMUNE", "A99")) recordFields.add(RecordField("ISTAT", "999999")) - dbFile.write(Record(*recordFields.toTypedArray())); + dbFile.write(Record(*recordFields.toTypedArray())) // Read new record dbFile.setll(buildMunicipalityKey("IT", "LOM", "BG", "PAPEROPOLI")) @@ -224,7 +221,7 @@ class SQLMunicipalityPerfTest { assertEquals("PAPEROPOLI", getMunicipalityName(readResult.record)) // Delete added record - var chainResult= dbFile.chain(buildMunicipalityKey("IT", "LOM", "BG", "PAPEROPOLI")) + var chainResult = dbFile.chain(buildMunicipalityKey("IT", "LOM", "BG", "PAPEROPOLI")) dbFile.delete(chainResult.record) chainResult = dbFile.chain(buildMunicipalityKey("IT", "LOM", "BG", "PAPEROPOLI")) assertTrue(dbFile.eof()) @@ -246,7 +243,7 @@ class SQLMunicipalityPerfTest { fun usupportedUncoherentKeys() { val dbFile = dbManager.openFile(MUNICIPALITY_TABLE_NAME) dbFile.setll(buildMunicipalityKey("IT", "LOM", "BS", "ZONE")) - assertFails {dbFile.readEqual(buildMunicipalityKey("IT", "LOM", "CO"))} + assertFails { dbFile.readEqual(buildMunicipalityKey("IT", "LOM", "CO")) } dbManager.closeFile(MUNICIPALITY_TABLE_NAME) } @@ -255,14 +252,14 @@ class SQLMunicipalityPerfTest { val dbFile = dbManager.openFile(MUNICIPALITY_TABLE_NAME) dbFile.setll(buildMunicipalityKey("IT", "LOM", "BS", "ZONE")) dbFile.readEqual(buildMunicipalityKey("IT", "LOM", "BS")) - assertFails {dbFile.read()} + assertFails { dbFile.read() } dbManager.closeFile(MUNICIPALITY_TABLE_NAME) } @Test fun usupportedUnpositioning() { val dbFile = dbManager.openFile(MUNICIPALITY_TABLE_NAME) - assertFails {dbFile.readEqual(buildMunicipalityKey("IT", "LOM", "BS"))} + assertFails { dbFile.readEqual(buildMunicipalityKey("IT", "LOM", "BS")) } dbManager.closeFile(MUNICIPALITY_TABLE_NAME) } @@ -271,7 +268,7 @@ class SQLMunicipalityPerfTest { val dbFile = dbManager.openFile(MUNICIPALITY_TABLE_NAME) dbFile.setll(buildMunicipalityKey("IT", "LOM", "BS", "ZONE")) dbFile.readEqual(buildMunicipalityKey("IT", "LOM", "BS")) - assertFails {dbFile.readPrevious()} + assertFails { dbFile.readPrevious() } dbManager.closeFile(MUNICIPALITY_TABLE_NAME) } @@ -283,4 +280,3 @@ class SQLMunicipalityPerfTest { usupportedReadChangeDirection() } } - diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLMunicipalityTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLMunicipalityTest.kt index 9e99211..88c42c9 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLMunicipalityTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLMunicipalityTest.kt @@ -25,11 +25,8 @@ import org.junit.Test import kotlin.test.assertEquals import kotlin.test.assertTrue - class SQLMunicipalityTest { - companion object { - private lateinit var dbManager: SQLDBMManager @BeforeClass @@ -82,11 +79,11 @@ class SQLMunicipalityTest { assertTrue(dbFile.setll(buildMunicipalityKey("IT", "LOM", "BS", "ERBUSCO"))) assertEquals( "EDOLO", - getMunicipalityName(dbFile.readPreviousEqual(buildMunicipalityKey("IT", "LOM", "BS")).record) + getMunicipalityName(dbFile.readPreviousEqual(buildMunicipalityKey("IT", "LOM", "BS")).record), ) assertEquals( "DESENZANO DEL GARDA", - getMunicipalityName(dbFile.readPreviousEqual(buildMunicipalityKey("IT", "LOM", "BS")).record) + getMunicipalityName(dbFile.readPreviousEqual(buildMunicipalityKey("IT", "LOM", "BS")).record), ) dbManager.closeFile(MUNICIPALITY_TABLE_NAME) } @@ -415,7 +412,4 @@ class SQLMunicipalityTest { assertEquals(32, count) dbManager.closeFile(MUNICIPALITY_TABLE_NAME) } - - } - diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadEqualTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadEqualTest.kt index 52ce186..4d32ea9 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadEqualTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadEqualTest.kt @@ -26,11 +26,9 @@ import kotlin.test.assertFailsWith import kotlin.test.assertTrue class SQLReadEqualTest { - companion object { - private lateinit var dbManager: SQLDBMManager - + @BeforeClass @JvmStatic fun setUp() { @@ -67,7 +65,7 @@ class SQLReadEqualTest { @Test fun findRecordsIfChainAndReadEExistingKey() { val dbFile = dbManager.openFile(XEMP2_VIEW_NAME) - val chainResult = dbFile.chain( "C01") + val chainResult = dbFile.chain("C01") assertEquals("SALLY KWAN", getEmployeeName(chainResult.record)) assertEquals("DELORES QUINTANA", getEmployeeName(dbFile.readEqual().record)) assertEquals("HEATHER NICHOLLS", getEmployeeName(dbFile.readEqual().record)) @@ -79,8 +77,8 @@ class SQLReadEqualTest { @Test fun readUntilEof() { val dbFile = dbManager.openFile(XEMP2_VIEW_NAME) - val chainResult = dbFile.chain( "C01") - var readed = 0; + val chainResult = dbFile.chain("C01") + var readed = 0 while (dbFile.eof() == false) { var readResult = dbFile.readEqual("C01") readed++ @@ -92,12 +90,11 @@ class SQLReadEqualTest { @Test fun equals() { val dbFile = dbManager.openFile(XEMP2_VIEW_NAME) - val chainResult = dbFile.setll( "C01") - assertTrue (dbFile.equal()) + val chainResult = dbFile.setll("C01") + assertTrue(dbFile.equal()) dbManager.closeFile(XEMP2_VIEW_NAME) } - @Test fun findRecordsIfReadEWithKeyExistingKey() { val dbFile = dbManager.openFile(XEMP2_VIEW_NAME) @@ -128,6 +125,4 @@ class SQLReadEqualTest { assertEquals(0, dbFile.readEqual("C01").record.size) dbManager.closeFile(XEMP2_VIEW_NAME) } - } - diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadPreviousTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadPreviousTest.kt index fca6e4c..a5a4a5d 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadPreviousTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadPreviousTest.kt @@ -25,11 +25,9 @@ import kotlin.test.assertEquals import kotlin.test.assertTrue class SQLReadPreviousTest { - companion object { - private lateinit var dbManager: SQLDBMManager - + @BeforeClass @JvmStatic fun setUp() { @@ -62,5 +60,4 @@ class SQLReadPreviousTest { assertEquals("MICHELLE SPRINGER", getEmployeeName(dbFile.readPrevious().record)) dbManager.closeFile(EMPLOYEE_TABLE_NAME) } - } diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLUtilsTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLUtilsTest.kt index 98da867..20d26c5 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLUtilsTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLUtilsTest.kt @@ -28,52 +28,54 @@ import org.junit.Test import kotlin.test.assertEquals class SQLUtilsTest { - @Test fun sqlForCreateTableTestWithPrimaryKeys() { - val fileMetadata = TypedMetadata( - "TSTTAB", - "TSTTAB", - listOf( - "TSTFLDCHR" fieldByType CharacterType(5), - "TSTFLDNBR" fieldByType DecimalType(7, 2), - "TSTFLDNB2" fieldByType DecimalType(2, 0) - ), - listOf( - "TSTFLDCHR", - "TSTFLDNBR" + val fileMetadata = + TypedMetadata( + "TSTTAB", + "TSTTAB", + listOf( + "TSTFLDCHR" fieldByType CharacterType(5), + "TSTFLDNBR" fieldByType DecimalType(7, 2), + "TSTFLDNB2" fieldByType DecimalType(2, 0), + ), + listOf( + "TSTFLDCHR", + "TSTFLDNBR", + ), ) - ) assertEquals( "CREATE TABLE TSTTAB (TSTFLDCHR CHAR(5) DEFAULT '' NOT NULL, TSTFLDNBR DECIMAL(7,2) DEFAULT 0 NOT NULL, TSTFLDNB2 DECIMAL(2,0) DEFAULT 0 NOT NULL, PRIMARY KEY(TSTFLDCHR, TSTFLDNBR))", - fileMetadata.toSQL() + fileMetadata.toSQL(), ) } @Test fun sqlForCreateTableTestWithoutPrimaryKeys() { - val fileMetadata = TypedMetadata( - "TSTTAB", - "TSTTAB", - listOf( - "TSTFLDCHR" fieldByType CharacterType(5), - "TSTFLDNBR" fieldByType DecimalType(7, 2), - "TSTFLDNB2" fieldByType DecimalType(2, 0) - ), - listOf() - ) + val fileMetadata = + TypedMetadata( + "TSTTAB", + "TSTTAB", + listOf( + "TSTFLDCHR" fieldByType CharacterType(5), + "TSTFLDNBR" fieldByType DecimalType(7, 2), + "TSTFLDNB2" fieldByType DecimalType(2, 0), + ), + listOf(), + ) assertEquals( "CREATE TABLE TSTTAB (TSTFLDCHR CHAR(5) DEFAULT '' NOT NULL, TSTFLDNBR DECIMAL(7,2) DEFAULT 0 NOT NULL, TSTFLDNB2 DECIMAL(2,0) DEFAULT 0 NOT NULL)", - fileMetadata.toSQL() + fileMetadata.toSQL(), ) } @Test fun sqlForInsertTest() { - val record = Record( - RecordField("TSTFLDCHR", "XXX"), - RecordField("TSTFLDNBR", "123.45") - ) + val record = + Record( + RecordField("TSTFLDCHR", "XXX"), + RecordField("TSTFLDNBR", "123.45"), + ) assertEquals("INSERT INTO TSTTAB (TSTFLDCHR, TSTFLDNBR) VALUES(?, ?)", "TSTTAB".insertSQL(record)) } diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/utils/SQLDBTestUtils.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/utils/SQLDBTestUtils.kt index e728a05..f0fd00f 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/utils/SQLDBTestUtils.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/utils/SQLDBTestUtils.kt @@ -43,11 +43,13 @@ const val TST2TAB_TABLE_NAME = "TSTTAB" const val MUNICIPALITY_TABLE_NAME = "MUNICIPALITY" const val TEST_LOG = false private val LOGGING_LEVEL = LoggingLevel.ALL -//do not change defaultValue -//if you want to create sqlconnection against another db use function: dbManagerForTest(testSQLDBType: TestSQLDBType) + +// do not change defaultValue +// if you want to create sqlconnection against another db use function: dbManagerForTest(testSQLDBType: TestSQLDBType) private var defaultDbType = TestSQLDBType.HSQLDB -//private var defaultDbType = TestSQLDBType.MY_SQL -//private var defaultDbType = TestSQLDBType.DB2_400 + +// private var defaultDbType = TestSQLDBType.MY_SQL +// private var defaultDbType = TestSQLDBType.DB2_400 const val DATABASE_NAME = "TEST" const val DB2_400_HOST = "SRVLAB01.SMEUP.COM" const val DB2_400_LIBRARY_NAME = "W_PARFRA" @@ -55,71 +57,85 @@ const val DB2_400_LIBRARY_NAME = "W_PARFRA" enum class TestSQLDBType( val connectionConfig: ConnectionConfig, val dbaConnectionConfig: ConnectionConfig? = connectionConfig, - val createDatabase : (dbaConnection: Connection) -> Unit = {}, - val destroyDatabase: (dbaConnection: Connection) -> Unit = {}) { + val createDatabase: (dbaConnection: Connection) -> Unit = {}, + val destroyDatabase: (dbaConnection: Connection) -> Unit = {}, +) { MY_SQL( - connectionConfig = ConnectionConfig( - fileName= "*", - url = "jdbc:mysql://localhost:3306/$DATABASE_NAME", - user = "root", - password = "root"), - dbaConnectionConfig = ConnectionConfig( - fileName= "*", - url = "jdbc:mysql://localhost:3306/", - user = "root", - password = "root"), - createDatabase = { dbaConnection -> dbaConnection.prepareStatement("CREATE DATABASE $DATABASE_NAME").use { it.execute() } }, - destroyDatabase = { dbaConnection -> dbaConnection.prepareStatement("DROP DATABASE $DATABASE_NAME").use { it.execute() } } + connectionConfig = + ConnectionConfig( + fileName = "*", + url = "jdbc:mysql://localhost:3306/$DATABASE_NAME", + user = "root", + password = "root", + ), + dbaConnectionConfig = + ConnectionConfig( + fileName = "*", + url = "jdbc:mysql://localhost:3306/", + user = "root", + password = "root", + ), + createDatabase = { dbaConnection -> dbaConnection.prepareStatement("CREATE DATABASE $DATABASE_NAME").use { it.execute() } }, + destroyDatabase = { dbaConnection -> dbaConnection.prepareStatement("DROP DATABASE $DATABASE_NAME").use { it.execute() } }, ), - HSQLDB(ConnectionConfig( - fileName= "*", - url = "jdbc:hsqldb:mem:$DATABASE_NAME", - user = "sa", - password = "root"), - destroyDatabase = { dbaConnection -> dbaConnection.prepareStatement("DROP SCHEMA PUBLIC CASCADE").use { it.execute() } } + HSQLDB( + ConnectionConfig( + fileName = "*", + url = "jdbc:hsqldb:mem:$DATABASE_NAME", + user = "sa", + password = "root", + ), + destroyDatabase = { dbaConnection -> dbaConnection.prepareStatement("DROP SCHEMA PUBLIC CASCADE").use { it.execute() } }, ), - DB2_400(ConnectionConfig( - fileName= "*", + DB2_400( + ConnectionConfig( + fileName = "*", driver = "com.ibm.as400.access.AS400JDBCDriver", url = "jdbc:as400://$DB2_400_HOST/$DB2_400_LIBRARY_NAME;", user = "USER", - password = "**********"), - - //force no create connection for dba operations - dbaConnectionConfig = null + password = "**********", + ), + // force no create connection for dba operations + dbaConnectionConfig = null, + ), + DB2_400_DAT( + ConnectionConfig( + fileName = "*", + driver = "com.ibm.as400.access.AS400JDBCDriver", + url = "jdbc:as400://$DB2_400_HOST/SMEUP_DAT", + user = "USER", + password = "**********", + ), + // force no create connection for dba operations + dbaConnectionConfig = null, ), - DB2_400_DAT(ConnectionConfig( - fileName= "*", - driver = "com.ibm.as400.access.AS400JDBCDriver", - url = "jdbc:as400://$DB2_400_HOST/SMEUP_DAT", - user = "USER", - password = "**********"), - - //force no create connection for dba operations - dbaConnectionConfig = null - ) - } object DatabaseNameFactory { var COUNTER = AtomicInteger() } -fun dbManagerDB2400ForTest(host: String, library:String): SQLDBMManager{ - val dbManager = SQLDBMManager(ConnectionConfig( - fileName= "*", - driver = "com.ibm.as400.access.AS400JDBCDriver", - url = "jdbc:as400://$host/$library;", - user = "USER", - password = "**********"), - ) +fun dbManagerDB2400ForTest( + host: String, + library: String, +): SQLDBMManager { + val dbManager = + SQLDBMManager( + ConnectionConfig( + fileName = "*", + driver = "com.ibm.as400.access.AS400JDBCDriver", + url = "jdbc:as400://$host/$library;", + user = "USER", + password = "**********", + ), + ) dbManager.logger = Logger.getSimpleInstance(LOGGING_LEVEL) return dbManager } fun dbManagerForTest() = dbManagerForTest(defaultDbType) -fun dbManagerForTest(testSQLDBType: TestSQLDBType) : SQLDBMManager { +fun dbManagerForTest(testSQLDBType: TestSQLDBType): SQLDBMManager { testLog("Creating SQLDBManager with db type = $testSQLDBType") val dbManager = SQLDBMManager(testSQLDBType.connectionConfig) @@ -146,68 +162,74 @@ fun destroyDatabase(testSQLDBType: TestSQLDBType) { } fun createAndPopulateTstTable(dbManager: SQLDBMManager?) { - val fields = listOf( - "TSTFLDCHR" fieldByType CharacterType(3), - "TSTFLDNBR" fieldByType DecimalType(5, 2) - ) - - val keys = listOf( - "TSTFLDCHR" - ) + val fields = + listOf( + "TSTFLDCHR" fieldByType CharacterType(3), + "TSTFLDNBR" fieldByType DecimalType(5, 2), + ) + val keys = + listOf( + "TSTFLDCHR", + ) createAndPopulateTable(dbManager, TSTTAB_TABLE_NAME, TSTTAB_TABLE_NAME, fields, keys, "src/test/resources/csv/TstTab.csv") } fun createAndPopulateTst2Table(dbManager: SQLDBMManager?) { - val fields = listOf( - "TSTFLDCHR" fieldByType VarcharType(3), - "TSTFLDNBR" fieldByType DecimalType(5, 2), - "DESTST" fieldByType VarcharType(40) - ) - - val keys = listOf( - "TSTFLDCHR", - "TSTFLDNBR" - ) - - createAndPopulateTable(dbManager, TST2TAB_TABLE_NAME, TST2TAB_TABLE_NAME, fields, keys,"src/test/resources/csv/Tst2Tab.csv") + val fields = + listOf( + "TSTFLDCHR" fieldByType VarcharType(3), + "TSTFLDNBR" fieldByType DecimalType(5, 2), + "DESTST" fieldByType VarcharType(40), + ) + + val keys = + listOf( + "TSTFLDCHR", + "TSTFLDNBR", + ) + + createAndPopulateTable(dbManager, TST2TAB_TABLE_NAME, TST2TAB_TABLE_NAME, fields, keys, "src/test/resources/csv/Tst2Tab.csv") } fun createAndPopulateEmployeeTable(dbManager: SQLDBMManager?) { - val fields = listOf( - "EMPNO" fieldByType CharacterType(6), - "FIRSTNME" fieldByType VarcharType(12), - "MIDINIT" fieldByType VarcharType(1), - "LASTNAME" fieldByType VarcharType(15), - "WORKDEPT" fieldByType CharacterType(3) - ) - - val keys = listOf( - "EMPNO" - ) - - createAndPopulateTable(dbManager, EMPLOYEE_TABLE_NAME, EMPLOYEE_TABLE_NAME, fields, keys,"src/test/resources/csv/Employee.csv") + val fields = + listOf( + "EMPNO" fieldByType CharacterType(6), + "FIRSTNME" fieldByType VarcharType(12), + "MIDINIT" fieldByType VarcharType(1), + "LASTNAME" fieldByType VarcharType(15), + "WORKDEPT" fieldByType CharacterType(3), + ) + + val keys = + listOf( + "EMPNO", + ) + + createAndPopulateTable(dbManager, EMPLOYEE_TABLE_NAME, EMPLOYEE_TABLE_NAME, fields, keys, "src/test/resources/csv/Employee.csv") } fun createAndPopulateXemp2View(dbManager: SQLDBMManager?) { // create view executing sql -> TODO: insert a createView method in DBMManager and use it fun createXEMP2() = "CREATE VIEW $XEMP2_VIEW_NAME AS SELECT * FROM EMPLOYEE ORDER BY WORKDEPT, EMPNO" - fun createXEMP2Index() = - "CREATE INDEX $XEMP2_VIEW_NAME$CONVENTIONAL_INDEX_SUFFIX ON EMPLOYEE (WORKDEPT ASC, EMPNO ASC)" + fun createXEMP2Index() = "CREATE INDEX $XEMP2_VIEW_NAME$CONVENTIONAL_INDEX_SUFFIX ON EMPLOYEE (WORKDEPT ASC, EMPNO ASC)" - val fields = listOf( - "EMPNO" fieldByType CharacterType(6), - "FIRSTNME" fieldByType VarcharType(12), - "MIDINIT" fieldByType VarcharType(1), - "LASTNAME" fieldByType VarcharType(15), - "WORKDEPT" fieldByType CharacterType(3) - ) + val fields = + listOf( + "EMPNO" fieldByType CharacterType(6), + "FIRSTNME" fieldByType VarcharType(12), + "MIDINIT" fieldByType VarcharType(1), + "LASTNAME" fieldByType VarcharType(15), + "WORKDEPT" fieldByType CharacterType(3), + ) - val keys = listOf( - "WORKDEPT" - ) + val keys = + listOf( + "WORKDEPT", + ) val metadata = FileMetadata("$XEMP2_VIEW_NAME", "EMPLOYEE", fields.fieldList(), keys) dbManager!!.registerMetadata(metadata, true) @@ -215,24 +237,25 @@ fun createAndPopulateXemp2View(dbManager: SQLDBMManager?) { } fun createAndPopulateMunicipalityTable(dbManager: SQLDBMManager?) { - val fields = listOf( - "NAZ" fieldByType CharacterType(2), - "REG" fieldByType CharacterType(3), - "PROV" fieldByType CharacterType(2), - "CITTA" fieldByType VarcharType(35), - "CAP" fieldByType CharacterType(5), - "PREF" fieldByType CharacterType(4), - "COMUNE" fieldByType CharacterType(4), - "ISTAT" fieldByType CharacterType(6) - ) - - val keys = listOf( - "NAZ", - "REG", - "PROV", - "CITTA" - ) - + val fields = + listOf( + "NAZ" fieldByType CharacterType(2), + "REG" fieldByType CharacterType(3), + "PROV" fieldByType CharacterType(2), + "CITTA" fieldByType VarcharType(35), + "CAP" fieldByType CharacterType(5), + "PREF" fieldByType CharacterType(4), + "COMUNE" fieldByType CharacterType(4), + "ISTAT" fieldByType CharacterType(6), + ) + + val keys = + listOf( + "NAZ", + "REG", + "PROV", + "CITTA", + ) createAndPopulateTable( dbManager, @@ -240,7 +263,7 @@ fun createAndPopulateMunicipalityTable(dbManager: SQLDBMManager?) { MUNICIPALITY_TABLE_NAME, fields, keys, - "src/test/resources/csv/Municipality.csv" + "src/test/resources/csv/Municipality.csv", ) } @@ -268,9 +291,8 @@ private fun createAndPopulateTable( tableName: String, fields: List, keys: List, - dataFilePath: String + dataFilePath: String, ) { - val tMetadata = TypedMetadata(name, tableName, fields, keys) createFile(tMetadata, dbManager!!) Assert.assertTrue(dbManager.existFile(tableName)) @@ -294,15 +316,18 @@ fun buildMunicipalityKey(vararg values: String): List { val keyValues = mutableListOf() val keys = arrayOf("NAZ", "REG", "PROV", "CITTA") for ((index, value) in values.withIndex()) { - if (keys.size> index) { + if (keys.size > index) { keyValues.add(value) } } return keyValues } -fun createFile(tMetadata: TypedMetadata, dbManager: SQLDBMManager) { - val metadata: FileMetadata = tMetadata.fileMetadata(); +fun createFile( + tMetadata: TypedMetadata, + dbManager: SQLDBMManager, +) { + val metadata: FileMetadata = tMetadata.fileMetadata() dbManager.connection.createStatement().use { it.execute(tMetadata.toSQL()) } @@ -311,7 +336,6 @@ fun createFile(tMetadata: TypedMetadata, dbManager: SQLDBMManager) { fun TypedMetadata.toSQL(): String = "CREATE TABLE ${this.tableName} (${this.fields.toSQL(this)})" - fun Collection.toSQL(tMetadata: TypedMetadata): String { val primaryKeys = tMetadata.fileKeys.joinToString { it } @@ -344,14 +368,16 @@ fun sql2Type(metadataResultSet: ResultSet): FieldType { return sql2Type(sqlType, columnSize, decimalDigits) } - - /** * Convert SQL type in FieldType */ -fun sql2Type(sqlType: String, columnSize: Int, decimalDigits: Int): FieldType = +fun sql2Type( + sqlType: String, + columnSize: Int, + decimalDigits: Int, +): FieldType = when (sqlType) { - "CHAR","CHARACTER","NCHAR" -> CharacterType(columnSize) + "CHAR", "CHARACTER", "NCHAR" -> CharacterType(columnSize) "VARCHAR" -> VarcharType(columnSize) "INT", "INTEGER" -> IntegerType "SMALLINT" -> SmallintType @@ -366,4 +392,4 @@ fun sql2Type(sqlType: String, columnSize: Int, decimalDigits: Int): FieldType = "BINARY" -> BinaryType(columnSize) "VARBINARY" -> VarbinaryType(columnSize) else -> TODO("Conversion from SQL Type not yet implemented: $sqlType") - } \ No newline at end of file + } From 4ac7c9d8cc217acbe5e0aca594fb4d76fdb18af5 Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Wed, 29 Nov 2023 16:17:06 +0100 Subject: [PATCH 21/35] Revert ktlint integrationd --- .mvn/jvm.config | 1 - .../kotlin/com/smeup/dbnative/DBMManager.kt | 16 +- .../com/smeup/dbnative/DBManagerBaseImpl.kt | 37 +-- .../smeup/dbnative/DBNativeAccessConfig.kt | 10 +- .../kotlin/com/smeup/dbnative/file/DBFile.kt | 15 +- .../kotlin/com/smeup/dbnative/file/Record.kt | 16 +- .../kotlin/com/smeup/dbnative/file/Result.kt | 2 +- .../kotlin/com/smeup/dbnative/log/Logging.kt | 100 +++---- .../dbnative/metadata/MetadataRegister.kt | 15 +- .../metadata/file/FSMetadataRegisterImpl.kt | 23 +- .../metadata/file/PropertiesSerializer.kt | 44 ++- .../kotlin/com/smeup/dbnative/model/Field.kt | 2 +- .../com/smeup/dbnative/model/FileMetadata.kt | 2 +- .../com/smeup/dbnative/utils/Comparison.kt | 2 +- .../com/smeup/dbnative/utils/FileUtilities.kt | 12 +- .../dbnative/PropertiesSerializationTest.kt | 9 +- .../com/smeup/dbnative/utils/FieldType.kt | 251 ++++++++-------- .../kotlin/com/smeup/dbnative/utils/Types.kt | 96 +++--- .../com/smeup/dbnative/jt400/JT400DBFile.kt | 91 +++--- .../smeup/dbnative/jt400/JT400DBMManager.kt | 23 +- .../dbnative/jt400/JT400Chain1KeyTest.kt | 3 + .../dbnative/jt400/JT400Chain2KeysTest.kt | 22 +- .../dbnative/jt400/JT400MunicipalityTest.kt | 11 +- .../dbnative/jt400/JT400OperationsOnFile.kt | 48 +-- .../dbnative/jt400/JT400ReadPreviousTest.kt | 3 + .../dbnative/jt400/utils/JT400DBTestUtils.kt | 181 ++++++------ .../smeup/dbnative/manager/DBFileFactory.kt | 54 ++-- .../smeup/dbnative/manager/DBFileWrapper.kt | 9 +- .../dbnative/manager/DBFileFactoryTest.kt | 92 +++--- .../com/smeup/dbnative/nosql/NoSQLDBFile.kt | 208 ++++++------- .../smeup/dbnative/nosql/NoSQLDBMManager.kt | 21 +- .../dbnative/nosql/utils/MongoDbUtils.kt | 23 +- .../smeup/dbnative/nosql/NoSQLDBFileTest.kt | 6 +- .../dbnative/nosql/NoSQLMunicipalityTest.kt | 12 +- .../dbnative/nosql/utils/NoSQLDBTestUtils.kt | 87 +++--- pom.xml | 14 - .../com/smeup/dbnative/sql/JDBCUtils.kt | 21 +- .../smeup/dbnative/sql/Native2SQLAdapter.kt | 200 +++++-------- .../com/smeup/dbnative/sql/SQLDBFile.kt | 74 +++-- .../com/smeup/dbnative/sql/SQLDBFileNoPerf.kt | 133 ++++----- .../com/smeup/dbnative/sql/SQLDBMManager.kt | 34 ++- .../kotlin/com/smeup/dbnative/sql/SQLUtils.kt | 94 +++--- .../dbnative/sql/DB2400OperationsOnFile.kt | 49 ++-- .../sql/DB2400OperationsOnFilePerfTest.kt | 48 ++- .../com/smeup/dbnative/sql/JDBCUtilsTest.kt | 11 +- .../smeup/dbnative/sql/SQLChain1KeyTest.kt | 4 + .../smeup/dbnative/sql/SQLChain2KeysTest.kt | 24 +- .../dbnative/sql/SQLMunicipalityPerfTest.kt | 28 +- .../smeup/dbnative/sql/SQLMunicipalityTest.kt | 10 +- .../smeup/dbnative/sql/SQLReadEqualTest.kt | 17 +- .../smeup/dbnative/sql/SQLReadPreviousTest.kt | 5 +- .../com/smeup/dbnative/sql/SQLUtilsTest.kt | 60 ++-- .../dbnative/sql/utils/SQLDBTestUtils.kt | 276 ++++++++---------- 53 files changed, 1247 insertions(+), 1402 deletions(-) delete mode 100644 .mvn/jvm.config diff --git a/.mvn/jvm.config b/.mvn/jvm.config deleted file mode 100644 index 45d7a1d..0000000 --- a/.mvn/jvm.config +++ /dev/null @@ -1 +0,0 @@ ---add-opens java.base/java.lang=ALL-UNNAMED \ No newline at end of file diff --git a/base/src/main/kotlin/com/smeup/dbnative/DBMManager.kt b/base/src/main/kotlin/com/smeup/dbnative/DBMManager.kt index 31e24a0..e8b2dc7 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/DBMManager.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/DBMManager.kt @@ -26,24 +26,16 @@ import com.smeup.dbnative.model.FileMetadata * A datasource can contains either only tables(views) or only documents. * File is an abstraction of table, view or document. * */ -interface DBMManager : AutoCloseable { - val connectionConfig: ConnectionConfig +interface DBMManager : AutoCloseable{ + val connectionConfig : ConnectionConfig - fun existFile(name: String): Boolean - - fun registerMetadata( - metadata: FileMetadata, - overwrite: Boolean, - ) + fun existFile(name: String): Boolean + fun registerMetadata(metadata: FileMetadata, overwrite: Boolean) fun metadataOf(name: String): FileMetadata - fun openFile(name: String): DBFile - fun closeFile(name: String) - fun unregisterMetadata(name: String) - /** * Validate connectionConfig. If validation fails, implementation has to throw an IllegalArgumentException * */ diff --git a/base/src/main/kotlin/com/smeup/dbnative/DBManagerBaseImpl.kt b/base/src/main/kotlin/com/smeup/dbnative/DBManagerBaseImpl.kt index 93d4e1a..395d642 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/DBManagerBaseImpl.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/DBManagerBaseImpl.kt @@ -15,13 +15,13 @@ * */ + package com.smeup.dbnative import com.smeup.dbnative.log.Logger import com.smeup.dbnative.metadata.MetadataRegister import com.smeup.dbnative.metadata.file.FSMetadataRegisterImpl import com.smeup.dbnative.model.FileMetadata -import java.util.* abstract class DBManagerBaseImpl : DBMManager { var logger: Logger? = null @@ -34,20 +34,14 @@ abstract class DBManagerBaseImpl : DBMManager { */ override fun metadataOf(name: String): FileMetadata { - return getMetadataRegister().getMetadata(name.uppercase(Locale.getDefault())) + return getMetadataRegister().getMetadata(name.toUpperCase()) } - override fun registerMetadata( - metadata: FileMetadata, - overwrite: Boolean, - ) { + override fun registerMetadata(metadata: FileMetadata, overwrite: Boolean) { if (getMetadataRegister().contains(metadata.name)) { - if (overwrite) { - getMetadataRegister().remove(metadata.name) - } else { - return - } - // TODO: send exception (existent metadata and no overwrite) + if (overwrite) getMetadataRegister().remove(metadata.name) + else return + //TODO: send exception (existent metadata and no overwrite) } getMetadataRegister().registerMetadata(metadata, overwrite) @@ -60,10 +54,11 @@ abstract class DBManagerBaseImpl : DBMManager { } override fun existFile(name: String): Boolean { - return getMetadataRegister().contains(name.uppercase()) + return getMetadataRegister().contains(name.toUpperCase()) } companion object { + val register: MetadataRegister get() { return FSMetadataRegisterImpl @@ -73,17 +68,11 @@ abstract class DBManagerBaseImpl : DBMManager { return register } - fun staticRegisterMetadata( - metadata: FileMetadata, - overwrite: Boolean, - ) { + fun staticRegisterMetadata(metadata: FileMetadata, overwrite: Boolean) { if (getMetadataRegister().contains(metadata.name)) { - if (overwrite) { - getMetadataRegister().remove(metadata.name) - } else { - return - } - // TODO: send exception (existent metadata and no overwrite) + if (overwrite) getMetadataRegister().remove(metadata.name) + else return + //TODO: send exception (existent metadata and no overwrite) } getMetadataRegister().registerMetadata(metadata, overwrite) @@ -96,7 +85,7 @@ abstract class DBManagerBaseImpl : DBMManager { } fun staticGetMetadata(name: String): FileMetadata { - return getMetadataRegister().getMetadata(name) + return getMetadataRegister().getMetadata(name); } } } diff --git a/base/src/main/kotlin/com/smeup/dbnative/DBNativeAccessConfig.kt b/base/src/main/kotlin/com/smeup/dbnative/DBNativeAccessConfig.kt index 387d5d7..beec4c5 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/DBNativeAccessConfig.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/DBNativeAccessConfig.kt @@ -19,8 +19,8 @@ package com.smeup.dbnative import com.smeup.dbnative.log.Logger -data class DBNativeAccessConfig(val connectionsConfig: List, val logger: Logger? = null) { - constructor(connectionsConfig: List) : this(connectionsConfig, null) +data class DBNativeAccessConfig (val connectionsConfig: List, val logger: Logger? = null){ + constructor(connectionsConfig: List):this(connectionsConfig, null) } /** @@ -34,12 +34,12 @@ data class DBNativeAccessConfig(val connectionsConfig: List, v * @param impl DBMManager implementation. If doesn't specified is assumed by url * @param properties Others connection properties * */ -data class ConnectionConfig( +data class ConnectionConfig ( val fileName: String, val url: String, val user: String, val password: String, val driver: String? = null, val impl: String? = null, - val properties: Map = mutableMapOf(), -) + val properties : Map = mutableMapOf()) + diff --git a/base/src/main/kotlin/com/smeup/dbnative/file/DBFile.kt b/base/src/main/kotlin/com/smeup/dbnative/file/DBFile.kt index 722051c..0ccba2a 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/file/DBFile.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/file/DBFile.kt @@ -23,44 +23,35 @@ import com.smeup.dbnative.model.FileMetadata /** * DBFile is an abstraction of table or view (in sql database) or document (in nosql database). * */ -interface DBFile : AutoCloseable { +interface DBFile: AutoCloseable { var name: String var fileMetadata: FileMetadata var logger: Logger? // Control functions fun eof(): Boolean - fun equal(): Boolean // Pointing functions fun setll(key: String): Boolean - fun setll(keys: List): Boolean - fun setgt(key: String): Boolean - fun setgt(keys: List): Boolean + // Read functions fun chain(key: String): Result - fun chain(keys: List): Result fun read(): Result - fun readPrevious(): Result fun readEqual(): Result - fun readEqual(key: String): Result - fun readEqual(keys: List): Result fun readPreviousEqual(): Result - fun readPreviousEqual(key: String): Result - fun readPreviousEqual(keys: List): Result // Write functions @@ -73,4 +64,4 @@ interface DBFile : AutoCloseable { fun delete(record: Record): Result override fun close() {} -} +} \ No newline at end of file diff --git a/base/src/main/kotlin/com/smeup/dbnative/file/Record.kt b/base/src/main/kotlin/com/smeup/dbnative/file/Record.kt index 33aa86d..bf99ace 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/file/Record.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/file/Record.kt @@ -24,20 +24,20 @@ class Record(vararg fields: RecordField) : LinkedHashMap() { } } - fun matches(keyFields: List) = - keyFields.all { - val value1 = this[it.name]?.trim() - val value2 = it.value.trim() + fun matches(keyFields: List) = keyFields.all { - value1.equals(value2.trim()) - } + var value1 = this[it.name]?.trim() + var value2 = it.value.trim(); + + value1.equals(value2.trim()) + } fun add(field: RecordField) { put(field.name, field.value) } - fun duplicate(): Record { + fun duplicate(): Record{ val thisMap = this return Record().apply { this.putAll(thisMap) } } -} +} \ No newline at end of file diff --git a/base/src/main/kotlin/com/smeup/dbnative/file/Result.kt b/base/src/main/kotlin/com/smeup/dbnative/file/Result.kt index f41dc00..d6f2e84 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/file/Result.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/file/Result.kt @@ -17,4 +17,4 @@ package com.smeup.dbnative.file -data class Result(var record: Record = Record(), var indicatorHI: Boolean = false, var indicatorLO: Boolean = false, var indicatorEQ: Boolean = false, var errorMsg: String = "") +data class Result(var record: Record = Record(), var indicatorHI: Boolean = false, var indicatorLO: Boolean = false, var indicatorEQ: Boolean = false, var errorMsg: String = "") \ No newline at end of file diff --git a/base/src/main/kotlin/com/smeup/dbnative/log/Logging.kt b/base/src/main/kotlin/com/smeup/dbnative/log/Logging.kt index f1485e1..528de58 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/log/Logging.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/log/Logging.kt @@ -3,95 +3,71 @@ package com.smeup.dbnative.log import java.text.SimpleDateFormat import java.util.* -enum class LoggingLevel { - OFF, - ERROR, - WARN, - INFO, - DEBUG, - TRACE, - ALL, +enum class LoggingLevel{ + OFF, ERROR, WARN, INFO, DEBUG, TRACE, ALL } -enum class LoggingKey(val level: LoggingLevel) { +enum class LoggingKey(val level: LoggingLevel){ native_access_method(LoggingLevel.TRACE), read_data(LoggingLevel.TRACE), execute_inquiry(LoggingLevel.DEBUG), search_data(LoggingLevel.DEBUG), - connection(LoggingLevel.DEBUG), + connection(LoggingLevel.DEBUG) } -enum class NativeMethod() { - equal, - setll, - setgt, - chain, - read, - readPrevious, - readEqual, - readPreviousEqual, - write, - update, - delete, +enum class NativeMethod(){ + equal, setll, setgt, chain, read, readPrevious, readEqual, readPreviousEqual, write, update, delete; } -data class LoggingEvent( - val eventKey: LoggingKey, - val message: String, - val callerMethod: String? = null, - val elapsedTime: Long? = null, - val nativeMethodCall: NativeMethod? = null, - val fileName: String? = null, -) { +data class LoggingEvent(val eventKey: LoggingKey, + val message: String, + val callerMethod: String? = null, + val elapsedTime: Long? = null, + val nativeMethodCall: NativeMethod? = null, + val fileName: String? = null){ val issueTime: Date = Date() - fun isMeasuredEvent() = elapsedTime != null } -open class Logger( - val level: LoggingLevel = LoggingLevel.OFF, - var loggingFunction: ((LoggingEvent) -> Unit)?, -) { - companion object { +open class Logger(val level:LoggingLevel = LoggingLevel.OFF, + var loggingFunction: ((LoggingEvent) -> Unit)?) +{ + companion object{ @JvmStatic - fun getSimpleInstance(level: LoggingLevel = LoggingLevel.DEBUG): Logger { + fun getSimpleInstance(level:LoggingLevel = LoggingLevel.DEBUG): Logger{ return Logger(level, loggingFunction = { val logged = "[%s][%s][%s][%s][%s] * %s %s" - println( - logged.format( - SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS").format(it.issueTime), - it.eventKey.level, - it.eventKey.name, - it.nativeMethodCall ?: "", - it.fileName ?: "", - it.message, - if (it.isMeasuredEvent()) "(${it.elapsedTime} ms)" else "", - ), - ) + println(logged.format(SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS").format(it.issueTime), + it.eventKey.level, + it.eventKey.name, + it.nativeMethodCall?:"", + it.fileName?:"", + it.message, + if(it.isMeasuredEvent()) "(${it.elapsedTime} ms)" else "") + ) }) } } - fun logEvent( - eventKey: LoggingKey, - message: String, - elapsedTime: Long? = null, - nativeMethodCall: NativeMethod? = null, - fileName: String? = null, - ): LoggingEvent? { - return if (eventKey.level.ordinal <= level.ordinal) { - val caller = - Thread.currentThread().getStackTrace().getOrNull(2)?.let { - "${it.className} ${it.methodName}:${it.lineNumber}" - } ?: "" + fun logEvent(eventKey: LoggingKey, + message: String, + elapsedTime: Long? = null, + nativeMethodCall: NativeMethod? = null, + fileName: String? = null): LoggingEvent?{ + return if(eventKey.level.ordinal <= level.ordinal) { + val caller = Thread.currentThread().getStackTrace().getOrNull(2)?.let { + "${it.className} ${it.methodName}:${it.lineNumber}" + }?:"" logEvent(LoggingEvent(eventKey, message, caller, elapsedTime, nativeMethodCall, fileName)) - } else { + } + else{ null } } - internal fun logEvent(ev: LoggingEvent): LoggingEvent { + internal fun logEvent(ev: LoggingEvent): LoggingEvent{ loggingFunction?.invoke(ev) return ev } } + diff --git a/base/src/main/kotlin/com/smeup/dbnative/metadata/MetadataRegister.kt b/base/src/main/kotlin/com/smeup/dbnative/metadata/MetadataRegister.kt index 2ea8769..af52dd8 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/metadata/MetadataRegister.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/metadata/MetadataRegister.kt @@ -20,14 +20,9 @@ package com.smeup.dbnative.metadata import com.smeup.dbnative.model.FileMetadata interface MetadataRegister { - fun registerMetadata( - metadata: FileMetadata, - overwrite: Boolean, - ) - fun getMetadata(filename: String): FileMetadata - - fun contains(fileName: String): Boolean - - fun remove(fileName: String) -} + fun registerMetadata(metadata: FileMetadata, overwrite: Boolean) + fun getMetadata(filename:String): FileMetadata + fun contains(fileName:String): Boolean + fun remove(fileName:String) +} \ No newline at end of file diff --git a/base/src/main/kotlin/com/smeup/dbnative/metadata/file/FSMetadataRegisterImpl.kt b/base/src/main/kotlin/com/smeup/dbnative/metadata/file/FSMetadataRegisterImpl.kt index be99aea..e3884dc 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/metadata/file/FSMetadataRegisterImpl.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/metadata/file/FSMetadataRegisterImpl.kt @@ -21,27 +21,22 @@ import com.smeup.dbnative.metadata.MetadataRegister import com.smeup.dbnative.model.FileMetadata import java.io.File -object FSMetadataRegisterImpl : MetadataRegister { +object FSMetadataRegisterImpl: MetadataRegister{ + var propertiesDirPath: String init { - propertiesDirPath = - System.getenv("DBNATIVE_DDS_DIR") ?: ( - "${System.getProperty("user.home")}${File.separatorChar}" + - "etc${File.separatorChar}" + - "dbnativeaccess${File.separatorChar}dds" - ) + propertiesDirPath = System.getenv("DBNATIVE_DDS_DIR") ?:"${System.getProperty("user.home")}${File.separatorChar}" + + "etc${File.separatorChar}" + + "dbnativeaccess${File.separatorChar}dds" if (File(propertiesDirPath).exists() == false) { File(propertiesDirPath).mkdirs() } } - override fun registerMetadata( - metadata: FileMetadata, - overwrite: Boolean, - ) { + override fun registerMetadata(metadata: FileMetadata, overwrite: Boolean) { PropertiesSerializer.metadataToProperties(propertiesDirPath, metadata, true) } @@ -50,11 +45,11 @@ object FSMetadataRegisterImpl : MetadataRegister { } override fun contains(fileName: String): Boolean { - return File("${propertiesDirPath}${File.separatorChar}$fileName.properties").exists() + return File("${propertiesDirPath}${File.separatorChar}${fileName}.properties").exists() } override fun remove(fileName: String) { - val propertiesFile = File("${propertiesDirPath}${File.separatorChar}$fileName.properties") + var propertiesFile = File("${propertiesDirPath}${File.separatorChar}${fileName}.properties") if (propertiesFile.exists()) propertiesFile.delete() } -} +} \ No newline at end of file diff --git a/base/src/main/kotlin/com/smeup/dbnative/metadata/file/PropertiesSerializer.kt b/base/src/main/kotlin/com/smeup/dbnative/metadata/file/PropertiesSerializer.kt index 4c3d254..2218ca3 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/metadata/file/PropertiesSerializer.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/metadata/file/PropertiesSerializer.kt @@ -27,22 +27,18 @@ import java.nio.charset.Charset import java.util.* import kotlin.collections.ArrayList + object PropertiesSerializer { - fun propertiesToMetadata( - propertiesDirPath: String, - fileName: String, - ): FileMetadata { - val propertiesFile = FileInputStream(File("$propertiesDirPath${File.separatorChar}${fileName.uppercase()}.properties")) - // val properties = Properties() - // properties.load(InputStreamReader(propertiesFile, Charset.forName("UTF-8"))) + + fun propertiesToMetadata(propertiesDirPath: String, fileName: String): FileMetadata{ + val propertiesFile = FileInputStream(File("$propertiesDirPath${File.separatorChar}${fileName.toUpperCase()}.properties")) + //val properties = Properties() + //properties.load(InputStreamReader(propertiesFile, Charset.forName("UTF-8"))) val mp: MutableMap = LinkedHashMap() object : Properties() { @Synchronized - override fun put( - key: Any, - value: Any, - ): Any? { + override fun put(key: Any, value: Any): Any? { return mp.put(key as String, value as String) } }.load(InputStreamReader(propertiesFile, Charset.forName("UTF-8"))) @@ -67,7 +63,7 @@ object PropertiesSerializer { // FieldKeys val fieldsKeys: MutableList = ArrayList() - if (!(mp["filekeys"]).isNullOrEmpty()) { + if(!(mp["filekeys"]).isNullOrEmpty()){ fieldsKeys.addAll((mp["filekeys"]?.split(",")!!)) } @@ -75,30 +71,27 @@ object PropertiesSerializer { return FileMetadata(fileName, tableName, fields, fieldsKeys) } - fun metadataToProperties( - propertiesDirPath: String, - fileMetadata: FileMetadata, - overwrite: Boolean, - ) { + + fun metadataToProperties(propertiesDirPath: String, fileMetadata: FileMetadata, overwrite: Boolean){ metadataToPropertiesImpl(propertiesDirPath, fileMetadata, fileMetadata.fieldsToProperties(), overwrite) } - private fun metadataToPropertiesImpl( - propertiesDirPath: String, - fileMetadata: FileMetadata, - properties: MutableList>, - overwrite: Boolean, - ) { + + private fun metadataToPropertiesImpl(propertiesDirPath: String, + fileMetadata: FileMetadata, + properties: MutableList>, + overwrite: Boolean){ properties.add(Pair("tablename", fileMetadata.tableName)) val keys = fileMetadata.fileKeys.joinToString(",") properties.add(Pair("filekeys", keys)) - val propertiesFilePath = "${propertiesDirPath}${File.separatorChar}${fileMetadata.name.uppercase(Locale.getDefault())}.properties" + + val propertiesFilePath = "${propertiesDirPath}${File.separatorChar}${fileMetadata.name.toUpperCase()}.properties" val propertiesFile = File(propertiesFilePath) - if (overwrite && propertiesFile.exists()) { + if (overwrite && propertiesFile.exists()) { propertiesFile.delete() } @@ -110,5 +103,6 @@ object PropertiesSerializer { } writer.flush() writer.close() + } } diff --git a/base/src/main/kotlin/com/smeup/dbnative/model/Field.kt b/base/src/main/kotlin/com/smeup/dbnative/model/Field.kt index 94e803d..f266536 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/model/Field.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/model/Field.kt @@ -17,4 +17,4 @@ package com.smeup.dbnative.model -data class Field(val name: String, val text: String = "") +data class Field(val name: String, val text:String = "") \ No newline at end of file diff --git a/base/src/main/kotlin/com/smeup/dbnative/model/FileMetadata.kt b/base/src/main/kotlin/com/smeup/dbnative/model/FileMetadata.kt index 3ae9f33..9aa1f00 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/model/FileMetadata.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/model/FileMetadata.kt @@ -17,4 +17,4 @@ package com.smeup.dbnative.model -data class FileMetadata(var name: String, var tableName: String, var fields: List, var fileKeys: List) +data class FileMetadata(var name: String, var tableName:String, var fields: List, var fileKeys:List) \ No newline at end of file diff --git a/base/src/main/kotlin/com/smeup/dbnative/utils/Comparison.kt b/base/src/main/kotlin/com/smeup/dbnative/utils/Comparison.kt index 52563d9..7995e1d 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/utils/Comparison.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/utils/Comparison.kt @@ -23,5 +23,5 @@ enum class Comparison(val symbol: String) { GT(">"), GE(">="), LT("<"), - LE("<="), + LE("<="); } diff --git a/base/src/main/kotlin/com/smeup/dbnative/utils/FileUtilities.kt b/base/src/main/kotlin/com/smeup/dbnative/utils/FileUtilities.kt index 97d546b..8176280 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/utils/FileUtilities.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/utils/FileUtilities.kt @@ -21,10 +21,12 @@ import com.smeup.dbnative.file.RecordField import com.smeup.dbnative.model.Field import com.smeup.dbnative.model.FileMetadata + /* Return true if passed keys are all primary fields in metadata - */ + */ fun FileMetadata.matchFileKeys(keys: List): Boolean { + val keysAsString = mutableListOf() keys.forEach { @@ -49,16 +51,16 @@ fun FileMetadata.getField(name: String): Field? { } } -fun FileMetadata.fieldsToProperties(): MutableList> { +fun FileMetadata.fieldsToProperties(): MutableList>{ val properties = mutableListOf>() for (field in fields.iterator()) { properties.add( Pair( "field.${field.name}", - field.text, - ), + "${field.text}" + ) ) } - return properties + return properties; } diff --git a/base/src/test/kotlin/com/smeup/dbnative/PropertiesSerializationTest.kt b/base/src/test/kotlin/com/smeup/dbnative/PropertiesSerializationTest.kt index ecc0baf..c3a44e9 100644 --- a/base/src/test/kotlin/com/smeup/dbnative/PropertiesSerializationTest.kt +++ b/base/src/test/kotlin/com/smeup/dbnative/PropertiesSerializationTest.kt @@ -22,24 +22,25 @@ import org.junit.Test import java.io.File class DBFileFactoryTest { + @Test fun loadAndSaveTest() { // Delete tmp file - val tmpFile = File("src/test/resources/dds/properties/out/BRARTI0F.properties") + var tmpFile = File("src/test/resources/dds/properties/out/BRARTI0F.properties") if (tmpFile.exists()) tmpFile.delete() tmpFile.parentFile.mkdirs() // Read metadata1 from properties - val metadata1 = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "BRARTI0F") + var metadata1 = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "BRARTI0F") println(metadata1) // Save metadata1 to tmp properties file PropertiesSerializer.metadataToProperties("src/test/resources/dds/properties/out", metadata1, true) // Read metadata2 from tmp properties file - val metadata2 = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/out/", "BRARTI0F") + var metadata2 = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/out/", "BRARTI0F") // Compare metadatas class assert(metadata2.equals(metadata1)) } -} +} \ No newline at end of file diff --git a/base/src/test/kotlin/com/smeup/dbnative/utils/FieldType.kt b/base/src/test/kotlin/com/smeup/dbnative/utils/FieldType.kt index fe099f3..b11b610 100644 --- a/base/src/test/kotlin/com/smeup/dbnative/utils/FieldType.kt +++ b/base/src/test/kotlin/com/smeup/dbnative/utils/FieldType.kt @@ -31,173 +31,190 @@ enum class Type { TIME, DATE, BINARY, - VARBINARY, + VARBINARY } sealed class FieldType { - abstract val type: Type - abstract val size: Int - abstract val digits: Int -} + + abstract val type: Type + abstract val size: Int + abstract val digits: Int + } // Fixed length string -data class CharacterType(val length: Int) : FieldType() { - override val type: Type - get() = Type.CHARACTER + data class CharacterType(val length: Int) : FieldType() { - override val size: Int - get() = length + override val type: Type + get() = Type.CHARACTER - override val digits: Int - get() = 0 -} + override val size: Int + get() = length + + override val digits: Int + get() = 0 + } // Varying length string (with max length) -data class VarcharType(val length: Int) : FieldType() { - override val type: Type - get() = Type.VARCHAR + data class VarcharType(val length: Int) : FieldType() { - override val size: Int - get() = length + override val type: Type + get() = Type.VARCHAR - override val digits: Int - get() = 0 -} + override val size: Int + get() = length -object IntegerType : FieldType() { - override val type: Type - get() = Type.INTEGER + override val digits: Int + get() = 0 + } - override val size: Int - get() = 10 + object IntegerType : FieldType() { - override val digits: Int - get() = 0 -} + override val type: Type + get() = Type.INTEGER -object SmallintType : FieldType() { - override val type: Type - get() = Type.SMALLINT + override val size: Int + get() = 10 - override val size: Int - get() = 5 + override val digits: Int + get() = 0 + } - override val digits: Int - get() = 0 -} + object SmallintType : FieldType() { -object BigintType : FieldType() { - override val type: Type - get() = Type.BIGINT + override val type: Type + get() = Type.SMALLINT - override val size: Int - get() = 19 + override val size: Int + get() = 5 - override val digits: Int - get() = 0 -} + override val digits: Int + get() = 0 + } -object BooleanType : FieldType() { - override val type: Type - get() = Type.BOOLEAN + object BigintType : FieldType() { - override val size: Int - get() = 1 + override val type: Type + get() = Type.BIGINT + + override val size: Int + get() = 19 + + override val digits: Int + get() = 0 + } + + object BooleanType : FieldType() { + + override val type: Type + get() = Type.BOOLEAN + + override val size: Int + get() = 1 + + override val digits: Int + get() = 0 + } - override val digits: Int - get() = 0 -} // Numeric with total length and number of digits (a.k.a. NUMERIC) -data class DecimalType(val length: Int, val precision: Int) : FieldType() { - override val type: Type - get() = Type.DECIMAL + data class DecimalType(val length: Int, val precision: Int) : FieldType() { - override val size: Int - get() = length + override val type: Type + get() = Type.DECIMAL - override val digits: Int - get() = precision -} + override val size: Int + get() = length -object FloatType : FieldType() { - override val type: Type - get() = Type.FLOAT + override val digits: Int + get() = precision + } - override val size: Int - get() = 19 + object FloatType : FieldType() { - override val digits: Int - get() = 0 -} + override val type: Type + get() = Type.FLOAT -object DoubleType : FieldType() { - override val type: Type - get() = Type.DOUBLE + override val size: Int + get() = 19 - override val size: Int - get() = 19 + override val digits: Int + get() = 0 + } - override val digits: Int - get() = 0 -} + object DoubleType : FieldType() { + + override val type: Type + get() = Type.DOUBLE + + override val size: Int + get() = 19 + + override val digits: Int + get() = 0 + } // Year, month, day, hour, minutes, seconds -object TimeStampType : FieldType() { - override val type: Type - get() = Type.TIMESTAMP + object TimeStampType : FieldType() { - override val size: Int - get() = 14 + override val type: Type + get() = Type.TIMESTAMP - override val digits: Int - get() = 0 -} + override val size: Int + get() = 14 + + override val digits: Int + get() = 0 + } // Year, month, day -object DateType : FieldType() { - override val type: Type - get() = Type.DATE + object DateType : FieldType() { - override val size: Int - get() = 8 + override val type: Type + get() = Type.DATE - override val digits: Int - get() = 0 -} + override val size: Int + get() = 8 + + override val digits: Int + get() = 0 + + } // hour, minutes, seconds -object TimeType : FieldType() { - override val type: Type - get() = Type.TIME + object TimeType : FieldType() { - override val size: Int - get() = 6 + override val type: Type + get() = Type.TIME - override val digits: Int - get() = 0 -} + override val size: Int + get() = 6 + + override val digits: Int + get() = 0 + } // Binary with fixed length -data class BinaryType(val length: Int) : FieldType() { - override val type: Type - get() = Type.BINARY + data class BinaryType(val length: Int) : FieldType() { - override val size: Int - get() = length + override val type: Type + get() = Type.BINARY - override val digits: Int - get() = 0 -} + override val size: Int + get() = length + + override val digits: Int + get() = 0 + } // Binary with varying length -data class VarbinaryType(val length: Int) : FieldType() { - override val type: Type - get() = Type.VARBINARY + data class VarbinaryType(val length: Int) : FieldType() { - override val size: Int - get() = length + override val type: Type + get() = Type.VARBINARY - override val digits: Int - get() = 0 -} + override val size: Int + get() = length + + override val digits: Int + get() = 0 + } diff --git a/base/src/test/kotlin/com/smeup/dbnative/utils/Types.kt b/base/src/test/kotlin/com/smeup/dbnative/utils/Types.kt index 163e3a7..e1ca8b8 100644 --- a/base/src/test/kotlin/com/smeup/dbnative/utils/Types.kt +++ b/base/src/test/kotlin/com/smeup/dbnative/utils/Types.kt @@ -8,36 +8,35 @@ import java.nio.charset.Charset import java.util.* import kotlin.collections.ArrayList -data class TypedField(val field: Field, val type: FieldType) +data class TypedField(val field: Field, val type: FieldType){ +} -fun Collection.fieldList(): List { - return map({ tf -> tf.field }) +fun Collection.fieldList():List{ + return map({tf -> tf.field}) } -fun Collection.fieldTypeList(): List { - return map({ tf -> tf.type }) +fun Collection.fieldTypeList():List{ + return map({tf -> tf.type}) } -data class TypedMetadata( - var name: String, - var tableName: String, - var fields: List, - var fileKeys: List, -) { - fun fileMetadata(): FileMetadata = FileMetadata(name, tableName, fields.fieldList(), fileKeys) +data class TypedMetadata(var name: String, + var tableName: String, + var fields: List, + var fileKeys:List){ + fun fileMetadata(): FileMetadata = FileMetadata(name, tableName, fields.fieldList(), fileKeys); - fun fieldsToProperties(): MutableList> { + fun fieldsToProperties(): MutableList>{ val properties = mutableListOf>() for ((index, field) in fields.iterator().withIndex()) { properties.add( Pair( "field.${field.field.name}", - "${field.field.text},${fields[index].type.type},${fields[index].type.size},${fields[index].type.digits}", - ), + "${field.field.text},${fields[index].type.type},${fields[index].type.size},${fields[index].type.digits}" + ) ) } - return properties + return properties; } fun getField(name: String): TypedField? { @@ -51,47 +50,38 @@ data class TypedMetadata( infix fun String.fieldByType(type: FieldType): TypedField = TypedField(Field(this), type) -fun String.getFieldTypeInstance( - columnSize: Int, - decimalDigits: Int, -): FieldType { - val fieldTypeObject = - when (this.uppercase()) { - "CHAR", "CHARACTER" -> CharacterType(columnSize) - "VARCHAR" -> VarcharType(columnSize) - "INT", "INTEGER" -> IntegerType - "SMALLINT" -> SmallintType - "BIGINT" -> BigintType - "BOOLEAN", "BOOL" -> BooleanType - "DECIMAL" -> DecimalType(columnSize, decimalDigits) - "DOUBLE" -> DoubleType - "FLOAT" -> FloatType - "TIMESTAMP" -> TimeStampType - "TIME" -> TimeType - "DATE" -> DateType - "BINARY" -> BinaryType(columnSize) - "VARBINARY" -> VarbinaryType(columnSize) - else -> throw IllegalArgumentException("Wrong type of FieldType") - } +fun String.getFieldTypeInstance(columnSize: Int, decimalDigits: Int): FieldType { + + val fieldTypeObject = when (this.toUpperCase()) { + "CHAR","CHARACTER" -> CharacterType(columnSize) + "VARCHAR" -> VarcharType(columnSize) + "INT", "INTEGER" -> IntegerType + "SMALLINT" -> SmallintType + "BIGINT" -> BigintType + "BOOLEAN", "BOOL" -> BooleanType + "DECIMAL" -> DecimalType(columnSize, decimalDigits) + "DOUBLE" -> DoubleType + "FLOAT" -> FloatType + "TIMESTAMP" -> TimeStampType + "TIME" -> TimeType + "DATE" -> DateType + "BINARY" -> BinaryType(columnSize) + "VARBINARY" -> VarbinaryType(columnSize) + else -> throw IllegalArgumentException("Wrong type of FieldType") + } return fieldTypeObject } -fun propertiesToTypedMetadata( - propertiesDirPath: String, - fileName: String, -): TypedMetadata { - val propertiesFile = FileInputStream(File("$propertiesDirPath${File.separatorChar}${fileName.uppercase()}.properties")) - // val properties = Properties() - // properties.load(InputStreamReader(propertiesFile, Charset.forName("UTF-8"))) +fun propertiesToTypedMetadata(propertiesDirPath: String, fileName: String): TypedMetadata { + val propertiesFile = FileInputStream(File("$propertiesDirPath${File.separatorChar}${fileName.toUpperCase()}.properties")) + //val properties = Properties() + //properties.load(InputStreamReader(propertiesFile, Charset.forName("UTF-8"))) val mp: MutableMap = LinkedHashMap() object : Properties() { @Synchronized - override fun put( - key: Any, - value: Any, - ): Any? { + override fun put(key: Any, value: Any): Any? { return mp.put(key as String, value as String) } }.load(InputStreamReader(propertiesFile, Charset.forName("UTF-8"))) @@ -109,17 +99,17 @@ fun propertiesToTypedMetadata( val datatype = fldAttributes[1].trim() val fieldType = datatype.getFieldTypeInstance(length, decimal) - fields.add(TypedField(Field(name, description), fieldType)) + fields.add(TypedField(Field(name, description), fieldType)) } // FormatName - val tablename = mp.get("tablename") ?: "" + val tablename = mp.get("tablename")?:"" // FieldKeys val fieldsKeys: MutableList = ArrayList() - if (!(mp.get("filekeys")).isNullOrEmpty()) { + if(!(mp.get("filekeys")).isNullOrEmpty()){ fieldsKeys.addAll((mp.get("filekeys")?.split(",")!!)) } return TypedMetadata(fileName, tablename, fields, fieldsKeys) -} +} \ No newline at end of file diff --git a/jt400/src/main/kotlin/com/smeup/dbnative/jt400/JT400DBFile.kt b/jt400/src/main/kotlin/com/smeup/dbnative/jt400/JT400DBFile.kt index 1ac67c3..aa8f24b 100644 --- a/jt400/src/main/kotlin/com/smeup/dbnative/jt400/JT400DBFile.kt +++ b/jt400/src/main/kotlin/com/smeup/dbnative/jt400/JT400DBFile.kt @@ -29,17 +29,14 @@ import com.smeup.dbnative.model.FileMetadata import java.math.BigDecimal private enum class CursorAction { - NONE, - SETLL, - SETGT, + NONE, SETLL, SETGT } -class JT400DBFile( - override var name: String, - override var fileMetadata: FileMetadata, - var file: KeyedFile, - override var logger: Logger? = null, -) : DBFile { +class JT400DBFile(override var name: String, + override var fileMetadata: FileMetadata, + var file: KeyedFile, + override var logger: Logger? = null) : DBFile { + private var equalFlag: Boolean = false private var eofReached: Boolean = false private var previousAction: CursorAction = CursorAction.NONE @@ -99,9 +96,9 @@ class JT400DBFile( } catch (e: AS400Exception) { } try { - // file.positionCursorBefore(keys2Array(keys)) + //file.positionCursorBefore(keys2Array(keys)) file.positionCursor(keys2Array(keys), KeyedFile.KEY_LT) - // file.positionCursor(keys2Array(keys), KeyedFile.KEY_LT) + //file.positionCursor(keys2Array(keys), KeyedFile.KEY_LT) return true } catch (e: AS400Exception) { handleAS400Error(e) @@ -145,14 +142,14 @@ class JT400DBFile( override fun chain(keys: List): Result { this.previousAction = CursorAction.NONE resetStatus() - // TODO("Attenzione alla gestione del lock") + //TODO("Attenzione alla gestione del lock") try { /* file.positionCursor(keys2Array(keys), KeyedFile.KEY_EQ) var r : Result? = Result(as400RecordToSmeUPRecord(file.read())) //file.positionCursorToNext(); return r ?: fail("Read failed"); - */ + */ return Result(as400RecordToSmeUPRecord(file.read(keys2Array(keys)))) } catch (e: AS400Exception) { handleAS400Error(e) @@ -164,13 +161,13 @@ class JT400DBFile( * The READ operation reads the record, currently pointed to, from a full procedural file. */ override fun read(): Result { - // https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_74/rzasd/zzread.htm - var r: Result + //https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_74/rzasd/zzread.htm + var r : Result try { - if (this.previousAction == CursorAction.SETLL) { + if (this.previousAction==CursorAction.SETLL) { file.positionCursorToNext() } - r = Result(as400RecordToSmeUPRecord(file.read())) + r = Result(as400RecordToSmeUPRecord(file.read())) } catch (e: AS400Exception) { handleAS400Error(e) r = Result(Record()) @@ -189,12 +186,12 @@ class JT400DBFile( */ override fun readPrevious(): Result { resetStatus() - var r: Result + var r : Result try { - if (this.previousAction != CursorAction.SETLL) { + if (this.previousAction!=CursorAction.SETLL) { file.positionCursorToPrevious() } - r = Result(as400RecordToSmeUPRecord(file.read())) + r = Result(as400RecordToSmeUPRecord(file.read())) } catch (e: AS400Exception) { handleAS400Error(e) r = Result(Record()) @@ -226,10 +223,10 @@ class JT400DBFile( override fun readEqual(keys: List): Result { resetStatus() - // https://code400.com/forum/forum/iseries-programming-languages/java/8386-noobie-question + //https://code400.com/forum/forum/iseries-programming-languages/java/8386-noobie-question return try { - // val r = if (this.previousAction==CursorAction.SETGT) file.read(keys2Array(keys)) else file.readNextEqual(keys2Array(keys)) - if (this.previousAction == CursorAction.SETGT) { + //val r = if (this.previousAction==CursorAction.SETGT) file.read(keys2Array(keys)) else file.readNextEqual(keys2Array(keys)) + if (this.previousAction==CursorAction.SETGT) { file.positionCursorToPrevious() } val r = file.readNextEqual(keys2Array(keys)) @@ -277,7 +274,7 @@ class JT400DBFile( override fun readPreviousEqual(keys: List): Result { resetStatus() return try { - if (this.previousAction == CursorAction.SETLL) { + if (this.previousAction==CursorAction.SETLL) { file.positionCursorToNext() } val r = file.readPreviousEqual(keys2Array(keys)) @@ -327,8 +324,8 @@ class JT400DBFile( * After a conversion mapping message on a read operation, the file is positioned to the record containing the data that caused the message. */ private fun handleAS400Error(e: AS400Exception) { - // CPF5001 End of file reached - // CPF5006 Record not found + //CPF5001 End of file reached + //CPF5006 Record not found val eid = as400ErrorID(e).toUpperCase() if (eid.startsWith("CPF5001")) { this.eofReached = true @@ -338,22 +335,20 @@ class JT400DBFile( } throw RuntimeException() } - - private fun as400ErrorID(e: AS400Exception): String { - // CPF5001 End of file reached - // CPF5006 Record not found - if (e.aS400Message != null && - e.aS400Message.id != null - ) { + private fun as400ErrorID(e: AS400Exception) : String { + //CPF5001 End of file reached + //CPF5006 Record not found + if (e.aS400Message != null + && e.aS400Message.id != null) { return e.aS400Message.id } return "" } private fun keys2Array(keys: List): Array { - // return keys.map { it.value }.toTypedArray() + //return keys.map { it.value }.toTypedArray() val keysValues = mutableListOf() - // for (key in fileMetadata.fileKeys) { + //for (key in fileMetadata.fileKeys) { for (i in keys.indices) { val keyName = fileMetadata.fileKeys[i] val keyValue = keys.get(i) @@ -378,7 +373,7 @@ class JT400DBFile( private fun as400RecordToSmeUPRecord(r: com.ibm.as400.access.Record?): Record { // TODO create a unit test for the isAfterLast condition - if (r == null) { // TODO || this.isAfterLast + if (r == null) { //TODO || this.isAfterLast return Record() } val result = Record() @@ -390,10 +385,10 @@ class JT400DBFile( return result } - // fun com.ibm.as400.access.Record?.currentRecordToValues(): Record { + //fun com.ibm.as400.access.Record?.currentRecordToValues(): Record { private fun smeUPRecordToAS400Record(r: Record?): com.ibm.as400.access.Record? { if (r == null) { - return null // com.ibm.as400.access.Record() + return null //com.ibm.as400.access.Record() } val result = com.ibm.as400.access.Record() result.recordFormat = file.recordFormat @@ -401,20 +396,20 @@ class JT400DBFile( if (numericField(name)) { result.setField(name, BigDecimal(value)) } else { - // try { - result.setField(name, value.trimEnd()) - // } catch (ex : Exception) { + //try { + result.setField(name, value.trimEnd()) + //} catch (ex : Exception) { // println(ex.message) - // } + //} } } return result } - private fun numericField(name: String): Boolean { + private fun numericField(name : String) : Boolean { val dataType = file.recordFormat.getFieldDescription(name).dataType.instanceType - // val field : Field? = this.fileMetadata.getField(name) - // val type : FieldType? = field?.type + //val field : Field? = this.fileMetadata.getField(name) + //val type : FieldType? = field?.type return when (dataType) { AS400DataType.TYPE_ZONED, AS400DataType.TYPE_PACKED, @@ -428,11 +423,11 @@ class JT400DBFile( AS400DataType.TYPE_UBIN4, AS400DataType.TYPE_UBIN8, AS400DataType.TYPE_FLOAT4, - AS400DataType.TYPE_FLOAT8, - -> + AS400DataType.TYPE_FLOAT8 -> true else -> false } } -} + +} \ No newline at end of file diff --git a/jt400/src/main/kotlin/com/smeup/dbnative/jt400/JT400DBMManager.kt b/jt400/src/main/kotlin/com/smeup/dbnative/jt400/JT400DBMManager.kt index 98da145..ca53bae 100644 --- a/jt400/src/main/kotlin/com/smeup/dbnative/jt400/JT400DBMManager.kt +++ b/jt400/src/main/kotlin/com/smeup/dbnative/jt400/JT400DBMManager.kt @@ -25,28 +25,29 @@ import com.smeup.dbnative.ConnectionConfig import com.smeup.dbnative.DBManagerBaseImpl import com.smeup.dbnative.file.DBFile -open class JT400DBMManager(final override val connectionConfig: ConnectionConfig) : DBManagerBaseImpl() { +open class JT400DBMManager(final override val connectionConfig: ConnectionConfig) : DBManagerBaseImpl() { + private var openedFile = mutableMapOf() // as400://SRVLAB01.SMEUP.COM/W_SCAARM private val match = Regex("as400://((?:\\w|\\.)+)/(\\w+)").find(connectionConfig.url) - private val host: String by lazy { + private val host : String by lazy { match!!.destructured.component1() } - private val library: String by lazy { + private val library : String by lazy { match!!.destructured.component2() } - private val connection: AS400 by lazy { + private val connection : AS400 by lazy { val as400 = AS400(host, connectionConfig.user, connectionConfig.password) as400.isGuiAvailable = false - // as400.addConnectionListener + //as400.addConnectionListener as400.connectService(AS400.RECORDACCESS) as400 } - override fun openFile(name: String): DBFile { + override fun openFile(name: String) : DBFile { require(existFile(name)) { "Cannot open unregistered file $name" } @@ -57,15 +58,16 @@ open class JT400DBMManager(final override val connectionConfig: ConnectionConfig // val fileName = QSYSObjectPathName(library, name, "*FILE", "MBR") val path = fileName.path - // println("Path: $path") + //println("Path: $path") val file = KeyedFile(connection, path) - // val rf = AS400FileRecordDescription(system, path).retrieveRecordFormat() - // file.recordFormat = rf[0] + //val rf = AS400FileRecordDescription(system, path).retrieveRecordFormat() + //file.recordFormat = rf[0] file.setRecordFormat() // Loads the record format directly from the server. file.open(AS400File.READ_WRITE, 0, AS400File.COMMIT_LOCK_LEVEL_NONE) val jt400File = JT400DBFile(name, metadataOf(name), file, logger) openedFile.putIfAbsent(name, jt400File) return jt400File + } override fun closeFile(name: String) { @@ -82,4 +84,5 @@ open class JT400DBMManager(final override val connectionConfig: ConnectionConfig override fun close() { connection.disconnectAllServices() } -} + +} \ No newline at end of file diff --git a/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400Chain1KeyTest.kt b/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400Chain1KeyTest.kt index 73bf549..cc11c72 100644 --- a/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400Chain1KeyTest.kt +++ b/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400Chain1KeyTest.kt @@ -28,6 +28,7 @@ import kotlin.test.assertEquals import kotlin.test.assertTrue class JT400Chain1KeyTest { + private lateinit var dbManager: JT400DBMManager @Before @@ -59,4 +60,6 @@ class JT400Chain1KeyTest { assertTrue(dbFile.chain("XYZ").record.isEmpty()) dbManager.closeFile(TSTTAB_TABLE_NAME) } + } + diff --git a/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400Chain2KeysTest.kt b/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400Chain2KeysTest.kt index 002611a..1b5972d 100644 --- a/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400Chain2KeysTest.kt +++ b/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400Chain2KeysTest.kt @@ -28,6 +28,7 @@ import kotlin.test.assertEquals import kotlin.test.assertTrue class JT400Chain2KeysTest { + private lateinit var dbManager: JT400DBMManager @Before @@ -47,11 +48,10 @@ class JT400Chain2KeysTest { @Test fun findRecordsIfChainWithExistingKey() { val dbFile = dbManager.openFile(TST2TAB_TABLE_NAME) - val key2 = - listOf( - "ABC", - "12.00", - ) + val key2 = listOf( + "ABC", + "12.00" + ) val chainResult = dbFile.chain(key2) assertEquals("ABC", chainResult.record["TSTFLDCHR"]) assertEquals("12.00", chainResult.record["TSTFLDNBR"]) @@ -62,12 +62,14 @@ class JT400Chain2KeysTest { @Test fun doesNotFindRecordsIfChainWithNotExistingKey() { val dbFile = dbManager.openFile(TST2TAB_TABLE_NAME) - val key2 = - listOf( - "ZZZ", - "12", - ) + val key2 = listOf( + "ZZZ", + "12" + ) assertTrue(dbFile.chain(key2).record.isEmpty()) dbManager.closeFile(TST2TAB_TABLE_NAME) } + + } + diff --git a/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400MunicipalityTest.kt b/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400MunicipalityTest.kt index c1a95ae..ab27a90 100644 --- a/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400MunicipalityTest.kt +++ b/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400MunicipalityTest.kt @@ -25,7 +25,9 @@ import org.junit.Test import kotlin.test.assertEquals import kotlin.test.assertTrue + class JT400MunicipalityTest { + private lateinit var dbManager: JT400DBMManager @Before @@ -78,11 +80,11 @@ class JT400MunicipalityTest { assertTrue(dbFile.setll(buildMunicipalityKey("IT", "LOM", "BS", "ERBUSCO"))) assertEquals( "EDOLO", - getMunicipalityName(dbFile.readPreviousEqual(buildMunicipalityKey("IT", "LOM", "BS")).record), + getMunicipalityName(dbFile.readPreviousEqual(buildMunicipalityKey("IT", "LOM", "BS")).record) ) assertEquals( "DESENZANO DEL GARDA", - getMunicipalityName(dbFile.readPreviousEqual(buildMunicipalityKey("IT", "LOM", "BS")).record), + getMunicipalityName(dbFile.readPreviousEqual(buildMunicipalityKey("IT", "LOM", "BS")).record) ) dbManager.closeFile(MUNICIPALITY_TABLE_NAME) } @@ -402,7 +404,7 @@ class JT400MunicipalityTest { fun t15_eof() { val dbFile = dbManager.openFile(MUNICIPALITY_TABLE_NAME) val key3A = buildMunicipalityKey("IT", "BAS", "MT") - // val key3A = buildMunicipalityKey("IT", "LOM", "PV", "PALESTRO") + //val key3A = buildMunicipalityKey("IT", "LOM", "PV", "PALESTRO") assertTrue(dbFile.setll(key3A)) var count = 0 while (!dbFile.eof()) { @@ -412,4 +414,7 @@ class JT400MunicipalityTest { assertEquals(32, count) dbManager.closeFile(MUNICIPALITY_TABLE_NAME) } + + } + diff --git a/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400OperationsOnFile.kt b/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400OperationsOnFile.kt index 600477d..5b50436 100644 --- a/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400OperationsOnFile.kt +++ b/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400OperationsOnFile.kt @@ -32,6 +32,7 @@ import kotlin.test.assertEquals import kotlin.test.assertTrue class JT400OperationsOnFile { + private lateinit var dbManager: JT400DBMManager @Before @@ -193,7 +194,7 @@ class JT400OperationsOnFile { var chainResult = dbFile.chain(keyList) assertEquals(0, chainResult.record.size) - // Set field values and write record + //Set field values and write record chainResult.record["A§ARTI"] = key chainResult.record["A§DEAR"] = "Kotlin DBNativeAccess Write " chainResult.record["A§TIAR"] = "ART " @@ -201,17 +202,17 @@ class JT400OperationsOnFile { dbFile.write(chainResult.record) - // Must exists correct write + //Must exists correct write chainResult = dbFile.chain(keyList) assertEquals(key, chainResult.record["A§ARTI"]) assertEquals("ART ", chainResult.record["A§TIAR"]) assertEquals("Kotlin DBNativeAccess Write ", chainResult.record["A§DEAR"]) assertEquals("0 ", chainResult.record["A§TPAR"]) - // Delete record + //Delete record dbFile.delete(chainResult.record) - // Check delete success + //Check delete success chainResult = dbFile.chain(keyList) assertEquals(0, chainResult.record.size) @@ -219,7 +220,7 @@ class JT400OperationsOnFile { } @Test - fun multipleUpdateOnReadE() { + fun multipleUpdateOnReadE(){ // TEST FLOW // Step1: write 100 records with "currentTimeMillis" as unique key // Step2: read above written records and update A§DEA2 field @@ -234,7 +235,7 @@ class JT400OperationsOnFile { // Create list of items to write into A§ARTI field val items = mutableListOf() - repeat(numberOfRecordsToHandle) { + repeat(numberOfRecordsToHandle){ items.add(System.currentTimeMillis().toString() + " ") Thread.sleep(5) } @@ -245,21 +246,19 @@ class JT400OperationsOnFile { val dea2Key = "Kotlin DBNativeAccess TEST-UPDATED " // WRITE - repeat(numberOfRecordsToHandle) { + repeat(numberOfRecordsToHandle){ val record = Record() - repeat(fieldsNumber) { index -> + repeat(fieldsNumber){ index -> val name: String = dbFile.fileMetadata.fields[index].name - // print(dbFile.fileMetadata.getField(name)?.type) - val value = - when (name) { - "A§ARTI" -> items[it] - "A§DEAR" -> dearKey - else -> - when (tMetadata.getField(name)?.type) { - is DecimalType -> "0" - else -> "" - } + //print(dbFile.fileMetadata.getField(name)?.type) + val value = when(name){ + "A§ARTI" -> items[it] + "A§DEAR" -> dearKey + else -> when(tMetadata.getField(name)?.type){ + is DecimalType -> "0" + else -> "" } + } val recordField = RecordField(name, value) record.add(recordField) @@ -271,7 +270,7 @@ class JT400OperationsOnFile { // Read records with same description (A§DEAR) and update field named 'secondary description' (A§DEA2) val keyList = listOf(dearKey) assertTrue(dbFile.setll(keyList)) - // dbFile.positionCursorBefore(keyList) //TODO rivedere + //dbFile.positionCursorBefore(keyList) //TODO rivedere // Update repeat(numberOfRecordsToHandle) { val readEResult = dbFile.readEqual(keyList) @@ -284,7 +283,7 @@ class JT400OperationsOnFile { // READ AND CHECK // Check all records are updated as expected assertTrue(dbFile.setll(keyList)) - // dbFile.positionCursorBefore(keyList) //TODO rivedere + //dbFile.positionCursorBefore(keyList) //TODO rivedere repeat(numberOfRecordsToHandle) { val readEResult = dbFile.readEqual(keyList) println("[READ AND CHECK]: " + readEResult.record["A§ARTI"]) @@ -293,13 +292,14 @@ class JT400OperationsOnFile { // DELETE assertTrue(dbFile.setll(keyList)) - // dbFile.positionCursorBefore(keyList) //TODO rivedere + //dbFile.positionCursorBefore(keyList) //TODO rivedere repeat(numberOfRecordsToHandle) { val readEResult = dbFile.readEqual(keyList) assertEquals(dea2Key, readEResult.record["A§DEA2"]) - // Delete record + //Delete record dbFile.delete(readEResult.record) } + } @Test @@ -345,7 +345,7 @@ class JT400OperationsOnFile { dbManager.registerMetadata(fileMetadata, false) val dbFile = dbManager.openFile("VERAPG1L") - // keys: V£DATA, V£NOME, V£IDOJ + //keys: V£DATA, V£NOME, V£IDOJ val data = "20200901" val nome = "BNUNCA " val idoj = "0002003070" @@ -449,4 +449,6 @@ class JT400OperationsOnFile { dbManager.closeFile("BRARTI0L") } */ + } + diff --git a/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400ReadPreviousTest.kt b/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400ReadPreviousTest.kt index a1a8953..ad69ad5 100644 --- a/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400ReadPreviousTest.kt +++ b/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400ReadPreviousTest.kt @@ -25,6 +25,7 @@ import kotlin.test.assertEquals import kotlin.test.assertTrue class JT400ReadPreviousTest { + private lateinit var dbManager: JT400DBMManager @Before @@ -79,4 +80,6 @@ class JT400ReadPreviousTest { assertEquals("SALLY KWAN", getEmployeeName(dbFile.read().record)) dbManager.closeFile(EMPLOYEE_TABLE_NAME) } + + } diff --git a/jt400/src/test/kotlin/com/smeup/dbnative/jt400/utils/JT400DBTestUtils.kt b/jt400/src/test/kotlin/com/smeup/dbnative/jt400/utils/JT400DBTestUtils.kt index 1ae3ad1..96de888 100644 --- a/jt400/src/test/kotlin/com/smeup/dbnative/jt400/utils/JT400DBTestUtils.kt +++ b/jt400/src/test/kotlin/com/smeup/dbnative/jt400/utils/JT400DBTestUtils.kt @@ -35,9 +35,8 @@ const val TSTTAB_TABLE_NAME = "TSTTAB" const val TST2TAB_TABLE_NAME = "TST2TAB" const val MUNICIPALITY_TABLE_NAME = "MUNIC0000B" const val TEST_LOG = false - -// do not change defaultValue -// if you want to create sqlconnection against another db use function: dbManagerForTest(testSQLDBType: TestSQLDBType) +//do not change defaultValue +//if you want to create sqlconnection against another db use function: dbManagerForTest(testSQLDBType: TestSQLDBType) private var defaultDbType = TestSQLDBType.DB2_400 const val DB2_400_HOST = "SRVLAB01.SMEUP.COM" const val DB2_400_LIBRARY_NAME = "W_PARFRA" @@ -47,34 +46,32 @@ const val CONVENTIONAL_INDEX_SUFFIX = "_INDEX" enum class TestSQLDBType( val connectionConfig: ConnectionConfig, val dbaConnectionConfig: ConnectionConfig? = connectionConfig, - val createDatabase: (dbaConnection: AS400) -> Unit = {}, - val destroyDatabase: (dbaConnection: AS400) -> Unit = {}, -) { - DB2_400( - ConnectionConfig( - fileName = "*", + val createDatabase : (dbaConnection: AS400) -> Unit = {}, + val destroyDatabase: (dbaConnection: AS400) -> Unit = {}) { + DB2_400(ConnectionConfig( + fileName= "*", driver = "com.ibm.as400.access.AS400JDBCDriver", url = "jdbc:as400://$DB2_400_HOST/$DB2_400_LIBRARY_NAME;", user = "USER", - password = "*********", - ), - // force no create connection for dba operations - dbaConnectionConfig = null, - ), + password = "*********"), + //force no create connection for dba operations + dbaConnectionConfig = null + ) + } fun dbManagerForTest() = dbManagerForTest(defaultDbType) -fun dbManagerForTest(testSQLDBType: TestSQLDBType): JT400DBMManager { +fun dbManagerForTest(testSQLDBType: TestSQLDBType) : JT400DBMManager { testLog("Creating SQLDBManager with db type = $testSQLDBType") val dbManager = JT400DBMManager(testSQLDBType.connectionConfig) if (testSQLDBType.dbaConnectionConfig != null) { - // JT400DBMMAnager(testSQLDBType.dbaConnectionConfig).connection.use { + //JT400DBMMAnager(testSQLDBType.dbaConnectionConfig).connection.use { // testSQLDBType.createDatabase(it) - // } + //} } - // dbManager.setSQLLog(TEST_LOG) + //dbManager.setSQLLog(TEST_LOG) return dbManager } @@ -84,121 +81,117 @@ fun destroyDatabase() { fun destroyDatabase(testSQLDBType: TestSQLDBType) { if (testSQLDBType.dbaConnectionConfig != null) { - // JT400DBMMAnager(testSQLDBType.dbaConnectionConfig).connection.use { + //JT400DBMMAnager(testSQLDBType.dbaConnectionConfig).connection.use { // testSQLDBType.destroyDatabase(it) - // } + //} } } fun createAndPopulateMunicipalityTable(dbManager: JT400DBMManager?) { - val fields = - listOf( - "NAZ" fieldByType CharacterType(2), - "REG" fieldByType CharacterType(3), - "PROV" fieldByType CharacterType(2), - "CITTA" fieldByType VarcharType(35), - "CAP" fieldByType CharacterType(5), - "PREF" fieldByType CharacterType(4), - "COMUNE" fieldByType CharacterType(4), - "ISTAT" fieldByType CharacterType(6), - ) - - val keys = - listOf( - "NAZ", - "REG", - "PROV", - "CITTA", - ) - - // createAndPopulateTable( /* ci mette tantissimo >20min, la teniamo fissa già creata */ + val fields = listOf( + "NAZ" fieldByType CharacterType(2), + "REG" fieldByType CharacterType(3), + "PROV" fieldByType CharacterType(2), + "CITTA" fieldByType VarcharType(35), + "CAP" fieldByType CharacterType(5), + "PREF" fieldByType CharacterType(4), + "COMUNE" fieldByType CharacterType(4), + "ISTAT" fieldByType CharacterType(6) + ) + + val keys = listOf( + "NAZ", + "REG", + "PROV", + "CITTA" + ) + + + //createAndPopulateTable( /* ci mette tantissimo >20min, la teniamo fissa già creata */ registerTable( dbManager, MUNICIPALITY_TABLE_NAME, "TSTREC", fields, keys, - "src/test/resources/csv/Municipality.csv", + "src/test/resources/csv/Municipality.csv" ) - // + /**/ } fun createAndPopulateTestTable(dbManager: JT400DBMManager?) { - val fields = - listOf( - "TSTFLDCHR" fieldByType CharacterType(3), - "TSTFLDNBR" fieldByType DecimalType(5, 2), - ) - - val keys = - listOf( - "TSTFLDCHR", - "TSTFLDNBR", - ) - - // createAndPopulateTable( /* ci mette tantissimo >20min, la teniamo fissa già creata */ + val fields = listOf( + "TSTFLDCHR" fieldByType CharacterType(3), + "TSTFLDNBR" fieldByType DecimalType(5, 2) + ) + + val keys = listOf( + "TSTFLDCHR", + "TSTFLDNBR" + ) + + + //createAndPopulateTable( /* ci mette tantissimo >20min, la teniamo fissa già creata */ registerTable( dbManager, TSTTAB_TABLE_NAME, "TSTREC", fields, keys, - "src/test/resources/csv/TstTab.csv", + "src/test/resources/csv/TstTab.csv" ) - // + /**/ } fun createAndPopulateTest2Table(dbManager: JT400DBMManager?) { - val fields = - listOf( - "TSTFLDCHR" fieldByType CharacterType(3), - "TSTFLDNBR" fieldByType DecimalType(5, 2), - "DESTST" fieldByType CharacterType(10), - ) - - val keys = - listOf( - "TSTFLDCHR", - "TSTFLDNBR", - ) - - // createAndPopulateTable( /* ci mette tantissimo >20min, la teniamo fissa già creata */ + val fields = listOf( + "TSTFLDCHR" fieldByType CharacterType(3), + "TSTFLDNBR" fieldByType DecimalType(5, 2), + "DESTST" fieldByType CharacterType(10), + ) + + val keys = listOf( + "TSTFLDCHR", + "TSTFLDNBR" + ) + + + //createAndPopulateTable( /* ci mette tantissimo >20min, la teniamo fissa già creata */ registerTable( dbManager, TST2TAB_TABLE_NAME, "TSTREC", fields, keys, - "src/test/resources/csv/TstTab.csv", + "src/test/resources/csv/TstTab.csv" ) - // + /**/ } fun createAndPopulateEmployeeTable(dbManager: JT400DBMManager?) { - val fields = - listOf( - "EMPNO" fieldByType CharacterType(6), - "FIRSTNME" fieldByType CharacterType(20), - "MIDINIT" fieldByType CharacterType(1), - "LASTNAME" fieldByType CharacterType(20), - "WORKDEPT" fieldByType CharacterType(3), - ) - - val keys = - listOf( - "EMPNO", - ) - - // createAndPopulateTable( /* ci mette tantissimo >20min, la teniamo fissa già creata */ + val fields = listOf( + "EMPNO" fieldByType CharacterType(6), + "FIRSTNME" fieldByType CharacterType(20), + "MIDINIT" fieldByType CharacterType(1), + "LASTNAME" fieldByType CharacterType(20), + "WORKDEPT" fieldByType CharacterType(3), + ) + + val keys = listOf( + "EMPNO" + ) + + + //createAndPopulateTable( /* ci mette tantissimo >20min, la teniamo fissa già creata */ registerTable( dbManager, EMPLOYEE_TABLE_NAME, "TSTREC", fields, keys, - "src/test/resources/csv/Employee.csv", + "src/test/resources/csv/Employee.csv" ) - // + /**/ } fun getEmployeeName(record: Record): String { @@ -221,7 +214,7 @@ private fun registerTable( formatName: String, fields: List, keys: List, - dataFilePath: String, + dataFilePath: String ) { val metadata = TypedMetadata(tableName, formatName, fields, keys).fileMetadata() dbManager!!.registerMetadata(metadata, true) @@ -268,7 +261,7 @@ fun buildMunicipalityKey(vararg values: String): List { val recordFields = mutableListOf() val keys = arrayOf("NAZ", "REG", "PROV", "CITTA") for ((index, value) in values.withIndex()) { - if (keys.size > index) { + if (keys.size> index) { recordFields.add(value) } } @@ -297,3 +290,5 @@ fun connectJDBC() : Connection { return DriverManager.getConnection(connectionConfig.url, connectionConfig.user, connectionConfig.password) } */ + + diff --git a/manager/src/main/kotlin/com/smeup/dbnative/manager/DBFileFactory.kt b/manager/src/main/kotlin/com/smeup/dbnative/manager/DBFileFactory.kt index a909a28..6b17deb 100644 --- a/manager/src/main/kotlin/com/smeup/dbnative/manager/DBFileFactory.kt +++ b/manager/src/main/kotlin/com/smeup/dbnative/manager/DBFileFactory.kt @@ -40,9 +40,10 @@ import com.smeup.dbnative.model.FileMetadata * */ class DBFileFactory( private val config: DBNativeAccessConfig, - private val fileNameNormalizer: (String) -> String = { it }, + private val fileNameNormalizer: (String) -> String = {it} ) : AutoCloseable { - private val managers = mutableMapOf() + + private val managers = mutableMapOf () /** * Open the file named fileName. A file can only be opened after registration of its metadata. @@ -53,13 +54,10 @@ class DBFileFactory( * @param fileName file to open * @param fileMetadata metadata to register. If passed, file metadata is registered before file opening * */ - fun open( - fileName: String, - fileMetadata: FileMetadata?, - ): DBFile { + fun open(fileName: String, fileMetadata: FileMetadata?) : DBFile { val fileNameNormalized = fileNameNormalizer(fileName) val configMatch = findConnectionConfigFor(fileNameNormalized, config.connectionsConfig) - val dbmManager = managers.getOrPut(configMatch) { createDBManager(configMatch, config.logger).apply { validateConfig() } } + val dbmManager = managers.getOrPut(configMatch) {createDBManager(configMatch, config.logger).apply { validateConfig() }} if (fileMetadata != null) { dbmManager.registerMetadata(fileMetadata, true) @@ -89,7 +87,7 @@ class DBFileFactory( } override fun close() { - managers.values.forEach { it.close() } + managers.values.forEach {it.close()} } } @@ -98,42 +96,34 @@ class DBFileFactory( * @param fileName file name * @param connectionsConfig ConnectionConfig entries * */ -fun findConnectionConfigFor( - fileName: String, - connectionsConfig: List, -): ConnectionConfig { - val configList = - connectionsConfig.filter { - it.fileName.toUpperCase() == fileName.toUpperCase() || it.fileName == "*" || +fun findConnectionConfigFor(fileName: String, connectionsConfig: List) : ConnectionConfig { + val configList = connectionsConfig.filter { + it.fileName.toUpperCase() == fileName.toUpperCase() || it.fileName == "*" || fileName.toUpperCase().matches(Regex(it.fileName.toUpperCase().replace("*", ".*"))) - } + } require(configList.isNotEmpty()) { "Wrong configuration. Not found a ConnectionConfig entry matching name: $fileName" } - // At the top of the list we have ConnectionConfig whose property file does not have wildcards + //At the top of the list we have ConnectionConfig whose property file does not have wildcards return configList.sortedWith(DBFileFactory.COMPARATOR)[0] } -private fun createDBManager( - config: ConnectionConfig, - logger: Logger? = null, -): DBMManager { +private fun createDBManager(config: ConnectionConfig, logger: Logger? = null): DBMManager { val impl = getImplByUrl(config) - val clazz: Class? = Class.forName(impl) as Class? + val clazz :Class? = Class.forName(impl) as Class? return clazz?.let { val constructor = it.getConstructor(ConnectionConfig::class.java) val dbmManager = constructor.newInstance(config) - if (dbmManager is DBManagerBaseImpl) - { - dbmManager.logger = logger - } + if(dbmManager is DBManagerBaseImpl){ + dbmManager.logger = logger + } return dbmManager }!! } -private fun getImplByUrl(config: ConnectionConfig): String { +private fun getImplByUrl(config: ConnectionConfig) : String { return when { config.impl != null && config.impl!!.trim().isEmpty() -> config.impl!! config.url.startsWith("jdbc:") -> "com.smeup.dbnative.sql.SQLDBMManager" @@ -143,12 +133,10 @@ private fun getImplByUrl(config: ConnectionConfig): String { } } -// ConnectionConfig.file with wildcards at the bottom +//ConnectionConfig.file with wildcards at the bottom class ConnectionConfigComparator : Comparator { - override fun compare( - o1: ConnectionConfig?, - o2: ConnectionConfig?, - ): Int { + + override fun compare(o1: ConnectionConfig?, o2: ConnectionConfig?): Int { require(o1 != null) require(o2 != null) return when { @@ -160,4 +148,4 @@ class ConnectionConfigComparator : Comparator { else -> o1.fileName.compareTo(o2.fileName) } } -} +} \ No newline at end of file diff --git a/manager/src/main/kotlin/com/smeup/dbnative/manager/DBFileWrapper.kt b/manager/src/main/kotlin/com/smeup/dbnative/manager/DBFileWrapper.kt index 0fd69ff..8b78eb4 100644 --- a/manager/src/main/kotlin/com/smeup/dbnative/manager/DBFileWrapper.kt +++ b/manager/src/main/kotlin/com/smeup/dbnative/manager/DBFileWrapper.kt @@ -24,7 +24,8 @@ import com.smeup.dbnative.file.Result import com.smeup.dbnative.log.Logger import com.smeup.dbnative.model.FileMetadata -class DBFileWrapper(private val dbFile: DBFile, private val dbmManager: DBMManager) : DBFile { +class DBFileWrapper (private val dbFile: DBFile, private val dbmManager: DBMManager): DBFile { + private var closed = false override var name: String @@ -36,9 +37,7 @@ class DBFileWrapper(private val dbFile: DBFile, private val dbmManager: DBMManag set(value) {} override var logger: Logger? get() = dbFile.logger - set(value) { - dbFile.logger = value - } + set(value) {dbFile.logger = value} override fun eof(): Boolean { return dbFile.eof() @@ -143,4 +142,4 @@ class DBFileWrapper(private val dbFile: DBFile, private val dbmManager: DBMManag closed = true dbmManager.closeFile(fileMetadata.tableName) } -} +} \ No newline at end of file diff --git a/manager/src/test/kotlin/com/smeup/dbnative/manager/DBFileFactoryTest.kt b/manager/src/test/kotlin/com/smeup/dbnative/manager/DBFileFactoryTest.kt index 4c03040..acbb3a4 100644 --- a/manager/src/test/kotlin/com/smeup/dbnative/manager/DBFileFactoryTest.kt +++ b/manager/src/test/kotlin/com/smeup/dbnative/manager/DBFileFactoryTest.kt @@ -32,57 +32,51 @@ import org.junit.Before import org.junit.Test import kotlin.test.assertEquals import kotlin.test.assertTrue - private val LOGGING_LEVEL = LoggingLevel.OFF private enum class TestConnectionConfig( - val connectionConfig: ConnectionConfig, + val connectionConfig: ConnectionConfig ) { DEFAULT( - connectionConfig = - ConnectionConfig( - fileName = "*", - url = "jdbc:hsqldb:mem:TEST", - user = "", - password = "", - driver = "org.hsqldb.jdbcDriver", - ), + connectionConfig = ConnectionConfig( + fileName= "*", + url = "jdbc:hsqldb:mem:TEST", + user = "", + password = "", + driver = "org.hsqldb.jdbcDriver" + ) ), STARTS_WITH_TEST( - connectionConfig = - ConnectionConfig( - fileName = "TEST*", - url = "jdbc:hsqldb:mem:TEST", - user = "", - password = "", - driver = "org.hsqldb.jdbcDriver", - ), + connectionConfig = ConnectionConfig( + fileName= "TEST*", + url = "jdbc:hsqldb:mem:TEST", + user = "", + password = "", + driver = "org.hsqldb.jdbcDriver" + ) ), MUNICIPALITY( ConnectionConfig( - fileName = "MUNICIPALITY", + fileName= "MUNICIPALITY", url = "mongodb://localhost:27017/W_TEST", user = "", - password = "", - ), - ), + password = "") + ) } class DBFileFactoryTest { - private lateinit var config: DBNativeAccessConfig + + private lateinit var config : DBNativeAccessConfig private lateinit var manager: SQLDBMManager @Before fun setUp() { - config = - DBNativeAccessConfig( - mutableListOf( - TestConnectionConfig.DEFAULT.connectionConfig, - TestConnectionConfig.STARTS_WITH_TEST.connectionConfig, - TestConnectionConfig.MUNICIPALITY.connectionConfig, - ), - Logger.getSimpleInstance(LOGGING_LEVEL), - ) + config = DBNativeAccessConfig(mutableListOf( + TestConnectionConfig.DEFAULT.connectionConfig, + TestConnectionConfig.STARTS_WITH_TEST.connectionConfig, + TestConnectionConfig.MUNICIPALITY.connectionConfig + ), + Logger.getSimpleInstance(LOGGING_LEVEL)) manager = SQLDBMManager(TestConnectionConfig.STARTS_WITH_TEST.connectionConfig) manager.connection.createStatement().use { it.executeUpdate("CREATE TABLE TEST1F (NAME CHAR(20))") @@ -100,36 +94,31 @@ class DBFileFactoryTest { testFields.add("NAME" fieldByType CharacterType(20)) val testTableMetadata = FileMetadata("TEST1L", "TEST1F", testFields.fieldList(), listOf("NAME")) manager.registerMetadata(testTableMetadata, true) + } @Test fun findConnectionForPIPPO() { - assertEquals( - TestConnectionConfig.DEFAULT.connectionConfig, - findConnectionConfigFor("PIPPO/PLUTO", config.connectionsConfig), - ) + assertEquals(TestConnectionConfig.DEFAULT.connectionConfig, + findConnectionConfigFor("PIPPO/PLUTO", config.connectionsConfig)) } @Test fun findConnectionForTESTXXX() { - assertEquals( - TestConnectionConfig.STARTS_WITH_TEST.connectionConfig, - findConnectionConfigFor("TEST3L", config.connectionsConfig), - ) + assertEquals(TestConnectionConfig.STARTS_WITH_TEST.connectionConfig, + findConnectionConfigFor("TEST3L", config.connectionsConfig)) } @Test fun findConnectionForMUNICIPALITY() { - assertEquals( - TestConnectionConfig.MUNICIPALITY.connectionConfig, - findConnectionConfigFor("MUNICIPALITY", config.connectionsConfig), - ) + assertEquals(TestConnectionConfig.MUNICIPALITY.connectionConfig, + findConnectionConfigFor("MUNICIPALITY", config.connectionsConfig)) } - // test ok if no throw exception + //test ok if no throw exception @Test fun openExistingTables() { - DBFileFactory(config).use { dbFileFactory -> + DBFileFactory(config).use {dbFileFactory -> // Open a file already registered dbFileFactory.open("TEST1L", null) @@ -154,9 +143,9 @@ class DBFileFactoryTest { DBFileFactory(config).use { dbFileFactory -> val dbFile = dbFileFactory.open("TEST1L", null) var result = dbFile.chain("MARCO") - assertTrue(result.record["NAME"]?.trim().equals("MARCO")) + assertTrue (result.record["NAME"]?.trim().equals("MARCO")) result = dbFile.chain("DARIO") - assertTrue(result.record["NAME"]?.trim().equals("DARIO")) + assertTrue (result.record["NAME"]?.trim().equals("DARIO")) dbFile.close() } @@ -171,12 +160,12 @@ class DBFileFactoryTest { @Test fun reopenClosedFile() { - DBFileFactory(config).use { dbFileFactory -> + DBFileFactory(config).use {dbFileFactory -> val dbFile = dbFileFactory.open("TEST1L", null) dbFile.setll("DARIO") dbFile.read() dbFile.close() - assertTrue(dbFile.runCatching { read() }.isFailure) + assertTrue (dbFile.runCatching { read() }.isFailure) } } @@ -195,4 +184,5 @@ class DBFileFactoryTest { manager.unregisterMetadata("TEST2L") manager.unregisterMetadata("TEST3L") } -} + +} \ No newline at end of file diff --git a/nosql/src/main/kotlin/com/smeup/dbnative/nosql/NoSQLDBFile.kt b/nosql/src/main/kotlin/com/smeup/dbnative/nosql/NoSQLDBFile.kt index 7e0e98e..be0bb2e 100644 --- a/nosql/src/main/kotlin/com/smeup/dbnative/nosql/NoSQLDBFile.kt +++ b/nosql/src/main/kotlin/com/smeup/dbnative/nosql/NoSQLDBFile.kt @@ -35,12 +35,11 @@ import com.smeup.dbnative.utils.matchFileKeys import org.bson.Document import kotlin.system.measureTimeMillis -class NoSQLDBFile( - override var name: String, - override var fileMetadata: FileMetadata, - private val database: MongoDatabase, - override var logger: Logger? = null, -) : DBFile { +class NoSQLDBFile(override var name: String, + override var fileMetadata: FileMetadata, + private val database: MongoDatabase, + override var logger: Logger? = null): DBFile { + private var globalCursor: MongoCursor? = null private var up_direction: Boolean = true private var last_set_keys: List = emptyList() @@ -49,11 +48,8 @@ class NoSQLDBFile( private var eof: Boolean = false private var lastNativeMethod: NativeMethod? = null - private fun logEvent( - loggingKey: LoggingKey, - message: String, - elapsedTime: Long? = null, - ) = logger?.logEvent(loggingKey, message, elapsedTime, lastNativeMethod, fileMetadata.name) + private fun logEvent(loggingKey: LoggingKey, message: String, elapsedTime: Long? = null) = + logger?.logEvent(loggingKey, message, elapsedTime, lastNativeMethod, fileMetadata.name) override fun eof(): Boolean { return eof @@ -71,6 +67,7 @@ class NoSQLDBFile( } } + override fun setll(key: String): Boolean { return setll(mutableListOf(key)) } @@ -85,11 +82,10 @@ class NoSQLDBFile( measureTimeMillis { eof = false - var keyAsRecordField = - keys.mapIndexed { index, value -> - val keyname = fileMetadata.fileKeys.get(index) - RecordField(keyname, value) - } + var keyAsRecordField = keys.mapIndexed { index, value -> + val keyname = fileMetadata.fileKeys.get(index) + RecordField(keyname, value) + } /* Passed keys are not primary key for DBFile @@ -98,6 +94,7 @@ class NoSQLDBFile( return false } + /* Find syntax @@ -107,7 +104,7 @@ class NoSQLDBFile( {$and:[{ NAZ: { $eq: "IT" } }, { REG: { $eq: "LOM" } }, { PROV: { $eq: "BS" } }, { CITTA: { $gt: "ERBUSCO" } } ] } - */ + */ /* val filter = StringBuilder() @@ -155,7 +152,7 @@ class NoSQLDBFile( up_direction = true last_keys = keys - */ + */ val cursor = calculateCursor(keyAsRecordField, true, true) @@ -188,11 +185,10 @@ class NoSQLDBFile( measureTimeMillis { eof = false - var keyAsRecordField = - keys.mapIndexed { index, value -> - val keyname = fileMetadata.fileKeys.get(index) - RecordField(keyname, value) - } + var keyAsRecordField = keys.mapIndexed { index, value -> + val keyname = fileMetadata.fileKeys.get(index) + RecordField(keyname, value) + } /* Passed keys are not primary key for DBFile @@ -210,19 +206,19 @@ class NoSQLDBFile( {$and:[{ NAZ: { $gte: "IT" } }, { REG: { $gte: "LOM" } }, { PROV: { $gte: "BS" } }, { CITTA: { $gte: "ERBUSCO" } } ] } - *** SETGT forward: + *** SETGT forward: {$and:[{ NAZ: { $eq: "IT" } }, { REG: { $eq: "LOM" } }, { PROV: { $eq: "BS" } }, { CITTA: { $gt: "ERBUSCO" } } ] } with order {NAZ: 1, REG: 1, PROV: 1, CITTA: 1} - ***SETGT backward: + ***SETGT backward: {$and:[{ NAZ: { $eq: "IT" } }, { REG: { $eq: "LOM" } }, { PROV: { $eq: "BS" } }, { CITTA: { $gt: "ERBUSCO" } } ] } with order {NAZ: 1, REG: 1, PROV: 1, CITTA: -1} - */ + */ /* val filter = StringBuilder() @@ -235,7 +231,8 @@ class NoSQLDBFile( filter.append("{ ${dbField.name}: {\$gt: \"${keys.get(keys.indexOfFirst { recordField -> recordField.name == dbField.name }).value}\" } }") } } - */ + */ + /* Sort sintax: @@ -276,13 +273,14 @@ class NoSQLDBFile( last_set_keys = keyAsRecordField IncludeFirst = false }.apply { - logEvent(LoggingKey.native_access_method, "setgt executed", this) + logEvent(LoggingKey.native_access_method, "setgt executed", this) } lastNativeMethod = null return result } override fun chain(key: String): Result { + return chain(mutableListOf(key)) } @@ -293,37 +291,37 @@ class NoSQLDBFile( measureTimeMillis { eof = false - var keyAsRecordField = - keys.mapIndexed { index, value -> - val keyname = fileMetadata.fileKeys.get(index) - RecordField(keyname, value) - } + var keyAsRecordField = keys.mapIndexed { index, value -> + val keyname = fileMetadata.fileKeys.get(index) + RecordField(keyname, value) + } /* Passed keys are not primary key for DBFile */ if (fileMetadata.matchFileKeys(keyAsRecordField) == false) { - result = Result(record = Record(), indicatorLO = true) - } else { + result = Result(record = Record(), indicatorLO = true) + } + else { + val cursor = calculateCursor(keyAsRecordField, true, true) globalCursor = cursor.iterator() up_direction = true last_set_keys = keyAsRecordField - // when globalCursor is empty return result empty + //when globalCursor is empty return result empty val document = globalCursor!!.tryNext() - if (document == null) - { - result = Result(Record()) - } else { - if (matchKeys(document, keyAsRecordField)) { - val record = documentToRecord(document) - updateLastKeys(record) - result = Result(record) - } else { - result = Result(Record()) - } + if(document == null){ + result = Result(Record()) + } + else + if (matchKeys(document, keyAsRecordField)) { + val record = documentToRecord(document) + updateLastKeys(record) + result = Result(record) + } else { + result = Result(Record()) } } }.apply { @@ -343,7 +341,7 @@ class NoSQLDBFile( if (globalCursor == null) { return Result( indicatorLO = true, - errorMsg = "Cursor not defined. Call SETLL or SETGT before invoke READ command", + errorMsg = "Cursor not defined. Call SETLL or SETGT before invoke READ command" ) } @@ -358,6 +356,7 @@ class NoSQLDBFile( IncludeFirst = true if (globalCursor != null) { + if (globalCursor!!.hasNext()) { val record = documentToRecord(globalCursor!!.next()) if (globalCursor!!.hasNext()) { @@ -399,11 +398,10 @@ class NoSQLDBFile( lastNativeMethod = NativeMethod.readEqual logEvent(LoggingKey.native_access_method, "Executing readEqual on keys $keys") measureTimeMillis { - var keyAsRecordField = - keys.mapIndexed { index, value -> - val keyname = fileMetadata.fileKeys.get(index) - RecordField(keyname, value) - } + var keyAsRecordField = keys.mapIndexed { index, value -> + val keyname = fileMetadata.fileKeys.get(index) + RecordField(keyname, value) + } if (globalCursor == null) { globalCursor = calculateCursor(keyAsRecordField, true, true).iterator() @@ -428,6 +426,7 @@ class NoSQLDBFile( while (true) { if (globalCursor!!.hasNext()) { + val document = globalCursor!!.next() val record = documentToRecord(document) @@ -458,7 +457,7 @@ class NoSQLDBFile( if (globalCursor == null) { return Result( indicatorLO = true, - errorMsg = "Cursor not defined. Call SETLL or SETGT before invoke READ command", + errorMsg = "Cursor not defined. Call SETLL or SETGT before invoke READ command" ) } @@ -473,6 +472,7 @@ class NoSQLDBFile( IncludeFirst = true if (globalCursor != null) { + if (globalCursor!!.hasNext()) { val record = documentToRecord(globalCursor!!.next()) if (globalCursor!!.hasNext()) { @@ -506,16 +506,15 @@ class NoSQLDBFile( lastNativeMethod = NativeMethod.readPreviousEqual logEvent(LoggingKey.native_access_method, "Executing readPreviousEqual on keys $keys") measureTimeMillis { - var keyAsRecordField = - keys.mapIndexed { index, value -> - val keyname = fileMetadata.fileKeys.get(index) - RecordField(keyname, value) - } + var keyAsRecordField = keys.mapIndexed { index, value -> + val keyname = fileMetadata.fileKeys.get(index) + RecordField(keyname, value) + } if (globalCursor == null) { return Result( indicatorLO = true, - errorMsg = "Cursor not defined. Call SETLL or SETGT before invoke READ command", + errorMsg = "Cursor not defined. Call SETLL or SETGT before invoke READ command" ) } @@ -537,8 +536,10 @@ class NoSQLDBFile( IncludeFirst = true + while (true) { if (globalCursor!!.hasNext()) { + val document = globalCursor!!.next() val record = documentToRecord(document) @@ -562,6 +563,7 @@ class NoSQLDBFile( lastNativeMethod = null } + override fun write(record: Record): Result { lastNativeMethod = NativeMethod.write logEvent(LoggingKey.native_access_method, "Executing write for record $record") @@ -577,7 +579,7 @@ class NoSQLDBFile( } override fun update(record: Record): Result { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun delete(record: Record): Result { @@ -589,10 +591,8 @@ class NoSQLDBFile( /* Evaluate matching between values of passed keys and relative values in document */ - private fun matchKeys( - document: Document, - keys: List, - ): Boolean { + private fun matchKeys(document: Document, keys: List): Boolean { + var match = true keys.forEach({ @@ -602,8 +602,10 @@ class NoSQLDBFile( }) return match + } + private fun documentToRecord(document: Document?): Record { val result = Record() @@ -615,11 +617,7 @@ class NoSQLDBFile( return result } - private fun calculateCursor( - keys: List, - up_direction: Boolean, - includeFirst: Boolean, - ): FindIterable { + private fun calculateCursor(keys: List, up_direction: Boolean, includeFirst: Boolean): FindIterable { /* Complete examples for filters in file filter_syntax_examples.txt @@ -652,7 +650,7 @@ class NoSQLDBFile( ] } - */ + */ var operator1: MongoOperator = MongoOperator.EQ var operator2: MongoOperator = MongoOperator.EQ @@ -694,36 +692,25 @@ class NoSQLDBFile( } } + val filter = StringBuilder() filter.append("{\$or:[") val orContent = StringBuilder() + // Add first line val line = StringBuilder() line.append("{\$and:[") - keyFields.forEachIndexed { index: Int, dbField: Field -> - if (index != keyFields.size - 1) { - line.append( - "{ \"${dbField.name}\": {${operator3.symbol} \"${keys.get( - keys.indexOfFirst { - recordField -> - recordField.name == dbField.name - }, - ).value}\" } }, ", - ) - } else { - line.append( - "{ \"${dbField.name}\": {${operator1.symbol} \"${keys.get( - keys.indexOfFirst { - recordField -> - recordField.name == dbField.name - }, - ).value}\" } }", - ) + keyFields.forEachIndexed{index: Int, dbField: Field -> + if (index != keyFields.size-1) { + line.append("{ \"${dbField.name}\": {${operator3.symbol} \"${keys.get(keys.indexOfFirst { recordField -> recordField.name == dbField.name }).value}\" } }, ") + } + else { + line.append("{ \"${dbField.name}\": {${operator1.symbol} \"${keys.get(keys.indexOfFirst { recordField -> recordField.name == dbField.name }).value}\" } }") } } @@ -733,34 +720,23 @@ class NoSQLDBFile( // Add other lines if (keyFields.size > 1) { + var while_index = keyFields.size while (while_index > 1) { + val tempLine = StringBuilder() tempLine.append(", {\$and:[") - val subList = keyFields.subList(0, while_index - 1) - - subList.forEachIndexed { index: Int, dbField: Field -> - if (index != subList.size - 1) { - tempLine.append( - "{ \"${dbField.name}\": {${operator3.symbol} \"${keys.get( - keys.indexOfFirst { - recordField -> - recordField.name == dbField.name - }, - ).value}\" } }, ", - ) - } else { - tempLine.append( - "{ \"${dbField.name}\": {${operator2.symbol} \"${keys.get( - keys.indexOfFirst { - recordField -> - recordField.name == dbField.name - }, - ).value}\" } }", - ) + val subList = keyFields.subList(0, while_index-1) + + subList.forEachIndexed{index: Int, dbField: Field -> + if (index != subList.size-1) { + tempLine.append("{ \"${dbField.name}\": {${operator3.symbol} \"${keys.get(keys.indexOfFirst { recordField -> recordField.name == dbField.name }).value}\" } }, ") + } + else { + tempLine.append("{ \"${dbField.name}\": {${operator2.symbol} \"${keys.get(keys.indexOfFirst { recordField -> recordField.name == dbField.name }).value}\" } }") } } @@ -776,6 +752,7 @@ class NoSQLDBFile( filter.append("] }") + /* Sort sintax: @@ -785,7 +762,7 @@ class NoSQLDBFile( val sort = StringBuilder() - keyFields.joinTo(sort, separator = ",", prefix = "{", postfix = "}") { + keyFields.joinTo(sort, separator= ",", prefix= "{", postfix = "}") { if (up_direction) { "\"${it.name}\": 1" } else { @@ -794,7 +771,7 @@ class NoSQLDBFile( } sort.append("}") logEvent(LoggingKey.execute_inquiry, "Building filter command $filter with sort $sort") - // println("$filter - $sort") + //println("$filter - $sort") val cursor = database.getCollection(fileMetadata.tableName).find(Document.parse(filter.toString())) @@ -802,6 +779,7 @@ class NoSQLDBFile( } private fun updateLastKeys(record: Record) { + val lastKeys = mutableListOf() fileMetadata.fileKeys.forEach { lastKeys.add(RecordField(it, record.getValue(it))) @@ -815,6 +793,8 @@ class NoSQLDBFile( GT("\$gt:"), GE("\$gte:"), LT("\$lt:"), - LE("\$lte:"), + LE("\$lte:") } + } + diff --git a/nosql/src/main/kotlin/com/smeup/dbnative/nosql/NoSQLDBMManager.kt b/nosql/src/main/kotlin/com/smeup/dbnative/nosql/NoSQLDBMManager.kt index c84f690..9d195cd 100644 --- a/nosql/src/main/kotlin/com/smeup/dbnative/nosql/NoSQLDBMManager.kt +++ b/nosql/src/main/kotlin/com/smeup/dbnative/nosql/NoSQLDBMManager.kt @@ -17,11 +17,14 @@ package com.smeup.dbnative.nosql +import com.mongodb.BasicDBObject import com.mongodb.MongoClient +import com.mongodb.client.MongoCollection import com.mongodb.client.MongoDatabase import com.smeup.dbnative.ConnectionConfig import com.smeup.dbnative.DBManagerBaseImpl import com.smeup.dbnative.file.DBFile +import org.bson.Document /** * Assign table: @@ -31,23 +34,24 @@ import com.smeup.dbnative.file.DBFile * Record --> Object in collection */ -class NoSQLDBMManager(override val connectionConfig: ConnectionConfig) : DBManagerBaseImpl() { +class NoSQLDBMManager (override val connectionConfig: ConnectionConfig) : DBManagerBaseImpl() { + private val match = Regex("mongodb://((?:\\w|\\.)+):(\\d+)/(\\w+)").find(connectionConfig.url) - private val host: String by lazy { + private val host : String by lazy { match!!.destructured.component1() } - private val port: Int by lazy { + private val port : Int by lazy { match!!.destructured.component2().toInt() } - private val dataBase: String by lazy { + private val dataBase : String by lazy { match!!.destructured.component3() } - private val mongoClient: MongoClient by lazy { + private val mongoClient : MongoClient by lazy { MongoClient(host, port) } - val mongoDatabase: MongoDatabase by lazy { + val mongoDatabase : MongoDatabase by lazy { mongoClient.getDatabase(dataBase) } @@ -60,12 +64,13 @@ class NoSQLDBMManager(override val connectionConfig: ConnectionConfig) : DBManag } override fun close() { - openedFile.values.forEach { it.close() } + openedFile.values.forEach { it.close()} openedFile.clear() mongoClient.close() } override fun openFile(name: String): DBFile { + require(existFile(name)) { "Cannot open unregistered file $name" } @@ -88,4 +93,4 @@ class NoSQLDBMManager(override val connectionConfig: ConnectionConfig) : DBManag override fun closeFile(name: String) { openedFile.remove(name)!!.close() } -} +} \ No newline at end of file diff --git a/nosql/src/main/kotlin/com/smeup/dbnative/nosql/utils/MongoDbUtils.kt b/nosql/src/main/kotlin/com/smeup/dbnative/nosql/utils/MongoDbUtils.kt index 3ab6b17..ac0ed3a 100644 --- a/nosql/src/main/kotlin/com/smeup/dbnative/nosql/utils/MongoDbUtils.kt +++ b/nosql/src/main/kotlin/com/smeup/dbnative/nosql/utils/MongoDbUtils.kt @@ -20,16 +20,14 @@ package com.smeup.dbnative.nosql.utils import com.smeup.dbnative.file.Record import com.smeup.dbnative.model.FileMetadata -fun FileMetadata.buildInsertCommand( - filename: String, - record: Record, -): String { - // TODO: insert controls beetwen metadata and record format - println("Build insert command from $filename metadata") + +fun FileMetadata.buildInsertCommand(filename: String, record: Record): String { + //TODO: insert controls beetwen metadata and record format + println("Build insert command from ${filename} metadata") val documents = StringBuilder() - record.toList().joinTo(documents, separator = ",", prefix = "{", postfix = "}") { + record.toList().joinTo(documents, separator=",", prefix="{", postfix="}") { "\"${it.first}\": \"${it.second}\"" } @@ -43,8 +41,10 @@ fun FileMetadata.buildInsertCommand( println(result) return result + } + /* Expected command format: @@ -74,10 +74,11 @@ Expected command format: */ -fun FileMetadata.buildIndexCommand(): String { +fun FileMetadata.buildIndexCommand(): String{ + val keys = StringBuilder() - this.fileKeys.joinTo(keys, separator = ",", prefix = "{", postfix = "}") { + this.fileKeys.joinTo(keys, separator=",", prefix="{", postfix="}") { "\"${it}\": 1" } @@ -86,7 +87,7 @@ fun FileMetadata.buildIndexCommand(): String { createIndexes: "${this.tableName.toUpperCase()}", indexes: [ { - key: $keys, + key: ${keys}, name: "${this.tableName.toUpperCase()}_index", unique: false } @@ -97,4 +98,6 @@ fun FileMetadata.buildIndexCommand(): String { println(result) return result + } + diff --git a/nosql/src/test/kotlin/com/smeup/dbnative/nosql/NoSQLDBFileTest.kt b/nosql/src/test/kotlin/com/smeup/dbnative/nosql/NoSQLDBFileTest.kt index 7b42d4a..09a152d 100644 --- a/nosql/src/test/kotlin/com/smeup/dbnative/nosql/NoSQLDBFileTest.kt +++ b/nosql/src/test/kotlin/com/smeup/dbnative/nosql/NoSQLDBFileTest.kt @@ -27,10 +27,11 @@ import kotlin.test.assertEquals import kotlin.test.assertFalse class NoSQLDBFileTest { + private val tableName = TSTAB_TABLE_NAME companion object { - private lateinit var dbManager: NoSQLDBMManager + private lateinit var dbManager : NoSQLDBMManager @BeforeClass @JvmStatic @@ -83,5 +84,8 @@ class NoSQLDBFileTest { @After fun destroyEnv() { + } + } + diff --git a/nosql/src/test/kotlin/com/smeup/dbnative/nosql/NoSQLMunicipalityTest.kt b/nosql/src/test/kotlin/com/smeup/dbnative/nosql/NoSQLMunicipalityTest.kt index a5fd3db..4275e2d 100644 --- a/nosql/src/test/kotlin/com/smeup/dbnative/nosql/NoSQLMunicipalityTest.kt +++ b/nosql/src/test/kotlin/com/smeup/dbnative/nosql/NoSQLMunicipalityTest.kt @@ -29,6 +29,7 @@ import kotlin.test.assertEquals import kotlin.test.assertTrue class NoSQLMunicipalityTest { + private lateinit var dbManager: NoSQLDBMManager @Before @@ -73,11 +74,11 @@ class NoSQLMunicipalityTest { assertTrue(dbFile.setll(buildMunicipalityKey("IT", "LOM", "BS", "ERBUSCO"))) assertEquals( "EDOLO", - getMunicipalityName(dbFile.readPreviousEqual(buildMunicipalityKey("IT", "LOM", "BS")).record), + getMunicipalityName(dbFile.readPreviousEqual(buildMunicipalityKey("IT", "LOM", "BS")).record) ) assertEquals( "DESENZANO DEL GARDA", - getMunicipalityName(dbFile.readPreviousEqual(buildMunicipalityKey("IT", "LOM", "BS")).record), + getMunicipalityName(dbFile.readPreviousEqual(buildMunicipalityKey("IT", "LOM", "BS")).record) ) dbManager.closeFile(MUNICIPALITY_TABLE_NAME) } @@ -91,6 +92,7 @@ class NoSQLMunicipalityTest { dbManager.closeFile(MUNICIPALITY_TABLE_NAME) } + @Test fun t04_findLastOfBergamoWithSetll4AndReadPE2() { val dbFile = dbManager.openFile(MUNICIPALITY_TABLE_NAME) @@ -400,16 +402,20 @@ class NoSQLMunicipalityTest { @After fun destroyEnv() { + } + private fun buildMunicipalityKey(vararg values: String): List { val keyValues = mutableListOf() val keys = arrayOf("£NAZ", "§REG", "PROV", "CITTA") for ((index, value) in values.withIndex()) { - if (keys.size > index) { + if (keys.size> index) { keyValues.add(value) } } return keyValues } + } + diff --git a/nosql/src/test/kotlin/com/smeup/dbnative/nosql/utils/NoSQLDBTestUtils.kt b/nosql/src/test/kotlin/com/smeup/dbnative/nosql/utils/NoSQLDBTestUtils.kt index b121e6f..a307638 100644 --- a/nosql/src/test/kotlin/com/smeup/dbnative/nosql/utils/NoSQLDBTestUtils.kt +++ b/nosql/src/test/kotlin/com/smeup/dbnative/nosql/utils/NoSQLDBTestUtils.kt @@ -18,6 +18,7 @@ package com.smeup.dbnative.nosql.utils import com.github.doyaaaaaken.kotlincsv.dsl.csvReader +import com.mongodb.BasicDBObject import com.smeup.dbnative.ConnectionConfig import com.smeup.dbnative.file.DBFile import com.smeup.dbnative.file.Record @@ -29,6 +30,7 @@ import com.smeup.dbnative.nosql.NoSQLDBMManager import com.smeup.dbnative.utils.TypedField import com.smeup.dbnative.utils.TypedMetadata import com.smeup.dbnative.utils.fieldByType +import com.smeup.dbnative.utils.getFieldTypeInstance import org.bson.Document import org.junit.Assert import java.io.File @@ -40,23 +42,19 @@ private val LOGGING_LEVEL = LoggingLevel.OFF fun dbManagerForTest(): NoSQLDBMManager { testLog("Creating NOSQLDBManager with db type MONGO") - return NoSQLDBMManager(ConnectionConfig("*", "mongodb://localhost:27017/W_TEST", "", "")).apply { - logger = Logger.getSimpleInstance(LOGGING_LEVEL) - } + return NoSQLDBMManager(ConnectionConfig("*", "mongodb://localhost:27017/W_TEST", "", "")).apply { logger = Logger.getSimpleInstance(LOGGING_LEVEL) } } fun createAndPopulateTestTable(dbManager: NoSQLDBMManager) { // Create file - val fields = - listOf( - "TSTFLDCHR" fieldByType CharacterType(3), - "TSTFLDNBR" fieldByType DecimalType(5, 2), - ) - - val keys = - listOf( - "TSTFLDCHR", - ) + val fields = listOf( + "TSTFLDCHR" fieldByType CharacterType(3), + "TSTFLDNBR" fieldByType DecimalType(5, 2) + ) + + val keys = listOf( + "TSTFLDCHR" + ) val tMetadata = TypedMetadata(TSTAB_TABLE_NAME, "TSTREC", fields, keys) createFile(tMetadata, dbManager) @@ -69,32 +67,33 @@ fun createAndPopulateTestTable(dbManager: NoSQLDBMManager) { } fun createAndPopulateMunicipalityTable(dbManager: NoSQLDBMManager) { + if (!dbManager.existFile(MUNICIPALITY_TABLE_NAME)) { - val fields = - listOf( - "£NAZ" fieldByType CharacterType(2), - "§REG" fieldByType CharacterType(3), - "PROV" fieldByType CharacterType(2), - "CITTA" fieldByType VarcharType(35), - "CAP" fieldByType CharacterType(5), - "PREF" fieldByType CharacterType(4), - "COMUNE" fieldByType CharacterType(4), - "ISTAT" fieldByType CharacterType(6), - ) - - val keys = - listOf( - "£NAZ", - "§REG", - "PROV", - "CITTA", - ) + + val fields = listOf( + "£NAZ" fieldByType CharacterType(2), + "§REG" fieldByType CharacterType(3), + "PROV" fieldByType CharacterType(2), + "CITTA" fieldByType VarcharType(35), + "CAP" fieldByType CharacterType(5), + "PREF" fieldByType CharacterType(4), + "COMUNE" fieldByType CharacterType(4), + "ISTAT" fieldByType CharacterType(6) + ) + + val keys = listOf( + "£NAZ", + "§REG", + "PROV", + "CITTA" + ) createAndPopulateTable( + dbManager, MUNICIPALITY_TABLE_NAME, fields, keys, - "src/test/resources/csv/Municipality.csv", + "src/test/resources/csv/Municipality.csv" ) } } @@ -110,17 +109,13 @@ fun testLog(message: String) { } } -private fun createAndPopulateTable( - dbManager: NoSQLDBMManager, - tableName: String, - fields: List, - keys: List, - dataFilePath: String, -) { +private fun createAndPopulateTable(dbManager: NoSQLDBMManager, tableName: String, fields: List, keys:List, dataFilePath: String) { + val tMetadata = TypedMetadata(tableName, tableName, fields, keys) - // if not exist file on mongodb create and populate with data + //if not exist file on mongodb create and populate with data if (dbManager.existFile(tableName) == false) { + createFile(tMetadata, dbManager) Assert.assertTrue(dbManager.existFile(tableName)) var dbFile = dbManager.openFile(tableName) @@ -140,18 +135,18 @@ private fun createAndPopulateTable( } dbManager.closeFile(tableName) + } -fun createFile( - tMetadata: TypedMetadata, - dbManager: NoSQLDBMManager, -) { +fun createFile(tMetadata: TypedMetadata, dbManager: NoSQLDBMManager) { // Find table registration in library metadata file - val metadata: FileMetadata = tMetadata.fileMetadata() + val metadata: FileMetadata = tMetadata.fileMetadata(); if (dbManager.existFile(metadata.name) == false) { + // Create file index dbManager.mongoDatabase.runCommand(Document.parse(metadata.buildIndexCommand())) } dbManager.registerMetadata(metadata, true) + } diff --git a/pom.xml b/pom.xml index 9e95b8c..139fa96 100644 --- a/pom.xml +++ b/pom.xml @@ -181,20 +181,6 @@ - - com.github.gantsign.maven - ktlint-maven-plugin - 3.0.0 - - - format-and-check - - format - check - - - - diff --git a/sql/src/main/kotlin/com/smeup/dbnative/sql/JDBCUtils.kt b/sql/src/main/kotlin/com/smeup/dbnative/sql/JDBCUtils.kt index 9b256d9..72c7821 100644 --- a/sql/src/main/kotlin/com/smeup/dbnative/sql/JDBCUtils.kt +++ b/sql/src/main/kotlin/com/smeup/dbnative/sql/JDBCUtils.kt @@ -40,8 +40,7 @@ fun ResultSet.joinToString(separator: String = " - "): String { fun PreparedStatement.bind(values: List) { values.forEachIndexed { - i, value -> - this.setObject(i + 1, value) + i, value -> this.setObject(i + 1, value) } } @@ -56,8 +55,7 @@ fun Connection.recordFormatName(tableName: String): String? = return@use tableName } -private fun ResultSet.indexId() = - "${this.getString("TABLE_CAT")}." + +private fun ResultSet.indexId() = "${this.getString("TABLE_CAT")}." + "${this.getString("TABLE_SCHEM")}.${this.getString("INDEX_NAME")}" private fun ResultSet.isUnique() = this.getInt("NON_UNIQUE") == 0 @@ -69,10 +67,10 @@ fun Connection.primaryKeys(tableName: String): List { result.add(it.getString("COLUMN_NAME")) } } - // if primary key is not defined i will get it by first unique index + //if primary key is not defined i will get it by first unique index if (result.isEmpty()) { var indexId: String? = null - // a row for every field in the indexes + //a row for every field in the indexes this.metaData.getIndexInfo(null, null, tableName, true, false).use { while (it.next()) { if (indexId == null) { @@ -80,7 +78,8 @@ fun Connection.primaryKeys(tableName: String): List { } if (it.indexId() != indexId) { break - } else { + } + else { result.add(it.getString("COLUMN_NAME")) } } @@ -99,7 +98,7 @@ fun Connection.orderingFields(tableName: String): List { if (it.next()) { // TODO handle DESC and ASC keywords val fields = it.getString(field).toUpperCase().substringAfter("ORDER BY").split(",") - result.addAll(fields.map { fl: String -> fl.substring(fl.lastIndexOf('.') + 1).trim('`', ' ') }) + result.addAll(fields.map { fl: String -> fl.substring(fl.lastIndexOf('.') + 1).trim('`', ' ') }) } } } @@ -111,8 +110,7 @@ fun ResultSet?.closeIfOpen() { if (this != null) { try { this.close() - } catch (t: Throwable) { - } + } catch (t: Throwable) {} } } @@ -138,3 +136,6 @@ fun ResultSet?.currentRecordToValues(): Record { } return result } + + + diff --git a/sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt b/sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt index 5ab8b7c..1254fe5 100644 --- a/sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt +++ b/sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt @@ -1,39 +1,33 @@ package com.smeup.dbnative.sql import com.smeup.dbnative.file.Record -import com.smeup.dbnative.model.Field import com.smeup.dbnative.model.FileMetadata +import com.smeup.dbnative.model.Field import java.lang.Exception enum class PositioningMethod { - SETLL, - SETGT, + SETLL, SETGT; } -enum class ReadMethod(val forward: Boolean) { - READE(true), - READPE(false), - READP(false), - READ(true), - CHAIN(true), +enum class ReadMethod(val forward: Boolean){ + READE(true), READPE(false), READP(false), READ(true), CHAIN(true); } -enum class SortOrder(val symbol: String) { - ASCEDING("ASC"), - DESCENDING("DESC"), +enum class SortOrder(val symbol: String){ + ASCEDING("ASC"), DESCENDING("DESC"); } -class PositioningInstruction(val method: PositioningMethod, val keys: List) { +class PositioningInstruction(val method: PositioningMethod, val keys: List){ init { - require(keys.isNotEmpty()) { + require(keys.isNotEmpty()){ "No keys specified for positioning instruction $method" } } } -class ReadInstruction(var method: ReadMethod, var keys: List) { - constructor(method: ReadMethod) : this(method, emptyList()) { - require(admitEmptyKeys()) { +class ReadInstruction(var method: ReadMethod, var keys: List){ + constructor(method: ReadMethod): this(method, emptyList()){ + require(admitEmptyKeys()){ "Keys are mandatory for read instruction $method " } } @@ -45,43 +39,40 @@ class Native2SQL(val fileMetadata: FileMetadata) { private var lastPositioningInstruction: PositioningInstruction? = null private var lastReadInstruction: ReadInstruction? = null - private fun checkPositioning() { - requireNotNull(lastPositioningInstruction) { + private fun checkPositioning(){ + requireNotNull(lastPositioningInstruction){ "No positioning instruction found" } } - private fun checkKeys(keys: List) { - require(fileMetadata.fileKeys.size > 0) { + private fun checkKeys(keys: List){ + require(fileMetadata.fileKeys.size > 0){ "No keys specified in metadata" } - require(keys.size <= fileMetadata.fileKeys.size) { + require(keys.size <= fileMetadata.fileKeys.size){ "Number of metadata keys $fileMetadata.fileKeys less than number of positioning/read keys $keys" } } - private fun checkRead() { - requireNotNull(lastReadInstruction) { + private fun checkRead(){ + requireNotNull(lastReadInstruction){ "No read instruction found" } } - private fun checkReadKeys() { + private fun checkReadKeys(){ checkRead() - require(!lastReadInstruction!!.keys.isNullOrEmpty()) { + require(!lastReadInstruction!!.keys.isNullOrEmpty()){ "No keys specified for read instruction ${lastReadInstruction!!.method}" } } - private fun checkInstructions() { + private fun checkInstructions(){ checkPositioning() checkRead() } - fun setPositioning( - method: PositioningMethod, - keys: List, - ) { + fun setPositioning(method: PositioningMethod, keys: List){ checkKeys(keys) lastPositioningInstruction = PositioningInstruction(method, keys) lastReadInstruction = null @@ -90,17 +81,14 @@ class Native2SQL(val fileMetadata: FileMetadata) { /* * @return true if read method need new query execution */ - fun setRead( - method: ReadMethod, - keys: List? = null, - ): Boolean { + fun setRead(method: ReadMethod, keys: List? = null): Boolean{ checkKeys(keys ?: emptyList()) var executeQuery = false - when (method) { - ReadMethod.READPE, ReadMethod.READE -> { - val coherent = keys?.let { isCoherent(keys) } ?: true - // Test to remove on fully supported operations - require(coherent) { + when(method){ + ReadMethod.READPE, ReadMethod.READE ->{ + val coherent = keys?.let{isCoherent(keys)} ?: true + //Test to remove on fully supported operations + require(coherent){ "Uncoherent read not yet managed" } } @@ -113,105 +101,90 @@ class Native2SQL(val fileMetadata: FileMetadata) { require(lastReadInstruction == null || method == ReadMethod.CHAIN || method == lastReadInstruction!!.method) { "read operation " + method + " is allowed immediatly after positioning or after a same method read instruction" } - if (lastReadInstruction == null) { + if(lastReadInstruction == null){ executeQuery = true } - lastReadInstruction = ReadInstruction(method, keys ?: emptyList()) + lastReadInstruction = ReadInstruction(method, keys ?:emptyList()) return executeQuery } - fun clear() { + fun clear(){ lastReadInstruction = null lastPositioningInstruction = null } - fun getLastKeys() = lastReadInstruction?.keys ?: lastPositioningInstruction?.keys ?: throw Exception("Keys not yet set") + fun getLastKeys() = lastReadInstruction?.keys ?:lastPositioningInstruction?.keys ?: throw Exception("Keys not yet set") - fun isLastOperationSet() = lastReadInstruction == null + fun isLastOperationSet()=lastReadInstruction == null fun lastReadMatchRecord(record: Record): Boolean { - if (lastReadInstruction!!.keys.isEmpty()) { + if(lastReadInstruction!!.keys.isEmpty()){ return true } lastReadInstruction!!.keys.mapIndexed { index, value -> val keyname = fileMetadata.fileKeys.get(index) - if (record[keyname]?.trim() != value.trim()) { + if(record[keyname]?.trim() != value.trim()){ return false } } return true } - fun isCoherent(newKeys: List): Boolean { + + fun isCoherent(newKeys: List): Boolean{ checkPositioning() return newKeys.isEmpty() || if (newKeys.size <= lastPositioningInstruction!!.keys.size && - newKeys.size <= lastReadInstruction?.keys?.size ?: newKeys.size - ) { - newKeys.forEachIndexed { index, value -> - if (lastPositioningInstruction!!.keys.get(index) != value) { - return false - } + newKeys.size <= lastReadInstruction?.keys?.size?:newKeys.size) { + newKeys.forEachIndexed() { index, value -> + if(lastPositioningInstruction!!.keys.get(index) != value){ + return false } - return true - } else { - false } + return true + } + else false } + private fun getSortOrder(): SortOrder { checkInstructions() - return if (lastReadInstruction!!.method.forward) SortOrder.ASCEDING else SortOrder.DESCENDING + return if(lastReadInstruction!!.method.forward) SortOrder.ASCEDING else SortOrder.DESCENDING } - private fun getComparison(): Pair { + private fun getComparison(): Pair{ checkInstructions() - return if (lastReadInstruction!!.method.forward) { - when (lastPositioningInstruction!!.method) { - PositioningMethod.SETLL -> return Pair(Comparison.GE, Comparison.GT) - PositioningMethod.SETGT -> return Pair(Comparison.GT, Comparison.GT) + return if(lastReadInstruction!!.method.forward){ + when(lastPositioningInstruction!!.method){ + PositioningMethod.SETLL -> return Pair(Comparison.GE, Comparison.GT) + PositioningMethod.SETGT -> return Pair(Comparison.GT, Comparison.GT) } - } else { - when (lastPositioningInstruction!!.method) { + } + else{ + when(lastPositioningInstruction!!.method){ PositioningMethod.SETLL -> return Pair(Comparison.LT, Comparison.LT) PositioningMethod.SETGT -> return Pair(Comparison.LE, Comparison.LT) } } } - private fun getSQLOrderByClause(): String { + private fun getSQLOrderByClause(): String{ val sortOrder = getSortOrder() - return " ORDER BY " + fileMetadata.fileKeys.joinToString(separator = " " + sortOrder.symbol + ", ", postfix = " " + sortOrder.symbol) + return " ORDER BY " + fileMetadata.fileKeys.joinToString(separator = " " + sortOrder.symbol + ", ", postfix = " " + sortOrder.symbol ) } - fun getReadSqlStatement(): Pair> { + fun getReadSqlStatement(): Pair>{ checkPositioning() - return Pair( - getSQL( - fileMetadata.fields, - fileMetadata.fileKeys.subList(0, lastPositioningInstruction!!.keys.size), - Comparison.EQ, - fileMetadata.tableName, - ), - lastPositioningInstruction!!.keys, - ) + return Pair(getSQL(fileMetadata.fields, fileMetadata.fileKeys.subList(0, lastPositioningInstruction!!.keys.size), Comparison.EQ, fileMetadata.tableName), lastPositioningInstruction!!.keys) } - fun getSQLSatement(): Pair> { - when (lastReadInstruction!!.method) { - ReadMethod.CHAIN -> { + fun getSQLSatement(): Pair>{ + when(lastReadInstruction!!.method){ + ReadMethod.CHAIN ->{ checkReadKeys() - return Pair( - getSQL( - fileMetadata.fields, - fileMetadata.fileKeys.subList(0, lastReadInstruction!!.keys.size), - Comparison.EQ, - fileMetadata.tableName, - ), - lastReadInstruction!!.keys, - ) + return Pair(getSQL(fileMetadata.fields, fileMetadata.fileKeys.subList(0, lastReadInstruction!!.keys.size), Comparison.EQ, fileMetadata.tableName), lastReadInstruction!!.keys) } - ReadMethod.READ, ReadMethod.READP -> { + ReadMethod.READ,ReadMethod.READP -> { checkRead() return getCoherentSql(true) } @@ -222,28 +195,23 @@ class Native2SQL(val fileMetadata: FileMetadata) { } } - private fun getCoherentSql(fullUnion: Boolean = false): Pair> { + + private fun getCoherentSql(fullUnion: Boolean = false):Pair>{ checkPositioning() val queries = mutableListOf() val replacements = mutableListOf() val comparison = getComparison() - require(!lastPositioningInstruction!!.keys.isEmpty()) { + require(!lastPositioningInstruction!!.keys.isEmpty()){ "Empty positioning keys" } - if (lastPositioningInstruction!!.keys.size == 1) { + if(lastPositioningInstruction!!.keys.size == 1){ queries.add(getSQL(fileMetadata.fields, fileMetadata.fileKeys.subList(0, 1), comparison.first, fileMetadata.tableName)) replacements.addAll(lastPositioningInstruction!!.keys) - } else { - val limit = if (fullUnion)1 else 2 + } + else { + val limit = if(fullUnion)1 else 2 for (i in lastPositioningInstruction!!.keys.size downTo limit) { - queries.add( - getSQL( - fileMetadata.fields, - fileMetadata.fileKeys.subList(0, i), - if (i == lastPositioningInstruction!!.keys.size) comparison.first else comparison.second, - fileMetadata.tableName, - ), - ) + queries.add(getSQL(fileMetadata.fields, fileMetadata.fileKeys.subList(0, i), if(i == lastPositioningInstruction!!.keys.size) comparison.first else comparison.second, fileMetadata.tableName)) replacements.addAll(lastPositioningInstruction!!.keys.subList(0, i)) } } @@ -251,12 +219,7 @@ class Native2SQL(val fileMetadata: FileMetadata) { } } -private fun getSQL( - fields: List, - keys: List, - comparison: Comparison, - tableName: String, -): String { +private fun getSQL(fields: List, keys: List, comparison: Comparison, tableName: String): String{ var columns = "" fields.forEachIndexed { index, k -> run { @@ -267,23 +230,22 @@ private fun getSQL( var value = "" keys.forEachIndexed { index, k -> run { - value += "\"" + k + "\" " + (if (index < keys.size - 1) Comparison.EQ.symbol else comparison.symbol) + " ? AND " + value += "\"" + k + "\" " + (if (index < keys.size - 1) Comparison.EQ.symbol else comparison.symbol) + " ? AND " } } - return "(SELECT " + columns.removeSuffix(", ") + " FROM $tableName WHERE " + value.removeSuffix("AND ") + ")" + return "(SELECT " + columns.removeSuffix(", ")+ " FROM $tableName WHERE " + value.removeSuffix("AND ") + ")" } -fun main() { +fun main(){ var fields = listOf(Field("Regione", ""), Field("Provincia", ""), Field("Comune", "")) var fieldsKeys = listOf("Regione", "Provincia", "Comune") var metadata = FileMetadata("test", "rld_comuni", fields, fieldsKeys) - val adapter = - Native2SQL(metadata).apply { - setPositioning(PositioningMethod.SETLL, listOf("Lombardia", "Brescia", "Erbusco")) - println(isCoherent(listOf("Lombardia", "Brescia", "Erbusco"))) - setRead(ReadMethod.READE, listOf("Lombardia", "Brescia", "Erbusco")) - } - adapter.getSQLSatement().let { + val adapter = Native2SQL(metadata).apply{ + setPositioning(PositioningMethod.SETLL, listOf("Lombardia", "Brescia", "Erbusco")) + println(isCoherent(listOf("Lombardia", "Brescia", "Erbusco"))) + setRead(ReadMethod.READE, listOf("Lombardia", "Brescia", "Erbusco")) + } + adapter.getSQLSatement().let{ println(it.first) println(it.second) } diff --git a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFile.kt b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFile.kt index 903797e..45d48ae 100644 --- a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFile.kt +++ b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFile.kt @@ -17,6 +17,7 @@ package com.smeup.dbnative.sql + import com.smeup.dbnative.file.DBFile import com.smeup.dbnative.file.Record import com.smeup.dbnative.file.Result @@ -29,17 +30,14 @@ import java.sql.PreparedStatement import java.sql.ResultSet import kotlin.system.measureTimeMillis -class SQLDBFile( - override var name: String, - override var fileMetadata: FileMetadata, - var connection: Connection, - override var logger: Logger? = null, -) : DBFile { +class SQLDBFile(override var name: String, override var fileMetadata: FileMetadata, + var connection: Connection, + override var logger: Logger? = null) : DBFile { + constructor( name: String, fileMetadata: FileMetadata, - connection: Connection, - ) : this(name, fileMetadata, connection, null) + connection: Connection): this(name, fileMetadata, connection, null) private var preparedStatements: MutableMap = mutableMapOf() private var resultSet: ResultSet? = null @@ -47,8 +45,8 @@ class SQLDBFile( private var lastNativeMethod: NativeMethod? = null - // Search from: metadata, primary key, unique index, view ordering fields - // private val thisFileKeys: List by lazy { + //Search from: metadata, primary key, unique index, view ordering fields + //private val thisFileKeys: List by lazy { // // TODO: think about a right way (local file maybe?) to retrieve keylist // var indexes = this.fileMetadata.fileKeys // if(indexes.isEmpty()){ @@ -56,16 +54,14 @@ class SQLDBFile( // } // } // if (indexes.isEmpty()) connection.orderingFields(fileMetadata.name) else indexes - // } + //} private var adapter: Native2SQL = Native2SQL(this.fileMetadata) - private var eof: Boolean = false + private var eof:Boolean = false + + private fun logEvent(loggingKey: LoggingKey, message: String, elapsedTime: Long? = null) = + logger?.logEvent(loggingKey, message, elapsedTime, lastNativeMethod, fileMetadata.name) - private fun logEvent( - loggingKey: LoggingKey, - message: String, - elapsedTime: Long? = null, - ) = logger?.logEvent(loggingKey, message, elapsedTime, lastNativeMethod, fileMetadata.name) override fun setll(key: String): Boolean { return setll(mutableListOf(key)) @@ -89,6 +85,7 @@ class SQLDBFile( adapter.setPositioning(PositioningMethod.SETGT, keys) return true + } override fun chain(key: String): Result { @@ -101,6 +98,7 @@ class SQLDBFile( adapter.setRead(ReadMethod.CHAIN, keys) val read: Result measureTimeMillis { + executeQuery(adapter.getSQLSatement()) read = readNextFromResultSet() }.apply { @@ -115,7 +113,7 @@ class SQLDBFile( logEvent(LoggingKey.native_access_method, "Executing read") val read: Result measureTimeMillis { - if (adapter.setRead(ReadMethod.READ)) { + if (adapter.setRead(ReadMethod.READ) ) { executeQuery(adapter.getSQLSatement()) } read = readNextFromResultSet() @@ -155,6 +153,7 @@ class SQLDBFile( logEvent(LoggingKey.native_access_method, "Executing readEqual on keys $keys") val read: Result measureTimeMillis { + if (adapter.setRead(ReadMethod.READE, keys)) { executeQuery(adapter.getSQLSatement()) } @@ -166,6 +165,7 @@ class SQLDBFile( return read } + override fun readPreviousEqual(): Result { return readPreviousEqual(adapter.getLastKeys()) } @@ -179,6 +179,7 @@ class SQLDBFile( logEvent(LoggingKey.native_access_method, "Executing readPreviousEqual on keys $keys") val read: Result measureTimeMillis { + if (adapter.setRead(ReadMethod.READPE, keys)) { executeQuery(adapter.getSQLSatement()) } @@ -209,22 +210,19 @@ class SQLDBFile( override fun update(record: Record): Result { lastNativeMethod = NativeMethod.update - logEvent( - LoggingKey.native_access_method, - "Executing update record $actualRecord to $record with autocommit=${connection.autoCommit}", - ) + logEvent(LoggingKey.native_access_method, "Executing update record $actualRecord to $record with autocommit=${connection.autoCommit}") measureTimeMillis { // record before update is "actualRecord" // record post update will be "record" var atLeastOneFieldChanged = false actualRecord?.forEach { val fieldValue = record.getValue(it.key) - if (fieldValue != it.value) { + if(fieldValue != it.value){ atLeastOneFieldChanged = true this.getResultSet()?.updateObject(it.key, fieldValue) } - } ?: logEvent(LoggingKey.native_access_method, "No previous read executed, nothing to update") - if (atLeastOneFieldChanged) { + }?:logEvent(LoggingKey.native_access_method, "No previous read executed, nothing to update") + if(atLeastOneFieldChanged){ this.getResultSet()?.updateRow() } }.apply { @@ -236,14 +234,12 @@ class SQLDBFile( override fun delete(record: Record): Result { lastNativeMethod = NativeMethod.delete - logEvent( - LoggingKey.native_access_method, - "Executing delete for current record $actualRecord with autocommit=${connection.autoCommit}", - ) + logEvent(LoggingKey.native_access_method, "Executing delete for current record $actualRecord with autocommit=${connection.autoCommit}") measureTimeMillis { - if (actualRecord != null) { + if(actualRecord != null) { this.getResultSet()?.deleteRow() - } else { + } + else{ logEvent(LoggingKey.native_access_method, "No previous read executed, nothing to delete") } }.apply { @@ -257,17 +253,14 @@ class SQLDBFile( executeQuery(sqlAndValues.first, sqlAndValues.second) } - private fun executeQuery( - sql: String, - values: List, - ) { + private fun executeQuery(sql: String, values: List) { eof = false resultSet.closeIfOpen() logEvent(LoggingKey.execute_inquiry, "Preparing statement for query: $sql with bingings: $values") val stm: PreparedStatement measureTimeMillis { - stm = preparedStatements.get(sql) ?: connection.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE) - preparedStatements.putIfAbsent(sql, stm) + stm = preparedStatements.get(sql)?:connection.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE) + preparedStatements.putIfAbsent(sql, stm); stm.bind(values) }.apply { logEvent(LoggingKey.execute_inquiry, "Statement prepared, executing query for statement", this) @@ -279,6 +272,7 @@ class SQLDBFile( } } + private fun readNextFromResultSet(): Result { val result = Result(resultSet.toValues()) if (!eof() && adapter.lastReadMatchRecord(result.record)) { @@ -294,13 +288,14 @@ class SQLDBFile( } } - private fun closeResultSet() { + private fun closeResultSet(){ resultSet.closeIfOpen() resultSet = null } override fun eof() = eof + override fun equal(): Boolean { logEvent(LoggingKey.read_data, "Read current record for equal") lastNativeMethod = NativeMethod.equal @@ -308,6 +303,7 @@ class SQLDBFile( if (!adapter.isLastOperationSet()) { result = false } else { + measureTimeMillis { executeQuery(adapter.getReadSqlStatement()) result = resultSet?.next() ?: false @@ -327,4 +323,4 @@ class SQLDBFile( resultSet.closeIfOpen() preparedStatements.values.forEach { it.close() } } -} +} \ No newline at end of file diff --git a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFileNoPerf.kt b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFileNoPerf.kt index 5491987..5618b85 100644 --- a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFileNoPerf.kt +++ b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFileNoPerf.kt @@ -17,6 +17,7 @@ package com.smeup.dbnative.sql + import com.smeup.dbnative.file.DBFile import com.smeup.dbnative.file.Record import com.smeup.dbnative.file.RecordField @@ -30,17 +31,15 @@ import java.sql.PreparedStatement import java.sql.ResultSet import kotlin.system.measureTimeMillis -class SQLDBFileNoPerf( - override var name: String, - override var fileMetadata: FileMetadata, - var connection: Connection, - override var logger: Logger? = null, -) : DBFile { +class SQLDBFileNoPerf(override var name: String, + override var fileMetadata: FileMetadata, + var connection: Connection, + override var logger: Logger? = null) : DBFile { + constructor( name: String, fileMetadata: FileMetadata, - connection: Connection, - ) : this(name, fileMetadata, connection, null) + connection: Connection): this(name, fileMetadata, connection, null) private var resultSet: ResultSet? = null private var movingForward = true @@ -49,22 +48,21 @@ class SQLDBFileNoPerf( private var actualRecordToPop: Record? = null private var eof: Boolean = false private var lastOperationSet: Boolean = false - private var lastNativeMethod: NativeMethod? = null + private var lastNativeMethod: NativeMethod? = null; + + private val thisFileKeys: List by lazy { // TODO: think about a right way (local file maybe?) to retrieve keylist var indexes = this.fileMetadata.fileKeys - if (indexes.isEmpty()) { + if(indexes.isEmpty()){ indexes = connection.primaryKeys(fileMetadata.name) } if (indexes.isEmpty()) connection.orderingFields(fileMetadata.name) else indexes } - private fun logEvent( - loggingKey: LoggingKey, - message: String, - elapsedTime: Long? = null, - ) = logger?.logEvent(loggingKey, message, elapsedTime, lastNativeMethod, fileMetadata.tableName) + private fun logEvent(loggingKey: LoggingKey, message: String, elapsedTime: Long? = null) = + logger?.logEvent(loggingKey, message, elapsedTime, lastNativeMethod, fileMetadata.tableName) override fun setll(key: String): Boolean { return setll(mutableListOf(key)) @@ -77,15 +75,14 @@ class SQLDBFileNoPerf( measureTimeMillis { lastOperationSet = true - var keyAsRecordField = - keys.mapIndexed { index, value -> - val keyname = thisFileKeys.get(index) - RecordField(keyname, value) - } + var keyAsRecordField = keys.mapIndexed { index, value -> + val keyname = thisFileKeys.get(index) + RecordField(keyname, value) + } checkAndStoreLastKeys(keyAsRecordField) movingForward = true - point = point(keyAsRecordField) + point = point(keyAsRecordField); }.apply { logEvent(LoggingKey.native_access_method, "setll executed", this) } @@ -94,6 +91,7 @@ class SQLDBFileNoPerf( } override fun setgt(key: String): Boolean { + return setgt(mutableListOf(key)) } @@ -104,11 +102,10 @@ class SQLDBFileNoPerf( measureTimeMillis { lastOperationSet = true - var keyAsRecordField = - keys.mapIndexed { index, value -> - val keyname = thisFileKeys.get(index) - RecordField(keyname, value) - } + var keyAsRecordField = keys.mapIndexed { index, value -> + val keyname = thisFileKeys.get(index) + RecordField(keyname, value) + } checkAndStoreLastKeys(keyAsRecordField) movingForward = false @@ -131,11 +128,10 @@ class SQLDBFileNoPerf( measureTimeMillis { lastOperationSet = false - var keyAsRecordField = - keys.mapIndexed { index, value -> - val keyname = thisFileKeys.get(index) - RecordField(keyname, value) - } + var keyAsRecordField = keys.mapIndexed { index, value -> + val keyname = thisFileKeys.get(index) + RecordField(keyname, value) + } checkAndStoreLastKeys(keyAsRecordField) movingForward = true @@ -155,6 +151,7 @@ class SQLDBFileNoPerf( measureTimeMillis { lastOperationSet = false + if (resultSet == null) { pointAtUpperLL() } @@ -193,14 +190,15 @@ class SQLDBFileNoPerf( } override fun readEqual(): Result { - val lastKeysAsList = - lastKeys.map { - it.value - } + val lastKeysAsList = lastKeys.map { + it.value + } return readEqual(lastKeysAsList) } override fun readEqual(key: String): Result { + + return readEqual(mutableListOf(key)) } @@ -211,11 +209,10 @@ class SQLDBFileNoPerf( measureTimeMillis { lastOperationSet = false - var keysAsRecordField = - keys.mapIndexed { index, value -> - val keyname = thisFileKeys.get(index) - RecordField(keyname, value) - } + var keysAsRecordField = keys.mapIndexed { index, value -> + val keyname = thisFileKeys.get(index) + RecordField(keyname, value) + } checkAndStoreLastKeys(keysAsRecordField) if (resultSet == null) { @@ -234,10 +231,10 @@ class SQLDBFileNoPerf( } override fun readPreviousEqual(): Result { - val lastKeysAsList = - lastKeys.map { - it.value - } + + val lastKeysAsList = lastKeys.map { + it.value + } return readPreviousEqual(lastKeysAsList) } @@ -248,16 +245,15 @@ class SQLDBFileNoPerf( override fun readPreviousEqual(keys: List): Result { lastNativeMethod = NativeMethod.readPreviousEqual - logEvent(LoggingKey.native_access_method, "Executing readPreviousEqual on keys $keys") + logEvent(LoggingKey.native_access_method, "Executing readPreviousEqual on keys ${keys}") val read: Result measureTimeMillis { lastOperationSet = false - var keyAsRecordField = - keys.mapIndexed { index, value -> - val keyname = thisFileKeys.get(index) - RecordField(keyname, value) - } + var keyAsRecordField = keys.mapIndexed { index, value -> + val keyname = thisFileKeys.get(index) + RecordField(keyname, value) + } checkAndStoreLastKeys(keyAsRecordField) if (resultSet == null) { @@ -280,7 +276,7 @@ class SQLDBFileNoPerf( override fun write(record: Record): Result { lastNativeMethod = NativeMethod.write - logEvent(LoggingKey.native_access_method, "Executing write for record $record") + logEvent(LoggingKey.native_access_method, "Executing write for record ${record}") lastOperationSet = false measureTimeMillis { // TODO: manage errors @@ -298,7 +294,7 @@ class SQLDBFileNoPerf( override fun update(record: Record): Result { lastNativeMethod = NativeMethod.update - logEvent(LoggingKey.native_access_method, "Executing update for record $record") + logEvent(LoggingKey.native_access_method, "Executing update for record ${record}") lastOperationSet = false measureTimeMillis { // record before update is "actualRecord" @@ -306,12 +302,12 @@ class SQLDBFileNoPerf( var atLeastOneFieldChanged = false actualRecord?.forEach { var fieldValue = record.getValue(it.key) - if (fieldValue != it.value) { + if(fieldValue != it.value){ atLeastOneFieldChanged = true this.getResultSet()?.updateObject(it.key, fieldValue) } } - if (atLeastOneFieldChanged) { + if(atLeastOneFieldChanged){ this.getResultSet()?.updateRow() } }.apply { @@ -323,7 +319,7 @@ class SQLDBFileNoPerf( override fun delete(record: Record): Result { lastNativeMethod = NativeMethod.delete - logEvent(LoggingKey.native_access_method, "Executing delete for record $record") + logEvent(LoggingKey.native_access_method, "Executing delete for record ${record}") lastOperationSet = false measureTimeMillis { this.getResultSet()?.deleteRow() @@ -334,10 +330,8 @@ class SQLDBFileNoPerf( return Result(record) } - private fun executeQuery( - sql: String, - values: List, - ) { + + private fun executeQuery(sql: String, values: List) { resultSet.closeIfOpen() logEvent(LoggingKey.execute_inquiry, "Preparing statement for query: $sql with bingings: $values") val stm: PreparedStatement @@ -376,10 +370,7 @@ class SQLDBFileNoPerf( } // calculate the upper or the lower part of the ordered table given the input keys using an sql query (composed of selects in union if primary keys size > 1) - private fun calculateResultSet( - keys: List, - withEquals: Boolean = true, - ) { + private fun calculateResultSet(keys: List, withEquals: Boolean = true) { actualRecordToPop = null val sqlAndValues = filePartSQLAndValues(fileMetadata.tableName, movingForward, thisFileKeys, keys, withEquals) val values = sqlAndValues.first @@ -391,10 +382,7 @@ class SQLDBFileNoPerf( calculateResultSet(calculateRecordKeys(actualRecord, thisFileKeys), false) } - private fun calculateRecordKeys( - record: Record?, - keysNames: List, - ): List { + private fun calculateRecordKeys(record: Record?, keysNames: List): List { val result = mutableListOf() keysNames.forEach { result.add(RecordField(it, record!![it].toString())) @@ -422,7 +410,7 @@ class SQLDBFileNoPerf( } private fun readFromResultSetFilteringBy(keys: List): Result { - logEvent(LoggingKey.search_data, "Searching record for keys: $keys") + logEvent(LoggingKey.search_data, "Searching record for keys: ${keys}") var result: Result var counter = 0 measureTimeMillis { @@ -431,11 +419,7 @@ class SQLDBFileNoPerf( counter++ } while (!result.record.matches(keys) && resultSet.hasRecords() && !eof()) }.apply { - logEvent( - LoggingKey.search_data, - "Search stops after $counter ResultSet iterations. Is eof: ${eof()}. Current row number is ${resultSet?.row ?: " undefined"}}", - this, - ) + logEvent(LoggingKey.search_data, "Search stops after $counter ResultSet iterations. Is eof: ${eof()}. Current row number is ${resultSet?.row?:" undefined"}}", this) } return result } @@ -447,6 +431,7 @@ class SQLDBFileNoPerf( override fun eof(): Boolean = resultSet?.isAfterLast ?: true + override fun equal(): Boolean { lastNativeMethod = NativeMethod.equal if (lastOperationSet == false) { @@ -472,4 +457,4 @@ class SQLDBFileNoPerf( fun getResultSet(): ResultSet? { return this.resultSet } -} +} \ No newline at end of file diff --git a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBMManager.kt b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBMManager.kt index ccbfc0a..9ac0a1a 100644 --- a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBMManager.kt +++ b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBMManager.kt @@ -25,12 +25,13 @@ import java.sql.DriverManager import java.util.* import kotlin.system.measureTimeMillis -open class SQLDBMManager(override val connectionConfig: ConnectionConfig) : DBManagerBaseImpl() { +open class SQLDBMManager(override val connectionConfig: ConnectionConfig) : DBManagerBaseImpl() { + private var sqlLog: Boolean = false private var openedFile = mutableMapOf() - val connection: Connection by lazy { + val connection : Connection by lazy { logger?.logEvent(LoggingKey.connection, "Opening SQL connection on url ${connectionConfig.url}") val conn: Connection measureTimeMillis { @@ -38,13 +39,13 @@ open class SQLDBMManager(override val connectionConfig: ConnectionConfig) : DBMa Class.forName(connectionConfig.driver) } - val connectionProps = Properties() - connectionProps.put("user", connectionConfig.user) - connectionProps.put("password", connectionConfig.password) + val connectionProps = Properties(); + connectionProps.put("user", connectionConfig.user); + connectionProps.put("password", connectionConfig.password); - connectionConfig.properties.forEach { - if (!it.key.equals("user") && !it.key.equals("password")) { - connectionProps.put(it.key, it.value) + connectionConfig.properties.forEach() { + if (!it.key.equals("user") && !it.key.equals("password")) { + connectionProps.put(it.key, it.value); } } conn = DriverManager.getConnection(connectionConfig.url, connectionProps) @@ -58,18 +59,18 @@ open class SQLDBMManager(override val connectionConfig: ConnectionConfig) : DBMa } override fun close() { - openedFile.values.forEach { it.close() } + openedFile.values.forEach { it.close()} openedFile.clear() connection.close() } - override fun openFile(name: String) = - openedFile.getOrPut(name) { - require(existFile(name)) { - "Cannot open a unregistered file $name" - } - SQLDBFile(name = name, fileMetadata = metadataOf(name), connection = connection, logger) + override fun openFile(name: String) = openedFile.getOrPut(name) { + require(existFile(name)) { + "Cannot open a unregistered file $name" } + SQLDBFile(name = name, fileMetadata = metadataOf(name), connection = connection, logger) + } + override fun closeFile(name: String) { openedFile.remove(name)?.close() @@ -89,4 +90,5 @@ open class SQLDBMManager(override val connectionConfig: ConnectionConfig) : DBMa fun setSQLLog(on: Boolean) { sqlLog = on } -} + +} \ No newline at end of file diff --git a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLUtils.kt b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLUtils.kt index 16217a1..49f22c5 100644 --- a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLUtils.kt +++ b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLUtils.kt @@ -20,6 +20,7 @@ package com.smeup.dbnative.sql import com.smeup.dbnative.file.Record import com.smeup.dbnative.file.RecordField + fun String.insertSQL(record: Record): String { val names = record.keys.joinToString { "\"" + it + "\"" } val questionMarks = record.keys.joinToString { "?" } @@ -39,24 +40,18 @@ fun String.deleteSQL(record: Record): String { return "DELETE FROM $this ${whereSQL(wheres, comparations)}" } -fun orderBySQL( - keysNames: List, - reverse: Boolean = false, -): String = +fun orderBySQL(keysNames: List, reverse: Boolean = false): String = if (keysNames.isEmpty()) { "" } else { if (reverse) { - "ORDER BY " + keysNames.joinToString(separator = " DESC, ", postfix = " DESC") { "\"$it\"" } + "ORDER BY " + keysNames.joinToString(separator = " DESC, ", postfix = " DESC") {"\"$it\""} } else { - "ORDER BY " + keysNames.joinToString { "\"$it\"" } + "ORDER BY " + keysNames.joinToString {"\"$it\""} } } -fun whereSQL( - wheres: List, - comparations: List, -): String { +fun whereSQL(wheres: List, comparations: List): String { return if (wheres.isEmpty()) { "" } else { @@ -71,8 +66,9 @@ fun filePartSQLAndValues( movingForward: Boolean, fileKeys: List, keys: List, - withEquals: Boolean, + withEquals: Boolean ): Pair, String> { + val queries = mutableListOf() val values = mutableListOf() @@ -80,12 +76,12 @@ fun filePartSQLAndValues( val keys2Size = keys2.size do { - var lastComparison = - if (movingForward) { - Comparison.GT - } else { - Comparison.LT - } + + var lastComparison = if (movingForward) { + Comparison.GT + } else { + Comparison.LT + } val comparisons = mutableListOf() keys2.forEachIndexed { index, _ -> @@ -105,20 +101,19 @@ fun filePartSQLAndValues( val sql = "(SELECT * FROM $tableName ${whereSQL( keys2.map { it.name }, - comparisons, + comparisons )})" values.addAll(keys2.map { it.value.toString() }) queries.add(sql) keys2 = keys2.subList(0, keys2.size - 1) + } while (keys2.isNotEmpty()) - val sql = - queries.joinToString(" UNION ") + " " + - orderBySQL( - fileKeys, - reverse = !movingForward, - ) + val sql = queries.joinToString(" UNION ") + " " + orderBySQL( + fileKeys, + reverse = !movingForward + ) return Pair(values, sql) } @@ -129,7 +124,7 @@ enum class Comparison(val symbol: String) { GT(">"), GE(">="), LT("<"), - LE("<="), + LE("<="); } fun createMarkerSQL(keysNames: List): String = @@ -138,47 +133,50 @@ fun createMarkerSQL(keysNames: List): String = } else { // in HSQLDB CONCAT needs at least two params! if (keysNames.size == 1) { - "CONCAT( " + keysNames.joinToString { "\"$it\"" } + ", '') AS NATIVE_ACCESS_MARKER" + "CONCAT( " + keysNames.joinToString{"\"$it\""} + ", '') AS NATIVE_ACCESS_MARKER" } else { - "CONCAT( " + keysNames.joinToString { "\"$it\"" } + ") AS NATIVE_ACCESS_MARKER" + "CONCAT( " + keysNames.joinToString{"\"$it\""} + ") AS NATIVE_ACCESS_MARKER" } + } fun calculateMarkerValue( keys: List, movingForward: Boolean = true, - withEquals: Boolean = true, + withEquals: Boolean = true ): String = if (keys.isEmpty()) { "" } else { - val padChar = - if (movingForward) { - ' ' - } else { - 'Z' - } + val padChar = if (movingForward) { + ' ' + } else { + 'Z' + } // NOTE: calculate max length of marker using primary fields max length (temp 100 but incorrect) if (withEquals) { keys.joinToString("") { it.value }.padEnd(100, padChar) } else { keys.joinToString("") { it.value } + } } -fun markerWhereSQL( - movingForward: Boolean, - withEquals: Boolean, -): String { - val comparison = - if (movingForward && !withEquals) { - Comparison.GT - } else if (movingForward && withEquals) { - Comparison.GE - } else if (!movingForward && !withEquals) { - Comparison.LT - } else { - Comparison.LE - } +fun markerWhereSQL(movingForward: Boolean, withEquals: Boolean): String { + val comparison = if (movingForward && !withEquals) { + Comparison.GT + } else if (movingForward && withEquals) { + Comparison.GE + } else if (!movingForward && !withEquals) { + Comparison.LT + } else { + Comparison.LE + } return " WHERE NATIVE_ACCESS_MARKER ${comparison.symbol} ? " } + + + + + + diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400OperationsOnFile.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400OperationsOnFile.kt index 5c8588c..2001976 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400OperationsOnFile.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400OperationsOnFile.kt @@ -31,9 +31,11 @@ import org.junit.Test import kotlin.test.assertEquals import kotlin.test.assertTrue -// @Ignore +//@Ignore class DB2400OperationsOnFile { + companion object { + private var dbManager: SQLDBMManager? = null @BeforeClass @@ -47,7 +49,7 @@ class DB2400OperationsOnFile { } } - // Ignored fields in metadata not necessary + //Ignored fields in metadata not necessary @Ignore @Test fun open() { @@ -201,7 +203,7 @@ class DB2400OperationsOnFile { var chainResult = dbFile.chain(key) assertEquals(0, chainResult.record.size) - // Set field values and write record + //Set field values and write record chainResult.record["A§ARTI"] = key chainResult.record["A§DEAR"] = "Kotlin DBNativeAccess Write " chainResult.record["A§TIAR"] = "ART " @@ -209,17 +211,17 @@ class DB2400OperationsOnFile { dbFile.write(chainResult.record) - // Must exists correct write + //Must exists correct write chainResult = dbFile.chain(key) assertEquals(key, chainResult.record["A§ARTI"]) assertEquals("ART ", chainResult.record["A§TIAR"]) assertEquals("Kotlin DBNativeAccess Write ", chainResult.record["A§DEAR"]) assertEquals("0 ", chainResult.record["A§TPAR"]) - // Delete record + //Delete record dbFile.delete(chainResult.record) - // Check delete success + //Check delete success chainResult = dbFile.chain(key) assertEquals(0, chainResult.record.size) @@ -229,7 +231,7 @@ class DB2400OperationsOnFile { // Ignore, fields in metadata non necessary @Ignore @Test - fun multipleUpdateOnReadE() { + fun multipleUpdateOnReadE(){ // TEST FLOW // Step1: write 100 records with "currentTimeMillis" as unique key // Step2: read above written records and update A§DEA2 field @@ -244,7 +246,7 @@ class DB2400OperationsOnFile { // Create list of items to write into A§ARTI field val items = mutableListOf() - repeat(numberOfRecordsToHandle) { + repeat(numberOfRecordsToHandle){ items.add(System.currentTimeMillis().toString() + " ") Thread.sleep(5) } @@ -255,21 +257,19 @@ class DB2400OperationsOnFile { val dea2Key = "Kotlin DBNativeAccess TEST-UPDATED " // WRITE - repeat(numberOfRecordsToHandle) { + repeat(numberOfRecordsToHandle){ var record = Record() - repeat(fieldsNumber) { index -> + repeat(fieldsNumber){ index -> var name: String = dbFile.fileMetadata.fields[index].name print(tMetadata.getField(name)?.type) - var value = - when (name) { - "A§ARTI" -> items[it] - "A§DEAR" -> dearKey - else -> - when (tMetadata.getField(name)?.type) { - is DecimalType -> "0" - else -> "" - } + var value = when(name){ + "A§ARTI" -> items[it] + "A§DEAR" -> dearKey + else -> when(tMetadata.getField(name)?.type){ + is DecimalType -> "0" + else -> "" } + } var recordField: RecordField = RecordField(name, value) record.add(recordField) @@ -303,9 +303,10 @@ class DB2400OperationsOnFile { repeat(numberOfRecordsToHandle) { var readEResult = dbFile.readEqual(dearKey) assertEquals(dea2Key, readEResult.record["A§DEA2"]) - // Delete record + //Delete record dbFile.delete(readEResult.record) } + } @Test @@ -351,7 +352,7 @@ class DB2400OperationsOnFile { dbManager!!.registerMetadata(fileMetadata, false) var dbFile = dbManager!!.openFile("VERAPG1L") - // keys: V£DATA, V£NOME, V£IDOJ + //keys: V£DATA, V£NOME, V£IDOJ val data = "20200901" val nome = "BNUNCA " val idoj = "0002003070" @@ -377,7 +378,7 @@ class DB2400OperationsOnFile { } @Test - fun resultSetCursorMovements() { + fun resultSetCursorMovements(){ val fileMetadata = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "BRARTI0L") dbManager!!.registerMetadata(fileMetadata, false) var dbFile = dbManager!!.openFile("BRARTI0L") @@ -401,7 +402,7 @@ class DB2400OperationsOnFile { } @Test - fun resultSetCursorUpdate() { + fun resultSetCursorUpdate(){ val fileMetadata = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "BRARTI0L") dbManager!!.registerMetadata(fileMetadata, false) var dbFile = dbManager!!.openFile("BRARTI0L") @@ -438,4 +439,6 @@ class DB2400OperationsOnFile { dbManager!!.closeFile("BRARTI0L") } + } + diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400OperationsOnFilePerfTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400OperationsOnFilePerfTest.kt index 13c2861..6bbe4fc 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400OperationsOnFilePerfTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400OperationsOnFilePerfTest.kt @@ -22,18 +22,21 @@ import com.smeup.dbnative.file.Record import com.smeup.dbnative.file.RecordField import com.smeup.dbnative.metadata.file.PropertiesSerializer import com.smeup.dbnative.sql.utils.* +import org.junit.AfterClass +import org.junit.BeforeClass import org.junit.Ignore import org.junit.Test import kotlin.test.assertEquals import kotlin.test.assertFalse +import kotlin.test.assertTrue + class DB2400OperationsOnFilePerfTest { + + private var dbManager: SQLDBMManager? = null - fun initDbManager( - host: String = DB2_400_HOST, - library: String = DB2_400_LIBRARY_NAME, - ) { + fun initDbManager(host: String = DB2_400_HOST, library: String = DB2_400_LIBRARY_NAME) { dbManager = dbManagerDB2400ForTest(host, library) } @@ -45,15 +48,12 @@ class DB2400OperationsOnFilePerfTest { PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "VERAPG0L") it!!.registerMetadata(fileMetadata, false) val dbFile = it!!.openFile("VERAPG0L") - for (i in 1..10) { - var record = - Record( - RecordField("V£IDOJ", "A3L00000X1"), - RecordField("V£DATA", "20210117"), - RecordField("V£NOME", "BUSFIO2 "), - RecordField("V£CDC", "SMEGL.001 "), - RecordField("V£COD1", "ERB "), - ) + for(i in 1..10) { + var record = Record(RecordField("V£IDOJ", "A3L00000X1"), + RecordField("V£DATA", "20210117"), + RecordField("V£NOME", "BUSFIO2 "), + RecordField("V£CDC", "SMEGL.001 "), + RecordField("V£COD1", "ERB ")) dbFile.write(record) record = dbFile.chain(arrayListOf("A3L00000X1")).record if (!dbFile.eof()) { @@ -93,14 +93,11 @@ class DB2400OperationsOnFilePerfTest { var record = dbFile.chain(arrayListOf("A3L0000001")).record if (dbFile.eof()) { - record = - Record( - RecordField("V£IDOJ", "A3L0000001"), - RecordField("V£DATA", "20210117"), - RecordField("V£NOME", "BUSFIO "), - RecordField("V£CDC", "SMEGL.001 "), - RecordField("V£COD1", "ERB "), - ) + record = Record(RecordField("V£IDOJ", "A3L0000001"), + RecordField("V£DATA", "20210117"), + RecordField("V£NOME", "BUSFIO "), + RecordField("V£CDC", "SMEGL.001 "), + RecordField("V£COD1", "ERB ")) dbFile.write(record) record = dbFile.chain(arrayListOf("A3L0000001")).record assertFalse { dbFile.eof() } @@ -113,6 +110,7 @@ class DB2400OperationsOnFilePerfTest { record = dbFile.chain(arrayListOf("A3L0000001")).record assertEquals(record["V£ATV0"], "2") dbFile.delete(record) + } } @@ -157,11 +155,11 @@ class DB2400OperationsOnFilePerfTest { } } - private fun doChain( - keys: List, - dbFile: DBFile, - ) { + private fun doChain(keys: List, dbFile: DBFile){ val chainResult = dbFile.chain(keys) assertEquals(keys[0], chainResult.record["A§ARTI"]?.trim()) } + + } + diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/JDBCUtilsTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/JDBCUtilsTest.kt index 6d2e022..e6b3ca3 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/JDBCUtilsTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/JDBCUtilsTest.kt @@ -25,6 +25,7 @@ import org.junit.Test import kotlin.test.assertEquals class JDBCUtilsTest { + private lateinit var dbManager: SQLDBMManager @Before @@ -36,9 +37,7 @@ class JDBCUtilsTest { fun primaryKeysTest() { dbManager.connection.use { it.createStatement() - .execute( - "CREATE TABLE TSTTAB00 (TSTFLDCHR CHAR (5) NOT NULL, TSTFLDNBR DECIMAL (7, 2) NOT NULL, TSTFLDNB2 DECIMAL (2, 0) NOT NULL, PRIMARY KEY(TSTFLDCHR, TSTFLDNBR))", - ) + .execute("CREATE TABLE TSTTAB00 (TSTFLDCHR CHAR (5) NOT NULL, TSTFLDNBR DECIMAL (7, 2) NOT NULL, TSTFLDNB2 DECIMAL (2, 0) NOT NULL, PRIMARY KEY(TSTFLDCHR, TSTFLDNBR))") assertEquals(listOf("TSTFLDCHR", "TSTFLDNBR"), it.primaryKeys("TSTTAB00")) } } @@ -47,9 +46,7 @@ class JDBCUtilsTest { fun orderingFieldsTest() { dbManager.connection.use { it.createStatement() - .execute( - "CREATE TABLE TSTTAB00 (TSTFLDCHR CHAR (5) NOT NULL, TSTFLDNBR DECIMAL (7, 2) NOT NULL, TSTFLDNB2 DECIMAL (2, 0) NOT NULL, PRIMARY KEY(TSTFLDCHR, TSTFLDNBR))", - ) + .execute("CREATE TABLE TSTTAB00 (TSTFLDCHR CHAR (5) NOT NULL, TSTFLDNBR DECIMAL (7, 2) NOT NULL, TSTFLDNB2 DECIMAL (2, 0) NOT NULL, PRIMARY KEY(TSTFLDCHR, TSTFLDNBR))") it.createStatement().execute("CREATE VIEW TSTVIEW AS SELECT * FROM TSTTAB00 ORDER BY TSTFLDNB2, TSTFLDNBR") it.createStatement() .execute("CREATE INDEX TSTVIEW$CONVENTIONAL_INDEX_SUFFIX ON TSTTAB00 (TSTFLDNB2, TSTFLDNBR)") @@ -61,4 +58,4 @@ class JDBCUtilsTest { fun tearDownEach() { destroyDatabase() } -} +} \ No newline at end of file diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLChain1KeyTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLChain1KeyTest.kt index 7229cd4..1fb9bcd 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLChain1KeyTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLChain1KeyTest.kt @@ -28,7 +28,9 @@ import kotlin.test.assertEquals import kotlin.test.assertTrue class SQLChain1KeyTest { + companion object { + private var dbManager: SQLDBMManager? = null private var libName: String? = null @@ -61,4 +63,6 @@ class SQLChain1KeyTest { assertTrue(dbFile.chain("XYZ").record.isEmpty()) dbManager!!.closeFile(TSTTAB_TABLE_NAME) } + } + diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLChain2KeysTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLChain2KeysTest.kt index 6daae14..bcbeaf9 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLChain2KeysTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLChain2KeysTest.kt @@ -28,9 +28,12 @@ import kotlin.test.assertEquals import kotlin.test.assertTrue class SQLChain2KeysTest { + companion object { + private lateinit var dbManager: SQLDBMManager + @BeforeClass @JvmStatic fun setUp() { @@ -48,11 +51,10 @@ class SQLChain2KeysTest { @Test fun findRecordsIfChainWithExistingKey() { val dbFile = dbManager.openFile(TST2TAB_TABLE_NAME) - val key2 = - listOf( - "ABC", - "12.00", - ) + val key2 = listOf( + "ABC", + "12.00" + ) val chainResult = dbFile.chain(key2) assertEquals("ABC", chainResult.record["TSTFLDCHR"]) assertEquals("12.00", chainResult.record["TSTFLDNBR"]) @@ -63,12 +65,14 @@ class SQLChain2KeysTest { @Test fun doesNotFindRecordsIfChainWithNotExistingKey() { val dbFile = dbManager.openFile(TST2TAB_TABLE_NAME) - val key2 = - listOf( - "ZZZ", - "12", - ) + val key2 = listOf( + "ZZZ", + "12" + ) assertTrue(dbFile.chain(key2).record.isEmpty()) dbManager.closeFile(TST2TAB_TABLE_NAME) } + + } + diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLMunicipalityPerfTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLMunicipalityPerfTest.kt index 1ad5b89..be563c1 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLMunicipalityPerfTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLMunicipalityPerfTest.kt @@ -27,8 +27,11 @@ import kotlin.test.assertEquals import kotlin.test.assertFails import kotlin.test.assertTrue + class SQLMunicipalityPerfTest { + companion object { + private lateinit var dbManager: SQLDBMManager @BeforeClass @@ -49,11 +52,11 @@ class SQLMunicipalityPerfTest { fun read() { val dbFile = dbManager.openFile(MUNICIPALITY_TABLE_NAME) assertTrue(dbFile.setll(buildMunicipalityKey("IT", "LOM", "BS", "ERBUSCO"))) - for (index in 0..138) { - var result = dbFile.read() - assertTrue { !dbFile.eof() } - if (index == 138) { - assertEquals("CO", getMunicipalityProv(result.record)) + for(index in 0..138){ + var result = dbFile.read(); + assertTrue{!dbFile.eof()} + if(index == 138) { + assertEquals("CO" , getMunicipalityProv(result.record)) } } dbManager.closeFile(MUNICIPALITY_TABLE_NAME) @@ -157,7 +160,7 @@ class SQLMunicipalityPerfTest { recordFields.add(RecordField("PREF", "1234")) recordFields.add(RecordField("COMUNE", "A99")) recordFields.add(RecordField("ISTAT", "999999")) - dbFile.write(Record(*recordFields.toTypedArray())) + dbFile.write(Record(*recordFields.toTypedArray())); // Read new record for control var chainResult = dbFile.chain(buildMunicipalityKey("IT", "LOM", "BG", "TOPOLINIA")) @@ -213,7 +216,7 @@ class SQLMunicipalityPerfTest { recordFields.add(RecordField("PREF", "4321")) recordFields.add(RecordField("COMUNE", "A99")) recordFields.add(RecordField("ISTAT", "999999")) - dbFile.write(Record(*recordFields.toTypedArray())) + dbFile.write(Record(*recordFields.toTypedArray())); // Read new record dbFile.setll(buildMunicipalityKey("IT", "LOM", "BG", "PAPEROPOLI")) @@ -221,7 +224,7 @@ class SQLMunicipalityPerfTest { assertEquals("PAPEROPOLI", getMunicipalityName(readResult.record)) // Delete added record - var chainResult = dbFile.chain(buildMunicipalityKey("IT", "LOM", "BG", "PAPEROPOLI")) + var chainResult= dbFile.chain(buildMunicipalityKey("IT", "LOM", "BG", "PAPEROPOLI")) dbFile.delete(chainResult.record) chainResult = dbFile.chain(buildMunicipalityKey("IT", "LOM", "BG", "PAPEROPOLI")) assertTrue(dbFile.eof()) @@ -243,7 +246,7 @@ class SQLMunicipalityPerfTest { fun usupportedUncoherentKeys() { val dbFile = dbManager.openFile(MUNICIPALITY_TABLE_NAME) dbFile.setll(buildMunicipalityKey("IT", "LOM", "BS", "ZONE")) - assertFails { dbFile.readEqual(buildMunicipalityKey("IT", "LOM", "CO")) } + assertFails {dbFile.readEqual(buildMunicipalityKey("IT", "LOM", "CO"))} dbManager.closeFile(MUNICIPALITY_TABLE_NAME) } @@ -252,14 +255,14 @@ class SQLMunicipalityPerfTest { val dbFile = dbManager.openFile(MUNICIPALITY_TABLE_NAME) dbFile.setll(buildMunicipalityKey("IT", "LOM", "BS", "ZONE")) dbFile.readEqual(buildMunicipalityKey("IT", "LOM", "BS")) - assertFails { dbFile.read() } + assertFails {dbFile.read()} dbManager.closeFile(MUNICIPALITY_TABLE_NAME) } @Test fun usupportedUnpositioning() { val dbFile = dbManager.openFile(MUNICIPALITY_TABLE_NAME) - assertFails { dbFile.readEqual(buildMunicipalityKey("IT", "LOM", "BS")) } + assertFails {dbFile.readEqual(buildMunicipalityKey("IT", "LOM", "BS"))} dbManager.closeFile(MUNICIPALITY_TABLE_NAME) } @@ -268,7 +271,7 @@ class SQLMunicipalityPerfTest { val dbFile = dbManager.openFile(MUNICIPALITY_TABLE_NAME) dbFile.setll(buildMunicipalityKey("IT", "LOM", "BS", "ZONE")) dbFile.readEqual(buildMunicipalityKey("IT", "LOM", "BS")) - assertFails { dbFile.readPrevious() } + assertFails {dbFile.readPrevious()} dbManager.closeFile(MUNICIPALITY_TABLE_NAME) } @@ -280,3 +283,4 @@ class SQLMunicipalityPerfTest { usupportedReadChangeDirection() } } + diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLMunicipalityTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLMunicipalityTest.kt index 88c42c9..9e99211 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLMunicipalityTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLMunicipalityTest.kt @@ -25,8 +25,11 @@ import org.junit.Test import kotlin.test.assertEquals import kotlin.test.assertTrue + class SQLMunicipalityTest { + companion object { + private lateinit var dbManager: SQLDBMManager @BeforeClass @@ -79,11 +82,11 @@ class SQLMunicipalityTest { assertTrue(dbFile.setll(buildMunicipalityKey("IT", "LOM", "BS", "ERBUSCO"))) assertEquals( "EDOLO", - getMunicipalityName(dbFile.readPreviousEqual(buildMunicipalityKey("IT", "LOM", "BS")).record), + getMunicipalityName(dbFile.readPreviousEqual(buildMunicipalityKey("IT", "LOM", "BS")).record) ) assertEquals( "DESENZANO DEL GARDA", - getMunicipalityName(dbFile.readPreviousEqual(buildMunicipalityKey("IT", "LOM", "BS")).record), + getMunicipalityName(dbFile.readPreviousEqual(buildMunicipalityKey("IT", "LOM", "BS")).record) ) dbManager.closeFile(MUNICIPALITY_TABLE_NAME) } @@ -412,4 +415,7 @@ class SQLMunicipalityTest { assertEquals(32, count) dbManager.closeFile(MUNICIPALITY_TABLE_NAME) } + + } + diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadEqualTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadEqualTest.kt index 4d32ea9..52ce186 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadEqualTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadEqualTest.kt @@ -26,9 +26,11 @@ import kotlin.test.assertFailsWith import kotlin.test.assertTrue class SQLReadEqualTest { + companion object { - private lateinit var dbManager: SQLDBMManager + private lateinit var dbManager: SQLDBMManager + @BeforeClass @JvmStatic fun setUp() { @@ -65,7 +67,7 @@ class SQLReadEqualTest { @Test fun findRecordsIfChainAndReadEExistingKey() { val dbFile = dbManager.openFile(XEMP2_VIEW_NAME) - val chainResult = dbFile.chain("C01") + val chainResult = dbFile.chain( "C01") assertEquals("SALLY KWAN", getEmployeeName(chainResult.record)) assertEquals("DELORES QUINTANA", getEmployeeName(dbFile.readEqual().record)) assertEquals("HEATHER NICHOLLS", getEmployeeName(dbFile.readEqual().record)) @@ -77,8 +79,8 @@ class SQLReadEqualTest { @Test fun readUntilEof() { val dbFile = dbManager.openFile(XEMP2_VIEW_NAME) - val chainResult = dbFile.chain("C01") - var readed = 0 + val chainResult = dbFile.chain( "C01") + var readed = 0; while (dbFile.eof() == false) { var readResult = dbFile.readEqual("C01") readed++ @@ -90,11 +92,12 @@ class SQLReadEqualTest { @Test fun equals() { val dbFile = dbManager.openFile(XEMP2_VIEW_NAME) - val chainResult = dbFile.setll("C01") - assertTrue(dbFile.equal()) + val chainResult = dbFile.setll( "C01") + assertTrue (dbFile.equal()) dbManager.closeFile(XEMP2_VIEW_NAME) } + @Test fun findRecordsIfReadEWithKeyExistingKey() { val dbFile = dbManager.openFile(XEMP2_VIEW_NAME) @@ -125,4 +128,6 @@ class SQLReadEqualTest { assertEquals(0, dbFile.readEqual("C01").record.size) dbManager.closeFile(XEMP2_VIEW_NAME) } + } + diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadPreviousTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadPreviousTest.kt index a5a4a5d..fca6e4c 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadPreviousTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadPreviousTest.kt @@ -25,9 +25,11 @@ import kotlin.test.assertEquals import kotlin.test.assertTrue class SQLReadPreviousTest { + companion object { - private lateinit var dbManager: SQLDBMManager + private lateinit var dbManager: SQLDBMManager + @BeforeClass @JvmStatic fun setUp() { @@ -60,4 +62,5 @@ class SQLReadPreviousTest { assertEquals("MICHELLE SPRINGER", getEmployeeName(dbFile.readPrevious().record)) dbManager.closeFile(EMPLOYEE_TABLE_NAME) } + } diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLUtilsTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLUtilsTest.kt index 20d26c5..98da867 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLUtilsTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLUtilsTest.kt @@ -28,54 +28,52 @@ import org.junit.Test import kotlin.test.assertEquals class SQLUtilsTest { + @Test fun sqlForCreateTableTestWithPrimaryKeys() { - val fileMetadata = - TypedMetadata( - "TSTTAB", - "TSTTAB", - listOf( - "TSTFLDCHR" fieldByType CharacterType(5), - "TSTFLDNBR" fieldByType DecimalType(7, 2), - "TSTFLDNB2" fieldByType DecimalType(2, 0), - ), - listOf( - "TSTFLDCHR", - "TSTFLDNBR", - ), + val fileMetadata = TypedMetadata( + "TSTTAB", + "TSTTAB", + listOf( + "TSTFLDCHR" fieldByType CharacterType(5), + "TSTFLDNBR" fieldByType DecimalType(7, 2), + "TSTFLDNB2" fieldByType DecimalType(2, 0) + ), + listOf( + "TSTFLDCHR", + "TSTFLDNBR" ) + ) assertEquals( "CREATE TABLE TSTTAB (TSTFLDCHR CHAR(5) DEFAULT '' NOT NULL, TSTFLDNBR DECIMAL(7,2) DEFAULT 0 NOT NULL, TSTFLDNB2 DECIMAL(2,0) DEFAULT 0 NOT NULL, PRIMARY KEY(TSTFLDCHR, TSTFLDNBR))", - fileMetadata.toSQL(), + fileMetadata.toSQL() ) } @Test fun sqlForCreateTableTestWithoutPrimaryKeys() { - val fileMetadata = - TypedMetadata( - "TSTTAB", - "TSTTAB", - listOf( - "TSTFLDCHR" fieldByType CharacterType(5), - "TSTFLDNBR" fieldByType DecimalType(7, 2), - "TSTFLDNB2" fieldByType DecimalType(2, 0), - ), - listOf(), - ) + val fileMetadata = TypedMetadata( + "TSTTAB", + "TSTTAB", + listOf( + "TSTFLDCHR" fieldByType CharacterType(5), + "TSTFLDNBR" fieldByType DecimalType(7, 2), + "TSTFLDNB2" fieldByType DecimalType(2, 0) + ), + listOf() + ) assertEquals( "CREATE TABLE TSTTAB (TSTFLDCHR CHAR(5) DEFAULT '' NOT NULL, TSTFLDNBR DECIMAL(7,2) DEFAULT 0 NOT NULL, TSTFLDNB2 DECIMAL(2,0) DEFAULT 0 NOT NULL)", - fileMetadata.toSQL(), + fileMetadata.toSQL() ) } @Test fun sqlForInsertTest() { - val record = - Record( - RecordField("TSTFLDCHR", "XXX"), - RecordField("TSTFLDNBR", "123.45"), - ) + val record = Record( + RecordField("TSTFLDCHR", "XXX"), + RecordField("TSTFLDNBR", "123.45") + ) assertEquals("INSERT INTO TSTTAB (TSTFLDCHR, TSTFLDNBR) VALUES(?, ?)", "TSTTAB".insertSQL(record)) } diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/utils/SQLDBTestUtils.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/utils/SQLDBTestUtils.kt index f0fd00f..e728a05 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/utils/SQLDBTestUtils.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/utils/SQLDBTestUtils.kt @@ -43,13 +43,11 @@ const val TST2TAB_TABLE_NAME = "TSTTAB" const val MUNICIPALITY_TABLE_NAME = "MUNICIPALITY" const val TEST_LOG = false private val LOGGING_LEVEL = LoggingLevel.ALL - -// do not change defaultValue -// if you want to create sqlconnection against another db use function: dbManagerForTest(testSQLDBType: TestSQLDBType) +//do not change defaultValue +//if you want to create sqlconnection against another db use function: dbManagerForTest(testSQLDBType: TestSQLDBType) private var defaultDbType = TestSQLDBType.HSQLDB - -// private var defaultDbType = TestSQLDBType.MY_SQL -// private var defaultDbType = TestSQLDBType.DB2_400 +//private var defaultDbType = TestSQLDBType.MY_SQL +//private var defaultDbType = TestSQLDBType.DB2_400 const val DATABASE_NAME = "TEST" const val DB2_400_HOST = "SRVLAB01.SMEUP.COM" const val DB2_400_LIBRARY_NAME = "W_PARFRA" @@ -57,85 +55,71 @@ const val DB2_400_LIBRARY_NAME = "W_PARFRA" enum class TestSQLDBType( val connectionConfig: ConnectionConfig, val dbaConnectionConfig: ConnectionConfig? = connectionConfig, - val createDatabase: (dbaConnection: Connection) -> Unit = {}, - val destroyDatabase: (dbaConnection: Connection) -> Unit = {}, -) { + val createDatabase : (dbaConnection: Connection) -> Unit = {}, + val destroyDatabase: (dbaConnection: Connection) -> Unit = {}) { MY_SQL( - connectionConfig = - ConnectionConfig( - fileName = "*", - url = "jdbc:mysql://localhost:3306/$DATABASE_NAME", - user = "root", - password = "root", - ), - dbaConnectionConfig = - ConnectionConfig( - fileName = "*", - url = "jdbc:mysql://localhost:3306/", - user = "root", - password = "root", - ), - createDatabase = { dbaConnection -> dbaConnection.prepareStatement("CREATE DATABASE $DATABASE_NAME").use { it.execute() } }, - destroyDatabase = { dbaConnection -> dbaConnection.prepareStatement("DROP DATABASE $DATABASE_NAME").use { it.execute() } }, + connectionConfig = ConnectionConfig( + fileName= "*", + url = "jdbc:mysql://localhost:3306/$DATABASE_NAME", + user = "root", + password = "root"), + dbaConnectionConfig = ConnectionConfig( + fileName= "*", + url = "jdbc:mysql://localhost:3306/", + user = "root", + password = "root"), + createDatabase = { dbaConnection -> dbaConnection.prepareStatement("CREATE DATABASE $DATABASE_NAME").use { it.execute() } }, + destroyDatabase = { dbaConnection -> dbaConnection.prepareStatement("DROP DATABASE $DATABASE_NAME").use { it.execute() } } ), - HSQLDB( - ConnectionConfig( - fileName = "*", - url = "jdbc:hsqldb:mem:$DATABASE_NAME", - user = "sa", - password = "root", - ), - destroyDatabase = { dbaConnection -> dbaConnection.prepareStatement("DROP SCHEMA PUBLIC CASCADE").use { it.execute() } }, + HSQLDB(ConnectionConfig( + fileName= "*", + url = "jdbc:hsqldb:mem:$DATABASE_NAME", + user = "sa", + password = "root"), + destroyDatabase = { dbaConnection -> dbaConnection.prepareStatement("DROP SCHEMA PUBLIC CASCADE").use { it.execute() } } ), - DB2_400( - ConnectionConfig( - fileName = "*", + DB2_400(ConnectionConfig( + fileName= "*", driver = "com.ibm.as400.access.AS400JDBCDriver", url = "jdbc:as400://$DB2_400_HOST/$DB2_400_LIBRARY_NAME;", user = "USER", - password = "**********", - ), - // force no create connection for dba operations - dbaConnectionConfig = null, - ), - DB2_400_DAT( - ConnectionConfig( - fileName = "*", - driver = "com.ibm.as400.access.AS400JDBCDriver", - url = "jdbc:as400://$DB2_400_HOST/SMEUP_DAT", - user = "USER", - password = "**********", - ), - // force no create connection for dba operations - dbaConnectionConfig = null, + password = "**********"), + + //force no create connection for dba operations + dbaConnectionConfig = null ), + DB2_400_DAT(ConnectionConfig( + fileName= "*", + driver = "com.ibm.as400.access.AS400JDBCDriver", + url = "jdbc:as400://$DB2_400_HOST/SMEUP_DAT", + user = "USER", + password = "**********"), + + //force no create connection for dba operations + dbaConnectionConfig = null + ) + } object DatabaseNameFactory { var COUNTER = AtomicInteger() } -fun dbManagerDB2400ForTest( - host: String, - library: String, -): SQLDBMManager { - val dbManager = - SQLDBMManager( - ConnectionConfig( - fileName = "*", - driver = "com.ibm.as400.access.AS400JDBCDriver", - url = "jdbc:as400://$host/$library;", - user = "USER", - password = "**********", - ), - ) +fun dbManagerDB2400ForTest(host: String, library:String): SQLDBMManager{ + val dbManager = SQLDBMManager(ConnectionConfig( + fileName= "*", + driver = "com.ibm.as400.access.AS400JDBCDriver", + url = "jdbc:as400://$host/$library;", + user = "USER", + password = "**********"), + ) dbManager.logger = Logger.getSimpleInstance(LOGGING_LEVEL) return dbManager } fun dbManagerForTest() = dbManagerForTest(defaultDbType) -fun dbManagerForTest(testSQLDBType: TestSQLDBType): SQLDBMManager { +fun dbManagerForTest(testSQLDBType: TestSQLDBType) : SQLDBMManager { testLog("Creating SQLDBManager with db type = $testSQLDBType") val dbManager = SQLDBMManager(testSQLDBType.connectionConfig) @@ -162,74 +146,68 @@ fun destroyDatabase(testSQLDBType: TestSQLDBType) { } fun createAndPopulateTstTable(dbManager: SQLDBMManager?) { - val fields = - listOf( - "TSTFLDCHR" fieldByType CharacterType(3), - "TSTFLDNBR" fieldByType DecimalType(5, 2), - ) + val fields = listOf( + "TSTFLDCHR" fieldByType CharacterType(3), + "TSTFLDNBR" fieldByType DecimalType(5, 2) + ) + + val keys = listOf( + "TSTFLDCHR" + ) - val keys = - listOf( - "TSTFLDCHR", - ) createAndPopulateTable(dbManager, TSTTAB_TABLE_NAME, TSTTAB_TABLE_NAME, fields, keys, "src/test/resources/csv/TstTab.csv") } fun createAndPopulateTst2Table(dbManager: SQLDBMManager?) { - val fields = - listOf( - "TSTFLDCHR" fieldByType VarcharType(3), - "TSTFLDNBR" fieldByType DecimalType(5, 2), - "DESTST" fieldByType VarcharType(40), - ) - - val keys = - listOf( - "TSTFLDCHR", - "TSTFLDNBR", - ) - - createAndPopulateTable(dbManager, TST2TAB_TABLE_NAME, TST2TAB_TABLE_NAME, fields, keys, "src/test/resources/csv/Tst2Tab.csv") + val fields = listOf( + "TSTFLDCHR" fieldByType VarcharType(3), + "TSTFLDNBR" fieldByType DecimalType(5, 2), + "DESTST" fieldByType VarcharType(40) + ) + + val keys = listOf( + "TSTFLDCHR", + "TSTFLDNBR" + ) + + createAndPopulateTable(dbManager, TST2TAB_TABLE_NAME, TST2TAB_TABLE_NAME, fields, keys,"src/test/resources/csv/Tst2Tab.csv") } fun createAndPopulateEmployeeTable(dbManager: SQLDBMManager?) { - val fields = - listOf( - "EMPNO" fieldByType CharacterType(6), - "FIRSTNME" fieldByType VarcharType(12), - "MIDINIT" fieldByType VarcharType(1), - "LASTNAME" fieldByType VarcharType(15), - "WORKDEPT" fieldByType CharacterType(3), - ) - - val keys = - listOf( - "EMPNO", - ) - - createAndPopulateTable(dbManager, EMPLOYEE_TABLE_NAME, EMPLOYEE_TABLE_NAME, fields, keys, "src/test/resources/csv/Employee.csv") + val fields = listOf( + "EMPNO" fieldByType CharacterType(6), + "FIRSTNME" fieldByType VarcharType(12), + "MIDINIT" fieldByType VarcharType(1), + "LASTNAME" fieldByType VarcharType(15), + "WORKDEPT" fieldByType CharacterType(3) + ) + + val keys = listOf( + "EMPNO" + ) + + createAndPopulateTable(dbManager, EMPLOYEE_TABLE_NAME, EMPLOYEE_TABLE_NAME, fields, keys,"src/test/resources/csv/Employee.csv") } fun createAndPopulateXemp2View(dbManager: SQLDBMManager?) { // create view executing sql -> TODO: insert a createView method in DBMManager and use it fun createXEMP2() = "CREATE VIEW $XEMP2_VIEW_NAME AS SELECT * FROM EMPLOYEE ORDER BY WORKDEPT, EMPNO" - fun createXEMP2Index() = "CREATE INDEX $XEMP2_VIEW_NAME$CONVENTIONAL_INDEX_SUFFIX ON EMPLOYEE (WORKDEPT ASC, EMPNO ASC)" + fun createXEMP2Index() = + "CREATE INDEX $XEMP2_VIEW_NAME$CONVENTIONAL_INDEX_SUFFIX ON EMPLOYEE (WORKDEPT ASC, EMPNO ASC)" - val fields = - listOf( - "EMPNO" fieldByType CharacterType(6), - "FIRSTNME" fieldByType VarcharType(12), - "MIDINIT" fieldByType VarcharType(1), - "LASTNAME" fieldByType VarcharType(15), - "WORKDEPT" fieldByType CharacterType(3), - ) + val fields = listOf( + "EMPNO" fieldByType CharacterType(6), + "FIRSTNME" fieldByType VarcharType(12), + "MIDINIT" fieldByType VarcharType(1), + "LASTNAME" fieldByType VarcharType(15), + "WORKDEPT" fieldByType CharacterType(3) + ) - val keys = - listOf( - "WORKDEPT", - ) + val keys = listOf( + "WORKDEPT" + ) val metadata = FileMetadata("$XEMP2_VIEW_NAME", "EMPLOYEE", fields.fieldList(), keys) dbManager!!.registerMetadata(metadata, true) @@ -237,25 +215,24 @@ fun createAndPopulateXemp2View(dbManager: SQLDBMManager?) { } fun createAndPopulateMunicipalityTable(dbManager: SQLDBMManager?) { - val fields = - listOf( - "NAZ" fieldByType CharacterType(2), - "REG" fieldByType CharacterType(3), - "PROV" fieldByType CharacterType(2), - "CITTA" fieldByType VarcharType(35), - "CAP" fieldByType CharacterType(5), - "PREF" fieldByType CharacterType(4), - "COMUNE" fieldByType CharacterType(4), - "ISTAT" fieldByType CharacterType(6), - ) - - val keys = - listOf( - "NAZ", - "REG", - "PROV", - "CITTA", - ) + val fields = listOf( + "NAZ" fieldByType CharacterType(2), + "REG" fieldByType CharacterType(3), + "PROV" fieldByType CharacterType(2), + "CITTA" fieldByType VarcharType(35), + "CAP" fieldByType CharacterType(5), + "PREF" fieldByType CharacterType(4), + "COMUNE" fieldByType CharacterType(4), + "ISTAT" fieldByType CharacterType(6) + ) + + val keys = listOf( + "NAZ", + "REG", + "PROV", + "CITTA" + ) + createAndPopulateTable( dbManager, @@ -263,7 +240,7 @@ fun createAndPopulateMunicipalityTable(dbManager: SQLDBMManager?) { MUNICIPALITY_TABLE_NAME, fields, keys, - "src/test/resources/csv/Municipality.csv", + "src/test/resources/csv/Municipality.csv" ) } @@ -291,8 +268,9 @@ private fun createAndPopulateTable( tableName: String, fields: List, keys: List, - dataFilePath: String, + dataFilePath: String ) { + val tMetadata = TypedMetadata(name, tableName, fields, keys) createFile(tMetadata, dbManager!!) Assert.assertTrue(dbManager.existFile(tableName)) @@ -316,18 +294,15 @@ fun buildMunicipalityKey(vararg values: String): List { val keyValues = mutableListOf() val keys = arrayOf("NAZ", "REG", "PROV", "CITTA") for ((index, value) in values.withIndex()) { - if (keys.size > index) { + if (keys.size> index) { keyValues.add(value) } } return keyValues } -fun createFile( - tMetadata: TypedMetadata, - dbManager: SQLDBMManager, -) { - val metadata: FileMetadata = tMetadata.fileMetadata() +fun createFile(tMetadata: TypedMetadata, dbManager: SQLDBMManager) { + val metadata: FileMetadata = tMetadata.fileMetadata(); dbManager.connection.createStatement().use { it.execute(tMetadata.toSQL()) } @@ -336,6 +311,7 @@ fun createFile( fun TypedMetadata.toSQL(): String = "CREATE TABLE ${this.tableName} (${this.fields.toSQL(this)})" + fun Collection.toSQL(tMetadata: TypedMetadata): String { val primaryKeys = tMetadata.fileKeys.joinToString { it } @@ -368,16 +344,14 @@ fun sql2Type(metadataResultSet: ResultSet): FieldType { return sql2Type(sqlType, columnSize, decimalDigits) } + + /** * Convert SQL type in FieldType */ -fun sql2Type( - sqlType: String, - columnSize: Int, - decimalDigits: Int, -): FieldType = +fun sql2Type(sqlType: String, columnSize: Int, decimalDigits: Int): FieldType = when (sqlType) { - "CHAR", "CHARACTER", "NCHAR" -> CharacterType(columnSize) + "CHAR","CHARACTER","NCHAR" -> CharacterType(columnSize) "VARCHAR" -> VarcharType(columnSize) "INT", "INTEGER" -> IntegerType "SMALLINT" -> SmallintType @@ -392,4 +366,4 @@ fun sql2Type( "BINARY" -> BinaryType(columnSize) "VARBINARY" -> VarbinaryType(columnSize) else -> TODO("Conversion from SQL Type not yet implemented: $sqlType") - } + } \ No newline at end of file From 6887e184755a42982a49ea6935a4e681c69e4785 Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Wed, 13 Dec 2023 12:35:25 +0100 Subject: [PATCH 22/35] Patch and test refactoring - Patch for eof - Patch for read, reade and chain - Refactoring of test classes --- .../com/smeup/dbnative/DBManagerBaseImpl.kt | 3 +- .../smeup/dbnative/sql/Native2SQLAdapter.kt | 152 ++++++++++++++---- .../com/smeup/dbnative/sql/SQLDBFile.kt | 73 +++++++-- ...onsOnFilePerfTest.kt => DB2400PerfTest.kt} | 15 +- ...B2400OperationsOnFile.kt => DB2400Test.kt} | 3 +- .../smeup/dbnative/sql/SQLChain2KeysTest.kt | 78 --------- .../com/smeup/dbnative/sql/SQLChainTest.kt | 107 ++++++++++++ .../{SQLChain1KeyTest.kt => SQLEqualsTest.kt} | 38 ++--- .../dbnative/sql/SQLMunicipalityPerfTest.kt | 3 +- .../smeup/dbnative/sql/SQLMunicipalityTest.kt | 3 +- .../smeup/dbnative/sql/SQLReadEqualTest.kt | 78 ++++++--- .../smeup/dbnative/sql/SQLReadPreviousTest.kt | 17 +- .../com/smeup/dbnative/sql/SQLReadTest.kt | 104 ++++++++++++ .../sql/SQLUnsupportedFeaturesTest.kt | 82 ++++++++++ .../com/smeup/dbnative/sql/SQLUpdateTest.kt | 73 +++++++++ .../com/smeup/dbnative/sql/SQLUtilsTest.kt | 6 +- .../smeup/dbnative/sql/SQLWriteDeleteTest.kt | 121 ++++++++++++++ .../dbnative/sql/utils/SQLDBTestUtils.kt | 88 +++++----- sql/src/test/resources/csv/Tst2Tab.csv | 4 - sql/src/test/resources/csv/TstTab.csv | 2 - 20 files changed, 805 insertions(+), 245 deletions(-) rename sql/src/test/kotlin/com/smeup/dbnative/sql/{DB2400OperationsOnFilePerfTest.kt => DB2400PerfTest.kt} (93%) rename sql/src/test/kotlin/com/smeup/dbnative/sql/{DB2400OperationsOnFile.kt => DB2400Test.kt} (99%) delete mode 100644 sql/src/test/kotlin/com/smeup/dbnative/sql/SQLChain2KeysTest.kt create mode 100644 sql/src/test/kotlin/com/smeup/dbnative/sql/SQLChainTest.kt rename sql/src/test/kotlin/com/smeup/dbnative/sql/{SQLChain1KeyTest.kt => SQLEqualsTest.kt} (51%) create mode 100644 sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadTest.kt create mode 100644 sql/src/test/kotlin/com/smeup/dbnative/sql/SQLUnsupportedFeaturesTest.kt create mode 100644 sql/src/test/kotlin/com/smeup/dbnative/sql/SQLUpdateTest.kt create mode 100644 sql/src/test/kotlin/com/smeup/dbnative/sql/SQLWriteDeleteTest.kt delete mode 100644 sql/src/test/resources/csv/Tst2Tab.csv delete mode 100644 sql/src/test/resources/csv/TstTab.csv diff --git a/base/src/main/kotlin/com/smeup/dbnative/DBManagerBaseImpl.kt b/base/src/main/kotlin/com/smeup/dbnative/DBManagerBaseImpl.kt index 395d642..25728a9 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/DBManagerBaseImpl.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/DBManagerBaseImpl.kt @@ -22,6 +22,7 @@ import com.smeup.dbnative.log.Logger import com.smeup.dbnative.metadata.MetadataRegister import com.smeup.dbnative.metadata.file.FSMetadataRegisterImpl import com.smeup.dbnative.model.FileMetadata +import java.util.* abstract class DBManagerBaseImpl : DBMManager { var logger: Logger? = null @@ -54,7 +55,7 @@ abstract class DBManagerBaseImpl : DBMManager { } override fun existFile(name: String): Boolean { - return getMetadataRegister().contains(name.toUpperCase()) + return getMetadataRegister().contains(name.uppercase(Locale.getDefault())) } companion object { diff --git a/sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt b/sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt index 1254fe5..4b07971 100644 --- a/sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt +++ b/sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt @@ -36,8 +36,8 @@ class ReadInstruction(var method: ReadMethod, var keys: List){ } class Native2SQL(val fileMetadata: FileMetadata) { - private var lastPositioningInstruction: PositioningInstruction? = null private var lastReadInstruction: ReadInstruction? = null + private var lastPositioningInstruction: PositioningInstruction? = null private fun checkPositioning(){ requireNotNull(lastPositioningInstruction){ @@ -68,7 +68,7 @@ class Native2SQL(val fileMetadata: FileMetadata) { } private fun checkInstructions(){ - checkPositioning() + //checkPositioning() checkRead() } @@ -92,7 +92,7 @@ class Native2SQL(val fileMetadata: FileMetadata) { "Uncoherent read not yet managed" } } - ReadMethod.READ, ReadMethod.READP -> checkPositioning() + ReadMethod.READP -> checkPositioning() ReadMethod.CHAIN -> { lastPositioningInstruction = null executeQuery = true @@ -118,9 +118,11 @@ class Native2SQL(val fileMetadata: FileMetadata) { fun isLastOperationSet()=lastReadInstruction == null fun lastReadMatchRecord(record: Record): Boolean { + if(lastReadInstruction!!.keys.isEmpty()){ return true } + lastReadInstruction!!.keys.mapIndexed { index, value -> val keyname = fileMetadata.fileKeys.get(index) if(record[keyname]?.trim() != value.trim()){ @@ -132,21 +134,22 @@ class Native2SQL(val fileMetadata: FileMetadata) { fun isCoherent(newKeys: List): Boolean{ - checkPositioning() - return newKeys.isEmpty() || - if (newKeys.size <= lastPositioningInstruction!!.keys.size && - newKeys.size <= lastReadInstruction?.keys?.size?:newKeys.size) { - newKeys.forEachIndexed() { index, value -> - if(lastPositioningInstruction!!.keys.get(index) != value){ - return false - } - } - return true - } - else false + //checkPositioning() + if (lastPositioningInstruction != null) { + return newKeys.isEmpty() || + if (newKeys.size <= lastPositioningInstruction!!.keys.size && + newKeys.size <= lastReadInstruction?.keys?.size ?: newKeys.size + ) { + newKeys.forEachIndexed() { index, value -> + if (lastPositioningInstruction!!.keys.get(index) != value) { + return false + } + } + return true + } else false + } else return true } - private fun getSortOrder(): SortOrder { checkInstructions() return if(lastReadInstruction!!.method.forward) SortOrder.ASCEDING else SortOrder.DESCENDING @@ -154,9 +157,11 @@ class Native2SQL(val fileMetadata: FileMetadata) { private fun getComparison(): Pair{ checkInstructions() - return if(lastReadInstruction!!.method.forward){ + return if (lastPositioningInstruction == null) { + return Pair(Comparison.EQ, Comparison.GT) + } else if(lastReadInstruction!!.method.forward){ when(lastPositioningInstruction!!.method){ - PositioningMethod.SETLL -> return Pair(Comparison.GE, Comparison.GT) + PositioningMethod.SETLL -> return Pair(Comparison.EQ, Comparison.GT) PositioningMethod.SETGT -> return Pair(Comparison.GT, Comparison.GT) } } @@ -184,35 +189,118 @@ class Native2SQL(val fileMetadata: FileMetadata) { checkReadKeys() return Pair(getSQL(fileMetadata.fields, fileMetadata.fileKeys.subList(0, lastReadInstruction!!.keys.size), Comparison.EQ, fileMetadata.tableName), lastReadInstruction!!.keys) } - ReadMethod.READ,ReadMethod.READP -> { + ReadMethod.READ -> { + checkRead() + return getReadCoherentSql(true) + } + ReadMethod.READP -> { + checkPositioning() checkRead() return getCoherentSql(true) } else -> { + //checkPositioning() checkReadKeys() return getCoherentSql() } } } + /* + // Senza posizionamento + SELECT * FROM EMPLOF + + // Con posizionamento + SELECT * + FROM EMPL0F + WHERE WORKDEPT = 'C01' + UNION ALL + SELECT * + FROM EMPL0F + WHERE WORKDEPT >= 'C01' + */ + private fun getReadCoherentSql(fullUnion: Boolean = false): Pair> { + var queries = mutableListOf() + val replacements = mutableListOf() + if (lastPositioningInstruction == null) { + var columns = "" + fileMetadata.fields.forEachIndexed { index, k -> + run { + columns += "\"" + k.name + "\", " + } + } + return Pair("SELECT " + columns.removeSuffix(", ") + "FROM ${fileMetadata.tableName}", replacements) + } else { + var columns = "" + fileMetadata.fields.forEachIndexed { index, k -> + run { + columns += "\"" + k.name + "\", " + } + } + + var value = "" + val keys = fileMetadata.fileKeys + keys.forEachIndexed { index, k -> + run { + value += "\"" + k + "\" >= ? AND " + } + } + + queries.add( + "SELECT " + columns.removeSuffix(", ") + " FROM ${fileMetadata.tableName} WHERE " + value.removeSuffix( + " AND " + ) + ) + replacements.addAll(lastPositioningInstruction!!.keys) + return Pair(queries.joinToString(), replacements) + } + } private fun getCoherentSql(fullUnion: Boolean = false):Pair>{ - checkPositioning() val queries = mutableListOf() val replacements = mutableListOf() val comparison = getComparison() - require(!lastPositioningInstruction!!.keys.isEmpty()){ - "Empty positioning keys" - } - if(lastPositioningInstruction!!.keys.size == 1){ - queries.add(getSQL(fileMetadata.fields, fileMetadata.fileKeys.subList(0, 1), comparison.first, fileMetadata.tableName)) - replacements.addAll(lastPositioningInstruction!!.keys) - } - else { - val limit = if(fullUnion)1 else 2 - for (i in lastPositioningInstruction!!.keys.size downTo limit) { - queries.add(getSQL(fileMetadata.fields, fileMetadata.fileKeys.subList(0, i), if(i == lastPositioningInstruction!!.keys.size) comparison.first else comparison.second, fileMetadata.tableName)) - replacements.addAll(lastPositioningInstruction!!.keys.subList(0, i)) + + if (lastPositioningInstruction == null) { + var columns = "" + fileMetadata.fields.forEachIndexed { index, k -> + run { + columns += "\"" + k.name + "\", " + } + } + var value = "" + fileMetadata.fileKeys.forEachIndexed { index, k -> + run { + value += "\"" + k + "\" " + Comparison.EQ.symbol + " ? AND " + } + } + replacements.addAll(lastReadInstruction!!.keys) + + return Pair("SELECT " + columns.removeSuffix(", ") + "FROM ${fileMetadata.tableName} WHERE " + value.removeSuffix(" AND "), replacements) + } else { + if (lastPositioningInstruction!!.keys.size == 1) { + queries.add( + getSQL( + fileMetadata.fields, + fileMetadata.fileKeys.subList(0, 1), + comparison.first, + fileMetadata.tableName + ) + ) + replacements.addAll(lastPositioningInstruction!!.keys) + } else { + val limit = if (fullUnion) 1 else 2 + for (i in lastPositioningInstruction!!.keys.size downTo limit) { + queries.add( + getSQL( + fileMetadata.fields, + fileMetadata.fileKeys.subList(0, i), + if (i == lastPositioningInstruction!!.keys.size) comparison.first else comparison.second, + fileMetadata.tableName + ) + ) + replacements.addAll(lastPositioningInstruction!!.keys.subList(0, i)) + } } } return Pair(queries.joinToString(" UNION ") + getSQLOrderByClause(), replacements) diff --git a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFile.kt b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFile.kt index 45d48ae..1a63994 100644 --- a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFile.kt +++ b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFile.kt @@ -45,6 +45,8 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada private var lastNativeMethod: NativeMethod? = null + private var nextResult: Result? = null + //Search from: metadata, primary key, unique index, view ordering fields //private val thisFileKeys: List by lazy { // // TODO: think about a right way (local file maybe?) to retrieve keylist @@ -93,6 +95,7 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada } override fun chain(keys: List): Result { + nextResult = null lastNativeMethod = NativeMethod.chain logEvent(LoggingKey.native_access_method, "Executing chain on keys $keys") adapter.setRead(ReadMethod.CHAIN, keys) @@ -100,7 +103,7 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada measureTimeMillis { executeQuery(adapter.getSQLSatement()) - read = readNextFromResultSet() + read = readNextFromResultSet(false) }.apply { logEvent(LoggingKey.native_access_method, "chain executed", this) } @@ -116,7 +119,7 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada if (adapter.setRead(ReadMethod.READ) ) { executeQuery(adapter.getSQLSatement()) } - read = readNextFromResultSet() + read = readNextFromResultSet(true) }.apply { logEvent(LoggingKey.native_access_method, "read executed", this) } @@ -132,7 +135,7 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada if (adapter.setRead(ReadMethod.READP)) { executeQuery(adapter.getSQLSatement()) } - read = readNextFromResultSet() + read = readNextFromResultSet(true) }.apply { logEvent(LoggingKey.native_access_method, "readPrevious executed", this) } @@ -157,7 +160,7 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada if (adapter.setRead(ReadMethod.READE, keys)) { executeQuery(adapter.getSQLSatement()) } - read = readNextFromResultSet() + read = readNextFromResultSet(true) }.apply { logEvent(LoggingKey.native_access_method, "readEqual executed", this) } @@ -183,7 +186,7 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada if (adapter.setRead(ReadMethod.READPE, keys)) { executeQuery(adapter.getSQLSatement()) } - read = readNextFromResultSet() + read = readNextFromResultSet(true) }.apply { logEvent(LoggingKey.native_access_method, "readPreviousEqual executed", this) } @@ -208,7 +211,29 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada return Result(record) } + /* + override fun update(record: Record): Result { + lastNativeMethod = NativeMethod.update + logEvent(LoggingKey.native_access_method, "Executing write for record $record: with autocommit=${connection.autoCommit}") + measureTimeMillis { + // TODO: manage errors + val sql = fileMetadata.tableName.updateSQL(record) + connection.prepareStatement(sql).use { it -> + it.bind(record.values.map { it }) + it.execute() + } + }.apply { + logEvent(LoggingKey.native_access_method, "update executed", this) + } + lastNativeMethod = null + return Result(record) + } + */ + override fun update(record: Record): Result { + require(getResultSet() != null){ + "Positioning required before update " + } lastNativeMethod = NativeMethod.update logEvent(LoggingKey.native_access_method, "Executing update record $actualRecord to $record with autocommit=${connection.autoCommit}") measureTimeMillis { @@ -232,6 +257,7 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada return Result(record) } + override fun delete(record: Record): Result { lastNativeMethod = NativeMethod.delete logEvent(LoggingKey.native_access_method, "Executing delete for current record $actualRecord with autocommit=${connection.autoCommit}") @@ -273,19 +299,32 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada } - private fun readNextFromResultSet(): Result { - val result = Result(resultSet.toValues()) - if (!eof() && adapter.lastReadMatchRecord(result.record)) { - logEvent(LoggingKey.read_data, "Record read: ${result.record}") - actualRecord = result.record.duplicate() - eof = false - return result - } else { - eof = true - closeResultSet() - logEvent(LoggingKey.read_data, "No more record to read") - return Result() + private fun readNextFromResultSet(loadNext: Boolean): Result { + if (nextResult == null) nextResult = Result(resultSet.toValues()) + val result = nextResult + + var found:Boolean = false + while( !found && !eof) { + if (adapter.lastReadMatchRecord(result!!.record)) { + logEvent(LoggingKey.read_data, "Record read: ${result.record}") + actualRecord = result.record.duplicate() + eof = false + found = true + } + + if (loadNext) { + nextResult = Result(resultSet.toValues()); + + if (nextResult!!.record.isEmpty()) { + eof = true; + closeResultSet() + logEvent(LoggingKey.read_data, "No more record to read") + } + } else { + eof = true; + } } + return result!! } private fun closeResultSet(){ diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400OperationsOnFilePerfTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400PerfTest.kt similarity index 93% rename from sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400OperationsOnFilePerfTest.kt rename to sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400PerfTest.kt index 6bbe4fc..4ae2b5c 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400OperationsOnFilePerfTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400PerfTest.kt @@ -22,16 +22,13 @@ import com.smeup.dbnative.file.Record import com.smeup.dbnative.file.RecordField import com.smeup.dbnative.metadata.file.PropertiesSerializer import com.smeup.dbnative.sql.utils.* -import org.junit.AfterClass -import org.junit.BeforeClass import org.junit.Ignore import org.junit.Test import kotlin.test.assertEquals import kotlin.test.assertFalse -import kotlin.test.assertTrue -class DB2400OperationsOnFilePerfTest { +class DB2400PerfTest { private var dbManager: SQLDBMManager? = null @@ -42,7 +39,7 @@ class DB2400OperationsOnFilePerfTest { @Test fun insert() { - initDbManager(library = "UP_PRR") + initDbManager(library = DB2_400_LIBRARY_NAME) dbManager.use { val fileMetadata = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "VERAPG0L") @@ -66,7 +63,7 @@ class DB2400OperationsOnFilePerfTest { @Test fun delete() { - initDbManager(library = "UP_PRR") + initDbManager(library = DB2_400_LIBRARY_NAME) dbManager.use { val fileMetadata = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "VERAPG0L") @@ -84,7 +81,7 @@ class DB2400OperationsOnFilePerfTest { @Ignore @Test fun updateMethods() { - initDbManager(library = "UP_PRR") + initDbManager(library = DB2_400_LIBRARY_NAME) dbManager.use { val fileMetadata = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "VERAPG0L") @@ -116,7 +113,7 @@ class DB2400OperationsOnFilePerfTest { @Test fun setllReadeNoMatch() { - initDbManager(library = "XSMEDATGRU") + initDbManager(library = DB2_400_LIBRARY_NAME) dbManager.use { val fileMetadata = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "VERAPG9L") @@ -130,7 +127,7 @@ class DB2400OperationsOnFilePerfTest { @Test fun chain() { - initDbManager(library = "UP_PRR") + initDbManager(library = DB2_400_LIBRARY_NAME) dbManager.use { val fileMetadata = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "BRARTI0L") diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400OperationsOnFile.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400Test.kt similarity index 99% rename from sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400OperationsOnFile.kt rename to sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400Test.kt index 2001976..a49a050 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400OperationsOnFile.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400Test.kt @@ -32,7 +32,7 @@ import kotlin.test.assertEquals import kotlin.test.assertTrue //@Ignore -class DB2400OperationsOnFile { +class DB2400Test { companion object { @@ -439,6 +439,5 @@ class DB2400OperationsOnFile { dbManager!!.closeFile("BRARTI0L") } - } diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLChain2KeysTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLChain2KeysTest.kt deleted file mode 100644 index bcbeaf9..0000000 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLChain2KeysTest.kt +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2020 The Reload project Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package com.smeup.dbnative.sql - -import com.smeup.dbnative.sql.utils.TST2TAB_TABLE_NAME -import com.smeup.dbnative.sql.utils.createAndPopulateTst2Table -import com.smeup.dbnative.sql.utils.dbManagerForTest -import com.smeup.dbnative.sql.utils.destroyDatabase -import org.junit.AfterClass -import org.junit.BeforeClass -import org.junit.Test -import kotlin.test.assertEquals -import kotlin.test.assertTrue - -class SQLChain2KeysTest { - - companion object { - - private lateinit var dbManager: SQLDBMManager - - - @BeforeClass - @JvmStatic - fun setUp() { - dbManager = dbManagerForTest() - createAndPopulateTst2Table(dbManager) - } - - @AfterClass - @JvmStatic - fun tearDown() { - destroyDatabase() - } - } - - @Test - fun findRecordsIfChainWithExistingKey() { - val dbFile = dbManager.openFile(TST2TAB_TABLE_NAME) - val key2 = listOf( - "ABC", - "12.00" - ) - val chainResult = dbFile.chain(key2) - assertEquals("ABC", chainResult.record["TSTFLDCHR"]) - assertEquals("12.00", chainResult.record["TSTFLDNBR"]) - assertEquals("ABC12", chainResult.record["DESTST"]) - dbManager.closeFile(TST2TAB_TABLE_NAME) - } - - @Test - fun doesNotFindRecordsIfChainWithNotExistingKey() { - val dbFile = dbManager.openFile(TST2TAB_TABLE_NAME) - val key2 = listOf( - "ZZZ", - "12" - ) - assertTrue(dbFile.chain(key2).record.isEmpty()) - dbManager.closeFile(TST2TAB_TABLE_NAME) - } - - -} - diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLChainTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLChainTest.kt new file mode 100644 index 0000000..2bef33c --- /dev/null +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLChainTest.kt @@ -0,0 +1,107 @@ +/* + * Copyright 2023 The Reload project Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * + */ +package com.smeup.dbnative.sql + +import com.smeup.dbnative.sql.utils.* +import org.junit.AfterClass +import org.junit.BeforeClass +import org.junit.Test +import kotlin.test.assertEquals + +class SQLChainTest { + companion object { + + private lateinit var dbManager: SQLDBMManager + + @BeforeClass + @JvmStatic + fun setUp() { + dbManager = dbManagerForTest() + createAndPopulateMunicipalityTable(dbManager) + } + + @AfterClass + @JvmStatic + fun tearDown() { + destroyDatabase() + } + } + + @Test + fun chainNotExisting() { + val dbFile = SQLChainTest.dbManager.openFile(MUNICIPALITY_TABLE_NAME) + val chainResult1 = dbFile.chain(buildMunicipalityKey("IT", "LOM", "BS", "ERBASCO")) + assertEquals(0, chainResult1.record.size) + SQLChainTest.dbManager.closeFile(MUNICIPALITY_TABLE_NAME) + } + + @Test + fun chainWithReducedKeys() { + val dbFile = SQLChainTest.dbManager.openFile(MUNICIPALITY_TABLE_NAME) + var chainResult = dbFile.chain(buildCountryKey("IT", "LOM", "BS")) + assertEquals("ACQUAFREDDA", getMunicipalityName(chainResult.record)) + chainResult = dbFile.chain(buildCountryKey("IT", "LOM", "CO")) + assertEquals("ALBAVILLA", getMunicipalityName(chainResult.record)) + chainResult = dbFile.chain(buildRegionKey("IT", "LOM")) + assertEquals("ADRARA SAN MARTINO", getMunicipalityName(chainResult.record)) + chainResult = dbFile.chain(buildNationKey("IT")) + assertEquals("ACCIANO", getMunicipalityName(chainResult.record)) + SQLChainTest.dbManager.closeFile(MUNICIPALITY_TABLE_NAME) + } + + @Test + fun chainExisting1() { + val dbFile = SQLChainTest.dbManager.openFile(MUNICIPALITY_TABLE_NAME) + val chainResult2 = dbFile.chain(buildMunicipalityKey("IT", "LOM", "BS", "ERBUSCO")) + assertEquals("ERBUSCO", getMunicipalityName(chainResult2.record)) + SQLChainTest.dbManager.closeFile(MUNICIPALITY_TABLE_NAME) + } + + @Test + fun chainExisting2() { + val dbFile = SQLChainTest.dbManager.openFile(MUNICIPALITY_TABLE_NAME) + val chainResult2 = dbFile.chain(buildMunicipalityKey("IT", "LOM", "BS", "ROVATO")) + assertEquals("ROVATO", getMunicipalityName(chainResult2.record)) + SQLChainTest.dbManager.closeFile(MUNICIPALITY_TABLE_NAME) + } + + @Test + fun multipleChainExisting() { + val dbFile = SQLChainTest.dbManager.openFile(MUNICIPALITY_TABLE_NAME) + val chainResult = dbFile.chain(buildMunicipalityKey("IT", "LOM", "BS", "ERBUSCO")) + assertEquals("ERBUSCO", getMunicipalityName(chainResult.record)) + val chainResult2 = dbFile.chain(buildMunicipalityKey("IT", "LOM", "BS", "ROVATO")) + assertEquals("ROVATO", getMunicipalityName(chainResult2.record)) + SQLChainTest.dbManager.closeFile(MUNICIPALITY_TABLE_NAME) + } + + @Test + fun readAndChain() { + val dbFile = SQLChainTest.dbManager.openFile(MUNICIPALITY_TABLE_NAME) + + dbFile.setll(buildMunicipalityKey("IT", "LOM", "BS", "ERBUSCO")) + val readResult = dbFile.read() + assertEquals("ERBUSCO", getMunicipalityName(readResult.record)) + + // Chain to another record + var chainResult = dbFile.chain(buildMunicipalityKey("IT", "LOM", "BS", "ADRO")) + assertEquals("ADRO", getMunicipalityName(chainResult.record)) + SQLChainTest.dbManager.closeFile(MUNICIPALITY_TABLE_NAME) + } +} + diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLChain1KeyTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLEqualsTest.kt similarity index 51% rename from sql/src/test/kotlin/com/smeup/dbnative/sql/SQLChain1KeyTest.kt rename to sql/src/test/kotlin/com/smeup/dbnative/sql/SQLEqualsTest.kt index 1fb9bcd..c3f598f 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLChain1KeyTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLEqualsTest.kt @@ -17,28 +17,25 @@ package com.smeup.dbnative.sql -import com.smeup.dbnative.sql.utils.TSTTAB_TABLE_NAME -import com.smeup.dbnative.sql.utils.createAndPopulateTstTable -import com.smeup.dbnative.sql.utils.dbManagerForTest -import com.smeup.dbnative.sql.utils.destroyDatabase +import com.smeup.dbnative.sql.utils.* import org.junit.AfterClass import org.junit.BeforeClass import org.junit.Test -import kotlin.test.assertEquals import kotlin.test.assertTrue -class SQLChain1KeyTest { +class SQLEqualsTest { companion object { - private var dbManager: SQLDBMManager? = null - private var libName: String? = null - + private lateinit var dbManager: SQLDBMManager + @BeforeClass @JvmStatic fun setUp() { dbManager = dbManagerForTest() - createAndPopulateTstTable(dbManager) + createAndPopulateMunicipalityTable(dbManager) + createAndPopulateEmployeeTable(dbManager) + createAndPopulateEmployeeView(dbManager) } @AfterClass @@ -49,20 +46,19 @@ class SQLChain1KeyTest { } @Test - fun findRecordsIfChainWithExistingKey() { - val dbFile = dbManager!!.openFile(TSTTAB_TABLE_NAME) - val chainResult = dbFile.chain("XXX") - assertEquals("XXX", chainResult.record["TSTFLDCHR"]) - assertEquals("123.45", chainResult.record["TSTFLDNBR"]) - dbManager!!.closeFile(TSTTAB_TABLE_NAME) + fun equal() { + val dbFile = SQLEqualsTest.dbManager.openFile(MUNICIPALITY_TABLE_NAME) + dbFile.setll(buildMunicipalityKey("IT", "LOM", "BS", "ERBUSCO")) + assertTrue(dbFile.equal()) + SQLEqualsTest.dbManager.closeFile(MUNICIPALITY_TABLE_NAME) } @Test - fun doesNotFindRecordsIfChainWithNotExistingKey() { - val dbFile = dbManager!!.openFile(TSTTAB_TABLE_NAME) - assertTrue(dbFile.chain("XYZ").record.isEmpty()) - dbManager!!.closeFile(TSTTAB_TABLE_NAME) + fun notEqual() { + val dbFile = SQLEqualsTest.dbManager.openFile(MUNICIPALITY_TABLE_NAME) + dbFile.setll(buildMunicipalityKey("IT", "LOM", "BS", "ERBASCO")) + assertTrue(!dbFile.equal()) + SQLEqualsTest.dbManager.closeFile(MUNICIPALITY_TABLE_NAME) } - } diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLMunicipalityPerfTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLMunicipalityPerfTest.kt index be563c1..2e0463a 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLMunicipalityPerfTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLMunicipalityPerfTest.kt @@ -22,12 +22,13 @@ import com.smeup.dbnative.file.RecordField import com.smeup.dbnative.sql.utils.* import org.junit.AfterClass import org.junit.BeforeClass +import org.junit.FixMethodOrder import org.junit.Test +import org.junit.runners.MethodSorters import kotlin.test.assertEquals import kotlin.test.assertFails import kotlin.test.assertTrue - class SQLMunicipalityPerfTest { companion object { diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLMunicipalityTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLMunicipalityTest.kt index 9e99211..81e2c3b 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLMunicipalityTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLMunicipalityTest.kt @@ -25,9 +25,8 @@ import org.junit.Test import kotlin.test.assertEquals import kotlin.test.assertTrue - +@Ignore class SQLMunicipalityTest { - companion object { private lateinit var dbManager: SQLDBMManager diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadEqualTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadEqualTest.kt index 52ce186..bf845ee 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadEqualTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadEqualTest.kt @@ -35,8 +35,9 @@ class SQLReadEqualTest { @JvmStatic fun setUp() { dbManager = dbManagerForTest() + createAndPopulateMunicipalityTable(dbManager) createAndPopulateEmployeeTable(dbManager) - createAndPopulateXemp2View(dbManager) + createAndPopulateEmployeeView(dbManager) } @AfterClass @@ -48,86 +49,111 @@ class SQLReadEqualTest { @Test fun throwsExceptionIfImmediatelyReadE() { - val dbFile = dbManager.openFile(XEMP2_VIEW_NAME) - assertFailsWith(IllegalArgumentException::class) { + val dbFile = dbManager.openFile(EMPLOYEE_VIEW_NAME) + assertFailsWith(Exception::class) { dbFile.readEqual() } - dbManager.closeFile(XEMP2_VIEW_NAME) + dbManager.closeFile(EMPLOYEE_VIEW_NAME) } @Test fun doesNotFindRecordsIfChainAndReadENotExistingKey() { - val dbFile = dbManager.openFile(XEMP2_VIEW_NAME) - val chainResult = dbFile.chain("XXX") - assertEquals(0, chainResult.record.size) + val dbFile = dbManager.openFile(EMPLOYEE_VIEW_NAME) + val chainResult = dbFile.setll("XXX") assertEquals(0, dbFile.readEqual().record.size) - dbManager.closeFile(XEMP2_VIEW_NAME) + dbManager.closeFile(EMPLOYEE_VIEW_NAME) } @Test fun findRecordsIfChainAndReadEExistingKey() { - val dbFile = dbManager.openFile(XEMP2_VIEW_NAME) - val chainResult = dbFile.chain( "C01") - assertEquals("SALLY KWAN", getEmployeeName(chainResult.record)) - assertEquals("DELORES QUINTANA", getEmployeeName(dbFile.readEqual().record)) - assertEquals("HEATHER NICHOLLS", getEmployeeName(dbFile.readEqual().record)) - assertEquals("KIM NATZ", getEmployeeName(dbFile.readEqual().record)) + val dbFile = dbManager.openFile(EMPLOYEE_VIEW_NAME) + val setllResult = dbFile.setll( "C01") + assertEquals("SALLY KWAN", getEmployeeName(dbFile.readEqual("C01").record)) + assertEquals("DELORES QUINTANA", getEmployeeName(dbFile.readEqual("C01").record)) + assertEquals("HEATHER NICHOLLS", getEmployeeName(dbFile.readEqual("C01").record)) + assertEquals("KIM NATZ", getEmployeeName(dbFile.readEqual("C01").record)) assertEquals(0, dbFile.readEqual().record.size) - dbManager.closeFile(XEMP2_VIEW_NAME) + dbManager.closeFile(EMPLOYEE_VIEW_NAME) } @Test fun readUntilEof() { - val dbFile = dbManager.openFile(XEMP2_VIEW_NAME) - val chainResult = dbFile.chain( "C01") + val dbFile = dbManager.openFile(EMPLOYEE_VIEW_NAME) + val setllResult = dbFile.setll( "C01") var readed = 0; while (dbFile.eof() == false) { var readResult = dbFile.readEqual("C01") readed++ } assertEquals(4, readed) - dbManager.closeFile(XEMP2_VIEW_NAME) + dbManager.closeFile(EMPLOYEE_VIEW_NAME) } @Test fun equals() { - val dbFile = dbManager.openFile(XEMP2_VIEW_NAME) + val dbFile = dbManager.openFile(EMPLOYEE_VIEW_NAME) val chainResult = dbFile.setll( "C01") assertTrue (dbFile.equal()) - dbManager.closeFile(XEMP2_VIEW_NAME) + dbManager.closeFile(EMPLOYEE_VIEW_NAME) } @Test fun findRecordsIfReadEWithKeyExistingKey() { - val dbFile = dbManager.openFile(XEMP2_VIEW_NAME) + val dbFile = dbManager.openFile(EMPLOYEE_VIEW_NAME) assertEquals("CHRISTINE HAAS", getEmployeeName(dbFile.readEqual("A00").record)) assertEquals("VINCENZO LUCCHESSI", getEmployeeName(dbFile.readEqual("A00").record)) assertEquals("SEAN O'CONNELL", getEmployeeName(dbFile.readEqual("A00").record)) assertEquals("DIAN HEMMINGER", getEmployeeName(dbFile.readEqual("A00").record)) assertEquals("GREG ORLANDO", getEmployeeName(dbFile.readEqual("A00").record)) assertEquals(0, dbFile.readEqual().record.size) - dbManager.closeFile(XEMP2_VIEW_NAME) + dbManager.closeFile(EMPLOYEE_VIEW_NAME) } @Test fun doesNotFindRecordsIfReadEWithKeyNotExistingKey() { - val dbFile = dbManager.openFile(XEMP2_VIEW_NAME) + val dbFile = dbManager.openFile(EMPLOYEE_VIEW_NAME) assertEquals(0, dbFile.readEqual("XXX").record.size) - dbManager.closeFile(XEMP2_VIEW_NAME) + dbManager.closeFile(EMPLOYEE_VIEW_NAME) } @Test fun findRecordsIfSetllAndReadEWithKeyExistingKey() { - val dbFile = dbManager.openFile(XEMP2_VIEW_NAME) + val dbFile = dbManager.openFile(EMPLOYEE_VIEW_NAME) assertTrue(dbFile.setll("C01")) assertEquals("SALLY KWAN", getEmployeeName(dbFile.readEqual("C01").record)) assertEquals("DELORES QUINTANA", getEmployeeName(dbFile.readEqual("C01").record)) assertEquals("HEATHER NICHOLLS", getEmployeeName(dbFile.readEqual("C01").record)) assertEquals("KIM NATZ", getEmployeeName(dbFile.readEqual("C01").record)) assertEquals(0, dbFile.readEqual("C01").record.size) - dbManager.closeFile(XEMP2_VIEW_NAME) + dbManager.closeFile(EMPLOYEE_VIEW_NAME) + } + @Test + fun setgtReade() { + val dbFile = SQLReadEqualTest.dbManager.openFile(MUNICIPALITY_TABLE_NAME) + assertTrue(dbFile.setgt(buildMunicipalityKey("IT", "LOM", "BS"))) + assertEquals("ALBAVILLA", getMunicipalityName(dbFile.readEqual(buildMunicipalityKey("IT", "LOM")).record)) + SQLReadEqualTest.dbManager.closeFile(MUNICIPALITY_TABLE_NAME) } + @Test + fun eofAfterRead() { + val dbFile = SQLReadEqualTest.dbManager.openFile(MUNICIPALITY_TABLE_NAME) + assertTrue(dbFile.setll(buildMunicipalityKey("IT", "LOM", "BS", "ZONE"))) + assertEquals("ZONE", getMunicipalityName(dbFile.readEqual(buildMunicipalityKey("IT", "LOM", "BS")).record)) + var r = dbFile.readEqual(buildMunicipalityKey("IT", "LOM", "BS")) + assertTrue(dbFile.eof()) + r = dbFile.readEqual(buildMunicipalityKey("IT", "LOM", "BS")) + assertTrue(dbFile.eof()) + SQLReadEqualTest.dbManager.closeFile(MUNICIPALITY_TABLE_NAME) + } + + @Test + fun setllReadeNoMatch() { + val dbFile = SQLReadEqualTest.dbManager.openFile(MUNICIPALITY_TABLE_NAME) + assertTrue(dbFile.setll(buildMunicipalityKey("IT", "LOM", "BS", "ERBASCO"))) + dbFile.readEqual(buildMunicipalityKey("IT", "LOM", "BS", "ERBASCO")) + SQLReadEqualTest.dbManager.closeFile(MUNICIPALITY_TABLE_NAME) + } } diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadPreviousTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadPreviousTest.kt index fca6e4c..96a4395 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadPreviousTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadPreviousTest.kt @@ -34,6 +34,7 @@ class SQLReadPreviousTest { @JvmStatic fun setUp() { dbManager = dbManagerForTest() + createAndPopulateMunicipalityTable(dbManager) createAndPopulateEmployeeTable(dbManager) } @@ -46,21 +47,29 @@ class SQLReadPreviousTest { @Test fun findRecordsIfSetllFromLastRecord() { - val dbFile = dbManager.openFile(EMPLOYEE_TABLE_NAME) + val dbFile = SQLReadPreviousTest.dbManager.openFile(EMPLOYEE_TABLE_NAME) assertTrue(dbFile.setll("200340")) assertEquals("HELENA WONG", getEmployeeName(dbFile.readPrevious().record)) assertEquals("MICHELLE SPRINGER", getEmployeeName(dbFile.readPrevious().record)) - dbManager.closeFile(EMPLOYEE_TABLE_NAME) + SQLReadPreviousTest.dbManager.closeFile(EMPLOYEE_TABLE_NAME) } @Test fun findRecordsIfSetGtFromLastRecord() { - val dbFile = dbManager.openFile(EMPLOYEE_TABLE_NAME) + val dbFile = SQLReadPreviousTest.dbManager.openFile(EMPLOYEE_TABLE_NAME) assertTrue(dbFile.setgt("200340")) assertEquals("ROY ALONZO", getEmployeeName(dbFile.readPrevious().record)) assertEquals("HELENA WONG", getEmployeeName(dbFile.readPrevious().record)) assertEquals("MICHELLE SPRINGER", getEmployeeName(dbFile.readPrevious().record)) - dbManager.closeFile(EMPLOYEE_TABLE_NAME) + SQLReadPreviousTest.dbManager.closeFile(EMPLOYEE_TABLE_NAME) + } + + @Test + fun setllReadpe() { + val dbFile = SQLReadPreviousTest.dbManager.openFile(MUNICIPALITY_TABLE_NAME) + assertTrue(dbFile.setll(buildMunicipalityKey("IT", "LOM", "BS", "ERBUSCO"))) + assertEquals("EDOLO", getMunicipalityName(dbFile.readPreviousEqual(buildMunicipalityKey("IT", "LOM")).record)) + SQLReadPreviousTest.dbManager.closeFile(MUNICIPALITY_TABLE_NAME) } } diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadTest.kt new file mode 100644 index 0000000..a83e264 --- /dev/null +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadTest.kt @@ -0,0 +1,104 @@ +/* + * Copyright 2020 The Reload project Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package com.smeup.dbnative.sql + +import com.smeup.dbnative.sql.utils.* +import org.junit.AfterClass +import org.junit.BeforeClass +import org.junit.Test +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +class SQLReadTest { + + companion object { + + private lateinit var dbManager: SQLDBMManager + + @BeforeClass + @JvmStatic + fun setUp() { + dbManager = dbManagerForTest() + createAndPopulateMunicipalityTable(dbManager) + createAndPopulateEmployeeTable(dbManager) + createAndPopulateEmployeeView(dbManager) + } + + @AfterClass + @JvmStatic + fun tearDown() { + destroyDatabase() + } + } + + @Test + fun readUntilEof() { + val dbFile = dbManager.openFile(EMPLOYEE_VIEW_NAME) + var readed = 0; + while (dbFile.eof() == false) { + var readResult = dbFile.read() + readed++ + System.out.println("Lettura $readed: " + getEmployeeName(readResult.record)) + } + assertEquals(42, readed) + dbManager.closeFile(EMPLOYEE_VIEW_NAME) + } + + @Test + fun positioningAndReadUntilEof() { + val dbFile = dbManager.openFile(EMPLOYEE_VIEW_NAME) + var readed = 0; + val setllResult = dbFile.setll( "C01") + while (dbFile.eof() == false) { + var readResult = dbFile.read() + readed++ + System.out.println("Lettura $readed: " + getEmployeeName(readResult.record)) + } + assertEquals(36, readed) + dbManager.closeFile(EMPLOYEE_VIEW_NAME) + } + + @Test + fun positioningBlankAndReadUntilEof() { + val dbFile = dbManager.openFile(EMPLOYEE_VIEW_NAME) + var readed = 0; + val setllResult = dbFile.setll( "") + while (dbFile.eof() == false) { + var readResult = dbFile.read() + readed++ + System.out.println("Lettura $readed: " + getEmployeeName(readResult.record)) + } + assertEquals(42, readed) + dbManager.closeFile(EMPLOYEE_VIEW_NAME) + } + + @Test + fun multipleRead() { + val dbFile = SQLReadTest.dbManager.openFile(MUNICIPALITY_TABLE_NAME) + assertTrue(dbFile.setll(buildMunicipalityKey("IT", "LOM", "BS", "ERBUSCO"))) + for(index in 0..138){ + var result = dbFile.read(); + assertTrue{!dbFile.eof()} + if(index == 138) { + assertEquals("CO" , getMunicipalityProv(result.record)) + } + } + SQLReadTest.dbManager.closeFile(MUNICIPALITY_TABLE_NAME) + } +} + diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLUnsupportedFeaturesTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLUnsupportedFeaturesTest.kt new file mode 100644 index 0000000..739cf5d --- /dev/null +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLUnsupportedFeaturesTest.kt @@ -0,0 +1,82 @@ +/* + * Copyright 2020 The Reload project Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package com.smeup.dbnative.sql + +import com.smeup.dbnative.sql.utils.* +import org.junit.AfterClass +import org.junit.BeforeClass +import org.junit.Test +import kotlin.test.assertEquals +import kotlin.test.assertFails +import kotlin.test.assertFailsWith +import kotlin.test.assertTrue + +class SQLUnsupportedFeaturesTest { + + companion object { + + private lateinit var dbManager: SQLDBMManager + + @BeforeClass + @JvmStatic + fun setUp() { + dbManager = dbManagerForTest() + createAndPopulateMunicipalityTable(dbManager) + } + + @AfterClass + @JvmStatic + fun tearDown() { + destroyDatabase() + } + } + + @Test + fun usupportedUncoherentKeys() { + val dbFile = SQLUnsupportedFeaturesTest.dbManager.openFile(MUNICIPALITY_TABLE_NAME) + dbFile.setll(buildMunicipalityKey("IT", "LOM", "BS", "ZONE")) + assertFails {dbFile.readEqual(buildMunicipalityKey("IT", "LOM", "CO"))} + SQLUnsupportedFeaturesTest.dbManager.closeFile(MUNICIPALITY_TABLE_NAME) + } + + @Test + fun usupportedDifferentReadMethods() { + val dbFile = SQLUnsupportedFeaturesTest.dbManager.openFile(MUNICIPALITY_TABLE_NAME) + dbFile.setll(buildMunicipalityKey("IT", "LOM", "BS", "ZONE")) + dbFile.readEqual(buildMunicipalityKey("IT", "LOM", "BS")) + assertFails {dbFile.read()} + SQLUnsupportedFeaturesTest.dbManager.closeFile(MUNICIPALITY_TABLE_NAME) + } + + @Test + fun usupportedUnpositioning() { + val dbFile = SQLUnsupportedFeaturesTest.dbManager.openFile(MUNICIPALITY_TABLE_NAME) + assertFails {dbFile.readEqual(buildMunicipalityKey("IT", "LOM", "BS"))} + SQLUnsupportedFeaturesTest.dbManager.closeFile(MUNICIPALITY_TABLE_NAME) + } + + @Test + fun usupportedReadChangeDirection() { + val dbFile = SQLUnsupportedFeaturesTest.dbManager.openFile(MUNICIPALITY_TABLE_NAME) + dbFile.setll(buildMunicipalityKey("IT", "LOM", "BS", "ZONE")) + dbFile.readEqual(buildMunicipalityKey("IT", "LOM", "BS")) + assertFails {dbFile.readPrevious()} + SQLUnsupportedFeaturesTest.dbManager.closeFile(MUNICIPALITY_TABLE_NAME) + } +} + diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLUpdateTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLUpdateTest.kt new file mode 100644 index 0000000..c49b182 --- /dev/null +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLUpdateTest.kt @@ -0,0 +1,73 @@ +/* + * Copyright 2023 The Reload project Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * + */ +package com.smeup.dbnative.sql + +import com.smeup.dbnative.file.Record +import com.smeup.dbnative.file.RecordField +import com.smeup.dbnative.sql.utils.* +import org.junit.AfterClass +import org.junit.BeforeClass +import org.junit.Test +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +class SQLUpdateTest { + companion object { + + private lateinit var dbManager: SQLDBMManager + + @BeforeClass + @JvmStatic + fun setUp() { + dbManager = dbManagerForTest() + createAndPopulateMunicipalityTable(dbManager) + } + + @AfterClass + @JvmStatic + fun tearDown() { + destroyDatabase() + } + } + + @Test + fun update() { + val dbFile = SQLUpdateTest.dbManager.openFile(MUNICIPALITY_TABLE_NAME) + + // Chain to record to modify + var chainResult = dbFile.chain(buildMunicipalityKey("IT", "LOM", "BG", "DALMINE")) + assertEquals("DALMINE", getMunicipalityName(chainResult.record)) + assertEquals("BG", getMunicipalityProv(chainResult.record)) + + // Update + val record = chainResult.record + record.set("PROV", "BS") + dbFile.update(record, ) + + // Verify changes + chainResult = dbFile.chain(buildMunicipalityKey("IT", "LOM", "BS", "DALMINE")) + assertEquals("BS", getMunicipalityProv(chainResult.record)) + + // Verify that old record is missing + chainResult = dbFile.chain(buildMunicipalityKey("IT", "LOM", "BS", "DALMINE")) + assertTrue(dbFile.eof()) + SQLUpdateTest.dbManager.closeFile(MUNICIPALITY_TABLE_NAME) + } + +} + diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLUtilsTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLUtilsTest.kt index 98da867..0b69c0d 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLUtilsTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLUtilsTest.kt @@ -74,13 +74,13 @@ class SQLUtilsTest { RecordField("TSTFLDCHR", "XXX"), RecordField("TSTFLDNBR", "123.45") ) - assertEquals("INSERT INTO TSTTAB (TSTFLDCHR, TSTFLDNBR) VALUES(?, ?)", "TSTTAB".insertSQL(record)) + assertEquals("INSERT INTO TSTTAB (\"TSTFLDCHR\", \"TSTFLDNBR\") VALUES(?, ?)", "TSTTAB".insertSQL(record)) } @Test fun sqlForOrderBy() { val fields = listOf("Field1", "Field2", "Field3") - assertEquals("ORDER BY Field1, Field2, Field3", orderBySQL(fields)) - assertEquals("ORDER BY Field1 DESC, Field2 DESC, Field3 DESC", orderBySQL(fields, true)) + assertEquals("ORDER BY \"Field1\", \"Field2\", \"Field3\"", orderBySQL(fields)) + assertEquals("ORDER BY \"Field1\" DESC, \"Field2\" DESC, \"Field3\" DESC", orderBySQL(fields, true)) } } diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLWriteDeleteTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLWriteDeleteTest.kt new file mode 100644 index 0000000..ffe26b1 --- /dev/null +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLWriteDeleteTest.kt @@ -0,0 +1,121 @@ +/* + * Copyright 2023 The Reload project Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * + */ +package com.smeup.dbnative.sql + +import com.smeup.dbnative.file.Record +import com.smeup.dbnative.file.RecordField +import com.smeup.dbnative.sql.utils.* +import org.junit.AfterClass +import org.junit.BeforeClass +import org.junit.Test +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +class SQLWriteDeleteTest { + companion object { + + private lateinit var dbManager: SQLDBMManager + + @BeforeClass + @JvmStatic + fun setUp() { + dbManager = dbManagerForTest() + createAndPopulateMunicipalityTable(dbManager) + } + + @AfterClass + @JvmStatic + fun tearDown() { + destroyDatabase() + } + } + + @Test + fun chainDeleteChain() { + val dbFile = SQLWriteDeleteTest.dbManager.openFile(MUNICIPALITY_TABLE_NAME) + val chainResult2 = dbFile.chain(buildMunicipalityKey("IT", "LOM", "BG", "CREDARO")) + assertEquals("CREDARO", getMunicipalityName(chainResult2.record)) + dbFile.delete(chainResult2.record) + dbFile.chain(buildMunicipalityKey("IT", "LOM", "BG", "CREDARO")) + assertTrue(dbFile.eof()) + SQLWriteDeleteTest.dbManager.closeFile(MUNICIPALITY_TABLE_NAME) + } + + @Test + fun readDeleteRead() { + val dbFile = SQLWriteDeleteTest.dbManager.openFile(MUNICIPALITY_TABLE_NAME) + assertTrue(dbFile.setll(buildMunicipalityKey("IT", "LOM", "BG", "COVO"))) + val record = dbFile.read().record + dbFile.delete(record) + assertTrue(dbFile.setll(buildMunicipalityKey("IT", "LOM", "BG", "COVO"))) + dbFile.readEqual(buildMunicipalityKey("IT", "LOM", "BG", "COVO")) + assertTrue(dbFile.eof()) + SQLWriteDeleteTest.dbManager.closeFile(MUNICIPALITY_TABLE_NAME) + } + + @Test + fun writeDelete() { + val dbFile = SQLWriteDeleteTest.dbManager.openFile(MUNICIPALITY_TABLE_NAME) + + // Write new record + val recordFields = emptyList().toMutableList() + recordFields.add(RecordField("NAZ", "IT")) + recordFields.add(RecordField("REG", "LOM")) + recordFields.add(RecordField("PROV", "BG")) + recordFields.add(RecordField("CITTA", "PAPEROPOLI")) + recordFields.add(RecordField("PREF", "4321")) + recordFields.add(RecordField("COMUNE", "A99")) + recordFields.add(RecordField("ISTAT", "999999")) + dbFile.write(Record(*recordFields.toTypedArray())); + + // Read new record + dbFile.setll(buildMunicipalityKey("IT", "LOM", "BG", "PAPEROPOLI")) + val readResult = dbFile.read() + assertEquals("PAPEROPOLI", getMunicipalityName(readResult.record)) + + // Delete added record + var chainResult= dbFile.chain(buildMunicipalityKey("IT", "LOM", "BG", "PAPEROPOLI")) + dbFile.delete(chainResult.record) + chainResult = dbFile.chain(buildMunicipalityKey("IT", "LOM", "BG", "PAPEROPOLI")) + assertTrue(dbFile.eof()) + SQLWriteDeleteTest.dbManager.closeFile(MUNICIPALITY_TABLE_NAME) + } + + fun writeChain() { + val dbFile = SQLWriteDeleteTest.dbManager.openFile(MUNICIPALITY_TABLE_NAME) + + // Write new record + val recordFields = emptyList().toMutableList() + recordFields.add(RecordField("NAZ", "IT")) + recordFields.add(RecordField("REG", "LOM")) + recordFields.add(RecordField("PROV", "BG")) + recordFields.add(RecordField("CITTA", "TOPOLINIA")) + recordFields.add(RecordField("PREF", "1234")) + recordFields.add(RecordField("COMUNE", "A99")) + recordFields.add(RecordField("ISTAT", "999999")) + dbFile.write(Record(*recordFields.toTypedArray())); + + // Read new record for control + var chainResult = dbFile.chain(buildMunicipalityKey("IT", "LOM", "BG", "TOPOLINIA")) + assertEquals("TOPOLINIA", getMunicipalityName(chainResult.record)) + SQLWriteDeleteTest.dbManager.closeFile(MUNICIPALITY_TABLE_NAME) + } + + +} + diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/utils/SQLDBTestUtils.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/utils/SQLDBTestUtils.kt index e728a05..accf1cb 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/utils/SQLDBTestUtils.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/utils/SQLDBTestUtils.kt @@ -37,9 +37,7 @@ import java.sql.ResultSet import java.util.concurrent.atomic.AtomicInteger const val EMPLOYEE_TABLE_NAME = "EMPLOYEE" -const val XEMP2_VIEW_NAME = "XEMP2" -const val TSTTAB_TABLE_NAME = "TSTTAB" -const val TST2TAB_TABLE_NAME = "TSTTAB" +const val EMPLOYEE_VIEW_NAME = "EMPLOYEE_VIEW" const val MUNICIPALITY_TABLE_NAME = "MUNICIPALITY" const val TEST_LOG = false private val LOGGING_LEVEL = LoggingLevel.ALL @@ -50,7 +48,7 @@ private var defaultDbType = TestSQLDBType.HSQLDB //private var defaultDbType = TestSQLDBType.DB2_400 const val DATABASE_NAME = "TEST" const val DB2_400_HOST = "SRVLAB01.SMEUP.COM" -const val DB2_400_LIBRARY_NAME = "W_PARFRA" +const val DB2_400_LIBRARY_NAME = "UP_PRR" enum class TestSQLDBType( val connectionConfig: ConnectionConfig, @@ -82,8 +80,8 @@ enum class TestSQLDBType( fileName= "*", driver = "com.ibm.as400.access.AS400JDBCDriver", url = "jdbc:as400://$DB2_400_HOST/$DB2_400_LIBRARY_NAME;", - user = "USER", - password = "**********"), + user = System.getenv("AS400_USR")?:"USER", + password = System.getenv("AS400_PWD")?:"PASSWORD"), //force no create connection for dba operations dbaConnectionConfig = null @@ -110,8 +108,8 @@ fun dbManagerDB2400ForTest(host: String, library:String): SQLDBMManager{ fileName= "*", driver = "com.ibm.as400.access.AS400JDBCDriver", url = "jdbc:as400://$host/$library;", - user = "USER", - password = "**********"), + user = System.getenv("AS400_USR")?:"USER", + password = System.getenv("AS400_PWD")?:"PASSWORD"), ) dbManager.logger = Logger.getSimpleInstance(LOGGING_LEVEL) return dbManager @@ -145,35 +143,6 @@ fun destroyDatabase(testSQLDBType: TestSQLDBType) { } } -fun createAndPopulateTstTable(dbManager: SQLDBMManager?) { - val fields = listOf( - "TSTFLDCHR" fieldByType CharacterType(3), - "TSTFLDNBR" fieldByType DecimalType(5, 2) - ) - - val keys = listOf( - "TSTFLDCHR" - ) - - - createAndPopulateTable(dbManager, TSTTAB_TABLE_NAME, TSTTAB_TABLE_NAME, fields, keys, "src/test/resources/csv/TstTab.csv") -} - -fun createAndPopulateTst2Table(dbManager: SQLDBMManager?) { - val fields = listOf( - "TSTFLDCHR" fieldByType VarcharType(3), - "TSTFLDNBR" fieldByType DecimalType(5, 2), - "DESTST" fieldByType VarcharType(40) - ) - - val keys = listOf( - "TSTFLDCHR", - "TSTFLDNBR" - ) - - createAndPopulateTable(dbManager, TST2TAB_TABLE_NAME, TST2TAB_TABLE_NAME, fields, keys,"src/test/resources/csv/Tst2Tab.csv") -} - fun createAndPopulateEmployeeTable(dbManager: SQLDBMManager?) { val fields = listOf( "EMPNO" fieldByType CharacterType(6), @@ -190,12 +159,12 @@ fun createAndPopulateEmployeeTable(dbManager: SQLDBMManager?) { createAndPopulateTable(dbManager, EMPLOYEE_TABLE_NAME, EMPLOYEE_TABLE_NAME, fields, keys,"src/test/resources/csv/Employee.csv") } -fun createAndPopulateXemp2View(dbManager: SQLDBMManager?) { +fun createAndPopulateEmployeeView(dbManager: SQLDBMManager?) { // create view executing sql -> TODO: insert a createView method in DBMManager and use it - fun createXEMP2() = "CREATE VIEW $XEMP2_VIEW_NAME AS SELECT * FROM EMPLOYEE ORDER BY WORKDEPT, EMPNO" + fun createXEMP2() = "CREATE VIEW $EMPLOYEE_VIEW_NAME AS SELECT * FROM ${EMPLOYEE_TABLE_NAME} ORDER BY WORKDEPT, EMPNO" - fun createXEMP2Index() = - "CREATE INDEX $XEMP2_VIEW_NAME$CONVENTIONAL_INDEX_SUFFIX ON EMPLOYEE (WORKDEPT ASC, EMPNO ASC)" + fun createEmployeeIndex() = + "CREATE INDEX $EMPLOYEE_VIEW_NAME$CONVENTIONAL_INDEX_SUFFIX ON ${EMPLOYEE_TABLE_NAME} (WORKDEPT ASC, EMPNO ASC)" val fields = listOf( "EMPNO" fieldByType CharacterType(6), @@ -209,9 +178,9 @@ fun createAndPopulateXemp2View(dbManager: SQLDBMManager?) { "WORKDEPT" ) - val metadata = FileMetadata("$XEMP2_VIEW_NAME", "EMPLOYEE", fields.fieldList(), keys) + val metadata = FileMetadata(EMPLOYEE_VIEW_NAME, EMPLOYEE_TABLE_NAME, fields.fieldList(), keys) dbManager!!.registerMetadata(metadata, true) - dbManager.execute(listOf(createXEMP2(), createXEMP2Index())) + dbManager.execute(listOf(createXEMP2(), createEmployeeIndex())) } fun createAndPopulateMunicipalityTable(dbManager: SQLDBMManager?) { @@ -301,6 +270,39 @@ fun buildMunicipalityKey(vararg values: String): List { return keyValues } +fun buildCountryKey(vararg values: String): List { + val keyValues = mutableListOf() + val keys = arrayOf("NAZ", "REG", "PROV") + for ((index, value) in values.withIndex()) { + if (keys.size> index) { + keyValues.add(value) + } + } + return keyValues +} + +fun buildRegionKey(vararg values: String): List { + val keyValues = mutableListOf() + val keys = arrayOf("NAZ", "REG") + for ((index, value) in values.withIndex()) { + if (keys.size> index) { + keyValues.add(value) + } + } + return keyValues +} + +fun buildNationKey(vararg values: String): List { + val keyValues = mutableListOf() + val keys = arrayOf("NAZ") + for ((index, value) in values.withIndex()) { + if (keys.size> index) { + keyValues.add(value) + } + } + return keyValues +} + fun createFile(tMetadata: TypedMetadata, dbManager: SQLDBMManager) { val metadata: FileMetadata = tMetadata.fileMetadata(); dbManager.connection.createStatement().use { diff --git a/sql/src/test/resources/csv/Tst2Tab.csv b/sql/src/test/resources/csv/Tst2Tab.csv deleted file mode 100644 index d005e63..0000000 --- a/sql/src/test/resources/csv/Tst2Tab.csv +++ /dev/null @@ -1,4 +0,0 @@ -"TSTFLDCHR","TSTFLDNBR","DESTST" -"ABA",1.34,"ABA1" -"ABC",12.00,"ABC12" -"XYZ",1.01,"XYZ1" diff --git a/sql/src/test/resources/csv/TstTab.csv b/sql/src/test/resources/csv/TstTab.csv deleted file mode 100644 index 8b8ddc1..0000000 --- a/sql/src/test/resources/csv/TstTab.csv +++ /dev/null @@ -1,2 +0,0 @@ -"TSTFLDCHR","TSTFLDNBR" -"XXX",123.45 From 63f6948c4cb3b90b74c3e83e4cfceaafc59712eb Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Wed, 13 Dec 2023 12:45:27 +0100 Subject: [PATCH 23/35] Add ignoring for old tests --- .../com/smeup/dbnative/sql/DB2400PerfTest.kt | 4 ++-- .../kotlin/com/smeup/dbnative/sql/DB2400Test.kt | 5 +++-- .../dbnative/sql/SQLMunicipalityPerfTest.kt | 2 ++ .../smeup/dbnative/sql/utils/SQLDBTestUtils.kt | 16 ++++++---------- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400PerfTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400PerfTest.kt index 4ae2b5c..da012d4 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400PerfTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400PerfTest.kt @@ -22,12 +22,12 @@ import com.smeup.dbnative.file.Record import com.smeup.dbnative.file.RecordField import com.smeup.dbnative.metadata.file.PropertiesSerializer import com.smeup.dbnative.sql.utils.* -import org.junit.Ignore import org.junit.Test +import kotlin.test.Ignore import kotlin.test.assertEquals import kotlin.test.assertFalse - +@Ignore class DB2400PerfTest { diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400Test.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400Test.kt index a49a050..8294590 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400Test.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400Test.kt @@ -26,12 +26,12 @@ import com.smeup.dbnative.sql.utils.dbManagerForTest import com.smeup.dbnative.utils.propertiesToTypedMetadata import org.junit.AfterClass import org.junit.BeforeClass -import org.junit.Ignore import org.junit.Test +import kotlin.test.Ignore import kotlin.test.assertEquals import kotlin.test.assertTrue -//@Ignore +@Ignore class DB2400Test { companion object { @@ -45,6 +45,7 @@ class DB2400Test { } @AfterClass + @JvmStatic fun tearDown() { } } diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLMunicipalityPerfTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLMunicipalityPerfTest.kt index 2e0463a..4616aac 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLMunicipalityPerfTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLMunicipalityPerfTest.kt @@ -23,12 +23,14 @@ import com.smeup.dbnative.sql.utils.* import org.junit.AfterClass import org.junit.BeforeClass import org.junit.FixMethodOrder +import org.junit.Ignore import org.junit.Test import org.junit.runners.MethodSorters import kotlin.test.assertEquals import kotlin.test.assertFails import kotlin.test.assertTrue +@Ignore class SQLMunicipalityPerfTest { companion object { diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/utils/SQLDBTestUtils.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/utils/SQLDBTestUtils.kt index accf1cb..3638019 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/utils/SQLDBTestUtils.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/utils/SQLDBTestUtils.kt @@ -34,7 +34,6 @@ import org.junit.Assert import java.io.File import java.sql.Connection import java.sql.ResultSet -import java.util.concurrent.atomic.AtomicInteger const val EMPLOYEE_TABLE_NAME = "EMPLOYEE" const val EMPLOYEE_VIEW_NAME = "EMPLOYEE_VIEW" @@ -99,10 +98,6 @@ enum class TestSQLDBType( } -object DatabaseNameFactory { - var COUNTER = AtomicInteger() -} - fun dbManagerDB2400ForTest(host: String, library:String): SQLDBMManager{ val dbManager = SQLDBMManager(ConnectionConfig( fileName= "*", @@ -161,10 +156,10 @@ fun createAndPopulateEmployeeTable(dbManager: SQLDBMManager?) { fun createAndPopulateEmployeeView(dbManager: SQLDBMManager?) { // create view executing sql -> TODO: insert a createView method in DBMManager and use it - fun createXEMP2() = "CREATE VIEW $EMPLOYEE_VIEW_NAME AS SELECT * FROM ${EMPLOYEE_TABLE_NAME} ORDER BY WORKDEPT, EMPNO" + fun createXEMP2() = "CREATE VIEW $EMPLOYEE_VIEW_NAME AS SELECT * FROM $EMPLOYEE_TABLE_NAME ORDER BY WORKDEPT, EMPNO" fun createEmployeeIndex() = - "CREATE INDEX $EMPLOYEE_VIEW_NAME$CONVENTIONAL_INDEX_SUFFIX ON ${EMPLOYEE_TABLE_NAME} (WORKDEPT ASC, EMPNO ASC)" + "CREATE INDEX $EMPLOYEE_VIEW_NAME$CONVENTIONAL_INDEX_SUFFIX ON $EMPLOYEE_TABLE_NAME (WORKDEPT ASC, EMPNO ASC)" val fields = listOf( "EMPNO" fieldByType CharacterType(6), @@ -218,11 +213,11 @@ fun getEmployeeName(record: Record): String { } fun getMunicipalityName(record: Record): String { - return (record["CITTA"]?.toString()?.trim() ?: "") + return (record["CITTA"]?.trim() ?: "") } fun getMunicipalityProv(record: Record): String { - return (record["PROV"]?.toString()?.trim() ?: "") + return (record["PROV"]?.trim() ?: "") } fun testLog(message: String) { @@ -304,7 +299,7 @@ fun buildNationKey(vararg values: String): List { } fun createFile(tMetadata: TypedMetadata, dbManager: SQLDBMManager) { - val metadata: FileMetadata = tMetadata.fileMetadata(); + val metadata: FileMetadata = tMetadata.fileMetadata() dbManager.connection.createStatement().use { it.execute(tMetadata.toSQL()) } @@ -339,6 +334,7 @@ fun TypedField.type2sql(): String = else -> TODO("Conversion to SQL Type not yet implemented: ${this.type}") } + fun sql2Type(metadataResultSet: ResultSet): FieldType { val sqlType = metadataResultSet.getString("TYPE_NAME") val columnSize = metadataResultSet.getInt("COLUMN_SIZE") From 1383712ee955aac738b5c073c73d9a9581d8d946 Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Fri, 15 Dec 2023 16:32:34 +0100 Subject: [PATCH 24/35] Patch for read Patch for read statement executed after positioning with fewer keys than those defined in the logical file --- .../com/smeup/dbnative/sql/Native2SQLAdapter.kt | 5 +++++ .../kotlin/com/smeup/dbnative/sql/SQLReadTest.kt | 14 ++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt b/sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt index 4b07971..1c8616c 100644 --- a/sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt +++ b/sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt @@ -251,7 +251,12 @@ class Native2SQL(val fileMetadata: FileMetadata) { " AND " ) ) + replacements.addAll(lastPositioningInstruction!!.keys) + val lostKeys = fileMetadata.fileKeys.size - lastPositioningInstruction!!.keys.size + repeat(lostKeys) { + replacements.add(""); + } return Pair(queries.joinToString(), replacements) } } diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadTest.kt index a83e264..b5e2fc3 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadTest.kt @@ -100,5 +100,19 @@ class SQLReadTest { } SQLReadTest.dbManager.closeFile(MUNICIPALITY_TABLE_NAME) } + + @Test + fun positioningWithLessKeysAndReadUntilEof() { + val dbFile = dbManager.openFile(MUNICIPALITY_TABLE_NAME) + var readed = 0; + val setllResult = dbFile.setll( buildCountryKey("IT", "LOM", "BS")) + while (dbFile.eof() == false) { + var readResult = dbFile.read() + readed++ + System.out.println("Lettura $readed: " + getMunicipalityName(readResult.record)) + } + assertEquals(1001, readed) + dbManager.closeFile(MUNICIPALITY_TABLE_NAME) + } } From d07dd0e53b76489241603dfea8d5cb9d915c9eea Mon Sep 17 00:00:00 2001 From: mossini-smeup Date: Mon, 18 Dec 2023 09:48:47 +0100 Subject: [PATCH 25/35] fix: manage indicators on READ** --- .../com/smeup/dbnative/sql/SQLDBFile.kt | 99 +++++++++++++------ .../com/smeup/dbnative/sql/SQLReadTest.kt | 33 ++++--- 2 files changed, 89 insertions(+), 43 deletions(-) diff --git a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFile.kt b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFile.kt index 1a63994..934c48c 100644 --- a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFile.kt +++ b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFile.kt @@ -30,14 +30,17 @@ import java.sql.PreparedStatement import java.sql.ResultSet import kotlin.system.measureTimeMillis -class SQLDBFile(override var name: String, override var fileMetadata: FileMetadata, - var connection: Connection, - override var logger: Logger? = null) : DBFile { +class SQLDBFile( + override var name: String, override var fileMetadata: FileMetadata, + var connection: Connection, + override var logger: Logger? = null +) : DBFile { constructor( name: String, fileMetadata: FileMetadata, - connection: Connection): this(name, fileMetadata, connection, null) + connection: Connection + ) : this(name, fileMetadata, connection, null) private var preparedStatements: MutableMap = mutableMapOf() private var resultSet: ResultSet? = null @@ -59,10 +62,10 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada //} private var adapter: Native2SQL = Native2SQL(this.fileMetadata) - private var eof:Boolean = false + private var eof: Boolean = false private fun logEvent(loggingKey: LoggingKey, message: String, elapsedTime: Long? = null) = - logger?.logEvent(loggingKey, message, elapsedTime, lastNativeMethod, fileMetadata.name) + logger?.logEvent(loggingKey, message, elapsedTime, lastNativeMethod, fileMetadata.name) override fun setll(key: String): Boolean { @@ -101,7 +104,6 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada adapter.setRead(ReadMethod.CHAIN, keys) val read: Result measureTimeMillis { - executeQuery(adapter.getSQLSatement()) read = readNextFromResultSet(false) }.apply { @@ -115,11 +117,18 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada lastNativeMethod = NativeMethod.read logEvent(LoggingKey.native_access_method, "Executing read") val read: Result + var queryError = false measureTimeMillis { - if (adapter.setRead(ReadMethod.READ) ) { - executeQuery(adapter.getSQLSatement()) + if (adapter.setRead(ReadMethod.READ)) { + try { + executeQuery(adapter.getSQLSatement()) + } catch (e: Exception) { + queryError = true + logEvent(LoggingKey.native_access_method, "Query execution failed: " + e.message) + } } read = readNextFromResultSet(true) + read.indicatorLO = queryError }.apply { logEvent(LoggingKey.native_access_method, "read executed", this) } @@ -131,11 +140,18 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada lastNativeMethod = NativeMethod.readPrevious logEvent(LoggingKey.native_access_method, "Executing readPrevious") val read: Result + var queryError = false measureTimeMillis { if (adapter.setRead(ReadMethod.READP)) { - executeQuery(adapter.getSQLSatement()) + try { + executeQuery(adapter.getSQLSatement()) + } catch (e: Exception) { + queryError = true + logEvent(LoggingKey.native_access_method, "Query execution failed: " + e.message) + } } read = readNextFromResultSet(true) + read.indicatorLO = queryError }.apply { logEvent(LoggingKey.native_access_method, "readPrevious executed", this) } @@ -155,12 +171,18 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada lastNativeMethod = NativeMethod.readEqual logEvent(LoggingKey.native_access_method, "Executing readEqual on keys $keys") val read: Result + var queryError = false measureTimeMillis { - if (adapter.setRead(ReadMethod.READE, keys)) { - executeQuery(adapter.getSQLSatement()) + try { + executeQuery(adapter.getSQLSatement()) + } catch (e: Exception) { + queryError = true + logEvent(LoggingKey.native_access_method, "Query execution failed: " + e.message) + } } read = readNextFromResultSet(true) + read.indicatorLO = queryError }.apply { logEvent(LoggingKey.native_access_method, "readEqual executed", this) } @@ -181,12 +203,18 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada lastNativeMethod = NativeMethod.readPreviousEqual logEvent(LoggingKey.native_access_method, "Executing readPreviousEqual on keys $keys") val read: Result + var queryError = false measureTimeMillis { - if (adapter.setRead(ReadMethod.READPE, keys)) { - executeQuery(adapter.getSQLSatement()) + try { + executeQuery(adapter.getSQLSatement()) + } catch (e: Exception) { + queryError = true + logEvent(LoggingKey.native_access_method, "Query execution failed: " + e.message) + } } read = readNextFromResultSet(true) + read.indicatorLO = queryError }.apply { logEvent(LoggingKey.native_access_method, "readPreviousEqual executed", this) } @@ -196,7 +224,10 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada override fun write(record: Record): Result { lastNativeMethod = NativeMethod.write - logEvent(LoggingKey.native_access_method, "Executing write for record $record: with autocommit=${connection.autoCommit}") + logEvent( + LoggingKey.native_access_method, + "Executing write for record $record: with autocommit=${connection.autoCommit}" + ) measureTimeMillis { // TODO: manage errors val sql = fileMetadata.tableName.insertSQL(record) @@ -231,23 +262,26 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada */ override fun update(record: Record): Result { - require(getResultSet() != null){ + require(getResultSet() != null) { "Positioning required before update " } lastNativeMethod = NativeMethod.update - logEvent(LoggingKey.native_access_method, "Executing update record $actualRecord to $record with autocommit=${connection.autoCommit}") + logEvent( + LoggingKey.native_access_method, + "Executing update record $actualRecord to $record with autocommit=${connection.autoCommit}" + ) measureTimeMillis { // record before update is "actualRecord" // record post update will be "record" var atLeastOneFieldChanged = false actualRecord?.forEach { val fieldValue = record.getValue(it.key) - if(fieldValue != it.value){ + if (fieldValue != it.value) { atLeastOneFieldChanged = true this.getResultSet()?.updateObject(it.key, fieldValue) } - }?:logEvent(LoggingKey.native_access_method, "No previous read executed, nothing to update") - if(atLeastOneFieldChanged){ + } ?: logEvent(LoggingKey.native_access_method, "No previous read executed, nothing to update") + if (atLeastOneFieldChanged) { this.getResultSet()?.updateRow() } }.apply { @@ -260,12 +294,14 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada override fun delete(record: Record): Result { lastNativeMethod = NativeMethod.delete - logEvent(LoggingKey.native_access_method, "Executing delete for current record $actualRecord with autocommit=${connection.autoCommit}") + logEvent( + LoggingKey.native_access_method, + "Executing delete for current record $actualRecord with autocommit=${connection.autoCommit}" + ) measureTimeMillis { - if(actualRecord != null) { + if (actualRecord != null) { this.getResultSet()?.deleteRow() - } - else{ + } else { logEvent(LoggingKey.native_access_method, "No previous read executed, nothing to delete") } }.apply { @@ -285,7 +321,11 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada logEvent(LoggingKey.execute_inquiry, "Preparing statement for query: $sql with bingings: $values") val stm: PreparedStatement measureTimeMillis { - stm = preparedStatements.get(sql)?:connection.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE) + stm = preparedStatements.get(sql) ?: connection.prepareStatement( + sql, + ResultSet.TYPE_FORWARD_ONLY, + ResultSet.CONCUR_UPDATABLE + ) preparedStatements.putIfAbsent(sql, stm); stm.bind(values) }.apply { @@ -303,8 +343,8 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada if (nextResult == null) nextResult = Result(resultSet.toValues()) val result = nextResult - var found:Boolean = false - while( !found && !eof) { + var found: Boolean = false + while (!found && !eof) { if (adapter.lastReadMatchRecord(result!!.record)) { logEvent(LoggingKey.read_data, "Record read: ${result.record}") actualRecord = result.record.duplicate() @@ -316,7 +356,8 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada nextResult = Result(resultSet.toValues()); if (nextResult!!.record.isEmpty()) { - eof = true; + eof = true + result.indicatorEQ = true closeResultSet() logEvent(LoggingKey.read_data, "No more record to read") } @@ -327,7 +368,7 @@ class SQLDBFile(override var name: String, override var fileMetadata: FileMetada return result!! } - private fun closeResultSet(){ + private fun closeResultSet() { resultSet.closeIfOpen() resultSet = null } diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadTest.kt index b5e2fc3..b706119 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadTest.kt @@ -17,6 +17,7 @@ package com.smeup.dbnative.sql +import com.smeup.dbnative.file.Result import com.smeup.dbnative.sql.utils.* import org.junit.AfterClass import org.junit.BeforeClass @@ -29,7 +30,7 @@ class SQLReadTest { companion object { private lateinit var dbManager: SQLDBMManager - + @BeforeClass @JvmStatic fun setUp() { @@ -50,12 +51,14 @@ class SQLReadTest { fun readUntilEof() { val dbFile = dbManager.openFile(EMPLOYEE_VIEW_NAME) var readed = 0; + var readResult = Result() while (dbFile.eof() == false) { - var readResult = dbFile.read() + readResult = dbFile.read() readed++ - System.out.println("Lettura $readed: " + getEmployeeName(readResult.record)) + println("Lettura $readed: " + getEmployeeName(readResult.record)) } assertEquals(42, readed) + assertTrue(readResult.indicatorEQ) dbManager.closeFile(EMPLOYEE_VIEW_NAME) } @@ -63,13 +66,15 @@ class SQLReadTest { fun positioningAndReadUntilEof() { val dbFile = dbManager.openFile(EMPLOYEE_VIEW_NAME) var readed = 0; - val setllResult = dbFile.setll( "C01") + dbFile.setll("C01") + var readResult = Result() while (dbFile.eof() == false) { - var readResult = dbFile.read() + readResult = dbFile.read() readed++ - System.out.println("Lettura $readed: " + getEmployeeName(readResult.record)) + println("Lettura $readed: " + getEmployeeName(readResult.record)) } assertEquals(36, readed) + assertTrue(readResult.indicatorEQ) dbManager.closeFile(EMPLOYEE_VIEW_NAME) } @@ -77,11 +82,11 @@ class SQLReadTest { fun positioningBlankAndReadUntilEof() { val dbFile = dbManager.openFile(EMPLOYEE_VIEW_NAME) var readed = 0; - val setllResult = dbFile.setll( "") + dbFile.setll("") while (dbFile.eof() == false) { var readResult = dbFile.read() readed++ - System.out.println("Lettura $readed: " + getEmployeeName(readResult.record)) + println("Lettura $readed: " + getEmployeeName(readResult.record)) } assertEquals(42, readed) dbManager.closeFile(EMPLOYEE_VIEW_NAME) @@ -91,11 +96,11 @@ class SQLReadTest { fun multipleRead() { val dbFile = SQLReadTest.dbManager.openFile(MUNICIPALITY_TABLE_NAME) assertTrue(dbFile.setll(buildMunicipalityKey("IT", "LOM", "BS", "ERBUSCO"))) - for(index in 0..138){ + for (index in 0..138) { var result = dbFile.read(); - assertTrue{!dbFile.eof()} - if(index == 138) { - assertEquals("CO" , getMunicipalityProv(result.record)) + assertTrue { !dbFile.eof() } + if (index == 138) { + assertEquals("CO", getMunicipalityProv(result.record)) } } SQLReadTest.dbManager.closeFile(MUNICIPALITY_TABLE_NAME) @@ -105,11 +110,11 @@ class SQLReadTest { fun positioningWithLessKeysAndReadUntilEof() { val dbFile = dbManager.openFile(MUNICIPALITY_TABLE_NAME) var readed = 0; - val setllResult = dbFile.setll( buildCountryKey("IT", "LOM", "BS")) + dbFile.setll(buildCountryKey("IT", "LOM", "BS")) while (dbFile.eof() == false) { var readResult = dbFile.read() readed++ - System.out.println("Lettura $readed: " + getMunicipalityName(readResult.record)) + println("Lettura $readed: " + getMunicipalityName(readResult.record)) } assertEquals(1001, readed) dbManager.closeFile(MUNICIPALITY_TABLE_NAME) From bd66fca69d24e4df0a84f151dd7a25e73dcdd955 Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Mon, 18 Dec 2023 10:30:52 +0100 Subject: [PATCH 26/35] Patch for read New test for read with less keysdeclared than metadata definition, and patch on test DB content. --- .../kotlin/com/smeup/dbnative/sql/SQLReadTest.kt | 14 ++++++++++++++ sql/src/test/resources/csv/Municipality.csv | 3 +-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadTest.kt index b5e2fc3..a3244e2 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadTest.kt @@ -114,5 +114,19 @@ class SQLReadTest { assertEquals(1001, readed) dbManager.closeFile(MUNICIPALITY_TABLE_NAME) } + + @Test + fun positioningWithHalfKeysAndReadUntilEof() { + val dbFile = dbManager.openFile(MUNICIPALITY_TABLE_NAME) + var readed = 0; + val setllResult = dbFile.setll( buildRegionKey("IT", "LOM")) + while (dbFile.eof() == false) { + var readResult = dbFile.read() + readed++ + System.out.println("Lettura $readed: " + getMunicipalityName(readResult.record)) + } + assertEquals(1244, readed) + dbManager.closeFile(MUNICIPALITY_TABLE_NAME) + } } diff --git a/sql/src/test/resources/csv/Municipality.csv b/sql/src/test/resources/csv/Municipality.csv index 116655c..03c5fb5 100644 --- a/sql/src/test/resources/csv/Municipality.csv +++ b/sql/src/test/resources/csv/Municipality.csv @@ -1677,7 +1677,7 @@ "IT","EMR","RE","CADELBOSCO DI SOPRA","42023","0522 ","B328","035008" "IT","EMR","RE","CAMPAGNOLA EMILIA","42012","0522 ","B499","035009" "IT","EMR","RE","CAMPEGINE","42040","0522 ","B502","035010" -"IT","EMR","RE","CANOSSA","-----","---- ","----","035018" +"IT","EMR","RE","CANOSSA",42026,"0522 ","C669","035018" "IT","EMR","RE","CARPINETI","42033","0522 ","B825","035011" "IT","EMR","RE","CASALGRANDE","42013","0522 ","B893","035012" "IT","EMR","RE","CASINA","42034","0522 ","B967","035013" @@ -3805,4 +3805,3 @@ "IT","LOM","PV","PANCARANA","27050","0383 ","G304","018108" "IT","LOM","PV","PARONA","27020","0384 ","G342","018109" "IT","LOM","PV","PAVIA","27100","0382 ","G388","018110" -"IT","BAQ","AA","AAAA","00000","0000 ","0000","000000" \ No newline at end of file From 76a1428399fb2c970f5b339b82cdb86dd6965f13 Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Mon, 18 Dec 2023 11:26:07 +0100 Subject: [PATCH 27/35] Patch for error on readE Handle error on readE without prior pointing with LO flag enabled in response --- .../kotlin/com/smeup/dbnative/sql/SQLDBFile.kt | 8 +++++++- .../com/smeup/dbnative/sql/SQLReadEqualTest.kt | 15 +++++++++------ .../dbnative/sql/SQLUnsupportedFeaturesTest.kt | 3 ++- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFile.kt b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFile.kt index 934c48c..bc548d0 100644 --- a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFile.kt +++ b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFile.kt @@ -160,7 +160,13 @@ class SQLDBFile( } override fun readEqual(): Result { - return readEqual(adapter.getLastKeys()) + var result = Result() + try { + result = readEqual(adapter.getLastKeys()) + } catch (exc: Exception) { + result.indicatorLO = true + } + return result } override fun readEqual(key: String): Result { diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadEqualTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadEqualTest.kt index bf845ee..1982e43 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadEqualTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadEqualTest.kt @@ -17,6 +17,7 @@ package com.smeup.dbnative.sql +import com.smeup.dbnative.file.Result import com.smeup.dbnative.sql.utils.* import org.junit.AfterClass import org.junit.BeforeClass @@ -48,11 +49,10 @@ class SQLReadEqualTest { } @Test - fun throwsExceptionIfImmediatelyReadE() { + fun errorIfImmediatelyReadE() { val dbFile = dbManager.openFile(EMPLOYEE_VIEW_NAME) - assertFailsWith(Exception::class) { - dbFile.readEqual() - } + var result = dbFile.readEqual() + assertTrue(result.indicatorLO) dbManager.closeFile(EMPLOYEE_VIEW_NAME) } @@ -81,11 +81,13 @@ class SQLReadEqualTest { val dbFile = dbManager.openFile(EMPLOYEE_VIEW_NAME) val setllResult = dbFile.setll( "C01") var readed = 0; + var readResult = Result() while (dbFile.eof() == false) { - var readResult = dbFile.readEqual("C01") + readResult = dbFile.readEqual("C01") readed++ } assertEquals(4, readed) + assertTrue (readResult.indicatorEQ) dbManager.closeFile(EMPLOYEE_VIEW_NAME) } @@ -132,7 +134,8 @@ class SQLReadEqualTest { fun setgtReade() { val dbFile = SQLReadEqualTest.dbManager.openFile(MUNICIPALITY_TABLE_NAME) assertTrue(dbFile.setgt(buildMunicipalityKey("IT", "LOM", "BS"))) - assertEquals("ALBAVILLA", getMunicipalityName(dbFile.readEqual(buildMunicipalityKey("IT", "LOM")).record)) + val result = dbFile.readEqual(buildMunicipalityKey("IT", "LOM")) + assertEquals("ALBAVILLA", getMunicipalityName(result.record)) SQLReadEqualTest.dbManager.closeFile(MUNICIPALITY_TABLE_NAME) } diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLUnsupportedFeaturesTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLUnsupportedFeaturesTest.kt index 739cf5d..1aece47 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLUnsupportedFeaturesTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLUnsupportedFeaturesTest.kt @@ -66,7 +66,8 @@ class SQLUnsupportedFeaturesTest { @Test fun usupportedUnpositioning() { val dbFile = SQLUnsupportedFeaturesTest.dbManager.openFile(MUNICIPALITY_TABLE_NAME) - assertFails {dbFile.readEqual(buildMunicipalityKey("IT", "LOM", "BS"))} + val result = dbFile.readEqual(buildMunicipalityKey("IT", "LOM", "BS")) + assertTrue { result.indicatorLO } SQLUnsupportedFeaturesTest.dbManager.closeFile(MUNICIPALITY_TABLE_NAME) } From 42c1074662598c911c8f73ce2e4d28443cf6b497 Mon Sep 17 00:00:00 2001 From: mossini-smeup Date: Mon, 18 Dec 2023 17:28:44 +0100 Subject: [PATCH 28/35] fix: multi setll --- .../com/smeup/dbnative/sql/SQLDBFile.kt | 2 +- .../smeup/dbnative/sql/SQLReadEqualTest.kt | 29 ++++++++++++++----- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFile.kt b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFile.kt index bc548d0..d00c945 100644 --- a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFile.kt +++ b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFile.kt @@ -346,7 +346,7 @@ class SQLDBFile( private fun readNextFromResultSet(loadNext: Boolean): Result { - if (nextResult == null) nextResult = Result(resultSet.toValues()) + if (nextResult == null || nextResult!!.record.isEmpty()) nextResult = Result(resultSet.toValues()) val result = nextResult var found: Boolean = false diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadEqualTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadEqualTest.kt index 1982e43..e607b63 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadEqualTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadEqualTest.kt @@ -23,7 +23,6 @@ import org.junit.AfterClass import org.junit.BeforeClass import org.junit.Test import kotlin.test.assertEquals -import kotlin.test.assertFailsWith import kotlin.test.assertTrue class SQLReadEqualTest { @@ -31,7 +30,7 @@ class SQLReadEqualTest { companion object { private lateinit var dbManager: SQLDBMManager - + @BeforeClass @JvmStatic fun setUp() { @@ -67,7 +66,7 @@ class SQLReadEqualTest { @Test fun findRecordsIfChainAndReadEExistingKey() { val dbFile = dbManager.openFile(EMPLOYEE_VIEW_NAME) - val setllResult = dbFile.setll( "C01") + val setllResult = dbFile.setll("C01") assertEquals("SALLY KWAN", getEmployeeName(dbFile.readEqual("C01").record)) assertEquals("DELORES QUINTANA", getEmployeeName(dbFile.readEqual("C01").record)) assertEquals("HEATHER NICHOLLS", getEmployeeName(dbFile.readEqual("C01").record)) @@ -79,7 +78,7 @@ class SQLReadEqualTest { @Test fun readUntilEof() { val dbFile = dbManager.openFile(EMPLOYEE_VIEW_NAME) - val setllResult = dbFile.setll( "C01") + val setllResult = dbFile.setll("C01") var readed = 0; var readResult = Result() while (dbFile.eof() == false) { @@ -87,15 +86,15 @@ class SQLReadEqualTest { readed++ } assertEquals(4, readed) - assertTrue (readResult.indicatorEQ) + assertTrue(readResult.indicatorEQ) dbManager.closeFile(EMPLOYEE_VIEW_NAME) } @Test fun equals() { val dbFile = dbManager.openFile(EMPLOYEE_VIEW_NAME) - val chainResult = dbFile.setll( "C01") - assertTrue (dbFile.equal()) + val chainResult = dbFile.setll("C01") + assertTrue(dbFile.equal()) dbManager.closeFile(EMPLOYEE_VIEW_NAME) } @@ -112,6 +111,20 @@ class SQLReadEqualTest { dbManager.closeFile(EMPLOYEE_VIEW_NAME) } + @Test + fun setllReadsetllReade() { + val dbFile = SQLReadEqualTest.dbManager.openFile(MUNICIPALITY_TABLE_NAME) + assertTrue(dbFile.setll(buildMunicipalityKey("IT", "LOM", "BS"))) + while (!dbFile.eof()) { + dbFile.read() + } + assertTrue(dbFile.setll(buildMunicipalityKey("IT", "LOM", "BS"))) + val result = dbFile.readEqual(buildMunicipalityKey("IT", "LOM", "BS")) + assertEquals("ACQUAFREDDA", getMunicipalityName(result.record)) + + SQLReadEqualTest.dbManager.closeFile(MUNICIPALITY_TABLE_NAME) + } + @Test fun doesNotFindRecordsIfReadEWithKeyNotExistingKey() { val dbFile = dbManager.openFile(EMPLOYEE_VIEW_NAME) @@ -130,6 +143,7 @@ class SQLReadEqualTest { assertEquals(0, dbFile.readEqual("C01").record.size) dbManager.closeFile(EMPLOYEE_VIEW_NAME) } + @Test fun setgtReade() { val dbFile = SQLReadEqualTest.dbManager.openFile(MUNICIPALITY_TABLE_NAME) @@ -146,6 +160,7 @@ class SQLReadEqualTest { assertEquals("ZONE", getMunicipalityName(dbFile.readEqual(buildMunicipalityKey("IT", "LOM", "BS")).record)) var r = dbFile.readEqual(buildMunicipalityKey("IT", "LOM", "BS")) assertTrue(dbFile.eof()) + assertTrue(r.indicatorEQ) r = dbFile.readEqual(buildMunicipalityKey("IT", "LOM", "BS")) assertTrue(dbFile.eof()) SQLReadEqualTest.dbManager.closeFile(MUNICIPALITY_TABLE_NAME) From 806c72fc90900d3781c2de2b52f7384552061036 Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Mon, 18 Dec 2023 18:07:12 +0100 Subject: [PATCH 29/35] Patch opened DBFile: remove buffer --- .../com/smeup/dbnative/sql/SQLDBMManager.kt | 24 +- .../com/smeup/dbnative/sql/DB2400Test.kt | 444 ------------------ .../smeup/dbnative/sql/SQLReadEqualTest.kt | 16 +- 3 files changed, 26 insertions(+), 458 deletions(-) delete mode 100644 sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400Test.kt diff --git a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBMManager.kt b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBMManager.kt index 9ac0a1a..dc6dc4f 100644 --- a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBMManager.kt +++ b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBMManager.kt @@ -19,19 +19,20 @@ package com.smeup.dbnative.sql import com.smeup.dbnative.ConnectionConfig import com.smeup.dbnative.DBManagerBaseImpl +import com.smeup.dbnative.file.DBFile import com.smeup.dbnative.log.LoggingKey import java.sql.Connection import java.sql.DriverManager import java.util.* import kotlin.system.measureTimeMillis -open class SQLDBMManager(override val connectionConfig: ConnectionConfig) : DBManagerBaseImpl() { +open class SQLDBMManager(override val connectionConfig: ConnectionConfig) : DBManagerBaseImpl() { private var sqlLog: Boolean = false - private var openedFile = mutableMapOf() + //private var openedFile = mutableMapOf() - val connection : Connection by lazy { + val connection: Connection by lazy { logger?.logEvent(LoggingKey.connection, "Opening SQL connection on url ${connectionConfig.url}") val conn: Connection measureTimeMillis { @@ -44,7 +45,7 @@ open class SQLDBMManager(override val connectionConfig: ConnectionConfig) : DBMa connectionProps.put("password", connectionConfig.password); connectionConfig.properties.forEach() { - if (!it.key.equals("user") && !it.key.equals("password")) { + if (!it.key.equals("user") && !it.key.equals("password")) { connectionProps.put(it.key, it.value); } } @@ -59,21 +60,18 @@ open class SQLDBMManager(override val connectionConfig: ConnectionConfig) : DBMa } override fun close() { - openedFile.values.forEach { it.close()} - openedFile.clear() + //openedFile.values.forEach { it.close()} + //openedFile.clear() connection.close() } - override fun openFile(name: String) = openedFile.getOrPut(name) { - require(existFile(name)) { - "Cannot open a unregistered file $name" - } - SQLDBFile(name = name, fileMetadata = metadataOf(name), connection = connection, logger) + override fun openFile(name: String): SQLDBFile { + require(this.existFile(name)) + return SQLDBFile(name = name, fileMetadata = metadataOf(name), connection = connection, logger) } - override fun closeFile(name: String) { - openedFile.remove(name)?.close() + //openedFile.remove(name)?.close() } fun execute(sqlStatements: List) { diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400Test.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400Test.kt deleted file mode 100644 index 8294590..0000000 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400Test.kt +++ /dev/null @@ -1,444 +0,0 @@ -/* - * Copyright 2020 The Reload project Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package com.smeup.dbnative.sql - -import com.smeup.dbnative.file.Record -import com.smeup.dbnative.file.RecordField -import com.smeup.dbnative.metadata.file.PropertiesSerializer -import com.smeup.dbnative.model.DecimalType -import com.smeup.dbnative.sql.utils.TestSQLDBType -import com.smeup.dbnative.sql.utils.dbManagerForTest -import com.smeup.dbnative.utils.propertiesToTypedMetadata -import org.junit.AfterClass -import org.junit.BeforeClass -import org.junit.Test -import kotlin.test.Ignore -import kotlin.test.assertEquals -import kotlin.test.assertTrue - -@Ignore -class DB2400Test { - - companion object { - - private var dbManager: SQLDBMManager? = null - - @BeforeClass - @JvmStatic - fun setUp() { - dbManager = dbManagerForTest(TestSQLDBType.DB2_400) - } - - @AfterClass - @JvmStatic - fun tearDown() { - } - } - - //Ignored fields in metadata not necessary - @Ignore - @Test - fun open() { - var fileMetadata = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "BRARTI0F") - dbManager!!.registerMetadata(fileMetadata, false) - var dbFile = dbManager!!.openFile("BRARTI0F") - assertEquals(115, dbFile.fileMetadata.fields.size) - dbManager!!.closeFile("BRARTI0F") - - fileMetadata = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "VERAPG0L") - dbManager!!.registerMetadata(fileMetadata, false) - dbFile = dbManager!!.openFile("VERAPG0L") - assertEquals(68, dbFile.fileMetadata.fields.size) - dbManager!!.closeFile("VERAPG0L") - } - - @Test - fun findRecordsIfChainWithExistingKey() { - val fileMetadata = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "BRARTI0L") - dbManager!!.registerMetadata(fileMetadata, false) - var dbFile = dbManager!!.openFile("BRARTI0L") - val key = "A01 " - val chainResult = dbFile.chain(key) - assertEquals(key, chainResult.record["A§ARTI"]) - assertEquals("ART ", chainResult.record["A§TIAR"]) - assertEquals("1 ", chainResult.record["A§TPAR"]) - dbManager!!.closeFile("BRARTI0L") - } - - @Test - fun findRecordsIfSetllAndReadEWithKeyExistingKey() { - val fileMetadata = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "BRARTI2L") - dbManager!!.registerMetadata(fileMetadata, false) - var dbFile = dbManager!!.openFile("BRARTI2L") - - val key = "ART " - assertTrue(dbFile.setll(key)) - - var readEResult = dbFile.readEqual(key) - assertEquals("2 ", readEResult.record["A§TPAR"]) - assertEquals("ACCENSIONE PIEZOELETTRICA ", readEResult.record["A§DEAR"]) - - readEResult = dbFile.readEqual(key) - assertEquals("1 ", readEResult.record["A§TPAR"]) - assertEquals("ARTICOLO PER PARALLELISMO ", readEResult.record["A§DEAR"]) - - readEResult = dbFile.readEqual(key) - assertEquals("1 ", readEResult.record["A§TPAR"]) - assertEquals("BIKE (PROVA ", readEResult.record["A§DEAR"]) - - dbManager!!.closeFile("BRARTI2L") - } - - @Test - fun updateRecordAfterSingleKeyChain() { - // TEST FLOW - // Step1: check record exists - // Step2: modify field and update - // Step3: check record is updated - // Step4: restore previous field value and update - // Step5: check record is updated (value must be as initial) - val fileMetadata = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "BRARTI0L") - dbManager!!.registerMetadata(fileMetadata, false) - var dbFile = dbManager!!.openFile("BRARTI0L") - - val key = "A02 " - var chainResult = dbFile.chain(key) - - // Check chain result as expected - assertEquals(key, chainResult.record["A§ARTI"]) - assertEquals("GRUPPO CAMBIO-PIGNONE ", chainResult.record["A§DEAR"]) - assertEquals("ART ", chainResult.record["A§TIAR"]) - assertEquals("2 ", chainResult.record["A§TPAR"]) - - // Change some current recordfields values (NOT the key), then update - chainResult.record["A§TIAR"] = "TRA " - chainResult.record["A§TPAR"] = "1 " - dbFile.update(chainResult.record) - - // Chain again (same single key) and check data as expected - chainResult = dbFile.chain(key) - assertEquals("TRA ", chainResult.record["A§TIAR"]) - assertEquals("1 ", chainResult.record["A§TPAR"]) - - // Restore initial values (chain not required) - chainResult.record["A§TIAR"] = "ART " - chainResult.record["A§TPAR"] = "2 " - dbFile.update(chainResult.record) - - // Check the initial values restore - chainResult = dbFile.chain(key) - assertEquals("ART ", chainResult.record["A§TIAR"]) - assertEquals("2 ", chainResult.record["A§TPAR"]) - - dbManager!!.closeFile("BRARTI0L") - } - - @Test - fun writeNotExistingRecord() { - // TEST FLOW - // Step1: check record not exists - // Step2: set fields and write - // Step3: check the new record exists - // Step4: delete written record - // Step5: check record not exists (DB must be as initial) - val fileMetadata = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "BRARTI0L") - dbManager!!.registerMetadata(fileMetadata, false) - var dbFile = dbManager!!.openFile("BRARTI0L") - val key = System.currentTimeMillis().toString() + " " - var chainResult = dbFile.chain(key) - assertEquals(0, chainResult.record.size) - - // Set field values and write record - chainResult.record["A§ARTI"] = key - chainResult.record["A§DEAR"] = "Kotlin DBNativeAccess Write " - chainResult.record["A§TIAR"] = "ART " - chainResult.record["A§DT01"] = "20200918" - dbFile.write(chainResult.record) - - // Check correct write - chainResult = dbFile.chain(key) - assertEquals(key, chainResult.record["A§ARTI"]) - assertEquals("ART ", chainResult.record["A§TIAR"]) - assertEquals("Kotlin DBNativeAccess Write ", chainResult.record["A§DEAR"]) - assertEquals("20200918", chainResult.record["A§DT01"]) - - // Delete record - dbFile.delete(chainResult.record) - - // Check record not exists - chainResult = dbFile.chain(key) - assertEquals(0, chainResult.record.size) - - dbManager!!.closeFile("BRARTI0L") - } - - @Test - fun deleteExistingRecord() { - // TEST FLOW - // Step1: check record not exists - // Step2: set fields and write - // Step3: check the new record exists - // Step4: delete written record - // Step5: check record not exists (DB must be as initial) - val fileMetadata = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "BRARTI0L") - dbManager!!.registerMetadata(fileMetadata, false) - var dbFile = dbManager!!.openFile("BRARTI0L") - val key = System.currentTimeMillis().toString() + " " - - // Not exists - var chainResult = dbFile.chain(key) - assertEquals(0, chainResult.record.size) - - //Set field values and write record - chainResult.record["A§ARTI"] = key - chainResult.record["A§DEAR"] = "Kotlin DBNativeAccess Write " - chainResult.record["A§TIAR"] = "ART " - chainResult.record["A§TPAR"] = "0 " - - dbFile.write(chainResult.record) - - //Must exists correct write - chainResult = dbFile.chain(key) - assertEquals(key, chainResult.record["A§ARTI"]) - assertEquals("ART ", chainResult.record["A§TIAR"]) - assertEquals("Kotlin DBNativeAccess Write ", chainResult.record["A§DEAR"]) - assertEquals("0 ", chainResult.record["A§TPAR"]) - - //Delete record - dbFile.delete(chainResult.record) - - //Check delete success - chainResult = dbFile.chain(key) - assertEquals(0, chainResult.record.size) - - dbManager!!.closeFile("BRARTI0L") - } - - // Ignore, fields in metadata non necessary - @Ignore - @Test - fun multipleUpdateOnReadE(){ - // TEST FLOW - // Step1: write 100 records with "currentTimeMillis" as unique key - // Step2: read above written records and update A§DEA2 field - // Step3: check and check for correct update - // Step4: delete written record. - val tMetadata = propertiesToTypedMetadata("src/test/resources/dds/properties/", "BRARTI1L") - dbManager!!.registerMetadata(tMetadata.fileMetadata(), false) - var dbFile = dbManager!!.openFile("BRARTI1L") - - // Number of record this test work with (write, update and delete) - val numberOfRecordsToHandle = 100 - - // Create list of items to write into A§ARTI field - val items = mutableListOf() - repeat(numberOfRecordsToHandle){ - items.add(System.currentTimeMillis().toString() + " ") - Thread.sleep(5) - } - - val fieldsNumber = tMetadata.fields.size - val empty35char = " " - val dearKey = "Kotlin DBNativeAccess TEST " - val dea2Key = "Kotlin DBNativeAccess TEST-UPDATED " - - // WRITE - repeat(numberOfRecordsToHandle){ - var record = Record() - repeat(fieldsNumber){ index -> - var name: String = dbFile.fileMetadata.fields[index].name - print(tMetadata.getField(name)?.type) - var value = when(name){ - "A§ARTI" -> items[it] - "A§DEAR" -> dearKey - else -> when(tMetadata.getField(name)?.type){ - is DecimalType -> "0" - else -> "" - } - } - - var recordField: RecordField = RecordField(name, value) - record.add(recordField) - } - dbFile.write(record) - } - - // READ AND UPDATE - // Read records with same description (A§DEAR) and update field named 'secondary description' (A§DEA2) - - assertTrue(dbFile.setll(dearKey)) - // Update - repeat(numberOfRecordsToHandle) { - var readEResult = dbFile.readEqual(dearKey) - assertEquals(dearKey, readEResult.record["A§DEAR"]) - assertEquals(empty35char, readEResult.record["A§DEA2"]) - readEResult.record["A§DEA2"] = dea2Key - dbFile.update(readEResult.record) - } - - // READ AND CHECK - // Check all records are updated as expected - assertTrue(dbFile.setll(dearKey)) - repeat(numberOfRecordsToHandle) { - var readEResult = dbFile.readEqual(dearKey) - assertEquals(dea2Key, readEResult.record["A§DEA2"]) - } - - // DELETE - assertTrue(dbFile.setll(dearKey)) - repeat(numberOfRecordsToHandle) { - var readEResult = dbFile.readEqual(dearKey) - assertEquals(dea2Key, readEResult.record["A§DEA2"]) - //Delete record - dbFile.delete(readEResult.record) - } - - } - - @Test - fun writeNotExistingRecordOnAHugeTable() { - // TEST FLOW (use a table with big amount of data, at lease >1.0M records) - // Step1: check record not exists - // Step2: set fields and write - // Step3: check the new record exists - // Step4: delete written record - // Step5: check record not exists (DB must be as initial) - - val fileMetadata = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "VERAPG0L") - dbManager!!.registerMetadata(fileMetadata, false) - var dbFile = dbManager!!.openFile("VERAPG0L") - val key = System.currentTimeMillis().toString().substring(3) - - var chainResult = dbFile.chain(key) - assertEquals(0, chainResult.record.size) - - // Set field values and write record - chainResult.record["V£IDOJ"] = key - chainResult.record["V£NOME"] = "DBNativeAccess " - dbFile.write(chainResult.record) - - // Check correct write - chainResult = dbFile.chain(key) - assertEquals(key, chainResult.record["V£IDOJ"]) - assertEquals("DBNativeAccess ", chainResult.record["V£NOME"]) - - // Delete record - dbFile.delete(chainResult.record) - - // Check record not exists - chainResult = dbFile.chain(key) - assertEquals(0, chainResult.record.size) - - dbManager!!.closeFile("VERAPG0L") - } - - @Test - fun findRecordsIfSetllAndReadWithKeyExistingKey() { - val fileMetadata = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "VERAPG1L") - dbManager!!.registerMetadata(fileMetadata, false) - var dbFile = dbManager!!.openFile("VERAPG1L") - - //keys: V£DATA, V£NOME, V£IDOJ - val data = "20200901" - val nome = "BNUNCA " - val idoj = "0002003070" - val keyList = listOf(data, nome, idoj) - assertTrue(dbFile.setll(keyList)) - - var readResult = dbFile.read() - assertEquals("20200901", readResult.record["V£DATA"]) - assertEquals("BOLPIE ", readResult.record["V£NOME"]) - assertEquals("0002003070", readResult.record["V£IDOJ"]) - - readResult = dbFile.read() - assertEquals("20200901", readResult.record["V£DATA"]) - assertEquals("BOLPIE ", readResult.record["V£NOME"]) - assertEquals("0002003106", readResult.record["V£IDOJ"]) - - readResult = dbFile.read() - assertEquals("20200901", readResult.record["V£DATA"]) - assertEquals("BOLPIE ", readResult.record["V£NOME"]) - assertEquals("0002003108", readResult.record["V£IDOJ"]) - - dbManager!!.closeFile("VERAPG1L") - } - - @Test - fun resultSetCursorMovements(){ - val fileMetadata = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "BRARTI0L") - dbManager!!.registerMetadata(fileMetadata, false) - var dbFile = dbManager!!.openFile("BRARTI0L") - - val key = "A01 " - - // Fill ResultSet - assertTrue(dbFile.setll(key)) - dbFile.read() - var resultSet = dbFile.getResultSet() - - // Cursor to 1st row - resultSet?.first() - assertEquals(resultSet?.getString("A§ARTI"), "A01 ") - - // Cursor to last row - resultSet?.last() - assertEquals(resultSet?.getString("A§ARTI"), "89807-04 ") - - dbManager!!.closeFile("BRARTI0L") - } - - @Test - fun resultSetCursorUpdate(){ - val fileMetadata = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "BRARTI0L") - dbManager!!.registerMetadata(fileMetadata, false) - var dbFile = dbManager!!.openFile("BRARTI0L") - - val key = "A01 " - - // Fill ResultSet - assertTrue(dbFile.setll(key)) - dbFile.read() - var resultSet = dbFile.getResultSet() - - // Cursor to 1st row - resultSet?.first() - assertEquals(resultSet?.getString("A§ARTI"), "A01 ") - - resultSet?.first() - assertEquals(resultSet?.getString("A§ARTI"), "A01 ") - - // Update record - resultSet?.updateString("A§TIAR", "XXXXX") - resultSet?.updateRow() - - // Move Cursor to last row - resultSet?.last() - assertEquals(resultSet?.getString("A§ARTI"), "89807-04 ") - - // Move Cursor to 1st row, the record should contain updated value - resultSet?.first() - assertEquals(resultSet?.getString("A§TIAR"), "XXXXX") - - // Restore initial field value - resultSet?.updateString("A§TIAR", "ART ") - resultSet?.updateRow() - - dbManager!!.closeFile("BRARTI0L") - } -} - diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadEqualTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadEqualTest.kt index 1982e43..3d760aa 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadEqualTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadEqualTest.kt @@ -22,6 +22,7 @@ import com.smeup.dbnative.sql.utils.* import org.junit.AfterClass import org.junit.BeforeClass import org.junit.Test +import kotlin.test.Ignore import kotlin.test.assertEquals import kotlin.test.assertFailsWith import kotlin.test.assertTrue @@ -99,7 +100,6 @@ class SQLReadEqualTest { dbManager.closeFile(EMPLOYEE_VIEW_NAME) } - @Test fun findRecordsIfReadEWithKeyExistingKey() { val dbFile = dbManager.openFile(EMPLOYEE_VIEW_NAME) @@ -158,5 +158,19 @@ class SQLReadEqualTest { dbFile.readEqual(buildMunicipalityKey("IT", "LOM", "BS", "ERBASCO")) SQLReadEqualTest.dbManager.closeFile(MUNICIPALITY_TABLE_NAME) } + + @Test + fun setGtReadsetGtReade() { + val dbFile = SQLReadEqualTest.dbManager.openFile(MUNICIPALITY_TABLE_NAME) + assertTrue(dbFile.setll(buildMunicipalityKey("IT", "LOM", "BS"))) + while(!dbFile.eof()) { + dbFile.read() + } + assertTrue(dbFile.setll(buildMunicipalityKey("IT", "LOM", "BS"))) + val result = dbFile.readEqual(buildMunicipalityKey("IT", "LOM", "BS")) + assertEquals("ACQUAFREDDA", getMunicipalityName(result.record)) + + SQLReadEqualTest.dbManager.closeFile(MUNICIPALITY_TABLE_NAME) + } } From 7e2f2f49dcae33f06b234bac0e33f224d3753105 Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Mon, 18 Dec 2023 18:08:50 +0100 Subject: [PATCH 30/35] Patch opened DBFile: remove buffer --- .../kotlin/com/smeup/dbnative/sql/SQLDBMManager.kt | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBMManager.kt b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBMManager.kt index dc6dc4f..87d0326 100644 --- a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBMManager.kt +++ b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBMManager.kt @@ -19,7 +19,6 @@ package com.smeup.dbnative.sql import com.smeup.dbnative.ConnectionConfig import com.smeup.dbnative.DBManagerBaseImpl -import com.smeup.dbnative.file.DBFile import com.smeup.dbnative.log.LoggingKey import java.sql.Connection import java.sql.DriverManager @@ -40,13 +39,13 @@ open class SQLDBMManager(override val connectionConfig: ConnectionConfig) : DBMa Class.forName(connectionConfig.driver) } - val connectionProps = Properties(); - connectionProps.put("user", connectionConfig.user); - connectionProps.put("password", connectionConfig.password); + val connectionProps = Properties() + connectionProps["user"] = connectionConfig.user + connectionProps["password"] = connectionConfig.password - connectionConfig.properties.forEach() { - if (!it.key.equals("user") && !it.key.equals("password")) { - connectionProps.put(it.key, it.value); + connectionConfig.properties.forEach { + if (it.key != "user" && it.key != "password") { + connectionProps[it.key] = it.value } } conn = DriverManager.getConnection(connectionConfig.url, connectionProps) From 74b1bee6ed02a3cf20d374b6de4edea463ec364c Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Mon, 25 Mar 2024 18:15:46 +0100 Subject: [PATCH 31/35] Postgres migration - New SQL syntax compaticle with postgres - Added isNumeric info to table columns - New metadata registration based on json serialization --- base/pom.xml | 8 + .../metadata/file/FSMetadataRegisterImpl.kt | 8 +- .../metadata/file/MetadataSerializer.kt | 58 +++++++ .../metadata/file/PropertiesSerializer.kt | 108 -------------- .../kotlin/com/smeup/dbnative/model/Field.kt | 2 +- .../com/smeup/dbnative/utils/FileUtilities.kt | 2 +- .../dbnative/PropertiesSerializationTest.kt | 31 ++-- .../dds/properties/BRARTI0F.properties | 141 ------------------ file_metadata.json | 20 +++ .../dbnative/jt400/JT400OperationsOnFile.kt | 33 ++-- .../dds/properties/BRARTI0F.properties | 141 ------------------ .../dds/properties/BRARTI0L.properties | 141 ------------------ .../dds/properties/BRARTI1L.properties | 141 ------------------ .../dds/properties/BRARTI2L.properties | 141 ------------------ .../dds/properties/VERAPG0F.properties | 94 ------------ .../dds/properties/VERAPG0L.properties | 94 ------------ .../dds/properties/VERAPG1L.properties | 94 ------------ sql/pom.xml | 5 + .../com/smeup/dbnative/sql/JDBCUtils.kt | 64 ++++++++ .../smeup/dbnative/sql/Native2SQLAdapter.kt | 98 ++++++++++-- .../com/smeup/dbnative/sql/SQLDBFile.kt | 6 - .../com/smeup/dbnative/sql/DB2400PerfTest.kt | 12 +- .../smeup/dbnative/sql/SQLReadEqualTest.kt | 10 ++ .../com/smeup/dbnative/sql/SQLUtilsTest.kt | 42 ------ .../com/smeup/dbnative/sql/utils/JsonTest.kt | 61 ++++++++ .../dbnative/sql/utils/SQLDBTestUtils.kt | 1 + sql/src/test/resources/dds/BRARTI0F.json | 8 + sql/src/test/resources/dds/BRARTI0L.json | 11 ++ sql/src/test/resources/dds/BRARTI1L.json | 11 ++ sql/src/test/resources/dds/BRARTI2L.json | 11 ++ sql/src/test/resources/dds/VERAPG0F.json | 9 ++ sql/src/test/resources/dds/VERAPG0L.json | 9 ++ sql/src/test/resources/dds/VERAPG1L.json | 12 ++ sql/src/test/resources/dds/VERAPG3L.json | 11 ++ sql/src/test/resources/dds/VERAPG9L.json | 10 ++ .../dds/properties/BRARTI0F.properties | 26 ---- .../dds/properties/BRARTI0L.properties | 26 ---- .../dds/properties/BRARTI1L.properties | 26 ---- .../dds/properties/BRARTI2L.properties | 26 ---- .../dds/properties/VERAPG0F.properties | 26 ---- .../dds/properties/VERAPG0L.properties | 26 ---- .../dds/properties/VERAPG1L.properties | 26 ---- .../dds/properties/VERAPG3L.properties | 3 - .../dds/properties/VERAPG9L.properties | 2 - 44 files changed, 448 insertions(+), 1387 deletions(-) create mode 100644 base/src/main/kotlin/com/smeup/dbnative/metadata/file/MetadataSerializer.kt delete mode 100644 base/src/main/kotlin/com/smeup/dbnative/metadata/file/PropertiesSerializer.kt delete mode 100644 base/src/test/resources/dds/properties/BRARTI0F.properties create mode 100644 file_metadata.json delete mode 100644 jt400/src/test/resources/dds/properties/BRARTI0F.properties delete mode 100644 jt400/src/test/resources/dds/properties/BRARTI0L.properties delete mode 100644 jt400/src/test/resources/dds/properties/BRARTI1L.properties delete mode 100644 jt400/src/test/resources/dds/properties/BRARTI2L.properties delete mode 100644 jt400/src/test/resources/dds/properties/VERAPG0F.properties delete mode 100644 jt400/src/test/resources/dds/properties/VERAPG0L.properties delete mode 100644 jt400/src/test/resources/dds/properties/VERAPG1L.properties create mode 100644 sql/src/test/kotlin/com/smeup/dbnative/sql/utils/JsonTest.kt create mode 100644 sql/src/test/resources/dds/BRARTI0F.json create mode 100644 sql/src/test/resources/dds/BRARTI0L.json create mode 100644 sql/src/test/resources/dds/BRARTI1L.json create mode 100644 sql/src/test/resources/dds/BRARTI2L.json create mode 100644 sql/src/test/resources/dds/VERAPG0F.json create mode 100644 sql/src/test/resources/dds/VERAPG0L.json create mode 100644 sql/src/test/resources/dds/VERAPG1L.json create mode 100644 sql/src/test/resources/dds/VERAPG3L.json create mode 100644 sql/src/test/resources/dds/VERAPG9L.json delete mode 100644 sql/src/test/resources/dds/properties/BRARTI0F.properties delete mode 100644 sql/src/test/resources/dds/properties/BRARTI0L.properties delete mode 100644 sql/src/test/resources/dds/properties/BRARTI1L.properties delete mode 100644 sql/src/test/resources/dds/properties/BRARTI2L.properties delete mode 100644 sql/src/test/resources/dds/properties/VERAPG0F.properties delete mode 100644 sql/src/test/resources/dds/properties/VERAPG0L.properties delete mode 100644 sql/src/test/resources/dds/properties/VERAPG1L.properties delete mode 100644 sql/src/test/resources/dds/properties/VERAPG3L.properties delete mode 100644 sql/src/test/resources/dds/properties/VERAPG9L.properties diff --git a/base/pom.xml b/base/pom.xml index 4865923..f224150 100644 --- a/base/pom.xml +++ b/base/pom.xml @@ -42,6 +42,14 @@ base + + + com.google.code.gson + gson + 2.10.1 + + + ${project.basedir}/src/main/kotlin ${project.basedir}/src/test/kotlin diff --git a/base/src/main/kotlin/com/smeup/dbnative/metadata/file/FSMetadataRegisterImpl.kt b/base/src/main/kotlin/com/smeup/dbnative/metadata/file/FSMetadataRegisterImpl.kt index e3884dc..bd837ce 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/metadata/file/FSMetadataRegisterImpl.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/metadata/file/FSMetadataRegisterImpl.kt @@ -37,19 +37,19 @@ object FSMetadataRegisterImpl: MetadataRegister{ } override fun registerMetadata(metadata: FileMetadata, overwrite: Boolean) { - PropertiesSerializer.metadataToProperties(propertiesDirPath, metadata, true) + MetadataSerializer.metadataToJson(propertiesDirPath, metadata, true) } override fun getMetadata(filename: String): FileMetadata { - return PropertiesSerializer.propertiesToMetadata(propertiesDirPath, filename) + return MetadataSerializer.jsonToMetadata(propertiesDirPath, filename) } override fun contains(fileName: String): Boolean { - return File("${propertiesDirPath}${File.separatorChar}${fileName}.properties").exists() + return File("${propertiesDirPath}${File.separatorChar}${fileName}.json").exists() } override fun remove(fileName: String) { - var propertiesFile = File("${propertiesDirPath}${File.separatorChar}${fileName}.properties") + var propertiesFile = File("${propertiesDirPath}${File.separatorChar}${fileName}.json") if (propertiesFile.exists()) propertiesFile.delete() } } \ No newline at end of file diff --git a/base/src/main/kotlin/com/smeup/dbnative/metadata/file/MetadataSerializer.kt b/base/src/main/kotlin/com/smeup/dbnative/metadata/file/MetadataSerializer.kt new file mode 100644 index 0000000..66115d1 --- /dev/null +++ b/base/src/main/kotlin/com/smeup/dbnative/metadata/file/MetadataSerializer.kt @@ -0,0 +1,58 @@ +/* + * Copyright 2020 The Reload project Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package com.smeup.dbnative.metadata.file + +import com.google.gson.Gson +import com.google.gson.GsonBuilder +import com.smeup.dbnative.model.FileMetadata +import java.io.File +import java.nio.charset.Charset + + +object MetadataSerializer { + + fun jsonToMetadata(directory: String, fileName: String): FileMetadata{ + // Read JSON data from file + val inputFile = File(directory, fileName.uppercase() + ".json") + val json: String = inputFile.readText() + + // Deserialize + val gson = Gson() + val fileMetadata: FileMetadata = gson.fromJson(json, FileMetadata::class.java) + + // if fileName field is undefined, set it with metadata file name + if (fileMetadata.tableName.isEmpty()) { + fileMetadata.tableName = fileName + } + return fileMetadata + } + + fun metadataToJson(directory: String, fileMetadata: FileMetadata, overwrite: Boolean){ + // Convert FileMetadata object to JSON + val gson: Gson = GsonBuilder().setPrettyPrinting().create() + val json: String = gson.toJson(fileMetadata) + + // Write JSON to file + val propertiesFilePath = "${directory}${File.separatorChar}${fileMetadata.name.uppercase()}.json" + val outputFile = File(propertiesFilePath) + if (overwrite && outputFile.exists()) { + outputFile.delete() + } + outputFile.writeText(json) + } +} diff --git a/base/src/main/kotlin/com/smeup/dbnative/metadata/file/PropertiesSerializer.kt b/base/src/main/kotlin/com/smeup/dbnative/metadata/file/PropertiesSerializer.kt deleted file mode 100644 index 2218ca3..0000000 --- a/base/src/main/kotlin/com/smeup/dbnative/metadata/file/PropertiesSerializer.kt +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 2020 The Reload project Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package com.smeup.dbnative.metadata.file - -import com.smeup.dbnative.model.Field -import com.smeup.dbnative.model.FileMetadata -import com.smeup.dbnative.utils.fieldsToProperties -import java.io.File -import java.io.FileInputStream -import java.io.InputStreamReader -import java.nio.charset.Charset -import java.util.* -import kotlin.collections.ArrayList - - -object PropertiesSerializer { - - fun propertiesToMetadata(propertiesDirPath: String, fileName: String): FileMetadata{ - val propertiesFile = FileInputStream(File("$propertiesDirPath${File.separatorChar}${fileName.toUpperCase()}.properties")) - //val properties = Properties() - //properties.load(InputStreamReader(propertiesFile, Charset.forName("UTF-8"))) - - val mp: MutableMap = LinkedHashMap() - object : Properties() { - @Synchronized - override fun put(key: Any, value: Any): Any? { - return mp.put(key as String, value as String) - } - }.load(InputStreamReader(propertiesFile, Charset.forName("UTF-8"))) - - // Fields - val flds = mp.filterKeys { it.startsWith("field.") } - val fields: MutableList = ArrayList() - flds.forEach { fld -> - val fieldName = fld.key.split(".")[1] - val fldAttributes = fld.value.split(",") - val description = fldAttributes[0].trim() - fields.add(Field(fieldName, description)) - } - - // fileName - var tableName = mp["tablename"]!! - - // if fileName field is undefined, set it with metadata file name - if (tableName.isEmpty()) { - tableName = fileName - } - - // FieldKeys - val fieldsKeys: MutableList = ArrayList() - if(!(mp["filekeys"]).isNullOrEmpty()){ - fieldsKeys.addAll((mp["filekeys"]?.split(",")!!)) - } - - // Create metadata - return FileMetadata(fileName, tableName, fields, fieldsKeys) - } - - - fun metadataToProperties(propertiesDirPath: String, fileMetadata: FileMetadata, overwrite: Boolean){ - metadataToPropertiesImpl(propertiesDirPath, fileMetadata, fileMetadata.fieldsToProperties(), overwrite) - } - - - private fun metadataToPropertiesImpl(propertiesDirPath: String, - fileMetadata: FileMetadata, - properties: MutableList>, - overwrite: Boolean){ - properties.add(Pair("tablename", fileMetadata.tableName)) - - val keys = fileMetadata.fileKeys.joinToString(",") - properties.add(Pair("filekeys", keys)) - - - val propertiesFilePath = "${propertiesDirPath}${File.separatorChar}${fileMetadata.name.toUpperCase()}.properties" - - val propertiesFile = File(propertiesFilePath) - - if (overwrite && propertiesFile.exists()) { - propertiesFile.delete() - } - - val writer = propertiesFile.bufferedWriter(Charset.forName("UTF-8")) - - properties.forEach { - writer.append("${it.first}=${it.second}") - writer.newLine() - } - writer.flush() - writer.close() - - } -} diff --git a/base/src/main/kotlin/com/smeup/dbnative/model/Field.kt b/base/src/main/kotlin/com/smeup/dbnative/model/Field.kt index f266536..f2c881d 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/model/Field.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/model/Field.kt @@ -17,4 +17,4 @@ package com.smeup.dbnative.model -data class Field(val name: String, val text:String = "") \ No newline at end of file +data class Field(val name: String, val text:String = "", val numeric:Boolean = false) \ No newline at end of file diff --git a/base/src/main/kotlin/com/smeup/dbnative/utils/FileUtilities.kt b/base/src/main/kotlin/com/smeup/dbnative/utils/FileUtilities.kt index 8176280..7daa565 100644 --- a/base/src/main/kotlin/com/smeup/dbnative/utils/FileUtilities.kt +++ b/base/src/main/kotlin/com/smeup/dbnative/utils/FileUtilities.kt @@ -58,7 +58,7 @@ fun FileMetadata.fieldsToProperties(): MutableList>{ properties.add( Pair( "field.${field.name}", - "${field.text}" + "${field.text}", ) ) } diff --git a/base/src/test/kotlin/com/smeup/dbnative/PropertiesSerializationTest.kt b/base/src/test/kotlin/com/smeup/dbnative/PropertiesSerializationTest.kt index c3a44e9..126fc37 100644 --- a/base/src/test/kotlin/com/smeup/dbnative/PropertiesSerializationTest.kt +++ b/base/src/test/kotlin/com/smeup/dbnative/PropertiesSerializationTest.kt @@ -17,7 +17,9 @@ package com.smeup.dbnative -import com.smeup.dbnative.metadata.file.PropertiesSerializer +import com.smeup.dbnative.metadata.file.MetadataSerializer +import com.smeup.dbnative.model.Field +import com.smeup.dbnative.model.FileMetadata import org.junit.Test import java.io.File @@ -25,22 +27,27 @@ class DBFileFactoryTest { @Test fun loadAndSaveTest() { - // Delete tmp file - var tmpFile = File("src/test/resources/dds/properties/out/BRARTI0F.properties") - if (tmpFile.exists()) tmpFile.delete() - tmpFile.parentFile.mkdirs() - // Read metadata1 from properties - var metadata1 = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "BRARTI0F") - println(metadata1) + val fileMetadata = FileMetadata( + "TEST", + "ExampleTable", + listOf( + Field("field1", "some text", false), + Field("field2", numeric = true) + ), + listOf("key1", "key2") + ) + + // Delete tmp file + val tmpDir = System.getProperty("java.io.tmpdir") // Save metadata1 to tmp properties file - PropertiesSerializer.metadataToProperties("src/test/resources/dds/properties/out", metadata1, true) + MetadataSerializer.metadataToJson(tmpDir, fileMetadata, true) - // Read metadata2 from tmp properties file - var metadata2 = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/out/", "BRARTI0F") + // Read metadata1 from properties + var metadata = MetadataSerializer.jsonToMetadata(tmpDir, "TEST") // Compare metadatas class - assert(metadata2.equals(metadata1)) + assert(metadata.name.equals("TEST")) } } \ No newline at end of file diff --git a/base/src/test/resources/dds/properties/BRARTI0F.properties b/base/src/test/resources/dds/properties/BRARTI0F.properties deleted file mode 100644 index d2825a9..0000000 --- a/base/src/test/resources/dds/properties/BRARTI0F.properties +++ /dev/null @@ -1,141 +0,0 @@ -# -# Copyright 2020 The Reload project Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# - -# -# - recordformat: declare record format name -# - list of fields (field.name = description, datatype, length, decimal) -# - fieldsKeys: list of fields keys, if any, comma separated -# -# ANAGRAFICA ARTICOLI -# -tablename = BRARTI0F -field.A§ARTI = Codice articolo,CHARACTER,15,0 -field.A§DEAR = Descrizione articolo,CHARACTER,35,0 -field.A§DEA2 = Descrizione aggiuntiva,CHARACTER,35,0 -field.A§TIAR = Tipo articolo,CHARACTER,5,0 -field.A§TPAR = Tipo parte,CHARACTER,3,0 -field.A§UNMS = Unità di misura gestione,CHARACTER,2,0 -field.A§PESO = Peso,DECIMAL,12,5 -field.A§VOLU = Volume,DECIMAL,12,5 -field.A§CALT = Codice alternativo,CHARACTER,15,0 -field.A§ARRI = Articolo di riferimento,CHARACTER,15,0 -field.A§DISE = Disegno,CHARACTER,20,0 -field.A§BARC = Barcode,CHARACTER,15,0 -field.A§STAT = Stato,CHARACTER,2,0 -field.A§LIVE = Livello,CHARACTER,1,0 -field.A§GRDI = Gruppo distinta,CHARACTER,15,0 -field.A§GRCI = Gruppo ciclo,CHARACTER,15,0 -field.A§NOMC = Nome configurazione,CHARACTER,20,0 -field.A§CSVQ = Cod. Sviluppo qtà,CHARACTER,5,0 -field.A§CSVA = Cod. svil. varianti,CHARACTER,5,0 -field.A§ENIR = Ente interno responsabile,CHARACTER,3,0 -field.A§LOTR = Lotto di riferimento,DECIMAL,11,3 -field.A§CONT = Contenitore,CHARACTER,15,0 -field.A§RCDV = Rif. catalogo di vendita,CHARACTER,15,0 -field.A§CASI = Assoggettamento IVA,CHARACTER,5,0 -field.A§NCOM = Nomenclatura combinata,CHARACTER,10,0 -field.A§CESP = Cespite,CHARACTER,15,0 -field.A§CLMA = Classe materiale,CHARACTER,5,0 -field.A§CLPR = Classe programmazione,CHARACTER,5,0 -field.A§CLGE = Classe gestione,CHARACTER,5,0 -field.A§CLCO = Classe contabile,CHARACTER,5,0 -field.A§CDLF = Classe fiscale,CHARACTER,5,0 -field.A§CLVA = Classe valore,CHARACTER,5,0 -field.A§CLFU = Classe funzionale,CHARACTER,5,0 -field.A§TC01 = Tipo classificazione 1,CHARACTER,12,0 -field.A§TC02 = Tipo classificazione 2,CHARACTER,12,0 -field.A§TC03 = Tipo classificazione 3,CHARACTER,12,0 -field.A§CL01 = Codice classificazione 1,CHARACTER,15,0 -field.A§CL02 = Codice classificazione 2,CHARACTER,15,0 -field.A§CL03 = Codice classificazione 3,CHARACTER,15,0 -field.A§COD1 = Codice 1,CHARACTER,15,0 -field.A§COD2 = Codice 2,CHARACTER,15,0 -field.A§COD3 = Codice 3,CHARACTER,15,0 -field.A§COD4 = Codice 4,CHARACTER,15,0 -field.A§COD5 = Codice 5,CHARACTER,15,0 -field.A§CD06 = Codice 6,CHARACTER,15,0 -field.A§CD07 = Codice 7,CHARACTER,15,0 -field.A§CD08 = Codice 8,CHARACTER,15,0 -field.A§CD09 = Codice 9,CHARACTER,15,0 -field.A§CD10 = Codice 10,CHARACTER,15,0 -field.A§NUM1 = Numero 1,DECIMAL,15,5 -field.A§NUM2 = Numero 2,DECIMAL,15,5 -field.A§NUM3 = Numero 3,DECIMAL,15,5 -field.A§NUM4 = Numero 4,DECIMAL,15,5 -field.A§NUM5 = Numero 5,DECIMAL,15,5 -field.A§NR06 = Numero 6,DECIMAL,15,5 -field.A§NR07 = Numero 7,DECIMAL,15,5 -field.A§NR08 = Numero 8,DECIMAL,15,5 -field.A§NR09 = Numero 9,DECIMAL,15,5 -field.A§NR10 = Numero 10,DECIMAL,15,5 -field.A§DT01 = Data 1,DECIMAL,8,0 -field.A§DT02 = Data 2,DECIMAL,8,0 -field.A§DT03 = Data 3,DECIMAL,8,0 -field.A§DT04 = Data 4,DECIMAL,8,0 -field.A§DT05 = Data 5,DECIMAL,8,0 -field.A§DT06 = Data 6,DECIMAL,8,0 -field.A§DT07 = Data 7,DECIMAL,8,0 -field.A§DT08 = Data 8,DECIMAL,8,0 -field.A§DT09 = Data 9,DECIMAL,8,0 -field.A§DT10 = Data 10,DECIMAL,8,0 -field.A§FL01 = Articolo non di magazzino (V2,CHARACTER,1,0 -field.A§FL02 = Codice da PDM (V2SI/NO),CHARACTER,1,0 -field.A§FL03 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL04 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL05 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL06 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL07 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL08 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL09 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL10 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL11 = Libero,CHARACTER,1,0 -field.A§FL12 = Libero,CHARACTER,1,0 -field.A§FL13 = Libero,CHARACTER,1,0 -field.A§FL14 = Libero,CHARACTER,1,0 -field.A§FL15 = Libero,CHARACTER,1,0 -field.A§FL16 = Libero,CHARACTER,1,0 -field.A§FL17 = Libero,CHARACTER,1,0 -field.A§FL18 = Libero,CHARACTER,1,0 -field.A§FL19 = Libero,CHARACTER,1,0 -field.A§FL20 = Libero,CHARACTER,1,0 -field.A§FL21 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL22 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL23 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL24 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL25 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL26 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL27 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL28 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL29 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL30 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL31 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL32 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL33 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL34 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL35 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL36 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL37 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL38 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL39 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL40 = Riservato UTENTE,CHARACTER,1,0 -field.A§USIN = Utente inserimento,CHARACTER,10,0 -field.A§DTIN = Data inserimento,DECIMAL,8,0 -field.A§ORIN = Ora inserimento,DECIMAL,6,0 -field.A§USAG = Utente aggiornamento,CHARACTER,10,0 -field.A§DTAG = Data aggiornamento,DECIMAL,8,0 -field.A§ORAG = Ora aggiornamento,DECIMAL,6,0 -filekeys = diff --git a/file_metadata.json b/file_metadata.json new file mode 100644 index 0000000..cc5f6e7 --- /dev/null +++ b/file_metadata.json @@ -0,0 +1,20 @@ +{ + "name": "example.txt", + "tableName": "ExampleTable", + "fields": [ + { + "name": "field1", + "text": "some text", + "numeric": false + }, + { + "name": "field2", + "text": "", + "numeric": true + } + ], + "fileKeys": [ + "key1", + "key2" + ] +} \ No newline at end of file diff --git a/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400OperationsOnFile.kt b/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400OperationsOnFile.kt index 5b50436..dc67fa3 100644 --- a/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400OperationsOnFile.kt +++ b/jt400/src/test/kotlin/com/smeup/dbnative/jt400/JT400OperationsOnFile.kt @@ -17,14 +17,10 @@ package com.smeup.dbnative.jt400 -import com.smeup.dbnative.file.Record -import com.smeup.dbnative.file.RecordField import com.smeup.dbnative.jt400.utils.createAndPopulateMunicipalityTable import com.smeup.dbnative.jt400.utils.dbManagerForTest import com.smeup.dbnative.jt400.utils.destroyDatabase -import com.smeup.dbnative.metadata.file.PropertiesSerializer -import com.smeup.dbnative.model.DecimalType -import com.smeup.dbnative.utils.propertiesToTypedMetadata +import com.smeup.dbnative.metadata.file.MetadataSerializer import org.junit.After import org.junit.Before import org.junit.Test @@ -51,13 +47,13 @@ class JT400OperationsOnFile { @Test fun open() { - var fileMetadata = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "BRARTI0F") + var fileMetadata = MetadataSerializer.jsonToMetadata("src/test/resources/dds/", "BRARTI0F") dbManager.registerMetadata(fileMetadata, false) val dbFile = dbManager.openFile("BRARTI0F") assertEquals(115, dbFile.fileMetadata.fields.size) dbManager.closeFile("BRARTI0F") - fileMetadata = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "VERAPG0L") + fileMetadata = MetadataSerializer.jsonToMetadata("src/test/resources/dds/", "VERAPG0L") dbManager.registerMetadata(fileMetadata, false) val dbFile2 = dbManager.openFile("VERAPG0L") assertEquals(68, dbFile2.fileMetadata.fields.size) @@ -66,7 +62,7 @@ class JT400OperationsOnFile { @Test fun findRecordsIfSetllAndReadEWithKeyExistingKey() { - val fileMetadata = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "BRARTI2L") + val fileMetadata = MetadataSerializer.jsonToMetadata("src/test/resources/dds/", "BRARTI2L") dbManager.registerMetadata(fileMetadata, false) val dbFile = dbManager.openFile("BRARTI2L") @@ -98,7 +94,7 @@ class JT400OperationsOnFile { // Step3: check record is updated // Step4: restore previous field value and update // Step5: check record is updated (value must be as initial) - val fileMetadata = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "BRARTI0L") + val fileMetadata = MetadataSerializer.jsonToMetadata("src/test/resources/dds/", "BRARTI0L") dbManager.registerMetadata(fileMetadata, false) val dbFile = dbManager.openFile("BRARTI0L") @@ -144,7 +140,7 @@ class JT400OperationsOnFile { // Step3: check the new record exists // Step4: delete written record // Step5: check record not exists (DB must be as initial) - val fileMetadata = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "BRARTI0L") + val fileMetadata = MetadataSerializer.jsonToMetadata("src/test/resources/dds/", "BRARTI0L") dbManager.registerMetadata(fileMetadata, false) val dbFile = dbManager.openFile("BRARTI0L") val key = System.currentTimeMillis().toString() + " " @@ -184,7 +180,7 @@ class JT400OperationsOnFile { // Step3: check the new record exists // Step4: delete written record // Step5: check record not exists (DB must be as initial) - val fileMetadata = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "BRARTI0L") + val fileMetadata = MetadataSerializer.jsonToMetadata("src/test/resources/dds/", "BRARTI0L") dbManager.registerMetadata(fileMetadata, false) val dbFile = dbManager.openFile("BRARTI0L") val key = System.currentTimeMillis().toString() + " " @@ -219,6 +215,7 @@ class JT400OperationsOnFile { dbManager.closeFile("BRARTI0L") } + /* @Test fun multipleUpdateOnReadE(){ // TEST FLOW @@ -226,7 +223,7 @@ class JT400OperationsOnFile { // Step2: read above written records and update A§DEA2 field // Step3: check and check for correct update // Step4: delete written record. - val tMetadata = propertiesToTypedMetadata("src/test/resources/dds/properties/", "BRARTI1L") + val tMetadata = propertiesToTypedMetadata("src/test/resources/dds/", "BRARTI1L") dbManager.registerMetadata(tMetadata.fileMetadata(), false) val dbFile = dbManager.openFile("BRARTI1L") @@ -299,8 +296,8 @@ class JT400OperationsOnFile { //Delete record dbFile.delete(readEResult.record) } - } + */ @Test fun writeNotExistingRecordOnAHugeTable() { @@ -311,7 +308,7 @@ class JT400OperationsOnFile { // Step4: delete written record // Step5: check record not exists (DB must be as initial) - val fileMetadata = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "VERAPG0L") + val fileMetadata = MetadataSerializer.jsonToMetadata("src/test/resources/dds/", "VERAPG0L") dbManager.registerMetadata(fileMetadata, false) val dbFile = dbManager.openFile("VERAPG0L") val key = System.currentTimeMillis().toString().substring(3) @@ -341,7 +338,7 @@ class JT400OperationsOnFile { @Test fun findRecordsIfSetllAndReadWithKeyExistingKey() { - val fileMetadata = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "VERAPG1L") + val fileMetadata = MetadataSerializer.jsonToMetadata("src/test/resources/dds/", "VERAPG1L") dbManager.registerMetadata(fileMetadata, false) val dbFile = dbManager.openFile("VERAPG1L") @@ -372,7 +369,7 @@ class JT400OperationsOnFile { @Test fun findRecordsIfChainWithExistingKey() { - val fileMetadata = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "BRARTI0L") + val fileMetadata = MetadataSerializer.jsonToMetadata("src/test/resources/dds/", "BRARTI0L") dbManager.registerMetadata(fileMetadata, false) val dbFile = dbManager.openFile("BRARTI0L") val key = "A01 " @@ -387,7 +384,7 @@ class JT400OperationsOnFile { /* @Test fun resultSetCursorMovements(){ - val fileMetadata = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "BRARTI0L") + val fileMetadata = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/", "BRARTI0L") dbManager.registerMetadata(fileMetadata, false) val dbFile = dbManager.openFile("BRARTI0L") @@ -411,7 +408,7 @@ class JT400OperationsOnFile { @Test fun resultSetCursorUpdate(){ - val fileMetadata = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "BRARTI0L") + val fileMetadata = PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/", "BRARTI0L") dbManager.registerMetadata(fileMetadata, false) val dbFile = dbManager.openFile("BRARTI0L") diff --git a/jt400/src/test/resources/dds/properties/BRARTI0F.properties b/jt400/src/test/resources/dds/properties/BRARTI0F.properties deleted file mode 100644 index de85b76..0000000 --- a/jt400/src/test/resources/dds/properties/BRARTI0F.properties +++ /dev/null @@ -1,141 +0,0 @@ -# -# Copyright 2020 The Reload project Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# - -# -# - recordformat: declare record format name -# - list of fields (field.name = description, datatype, length, decimal) -# - fieldsKeys: list of fields keys, if any, comma separated -# -# ANAGRAFICA ARTICOLI -# -recordformat = BRARTIR -field.A§ARTI = Codice articolo,CHARACTER,15,0 -field.A§DEAR = Descrizione articolo,CHARACTER,35,0 -field.A§DEA2 = Descrizione aggiuntiva,CHARACTER,35,0 -field.A§TIAR = Tipo articolo,CHARACTER,5,0 -field.A§TPAR = Tipo parte,CHARACTER,3,0 -field.A§UNMS = Unità di misura gestione,CHARACTER,2,0 -field.A§PESO = Peso,DECIMAL,12,5 -field.A§VOLU = Volume,DECIMAL,12,5 -field.A§CALT = Codice alternativo,CHARACTER,15,0 -field.A§ARRI = Articolo di riferimento,CHARACTER,15,0 -field.A§DISE = Disegno,CHARACTER,20,0 -field.A§BARC = Barcode,CHARACTER,15,0 -field.A§STAT = Stato,CHARACTER,2,0 -field.A§LIVE = Livello,CHARACTER,1,0 -field.A§GRDI = Gruppo distinta,CHARACTER,15,0 -field.A§GRCI = Gruppo ciclo,CHARACTER,15,0 -field.A§NOMC = Nome configurazione,CHARACTER,20,0 -field.A§CSVQ = Cod. Sviluppo qtà,CHARACTER,5,0 -field.A§CSVA = Cod. svil. varianti,CHARACTER,5,0 -field.A§ENIR = Ente interno responsabile,CHARACTER,3,0 -field.A§LOTR = Lotto di riferimento,DECIMAL,11,3 -field.A§CONT = Contenitore,CHARACTER,15,0 -field.A§RCDV = Rif. catalogo di vendita,CHARACTER,15,0 -field.A§CASI = Assoggettamento IVA,CHARACTER,5,0 -field.A§NCOM = Nomenclatura combinata,CHARACTER,10,0 -field.A§CESP = Cespite,CHARACTER,15,0 -field.A§CLMA = Classe materiale,CHARACTER,5,0 -field.A§CLPR = Classe programmazione,CHARACTER,5,0 -field.A§CLGE = Classe gestione,CHARACTER,5,0 -field.A§CLCO = Classe contabile,CHARACTER,5,0 -field.A§CDLF = Classe fiscale,CHARACTER,5,0 -field.A§CLVA = Classe valore,CHARACTER,5,0 -field.A§CLFU = Classe funzionale,CHARACTER,5,0 -field.A§TC01 = Tipo classificazione 1,CHARACTER,12,0 -field.A§TC02 = Tipo classificazione 2,CHARACTER,12,0 -field.A§TC03 = Tipo classificazione 3,CHARACTER,12,0 -field.A§CL01 = Codice classificazione 1,CHARACTER,15,0 -field.A§CL02 = Codice classificazione 2,CHARACTER,15,0 -field.A§CL03 = Codice classificazione 3,CHARACTER,15,0 -field.A§COD1 = Codice 1,CHARACTER,15,0 -field.A§COD2 = Codice 2,CHARACTER,15,0 -field.A§COD3 = Codice 3,CHARACTER,15,0 -field.A§COD4 = Codice 4,CHARACTER,15,0 -field.A§COD5 = Codice 5,CHARACTER,15,0 -field.A§CD06 = Codice 6,CHARACTER,15,0 -field.A§CD07 = Codice 7,CHARACTER,15,0 -field.A§CD08 = Codice 8,CHARACTER,15,0 -field.A§CD09 = Codice 9,CHARACTER,15,0 -field.A§CD10 = Codice 10,CHARACTER,15,0 -field.A§NUM1 = Numero 1,DECIMAL,15,5 -field.A§NUM2 = Numero 2,DECIMAL,15,5 -field.A§NUM3 = Numero 3,DECIMAL,15,5 -field.A§NUM4 = Numero 4,DECIMAL,15,5 -field.A§NUM5 = Numero 5,DECIMAL,15,5 -field.A§NR06 = Numero 6,DECIMAL,15,5 -field.A§NR07 = Numero 7,DECIMAL,15,5 -field.A§NR08 = Numero 8,DECIMAL,15,5 -field.A§NR09 = Numero 9,DECIMAL,15,5 -field.A§NR10 = Numero 10,DECIMAL,15,5 -field.A§DT01 = Data 1,DECIMAL,8,0 -field.A§DT02 = Data 2,DECIMAL,8,0 -field.A§DT03 = Data 3,DECIMAL,8,0 -field.A§DT04 = Data 4,DECIMAL,8,0 -field.A§DT05 = Data 5,DECIMAL,8,0 -field.A§DT06 = Data 6,DECIMAL,8,0 -field.A§DT07 = Data 7,DECIMAL,8,0 -field.A§DT08 = Data 8,DECIMAL,8,0 -field.A§DT09 = Data 9,DECIMAL,8,0 -field.A§DT10 = Data 10,DECIMAL,8,0 -field.A§FL01 = Articolo non di magazzino (V2,CHARACTER,1,0 -field.A§FL02 = Codice da PDM (V2SI/NO),CHARACTER,1,0 -field.A§FL03 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL04 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL05 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL06 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL07 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL08 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL09 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL10 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL11 = Libero,CHARACTER,1,0 -field.A§FL12 = Libero,CHARACTER,1,0 -field.A§FL13 = Libero,CHARACTER,1,0 -field.A§FL14 = Libero,CHARACTER,1,0 -field.A§FL15 = Libero,CHARACTER,1,0 -field.A§FL16 = Libero,CHARACTER,1,0 -field.A§FL17 = Libero,CHARACTER,1,0 -field.A§FL18 = Libero,CHARACTER,1,0 -field.A§FL19 = Libero,CHARACTER,1,0 -field.A§FL20 = Libero,CHARACTER,1,0 -field.A§FL21 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL22 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL23 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL24 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL25 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL26 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL27 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL28 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL29 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL30 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL31 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL32 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL33 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL34 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL35 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL36 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL37 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL38 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL39 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL40 = Riservato UTENTE,CHARACTER,1,0 -field.A§USIN = Utente inserimento,CHARACTER,10,0 -field.A§DTIN = Data inserimento,DECIMAL,8,0 -field.A§ORIN = Ora inserimento,DECIMAL,6,0 -field.A§USAG = Utente aggiornamento,CHARACTER,10,0 -field.A§DTAG = Data aggiornamento,DECIMAL,8,0 -field.A§ORAG = Ora aggiornamento,DECIMAL,6,0 -filekeys = diff --git a/jt400/src/test/resources/dds/properties/BRARTI0L.properties b/jt400/src/test/resources/dds/properties/BRARTI0L.properties deleted file mode 100644 index 04356ec..0000000 --- a/jt400/src/test/resources/dds/properties/BRARTI0L.properties +++ /dev/null @@ -1,141 +0,0 @@ -# -# Copyright 2020 The Reload project Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# - -# -# - recordformat: declare record format name -# - list of fields (field.name = description, datatype, length, decimal) -# - fieldsKeys: list of fields keys, if any, comma separated -# -# ANAGRAFICA ARTICOLI -# -recordformat = BRARTIR -field.A§ARTI = Codice articolo,CHARACTER,15,0 -field.A§DEAR = Descrizione articolo,CHARACTER,35,0 -field.A§DEA2 = Descrizione aggiuntiva,CHARACTER,35,0 -field.A§TIAR = Tipo articolo,CHARACTER,5,0 -field.A§TPAR = Tipo parte,CHARACTER,3,0 -field.A§UNMS = Unità di misura gestione,CHARACTER,2,0 -field.A§PESO = Peso,DECIMAL,12,5 -field.A§VOLU = Volume,DECIMAL,12,5 -field.A§CALT = Codice alternativo,CHARACTER,15,0 -field.A§ARRI = Articolo di riferimento,CHARACTER,15,0 -field.A§DISE = Disegno,CHARACTER,20,0 -field.A§BARC = Barcode,CHARACTER,15,0 -field.A§STAT = Stato,CHARACTER,2,0 -field.A§LIVE = Livello,CHARACTER,1,0 -field.A§GRDI = Gruppo distinta,CHARACTER,15,0 -field.A§GRCI = Gruppo ciclo,CHARACTER,15,0 -field.A§NOMC = Nome configurazione,CHARACTER,20,0 -field.A§CSVQ = Cod. Sviluppo qtà,CHARACTER,5,0 -field.A§CSVA = Cod. svil. varianti,CHARACTER,5,0 -field.A§ENIR = Ente interno responsabile,CHARACTER,3,0 -field.A§LOTR = Lotto di riferimento,DECIMAL,11,3 -field.A§CONT = Contenitore,CHARACTER,15,0 -field.A§RCDV = Rif. catalogo di vendita,CHARACTER,15,0 -field.A§CASI = Assoggettamento IVA,CHARACTER,5,0 -field.A§NCOM = Nomenclatura combinata,CHARACTER,10,0 -field.A§CESP = Cespite,CHARACTER,15,0 -field.A§CLMA = Classe materiale,CHARACTER,5,0 -field.A§CLPR = Classe programmazione,CHARACTER,5,0 -field.A§CLGE = Classe gestione,CHARACTER,5,0 -field.A§CLCO = Classe contabile,CHARACTER,5,0 -field.A§CDLF = Classe fiscale,CHARACTER,5,0 -field.A§CLVA = Classe valore,CHARACTER,5,0 -field.A§CLFU = Classe funzionale,CHARACTER,5,0 -field.A§TC01 = Tipo classificazione 1,CHARACTER,12,0 -field.A§TC02 = Tipo classificazione 2,CHARACTER,12,0 -field.A§TC03 = Tipo classificazione 3,CHARACTER,12,0 -field.A§CL01 = Codice classificazione 1,CHARACTER,15,0 -field.A§CL02 = Codice classificazione 2,CHARACTER,15,0 -field.A§CL03 = Codice classificazione 3,CHARACTER,15,0 -field.A§COD1 = Codice 1,CHARACTER,15,0 -field.A§COD2 = Codice 2,CHARACTER,15,0 -field.A§COD3 = Codice 3,CHARACTER,15,0 -field.A§COD4 = Codice 4,CHARACTER,15,0 -field.A§COD5 = Codice 5,CHARACTER,15,0 -field.A§CD06 = Codice 6,CHARACTER,15,0 -field.A§CD07 = Codice 7,CHARACTER,15,0 -field.A§CD08 = Codice 8,CHARACTER,15,0 -field.A§CD09 = Codice 9,CHARACTER,15,0 -field.A§CD10 = Codice 10,CHARACTER,15,0 -field.A§NUM1 = Numero 1,DECIMAL,15,5 -field.A§NUM2 = Numero 2,DECIMAL,15,5 -field.A§NUM3 = Numero 3,DECIMAL,15,5 -field.A§NUM4 = Numero 4,DECIMAL,15,5 -field.A§NUM5 = Numero 5,DECIMAL,15,5 -field.A§NR06 = Numero 6,DECIMAL,15,5 -field.A§NR07 = Numero 7,DECIMAL,15,5 -field.A§NR08 = Numero 8,DECIMAL,15,5 -field.A§NR09 = Numero 9,DECIMAL,15,5 -field.A§NR10 = Numero 10,DECIMAL,15,5 -field.A§DT01 = Data 1,DECIMAL,8,0 -field.A§DT02 = Data 2,DECIMAL,8,0 -field.A§DT03 = Data 3,DECIMAL,8,0 -field.A§DT04 = Data 4,DECIMAL,8,0 -field.A§DT05 = Data 5,DECIMAL,8,0 -field.A§DT06 = Data 6,DECIMAL,8,0 -field.A§DT07 = Data 7,DECIMAL,8,0 -field.A§DT08 = Data 8,DECIMAL,8,0 -field.A§DT09 = Data 9,DECIMAL,8,0 -field.A§DT10 = Data 10,DECIMAL,8,0 -field.A§FL01 = Articolo non di magazzino (V2,CHARACTER,1,0 -field.A§FL02 = Codice da PDM (V2SI/NO),CHARACTER,1,0 -field.A§FL03 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL04 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL05 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL06 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL07 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL08 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL09 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL10 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL11 = Libero,CHARACTER,1,0 -field.A§FL12 = Libero,CHARACTER,1,0 -field.A§FL13 = Libero,CHARACTER,1,0 -field.A§FL14 = Libero,CHARACTER,1,0 -field.A§FL15 = Libero,CHARACTER,1,0 -field.A§FL16 = Libero,CHARACTER,1,0 -field.A§FL17 = Libero,CHARACTER,1,0 -field.A§FL18 = Libero,CHARACTER,1,0 -field.A§FL19 = Libero,CHARACTER,1,0 -field.A§FL20 = Libero,CHARACTER,1,0 -field.A§FL21 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL22 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL23 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL24 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL25 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL26 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL27 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL28 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL29 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL30 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL31 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL32 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL33 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL34 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL35 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL36 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL37 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL38 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL39 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL40 = Riservato UTENTE,CHARACTER,1,0 -field.A§USIN = Utente inserimento,CHARACTER,10,0 -field.A§DTIN = Data inserimento,DECIMAL,8,0 -field.A§ORIN = Ora inserimento,DECIMAL,6,0 -field.A§USAG = Utente aggiornamento,CHARACTER,10,0 -field.A§DTAG = Data aggiornamento,DECIMAL,8,0 -field.A§ORAG = Ora aggiornamento,DECIMAL,6,0 -filekeys = A§ARTI \ No newline at end of file diff --git a/jt400/src/test/resources/dds/properties/BRARTI1L.properties b/jt400/src/test/resources/dds/properties/BRARTI1L.properties deleted file mode 100644 index 32351a8..0000000 --- a/jt400/src/test/resources/dds/properties/BRARTI1L.properties +++ /dev/null @@ -1,141 +0,0 @@ -# -# Copyright 2020 The Reload project Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# - -# -# - recordformat: declare record format name -# - list of fields (field.name = description, datatype, length, decimal) -# - fieldsKeys: list of fields keys, if any, comma separated -# -# ANAGRAFICA ARTICOLI -# -recordformat = BRARTIR -field.A§ARTI = Codice articolo,CHARACTER,15,0 -field.A§DEAR = Descrizione articolo,CHARACTER,35,0 -field.A§DEA2 = Descrizione aggiuntiva,CHARACTER,35,0 -field.A§TIAR = Tipo articolo,CHARACTER,5,0 -field.A§TPAR = Tipo parte,CHARACTER,3,0 -field.A§UNMS = Unità di misura gestione,CHARACTER,2,0 -field.A§PESO = Peso,DECIMAL,12,5 -field.A§VOLU = Volume,DECIMAL,12,5 -field.A§CALT = Codice alternativo,CHARACTER,15,0 -field.A§ARRI = Articolo di riferimento,CHARACTER,15,0 -field.A§DISE = Disegno,CHARACTER,20,0 -field.A§BARC = Barcode,CHARACTER,15,0 -field.A§STAT = Stato,CHARACTER,2,0 -field.A§LIVE = Livello,CHARACTER,1,0 -field.A§GRDI = Gruppo distinta,CHARACTER,15,0 -field.A§GRCI = Gruppo ciclo,CHARACTER,15,0 -field.A§NOMC = Nome configurazione,CHARACTER,20,0 -field.A§CSVQ = Cod. Sviluppo qtà,CHARACTER,5,0 -field.A§CSVA = Cod. svil. varianti,CHARACTER,5,0 -field.A§ENIR = Ente interno responsabile,CHARACTER,3,0 -field.A§LOTR = Lotto di riferimento,DECIMAL,11,3 -field.A§CONT = Contenitore,CHARACTER,15,0 -field.A§RCDV = Rif. catalogo di vendita,CHARACTER,15,0 -field.A§CASI = Assoggettamento IVA,CHARACTER,5,0 -field.A§NCOM = Nomenclatura combinata,CHARACTER,10,0 -field.A§CESP = Cespite,CHARACTER,15,0 -field.A§CLMA = Classe materiale,CHARACTER,5,0 -field.A§CLPR = Classe programmazione,CHARACTER,5,0 -field.A§CLGE = Classe gestione,CHARACTER,5,0 -field.A§CLCO = Classe contabile,CHARACTER,5,0 -field.A§CDLF = Classe fiscale,CHARACTER,5,0 -field.A§CLVA = Classe valore,CHARACTER,5,0 -field.A§CLFU = Classe funzionale,CHARACTER,5,0 -field.A§TC01 = Tipo classificazione 1,CHARACTER,12,0 -field.A§TC02 = Tipo classificazione 2,CHARACTER,12,0 -field.A§TC03 = Tipo classificazione 3,CHARACTER,12,0 -field.A§CL01 = Codice classificazione 1,CHARACTER,15,0 -field.A§CL02 = Codice classificazione 2,CHARACTER,15,0 -field.A§CL03 = Codice classificazione 3,CHARACTER,15,0 -field.A§COD1 = Codice 1,CHARACTER,15,0 -field.A§COD2 = Codice 2,CHARACTER,15,0 -field.A§COD3 = Codice 3,CHARACTER,15,0 -field.A§COD4 = Codice 4,CHARACTER,15,0 -field.A§COD5 = Codice 5,CHARACTER,15,0 -field.A§CD06 = Codice 6,CHARACTER,15,0 -field.A§CD07 = Codice 7,CHARACTER,15,0 -field.A§CD08 = Codice 8,CHARACTER,15,0 -field.A§CD09 = Codice 9,CHARACTER,15,0 -field.A§CD10 = Codice 10,CHARACTER,15,0 -field.A§NUM1 = Numero 1,DECIMAL,15,5 -field.A§NUM2 = Numero 2,DECIMAL,15,5 -field.A§NUM3 = Numero 3,DECIMAL,15,5 -field.A§NUM4 = Numero 4,DECIMAL,15,5 -field.A§NUM5 = Numero 5,DECIMAL,15,5 -field.A§NR06 = Numero 6,DECIMAL,15,5 -field.A§NR07 = Numero 7,DECIMAL,15,5 -field.A§NR08 = Numero 8,DECIMAL,15,5 -field.A§NR09 = Numero 9,DECIMAL,15,5 -field.A§NR10 = Numero 10,DECIMAL,15,5 -field.A§DT01 = Data 1,DECIMAL,8,0 -field.A§DT02 = Data 2,DECIMAL,8,0 -field.A§DT03 = Data 3,DECIMAL,8,0 -field.A§DT04 = Data 4,DECIMAL,8,0 -field.A§DT05 = Data 5,DECIMAL,8,0 -field.A§DT06 = Data 6,DECIMAL,8,0 -field.A§DT07 = Data 7,DECIMAL,8,0 -field.A§DT08 = Data 8,DECIMAL,8,0 -field.A§DT09 = Data 9,DECIMAL,8,0 -field.A§DT10 = Data 10,DECIMAL,8,0 -field.A§FL01 = Articolo non di magazzino (V2,CHARACTER,1,0 -field.A§FL02 = Codice da PDM (V2SI/NO),CHARACTER,1,0 -field.A§FL03 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL04 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL05 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL06 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL07 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL08 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL09 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL10 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL11 = Libero,CHARACTER,1,0 -field.A§FL12 = Libero,CHARACTER,1,0 -field.A§FL13 = Libero,CHARACTER,1,0 -field.A§FL14 = Libero,CHARACTER,1,0 -field.A§FL15 = Libero,CHARACTER,1,0 -field.A§FL16 = Libero,CHARACTER,1,0 -field.A§FL17 = Libero,CHARACTER,1,0 -field.A§FL18 = Libero,CHARACTER,1,0 -field.A§FL19 = Libero,CHARACTER,1,0 -field.A§FL20 = Libero,CHARACTER,1,0 -field.A§FL21 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL22 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL23 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL24 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL25 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL26 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL27 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL28 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL29 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL30 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL31 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL32 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL33 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL34 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL35 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL36 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL37 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL38 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL39 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL40 = Riservato UTENTE,CHARACTER,1,0 -field.A§USIN = Utente inserimento,CHARACTER,10,0 -field.A§DTIN = Data inserimento,DECIMAL,8,0 -field.A§ORIN = Ora inserimento,DECIMAL,6,0 -field.A§USAG = Utente aggiornamento,CHARACTER,10,0 -field.A§DTAG = Data aggiornamento,DECIMAL,8,0 -field.A§ORAG = Ora aggiornamento,DECIMAL,6,0 -filekeys = A§DEAR,A§ARTI diff --git a/jt400/src/test/resources/dds/properties/BRARTI2L.properties b/jt400/src/test/resources/dds/properties/BRARTI2L.properties deleted file mode 100644 index be18b10..0000000 --- a/jt400/src/test/resources/dds/properties/BRARTI2L.properties +++ /dev/null @@ -1,141 +0,0 @@ -# -# Copyright 2020 The Reload project Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# - -# -# - recordformat: declare record format name -# - list of fields (field.name = description, datatype, length, decimal) -# - fieldsKeys: list of fields keys, if any, comma separated -# -# ANAGRAFICA ARTICOLI -# -recordformat = BRARTIR -field.A§ARTI = Codice articolo,CHARACTER,15,0 -field.A§DEAR = Descrizione articolo,CHARACTER,35,0 -field.A§DEA2 = Descrizione aggiuntiva,CHARACTER,35,0 -field.A§TIAR = Tipo articolo,CHARACTER,5,0 -field.A§TPAR = Tipo parte,CHARACTER,3,0 -field.A§UNMS = Unità di misura gestione,CHARACTER,2,0 -field.A§PESO = Peso,DECIMAL,12,5 -field.A§VOLU = Volume,DECIMAL,12,5 -field.A§CALT = Codice alternativo,CHARACTER,15,0 -field.A§ARRI = Articolo di riferimento,CHARACTER,15,0 -field.A§DISE = Disegno,CHARACTER,20,0 -field.A§BARC = Barcode,CHARACTER,15,0 -field.A§STAT = Stato,CHARACTER,2,0 -field.A§LIVE = Livello,CHARACTER,1,0 -field.A§GRDI = Gruppo distinta,CHARACTER,15,0 -field.A§GRCI = Gruppo ciclo,CHARACTER,15,0 -field.A§NOMC = Nome configurazione,CHARACTER,20,0 -field.A§CSVQ = Cod. Sviluppo qtà,CHARACTER,5,0 -field.A§CSVA = Cod. svil. varianti,CHARACTER,5,0 -field.A§ENIR = Ente interno responsabile,CHARACTER,3,0 -field.A§LOTR = Lotto di riferimento,DECIMAL,11,3 -field.A§CONT = Contenitore,CHARACTER,15,0 -field.A§RCDV = Rif. catalogo di vendita,CHARACTER,15,0 -field.A§CASI = Assoggettamento IVA,CHARACTER,5,0 -field.A§NCOM = Nomenclatura combinata,CHARACTER,10,0 -field.A§CESP = Cespite,CHARACTER,15,0 -field.A§CLMA = Classe materiale,CHARACTER,5,0 -field.A§CLPR = Classe programmazione,CHARACTER,5,0 -field.A§CLGE = Classe gestione,CHARACTER,5,0 -field.A§CLCO = Classe contabile,CHARACTER,5,0 -field.A§CDLF = Classe fiscale,CHARACTER,5,0 -field.A§CLVA = Classe valore,CHARACTER,5,0 -field.A§CLFU = Classe funzionale,CHARACTER,5,0 -field.A§TC01 = Tipo classificazione 1,CHARACTER,12,0 -field.A§TC02 = Tipo classificazione 2,CHARACTER,12,0 -field.A§TC03 = Tipo classificazione 3,CHARACTER,12,0 -field.A§CL01 = Codice classificazione 1,CHARACTER,15,0 -field.A§CL02 = Codice classificazione 2,CHARACTER,15,0 -field.A§CL03 = Codice classificazione 3,CHARACTER,15,0 -field.A§COD1 = Codice 1,CHARACTER,15,0 -field.A§COD2 = Codice 2,CHARACTER,15,0 -field.A§COD3 = Codice 3,CHARACTER,15,0 -field.A§COD4 = Codice 4,CHARACTER,15,0 -field.A§COD5 = Codice 5,CHARACTER,15,0 -field.A§CD06 = Codice 6,CHARACTER,15,0 -field.A§CD07 = Codice 7,CHARACTER,15,0 -field.A§CD08 = Codice 8,CHARACTER,15,0 -field.A§CD09 = Codice 9,CHARACTER,15,0 -field.A§CD10 = Codice 10,CHARACTER,15,0 -field.A§NUM1 = Numero 1,DECIMAL,15,5 -field.A§NUM2 = Numero 2,DECIMAL,15,5 -field.A§NUM3 = Numero 3,DECIMAL,15,5 -field.A§NUM4 = Numero 4,DECIMAL,15,5 -field.A§NUM5 = Numero 5,DECIMAL,15,5 -field.A§NR06 = Numero 6,DECIMAL,15,5 -field.A§NR07 = Numero 7,DECIMAL,15,5 -field.A§NR08 = Numero 8,DECIMAL,15,5 -field.A§NR09 = Numero 9,DECIMAL,15,5 -field.A§NR10 = Numero 10,DECIMAL,15,5 -field.A§DT01 = Data 1,DECIMAL,8,0 -field.A§DT02 = Data 2,DECIMAL,8,0 -field.A§DT03 = Data 3,DECIMAL,8,0 -field.A§DT04 = Data 4,DECIMAL,8,0 -field.A§DT05 = Data 5,DECIMAL,8,0 -field.A§DT06 = Data 6,DECIMAL,8,0 -field.A§DT07 = Data 7,DECIMAL,8,0 -field.A§DT08 = Data 8,DECIMAL,8,0 -field.A§DT09 = Data 9,DECIMAL,8,0 -field.A§DT10 = Data 10,DECIMAL,8,0 -field.A§FL01 = Articolo non di magazzino (V2,CHARACTER,1,0 -field.A§FL02 = Codice da PDM (V2SI/NO),CHARACTER,1,0 -field.A§FL03 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL04 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL05 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL06 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL07 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL08 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL09 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL10 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL11 = Libero,CHARACTER,1,0 -field.A§FL12 = Libero,CHARACTER,1,0 -field.A§FL13 = Libero,CHARACTER,1,0 -field.A§FL14 = Libero,CHARACTER,1,0 -field.A§FL15 = Libero,CHARACTER,1,0 -field.A§FL16 = Libero,CHARACTER,1,0 -field.A§FL17 = Libero,CHARACTER,1,0 -field.A§FL18 = Libero,CHARACTER,1,0 -field.A§FL19 = Libero,CHARACTER,1,0 -field.A§FL20 = Libero,CHARACTER,1,0 -field.A§FL21 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL22 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL23 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL24 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL25 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL26 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL27 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL28 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL29 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL30 = Riservato Sme.UP ERP,CHARACTER,1,0 -field.A§FL31 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL32 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL33 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL34 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL35 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL36 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL37 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL38 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL39 = Riservato UTENTE,CHARACTER,1,0 -field.A§FL40 = Riservato UTENTE,CHARACTER,1,0 -field.A§USIN = Utente inserimento,CHARACTER,10,0 -field.A§DTIN = Data inserimento,DECIMAL,8,0 -field.A§ORIN = Ora inserimento,DECIMAL,6,0 -field.A§USAG = Utente aggiornamento,CHARACTER,10,0 -field.A§DTAG = Data aggiornamento,DECIMAL,8,0 -field.A§ORAG = Ora aggiornamento,DECIMAL,6,0 -filekeys = A§TIAR,A§ARTI \ No newline at end of file diff --git a/jt400/src/test/resources/dds/properties/VERAPG0F.properties b/jt400/src/test/resources/dds/properties/VERAPG0F.properties deleted file mode 100644 index a78d1c2..0000000 --- a/jt400/src/test/resources/dds/properties/VERAPG0F.properties +++ /dev/null @@ -1,94 +0,0 @@ -# -# Copyright 2020 The Reload project Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# - -# -# - recordformat: declare record format name -# - list of fields (field.name = description, datatype, length, decimal) -# - fieldsKeys: list of fields keys, if any, comma separated -# -# RAPPORTINI GIORNALIERI -# -recordformat = VERAPGR -field.V£IDOJ = Identificativo univoco record,CHARACTER,10,0 -field.V£ATV0 = Stato,CHARACTER,1,0 -field.V£DATA = Data attività,DECIMAL,8,0 -field.V£NOME = Codice nominativo,CHARACTER,15,0 -field.V£CDC = C.d.r./Commessa,CHARACTER,15,0 -field.V£TIPO = Tipo Attività,CHARACTER,3,0 -field.V£ORE = Ore,DECIMAL,5,2 -field.V£VIAC = Viaggi cliente,DECIMAL,5,2 -field.V£VIAS = Viaggi sede,DECIMAL,5,2 -field.V£KM = Chilometri cliente,DECIMAL,5,0 -field.V£KMSE = Chilometri sede,DECIMAL,5,0 -field.V£PEDC = Pedaggi cliente,DECIMAL,11,2 -field.V£PEDS = Pedaggi sede,DECIMAL,11,2 -field.V£RISC = Ristoranti cliente,DECIMAL,11,2 -field.V£RISS = Ristoranti sede,DECIMAL,11,2 -field.V£ALBC = Albergo cliente,DECIMAL,11,2 -field.V£ALBS = Albergo sede,DECIMAL,11,2 -field.V£SPEC = Altre spese cliente,DECIMAL,11,2 -field.V£SPES = Altre spese sede,DECIMAL,11,2 -field.V£CAUS = Causale altre spese,CHARACTER,3,0 -field.V£TCOM = Tipo Commento,CHARACTER,1,0 -field.V£COM1 = Commento 1,CHARACTER,210,0 -field.V£COM2 = Commento 2,CHARACTER,210,0 -field.V£DIAR = Diaria,DECIMAL,5,2 -field.V£DIUS = Dirito di uscita ,DECIMAL,5,2 -field.V£NFAT = Numero fattura generata, A,10,0 -field.V£DFAT = Data fattura generata ,DECIMAL,8,0 -field.V£COD1 = Sede secondaria ,CHARACTER,15,0 -field.V£COD2 = Riga V5 fattura ,CHARACTER,15,0 -field.V£COD3 = Riga E4 fatt.pas.,CHARACTER,15,0 -field.V£COD4 = Riga V5 fatt.Ico,CHARACTER,15,0 -field.V£COD5 = Campo Alfanum. 5,CHARACTER,15,0 -field.V£COD6 = Campo Alfanum. 6,CHARACTER,15,0 -field.V£COD7 = Campo Alfanum. 7,CHARACTER,15,0 -field.V£COD8 = Campo Alfanum. 8,CHARACTER,15,0 -field.V£COD9 = Azienda commessa,CHARACTER,15,0 -field.V£COD0 = Cliente commessa,CHARACTER,15,0 -field.V£NUM1 = Ora inizio,DECIMAL,21,6 -field.V£NUM2 = Campo Numerico 2,DECIMAL,21,6 -field.V£NUM3 = Ora fine,DECIMAL,21,6 -field.V£NUM4 = Campo Numerico 4,DECIMAL,21,6 -field.V£NUM5 = Campo Numerico 5,DECIMAL,21,6 -field.V£FL01 = Flag,CHARACTER,1,0 -field.V£FL02 = Flag,CHARACTER,1,0 -field.V£FL03 = Flag,CHARACTER,1,0 -field.V£FL04 = Flag,CHARACTER,1,0 -field.V£FL05 = Flag,CHARACTER,1,0 -field.V£FL06 = Flag,CHARACTER,1,0 -field.V£FL07 = Flag,CHARACTER,1,0 -field.V£FL08 = Flag,CHARACTER,1,0 -field.V£FL09 = Flag,CHARACTER,1,0 -field.V£FL10 = Flag,CHARACTER,1,0 -field.V£FL11 = Flag,CHARACTER,1,0 -field.V£FL12 = Flag,CHARACTER,1,0 -field.V£FL13 = Flag,CHARACTER,1,0 -field.V£FL14 = Flag,CHARACTER,1,0 -field.V£FL15 = Flag,CHARACTER,1,0 -field.V£FL16 = Flag,CHARACTER,1,0 -field.V£FL17 = Flag,CHARACTER,1,0 -field.V£FL18 = Flag,CHARACTER,1,0 -field.V£FL19 = Flag,CHARACTER,1,0 -field.V£FL20 = Flag,CHARACTER,1,0 -field.V£USIN = Utente inserimento,CHARACTER,10,0 -field.V£DTIN = Data inserimento,DECIMAL,8,0 -field.V£ORIN = Ora inserimento,DECIMAL,6,0 -field.V£USAG = Utente aggiornamento,CHARACTER,10,0 -field.V£DTAG = Data aggiornamento,DECIMAL,8,0 -field.V£ORAG = Ora aggiornamento,DECIMAL,6,0 -filekeys = \ No newline at end of file diff --git a/jt400/src/test/resources/dds/properties/VERAPG0L.properties b/jt400/src/test/resources/dds/properties/VERAPG0L.properties deleted file mode 100644 index 4112acb..0000000 --- a/jt400/src/test/resources/dds/properties/VERAPG0L.properties +++ /dev/null @@ -1,94 +0,0 @@ -# -# Copyright 2020 The Reload project Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# - -# -# - recordformat: declare record format name -# - list of fields (field.name = description, datatype, length, decimal) -# - fieldsKeys: list of fields keys, if any, comma separated -# -# RAPPORTINI GIORNALIERI -# -recordformat = VERAPGR -field.V£IDOJ = Identificativo univoco record,CHARACTER,10,0 -field.V£ATV0 = Stato,CHARACTER,1,0 -field.V£DATA = Data attività,DECIMAL,8,0 -field.V£NOME = Codice nominativo,CHARACTER,15,0 -field.V£CDC = C.d.r./Commessa,CHARACTER,15,0 -field.V£TIPO = Tipo Attività,CHARACTER,3,0 -field.V£ORE = Ore,DECIMAL,5,2 -field.V£VIAC = Viaggi cliente,DECIMAL,5,2 -field.V£VIAS = Viaggi sede,DECIMAL,5,2 -field.V£KM = Chilometri cliente,DECIMAL,5,0 -field.V£KMSE = Chilometri sede,DECIMAL,5,0 -field.V£PEDC = Pedaggi cliente,DECIMAL,11,2 -field.V£PEDS = Pedaggi sede,DECIMAL,11,2 -field.V£RISC = Ristoranti cliente,DECIMAL,11,2 -field.V£RISS = Ristoranti sede,DECIMAL,11,2 -field.V£ALBC = Albergo cliente,DECIMAL,11,2 -field.V£ALBS = Albergo sede,DECIMAL,11,2 -field.V£SPEC = Altre spese cliente,DECIMAL,11,2 -field.V£SPES = Altre spese sede,DECIMAL,11,2 -field.V£CAUS = Causale altre spese,CHARACTER,3,0 -field.V£TCOM = Tipo Commento,CHARACTER,1,0 -field.V£COM1 = Commento 1,CHARACTER,210,0 -field.V£COM2 = Commento 2,CHARACTER,210,0 -field.V£DIAR = Diaria,DECIMAL,5,2 -field.V£DIUS = Dirito di uscita ,DECIMAL,5,2 -field.V£NFAT = Numero fattura generata, CHARACTER,10,0 -field.V£DFAT = Data fattura generata ,DECIMAL,8,0 -field.V£COD1 = Sede secondaria ,CHARACTER,15,0 -field.V£COD2 = Riga V5 fattura ,CHARACTER,15,0 -field.V£COD3 = Riga E4 fatt.pas.,CHARACTER,15,0 -field.V£COD4 = Riga V5 fatt.Ico,CHARACTER,15,0 -field.V£COD5 = Campo Alfanum. 5,CHARACTER,15,0 -field.V£COD6 = Campo Alfanum. 6,CHARACTER,15,0 -field.V£COD7 = Campo Alfanum. 7,CHARACTER,15,0 -field.V£COD8 = Campo Alfanum. 8,CHARACTER,15,0 -field.V£COD9 = Azienda commessa,CHARACTER,15,0 -field.V£COD0 = Cliente commessa,CHARACTER,15,0 -field.V£NUM1 = Ora inizio,DECIMAL,21,6 -field.V£NUM2 = Campo Numerico 2,DECIMAL,21,6 -field.V£NUM3 = Ora fine,DECIMAL,21,6 -field.V£NUM4 = Campo Numerico 4,DECIMAL,21,6 -field.V£NUM5 = Campo Numerico 5,DECIMAL,21,6 -field.V£FL01 = Flag,CHARACTER,1,0 -field.V£FL02 = Flag,CHARACTER,1,0 -field.V£FL03 = Flag,CHARACTER,1,0 -field.V£FL04 = Flag,CHARACTER,1,0 -field.V£FL05 = Flag,CHARACTER,1,0 -field.V£FL06 = Flag,CHARACTER,1,0 -field.V£FL07 = Flag,CHARACTER,1,0 -field.V£FL08 = Flag,CHARACTER,1,0 -field.V£FL09 = Flag,CHARACTER,1,0 -field.V£FL10 = Flag,CHARACTER,1,0 -field.V£FL11 = Flag,CHARACTER,1,0 -field.V£FL12 = Flag,CHARACTER,1,0 -field.V£FL13 = Flag,CHARACTER,1,0 -field.V£FL14 = Flag,CHARACTER,1,0 -field.V£FL15 = Flag,CHARACTER,1,0 -field.V£FL16 = Flag,CHARACTER,1,0 -field.V£FL17 = Flag,CHARACTER,1,0 -field.V£FL18 = Flag,CHARACTER,1,0 -field.V£FL19 = Flag,CHARACTER,1,0 -field.V£FL20 = Flag,CHARACTER,1,0 -field.V£USIN = Utente inserimento,CHARACTER,10,0 -field.V£DTIN = Data inserimento,DECIMAL,8,0 -field.V£ORIN = Ora inserimento,DECIMAL,6,0 -field.V£USAG = Utente aggiornamento,CHARACTER,10,0 -field.V£DTAG = Data aggiornamento,DECIMAL,8,0 -field.V£ORAG = Ora aggiornamento,DECIMAL,6,0 -filekeys = V£IDOJ diff --git a/jt400/src/test/resources/dds/properties/VERAPG1L.properties b/jt400/src/test/resources/dds/properties/VERAPG1L.properties deleted file mode 100644 index 80c8321..0000000 --- a/jt400/src/test/resources/dds/properties/VERAPG1L.properties +++ /dev/null @@ -1,94 +0,0 @@ -# -# Copyright 2020 The Reload project Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# - -# -# - recordformat: declare record format name -# - list of fields (field.name = description, datatype, length, decimal) -# - fieldsKeys: list of fields keys, if any, comma separated -# -# RAPPORTINI GIORNALIERI -# -recordformat = VERAPGR -field.V£IDOJ = Identificativo univoco record,CHARACTER,10,0 -field.V£ATV0 = Stato,CHARACTER,1,0 -field.V£DATA = Data attività,DECIMAL,8,0 -field.V£NOME = Codice nominativo,CHARACTER,15,0 -field.V£CDC = C.d.r./Commessa,CHARACTER,15,0 -field.V£TIPO = Tipo Attività,CHARACTER,3,0 -field.V£ORE = Ore,DECIMAL,5,2 -field.V£VIAC = Viaggi cliente,DECIMAL,5,2 -field.V£VIAS = Viaggi sede,DECIMAL,5,2 -field.V£KM = Chilometri cliente,DECIMAL,5,0 -field.V£KMSE = Chilometri sede,DECIMAL,5,0 -field.V£PEDC = Pedaggi cliente,DECIMAL,11,2 -field.V£PEDS = Pedaggi sede,DECIMAL,11,2 -field.V£RISC = Ristoranti cliente,DECIMAL,11,2 -field.V£RISS = Ristoranti sede,DECIMAL,11,2 -field.V£ALBC = Albergo cliente,DECIMAL,11,2 -field.V£ALBS = Albergo sede,DECIMAL,11,2 -field.V£SPEC = Altre spese cliente,DECIMAL,11,2 -field.V£SPES = Altre spese sede,DECIMAL,11,2 -field.V£CAUS = Causale altre spese,CHARACTER,3,0 -field.V£TCOM = Tipo Commento,CHARACTER,1,0 -field.V£COM1 = Commento 1,CHARACTER,210,0 -field.V£COM2 = Commento 2,CHARACTER,210,0 -field.V£DIAR = Diaria,DECIMAL,5,2 -field.V£DIUS = Dirito di uscita ,DECIMAL,5,2 -field.V£NFAT = Numero fattura generata, CHARACTER,10,0 -field.V£DFAT = Data fattura generata ,DECIMAL,8,0 -field.V£COD1 = Sede secondaria ,CHARACTER,15,0 -field.V£COD2 = Riga V5 fattura ,CHARACTER,15,0 -field.V£COD3 = Riga E4 fatt.pas.,CHARACTER,15,0 -field.V£COD4 = Riga V5 fatt.Ico,CHARACTER,15,0 -field.V£COD5 = Campo Alfanum. 5,CHARACTER,15,0 -field.V£COD6 = Campo Alfanum. 6,CHARACTER,15,0 -field.V£COD7 = Campo Alfanum. 7,CHARACTER,15,0 -field.V£COD8 = Campo Alfanum. 8,CHARACTER,15,0 -field.V£COD9 = Azienda commessa,CHARACTER,15,0 -field.V£COD0 = Cliente commessa,CHARACTER,15,0 -field.V£NUM1 = Ora inizio,DECIMAL,21,6 -field.V£NUM2 = Campo Numerico 2,DECIMAL,21,6 -field.V£NUM3 = Ora fine,DECIMAL,21,6 -field.V£NUM4 = Campo Numerico 4,DECIMAL,21,6 -field.V£NUM5 = Campo Numerico 5,DECIMAL,21,6 -field.V£FL01 = Flag,CHARACTER,1,0 -field.V£FL02 = Flag,CHARACTER,1,0 -field.V£FL03 = Flag,CHARACTER,1,0 -field.V£FL04 = Flag,CHARACTER,1,0 -field.V£FL05 = Flag,CHARACTER,1,0 -field.V£FL06 = Flag,CHARACTER,1,0 -field.V£FL07 = Flag,CHARACTER,1,0 -field.V£FL08 = Flag,CHARACTER,1,0 -field.V£FL09 = Flag,CHARACTER,1,0 -field.V£FL10 = Flag,CHARACTER,1,0 -field.V£FL11 = Flag,CHARACTER,1,0 -field.V£FL12 = Flag,CHARACTER,1,0 -field.V£FL13 = Flag,CHARACTER,1,0 -field.V£FL14 = Flag,CHARACTER,1,0 -field.V£FL15 = Flag,CHARACTER,1,0 -field.V£FL16 = Flag,CHARACTER,1,0 -field.V£FL17 = Flag,CHARACTER,1,0 -field.V£FL18 = Flag,CHARACTER,1,0 -field.V£FL19 = Flag,CHARACTER,1,0 -field.V£FL20 = Flag,CHARACTER,1,0 -field.V£USIN = Utente inserimento,CHARACTER,10,0 -field.V£DTIN = Data inserimento,DECIMAL,8,0 -field.V£ORIN = Ora inserimento,DECIMAL,6,0 -field.V£USAG = Utente aggiornamento,CHARACTER,10,0 -field.V£DTAG = Data aggiornamento,DECIMAL,8,0 -field.V£ORAG = Ora aggiornamento,DECIMAL,6,0 -filekeys = V£DATA,V£NOME,V£IDOJ diff --git a/sql/pom.xml b/sql/pom.xml index b99fcba..ee6b316 100644 --- a/sql/pom.xml +++ b/sql/pom.xml @@ -59,6 +59,11 @@ 8.0.18 test + + org.postgresql + postgresql + 42.7.3 + net.sf.jt400 diff --git a/sql/src/main/kotlin/com/smeup/dbnative/sql/JDBCUtils.kt b/sql/src/main/kotlin/com/smeup/dbnative/sql/JDBCUtils.kt index 72c7821..c9a1532 100644 --- a/sql/src/main/kotlin/com/smeup/dbnative/sql/JDBCUtils.kt +++ b/sql/src/main/kotlin/com/smeup/dbnative/sql/JDBCUtils.kt @@ -26,6 +26,70 @@ import java.sql.ResultSet const val CONVENTIONAL_INDEX_SUFFIX = "_INDEX" + + +fun Connection.isNumericColumn(tableName: String, columnName: String): Boolean { + var isNumeric = false + + createStatement().use { statement -> + statement.executeQuery("SELECT $columnName FROM $tableName LIMIT 0").use { resultSet -> + val metaData = resultSet.metaData + val columnType = metaData.getColumnType(1) + + // Check if the column type is numeric + isNumeric = when (columnType) { + java.sql.Types.BIGINT, java.sql.Types.NUMERIC, java.sql.Types.INTEGER, + java.sql.Types.SMALLINT, java.sql.Types.TINYINT, java.sql.Types.FLOAT, + java.sql.Types.REAL, java.sql.Types.DOUBLE, java.sql.Types.DECIMAL -> true + else -> false + } + } + } + return isNumeric +} + +fun Connection.getTableColumnTypes(tableName: String): Map { + val columnTypes = mutableMapOf() + + createStatement().use { statement -> + val resultSet = statement.executeQuery("SELECT * FROM $tableName LIMIT 0") + val metaData = resultSet.metaData + val columnCount = metaData.columnCount + + for (i in 1..columnCount) { + val columnName = metaData.getColumnName(i) + val columnType = metaData.getColumnType(i) + columnTypes[columnName] = columnType + } + } + + return columnTypes +} + +fun Connection.getNumeriColumns(tableName: String): List { + val numericColumns = mutableListOf() + var isNumeric = false + + createStatement().use { statement -> + val resultSet = statement.executeQuery("SELECT * FROM $tableName LIMIT 0") + val metaData = resultSet.metaData + val columnCount = metaData.columnCount + + for (i in 1..columnCount) { + val columnType = metaData.getColumnType(i) + isNumeric = when (columnType) { + java.sql.Types.BIGINT, java.sql.Types.NUMERIC, java.sql.Types.INTEGER, + java.sql.Types.SMALLINT, java.sql.Types.TINYINT, java.sql.Types.FLOAT, + java.sql.Types.REAL, java.sql.Types.DOUBLE, java.sql.Types.DECIMAL -> true + else -> false + } + if (isNumeric) numericColumns.add(metaData.getColumnName(i)); + } + } + return numericColumns +} + + fun ResultSet.joinToString(separator: String = " - "): String { val sb = StringBuilder() while (this.next()) { diff --git a/sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt b/sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt index 1c8616c..cecce72 100644 --- a/sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt +++ b/sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt @@ -4,6 +4,7 @@ import com.smeup.dbnative.file.Record import com.smeup.dbnative.model.FileMetadata import com.smeup.dbnative.model.Field import java.lang.Exception +import java.sql.Connection enum class PositioningMethod { SETLL, SETGT; @@ -39,6 +40,34 @@ class Native2SQL(val fileMetadata: FileMetadata) { private var lastReadInstruction: ReadInstruction? = null private var lastPositioningInstruction: PositioningInstruction? = null + /** + * Build values replacements for store procedures settings empty numerics values as 0 + */ + private fun buildRepalcements(values: List): MutableList { + val result = mutableListOf() + values.forEachIndexed { index, s -> + if (s.isNullOrEmpty()) { + if (isNumeric(fileMetadata.fileKeys[index])) { + result.add("0") + } else { + result.add(""); + } + } else { + result.add(s) + } + } + return result + } + + private fun isNumeric(fieldName: String ):Boolean { + val field = fileMetadata.fields.find { it.name == fieldName } + if (field != null) { + return field.numeric + } else { + return false + } + } + private fun checkPositioning(){ requireNotNull(lastPositioningInstruction){ "No positioning instruction found" @@ -78,6 +107,36 @@ class Native2SQL(val fileMetadata: FileMetadata) { lastReadInstruction = null } + /** + * Check key list: + * - If passed key are less then file metadata keys fill missing var with empty values + * - If a key is numeric and is empty, set its value to 0 + */ + private fun checkEmptyKeys(keys: List): List { + val result = mutableListOf() + + result.addAll(keys) + val lostKeys = fileMetadata.fileKeys.size - result.size + repeat(lostKeys) { + result.add(""); + } + + val checkedResult = mutableListOf() + result.forEachIndexed { index, s -> + if (s.isNullOrEmpty() ) { + if (isNumeric(fileMetadata.fileKeys.get(index))) { + checkedResult.add("0") + } else { + checkedResult.add("") + } + } else { + checkedResult.add(s) + } + } + + return checkedResult + } + /* * @return true if read method need new query execution */ @@ -175,7 +234,12 @@ class Native2SQL(val fileMetadata: FileMetadata) { private fun getSQLOrderByClause(): String{ val sortOrder = getSortOrder() - return " ORDER BY " + fileMetadata.fileKeys.joinToString(separator = " " + sortOrder.symbol + ", ", postfix = " " + sortOrder.symbol ) + var result = "ORDER BY" + + fileMetadata.fileKeys.forEach() { + result += " \"" + it + "\" " + sortOrder.symbol +"," + } + return result.removeSuffix(",") } fun getReadSqlStatement(): Pair>{ @@ -221,7 +285,7 @@ class Native2SQL(val fileMetadata: FileMetadata) { */ private fun getReadCoherentSql(fullUnion: Boolean = false): Pair> { var queries = mutableListOf() - val replacements = mutableListOf() + var replacements = mutableListOf() if (lastPositioningInstruction == null) { var columns = "" fileMetadata.fields.forEachIndexed { index, k -> @@ -229,7 +293,7 @@ class Native2SQL(val fileMetadata: FileMetadata) { columns += "\"" + k.name + "\", " } } - return Pair("SELECT " + columns.removeSuffix(", ") + "FROM ${fileMetadata.tableName}", replacements) + return Pair("SELECT " + columns.removeSuffix(", ") + "FROM \"${fileMetadata.tableName}\"", replacements) } else { var columns = "" fileMetadata.fields.forEachIndexed { index, k -> @@ -239,31 +303,33 @@ class Native2SQL(val fileMetadata: FileMetadata) { } var value = "" - val keys = fileMetadata.fileKeys - keys.forEachIndexed { index, k -> + val keys = lastPositioningInstruction?.keys + keys?.forEachIndexed { index, k -> run { - value += "\"" + k + "\" >= ? AND " + value += "\"" + fileMetadata.fileKeys[index] + "\" >= ? AND " } } queries.add( - "SELECT " + columns.removeSuffix(", ") + " FROM ${fileMetadata.tableName} WHERE " + value.removeSuffix( + "SELECT " + columns.removeSuffix(", ") + " FROM \"${fileMetadata.tableName}\" WHERE " + value.removeSuffix( " AND " ) ) - replacements.addAll(lastPositioningInstruction!!.keys) + replacements.addAll(buildRepalcements(lastPositioningInstruction!!.keys)) + /* val lostKeys = fileMetadata.fileKeys.size - lastPositioningInstruction!!.keys.size repeat(lostKeys) { replacements.add(""); } - return Pair(queries.joinToString(), replacements) + */ + return Pair(queries.joinToString() + " " + getSQLOrderByClause(), replacements) } } private fun getCoherentSql(fullUnion: Boolean = false):Pair>{ val queries = mutableListOf() - val replacements = mutableListOf() + var replacements = mutableListOf() val comparison = getComparison() if (lastPositioningInstruction == null) { @@ -279,9 +345,9 @@ class Native2SQL(val fileMetadata: FileMetadata) { value += "\"" + k + "\" " + Comparison.EQ.symbol + " ? AND " } } - replacements.addAll(lastReadInstruction!!.keys) + replacements.addAll(buildRepalcements(lastReadInstruction!!.keys)) - return Pair("SELECT " + columns.removeSuffix(", ") + "FROM ${fileMetadata.tableName} WHERE " + value.removeSuffix(" AND "), replacements) + return Pair("SELECT " + columns.removeSuffix(", ") + "FROM \"${fileMetadata.tableName}\" WHERE " + value.removeSuffix(" AND "), replacements) } else { if (lastPositioningInstruction!!.keys.size == 1) { queries.add( @@ -292,7 +358,7 @@ class Native2SQL(val fileMetadata: FileMetadata) { fileMetadata.tableName ) ) - replacements.addAll(lastPositioningInstruction!!.keys) + replacements.addAll(buildRepalcements(lastPositioningInstruction!!.keys)) } else { val limit = if (fullUnion) 1 else 2 for (i in lastPositioningInstruction!!.keys.size downTo limit) { @@ -304,7 +370,7 @@ class Native2SQL(val fileMetadata: FileMetadata) { fileMetadata.tableName ) ) - replacements.addAll(lastPositioningInstruction!!.keys.subList(0, i)) + replacements.addAll(buildRepalcements(lastPositioningInstruction!!.keys.subList(0, i))) } } } @@ -326,9 +392,11 @@ private fun getSQL(fields: List, keys: List, comparison: Comparis value += "\"" + k + "\" " + (if (index < keys.size - 1) Comparison.EQ.symbol else comparison.symbol) + " ? AND " } } - return "(SELECT " + columns.removeSuffix(", ")+ " FROM $tableName WHERE " + value.removeSuffix("AND ") + ")" + return "(SELECT " + columns.removeSuffix(", ")+ " FROM \"$tableName\" WHERE " + value.removeSuffix("AND ") + ")" } + + fun main(){ var fields = listOf(Field("Regione", ""), Field("Provincia", ""), Field("Comune", "")) var fieldsKeys = listOf("Regione", "Provincia", "Comune") diff --git a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFile.kt b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFile.kt index d00c945..f6a496e 100644 --- a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFile.kt +++ b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLDBFile.kt @@ -36,12 +36,6 @@ class SQLDBFile( override var logger: Logger? = null ) : DBFile { - constructor( - name: String, - fileMetadata: FileMetadata, - connection: Connection - ) : this(name, fileMetadata, connection, null) - private var preparedStatements: MutableMap = mutableMapOf() private var resultSet: ResultSet? = null private var actualRecord: Record? = null diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400PerfTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400PerfTest.kt index da012d4..f9161af 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400PerfTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/DB2400PerfTest.kt @@ -20,7 +20,7 @@ package com.smeup.dbnative.sql import com.smeup.dbnative.file.DBFile import com.smeup.dbnative.file.Record import com.smeup.dbnative.file.RecordField -import com.smeup.dbnative.metadata.file.PropertiesSerializer +import com.smeup.dbnative.metadata.file.MetadataSerializer import com.smeup.dbnative.sql.utils.* import org.junit.Test import kotlin.test.Ignore @@ -42,7 +42,7 @@ class DB2400PerfTest { initDbManager(library = DB2_400_LIBRARY_NAME) dbManager.use { val fileMetadata = - PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "VERAPG0L") + MetadataSerializer.jsonToMetadata("src/test/resources/dds/", "VERAPG0L") it!!.registerMetadata(fileMetadata, false) val dbFile = it!!.openFile("VERAPG0L") for(i in 1..10) { @@ -66,7 +66,7 @@ class DB2400PerfTest { initDbManager(library = DB2_400_LIBRARY_NAME) dbManager.use { val fileMetadata = - PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "VERAPG0L") + MetadataSerializer.jsonToMetadata("src/test/resources/dds/", "VERAPG0L") it!!.registerMetadata(fileMetadata, false) val dbFile = it!!.openFile("VERAPG0L") @@ -84,7 +84,7 @@ class DB2400PerfTest { initDbManager(library = DB2_400_LIBRARY_NAME) dbManager.use { val fileMetadata = - PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "VERAPG0L") + MetadataSerializer.jsonToMetadata("src/test/resources/dds/", "VERAPG0L") it!!.registerMetadata(fileMetadata, false) val dbFile = it!!.openFile("VERAPG0L") @@ -116,7 +116,7 @@ class DB2400PerfTest { initDbManager(library = DB2_400_LIBRARY_NAME) dbManager.use { val fileMetadata = - PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "VERAPG9L") + MetadataSerializer.jsonToMetadata("src/test/resources/dds/", "VERAPG9L") it!!.registerMetadata(fileMetadata, false) val dbFile = it!!.openFile("VERAPG9L") var keys = arrayListOf("20210117", "SMEGL.001 ") @@ -130,7 +130,7 @@ class DB2400PerfTest { initDbManager(library = DB2_400_LIBRARY_NAME) dbManager.use { val fileMetadata = - PropertiesSerializer.propertiesToMetadata("src/test/resources/dds/properties/", "BRARTI0L") + MetadataSerializer.jsonToMetadata("src/test/resources/dds/", "BRARTI0L") it!!.registerMetadata(fileMetadata, false) val dbFile = it!!.openFile("BRARTI0L") var keys = arrayListOf("ASACC0001") diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadEqualTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadEqualTest.kt index e93f30d..87f6ddb 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadEqualTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLReadEqualTest.kt @@ -187,5 +187,15 @@ class SQLReadEqualTest { SQLReadEqualTest.dbManager.closeFile(MUNICIPALITY_TABLE_NAME) } + + @Test + fun setLlReadEWithMoreKeys() { + val dbFile = SQLReadEqualTest.dbManager.openFile(MUNICIPALITY_TABLE_NAME) + assertTrue(dbFile.setll(buildMunicipalityKey("IT", "LOM"))) + val result = dbFile.readEqual(buildMunicipalityKey("IT", "LOM", "BS")) + assertEquals("ACQUAFREDDA", getMunicipalityName(result.record)) + + SQLReadEqualTest.dbManager.closeFile(MUNICIPALITY_TABLE_NAME) + } } diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLUtilsTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLUtilsTest.kt index 0b69c0d..e3ae586 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLUtilsTest.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/SQLUtilsTest.kt @@ -22,52 +22,10 @@ import com.smeup.dbnative.file.RecordField import com.smeup.dbnative.model.CharacterType import com.smeup.dbnative.model.DecimalType import com.smeup.dbnative.sql.utils.toSQL -import com.smeup.dbnative.utils.TypedMetadata -import com.smeup.dbnative.utils.fieldByType import org.junit.Test import kotlin.test.assertEquals class SQLUtilsTest { - - @Test - fun sqlForCreateTableTestWithPrimaryKeys() { - val fileMetadata = TypedMetadata( - "TSTTAB", - "TSTTAB", - listOf( - "TSTFLDCHR" fieldByType CharacterType(5), - "TSTFLDNBR" fieldByType DecimalType(7, 2), - "TSTFLDNB2" fieldByType DecimalType(2, 0) - ), - listOf( - "TSTFLDCHR", - "TSTFLDNBR" - ) - ) - assertEquals( - "CREATE TABLE TSTTAB (TSTFLDCHR CHAR(5) DEFAULT '' NOT NULL, TSTFLDNBR DECIMAL(7,2) DEFAULT 0 NOT NULL, TSTFLDNB2 DECIMAL(2,0) DEFAULT 0 NOT NULL, PRIMARY KEY(TSTFLDCHR, TSTFLDNBR))", - fileMetadata.toSQL() - ) - } - - @Test - fun sqlForCreateTableTestWithoutPrimaryKeys() { - val fileMetadata = TypedMetadata( - "TSTTAB", - "TSTTAB", - listOf( - "TSTFLDCHR" fieldByType CharacterType(5), - "TSTFLDNBR" fieldByType DecimalType(7, 2), - "TSTFLDNB2" fieldByType DecimalType(2, 0) - ), - listOf() - ) - assertEquals( - "CREATE TABLE TSTTAB (TSTFLDCHR CHAR(5) DEFAULT '' NOT NULL, TSTFLDNBR DECIMAL(7,2) DEFAULT 0 NOT NULL, TSTFLDNB2 DECIMAL(2,0) DEFAULT 0 NOT NULL)", - fileMetadata.toSQL() - ) - } - @Test fun sqlForInsertTest() { val record = Record( diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/utils/JsonTest.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/utils/JsonTest.kt new file mode 100644 index 0000000..b95adc8 --- /dev/null +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/utils/JsonTest.kt @@ -0,0 +1,61 @@ +/* + * Copyright 2024 The Reload project Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * + */ + +package com.smeup.dbnative.sql.utils + +import com.google.gson.Gson +import com.google.gson.GsonBuilder +import java.io.File + +data class Field( + val name: String, + val text: String = "", + val numeric: Boolean = false +) + +data class FileMetadata( + var name: String, + var tableName: String, + var fields: List, + var fileKeys: List +) + +fun main() { + // Create an instance of FileMetadata + val fileMetadata = FileMetadata( + "example.txt", + "ExampleTable", + listOf( + Field("field1", "some text", false), + Field("field2", numeric = true) + ), + listOf("key1", "key2") + ) + + // Convert FileMetadata object to JSON + val gson: Gson = GsonBuilder().setPrettyPrinting().create() + val json: String = gson.toJson(fileMetadata) + + // Write JSON to a file + val outputFile = File("file_metadata.json") + outputFile.writeText(json) + + System.out.println(json); + + println("File metadata has been written to file_metadata.json") +} diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/utils/SQLDBTestUtils.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/utils/SQLDBTestUtils.kt index 3638019..1c6ef0e 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/utils/SQLDBTestUtils.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/utils/SQLDBTestUtils.kt @@ -24,6 +24,7 @@ import com.smeup.dbnative.file.RecordField import com.smeup.dbnative.log.Logger import com.smeup.dbnative.log.LoggingLevel import com.smeup.dbnative.model.* +import com.smeup.dbnative.model.FileMetadata import com.smeup.dbnative.sql.CONVENTIONAL_INDEX_SUFFIX import com.smeup.dbnative.sql.SQLDBMManager import com.smeup.dbnative.utils.TypedField diff --git a/sql/src/test/resources/dds/BRARTI0F.json b/sql/src/test/resources/dds/BRARTI0F.json new file mode 100644 index 0000000..9de6b45 --- /dev/null +++ b/sql/src/test/resources/dds/BRARTI0F.json @@ -0,0 +1,8 @@ +{ + "name": "BRARTI0F", + "tableName": "BRARTI0F", + "fields": [ + ], + "fileKeys": [ + ] +} \ No newline at end of file diff --git a/sql/src/test/resources/dds/BRARTI0L.json b/sql/src/test/resources/dds/BRARTI0L.json new file mode 100644 index 0000000..f539e90 --- /dev/null +++ b/sql/src/test/resources/dds/BRARTI0L.json @@ -0,0 +1,11 @@ +{ + "name": "BRARTI0L", + "tableName": "BRARTI0F", + "fields": [ + ], + "fileKeys": [ + "A§ARTI" + ] +} + + diff --git a/sql/src/test/resources/dds/BRARTI1L.json b/sql/src/test/resources/dds/BRARTI1L.json new file mode 100644 index 0000000..197baa7 --- /dev/null +++ b/sql/src/test/resources/dds/BRARTI1L.json @@ -0,0 +1,11 @@ +{ + "name": "BRARTI1L", + "tableName": "BRARTI0F", + "fields": [ + ], + "fileKeys": [ + "A§DEAR", + "A§ARTI" + ] +} + diff --git a/sql/src/test/resources/dds/BRARTI2L.json b/sql/src/test/resources/dds/BRARTI2L.json new file mode 100644 index 0000000..d4dc8fb --- /dev/null +++ b/sql/src/test/resources/dds/BRARTI2L.json @@ -0,0 +1,11 @@ +{ + "name": "BRARTI2L", + "tableName": "BRARTI0F", + "fields": [ + ], + "fileKeys": [ + "A§TIAR", + "A§ARTI" + ] +} + diff --git a/sql/src/test/resources/dds/VERAPG0F.json b/sql/src/test/resources/dds/VERAPG0F.json new file mode 100644 index 0000000..904e002 --- /dev/null +++ b/sql/src/test/resources/dds/VERAPG0F.json @@ -0,0 +1,9 @@ +{ + "name": "VERAPG0F", + "tableName": "VERAPG0F", + "fields": [ + ], + "fileKeys": [ + ] +} + diff --git a/sql/src/test/resources/dds/VERAPG0L.json b/sql/src/test/resources/dds/VERAPG0L.json new file mode 100644 index 0000000..0992fea --- /dev/null +++ b/sql/src/test/resources/dds/VERAPG0L.json @@ -0,0 +1,9 @@ +{ + "name": "VERAPG0L", + "tableName": "VERAPG0F", + "fields": [ + ], + "fileKeys": [ + "V£IDOJ" + ] +} diff --git a/sql/src/test/resources/dds/VERAPG1L.json b/sql/src/test/resources/dds/VERAPG1L.json new file mode 100644 index 0000000..78907ca --- /dev/null +++ b/sql/src/test/resources/dds/VERAPG1L.json @@ -0,0 +1,12 @@ +{ + "name": "VERAPG1L", + "tableName": "VERAPG0F", + "fields": [ + ], + "fileKeys": [ + "V£DATA", + "V£NOME", + "V£IDOJ" + ] +} + diff --git a/sql/src/test/resources/dds/VERAPG3L.json b/sql/src/test/resources/dds/VERAPG3L.json new file mode 100644 index 0000000..cb17b8d --- /dev/null +++ b/sql/src/test/resources/dds/VERAPG3L.json @@ -0,0 +1,11 @@ +{ + "name": "VERAPG3L", + "tableName": "VERAPG0F", + "fields": [ + ], + "fileKeys": [ + "V£CDC", + "V£DATA", + "V£NOME" + ] +} diff --git a/sql/src/test/resources/dds/VERAPG9L.json b/sql/src/test/resources/dds/VERAPG9L.json new file mode 100644 index 0000000..ef1f276 --- /dev/null +++ b/sql/src/test/resources/dds/VERAPG9L.json @@ -0,0 +1,10 @@ +{ + "name": "VERAPG9L", + "tableName": "VERAPG0F", + "fields": [ + ], + "fileKeys": [ + "V£DATA", + "V£CDC" + ] +} diff --git a/sql/src/test/resources/dds/properties/BRARTI0F.properties b/sql/src/test/resources/dds/properties/BRARTI0F.properties deleted file mode 100644 index 9b6b262..0000000 --- a/sql/src/test/resources/dds/properties/BRARTI0F.properties +++ /dev/null @@ -1,26 +0,0 @@ -# -# Copyright 2020 The Reload project Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# - -# -# - recordformat: declare record format name -# - list of fields (field.name = description, datatype, length, decimal) -# - fieldsKeys: list of fields keys, if any, comma separated -# -# ANAGRAFICA ARTICOLI -# -tablename = BRARTI0F -filekeys = diff --git a/sql/src/test/resources/dds/properties/BRARTI0L.properties b/sql/src/test/resources/dds/properties/BRARTI0L.properties deleted file mode 100644 index c8f2b54..0000000 --- a/sql/src/test/resources/dds/properties/BRARTI0L.properties +++ /dev/null @@ -1,26 +0,0 @@ -# -# Copyright 2020 The Reload project Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# - -# -# - recordformat: declare record format name -# - list of fields (field.name = description, datatype, length, decimal) -# - fieldsKeys: list of fields keys, if any, comma separated -# -# ANAGRAFICA ARTICOLI -# -tablename = BRARTI0F -filekeys = A§ARTI diff --git a/sql/src/test/resources/dds/properties/BRARTI1L.properties b/sql/src/test/resources/dds/properties/BRARTI1L.properties deleted file mode 100644 index 937d980..0000000 --- a/sql/src/test/resources/dds/properties/BRARTI1L.properties +++ /dev/null @@ -1,26 +0,0 @@ -# -# Copyright 2020 The Reload project Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# - -# -# - recordformat: declare record format name -# - list of fields (field.name = description, datatype, length, decimal) -# - fieldsKeys: list of fields keys, if any, comma separated -# -# ANAGRAFICA ARTICOLI -# -tablename = BRARTI0F -filekeys = A§DEAR,A§ARTI diff --git a/sql/src/test/resources/dds/properties/BRARTI2L.properties b/sql/src/test/resources/dds/properties/BRARTI2L.properties deleted file mode 100644 index 7ae86fc..0000000 --- a/sql/src/test/resources/dds/properties/BRARTI2L.properties +++ /dev/null @@ -1,26 +0,0 @@ -# -# Copyright 2020 The Reload project Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# - -# -# - recordformat: declare record format name -# - list of fields (field.name = description, datatype, length, decimal) -# - fieldsKeys: list of fields keys, if any, comma separated -# -# ANAGRAFICA ARTICOLI -# -tablename = BRARTI0F -filekeys = A§TIAR,A§ARTI diff --git a/sql/src/test/resources/dds/properties/VERAPG0F.properties b/sql/src/test/resources/dds/properties/VERAPG0F.properties deleted file mode 100644 index 14b8a90..0000000 --- a/sql/src/test/resources/dds/properties/VERAPG0F.properties +++ /dev/null @@ -1,26 +0,0 @@ -# -# Copyright 2020 The Reload project Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# - -# -# - recordformat: declare record format name -# - list of fields (field.name = description, datatype, length, decimal) -# - fieldsKeys: list of fields keys, if any, comma separated -# -# RAPPORTINI GIORNALIERI -# -tablename = -filekeys = diff --git a/sql/src/test/resources/dds/properties/VERAPG0L.properties b/sql/src/test/resources/dds/properties/VERAPG0L.properties deleted file mode 100644 index 0078aac..0000000 --- a/sql/src/test/resources/dds/properties/VERAPG0L.properties +++ /dev/null @@ -1,26 +0,0 @@ -# -# Copyright 2020 The Reload project Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# - -# -# - recordformat: declare record format name -# - list of fields (field.name = description, datatype, length, decimal) -# - fieldsKeys: list of fields keys, if any, comma separated -# -# RAPPORTINI GIORNALIERI -# -tablename = VERAPG0F -filekeys = V£IDOJ \ No newline at end of file diff --git a/sql/src/test/resources/dds/properties/VERAPG1L.properties b/sql/src/test/resources/dds/properties/VERAPG1L.properties deleted file mode 100644 index 2d8cde1..0000000 --- a/sql/src/test/resources/dds/properties/VERAPG1L.properties +++ /dev/null @@ -1,26 +0,0 @@ -# -# Copyright 2020 The Reload project Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# - -# -# - recordformat: declare record format name -# - list of fields (field.name = description, datatype, length, decimal) -# - fieldsKeys: list of fields keys, if any, comma separated -# -# RAPPORTINI GIORNALIERI -# -tablename = VERAPG0F -filekeys = V£DATA,V£NOME,V£IDOJ diff --git a/sql/src/test/resources/dds/properties/VERAPG3L.properties b/sql/src/test/resources/dds/properties/VERAPG3L.properties deleted file mode 100644 index 687bfce..0000000 --- a/sql/src/test/resources/dds/properties/VERAPG3L.properties +++ /dev/null @@ -1,3 +0,0 @@ -tablename = VERAPG0F -name = VERAPG3L -filekeys = V£CDC,V£DATA,V£NOME diff --git a/sql/src/test/resources/dds/properties/VERAPG9L.properties b/sql/src/test/resources/dds/properties/VERAPG9L.properties deleted file mode 100644 index 45fac5b..0000000 --- a/sql/src/test/resources/dds/properties/VERAPG9L.properties +++ /dev/null @@ -1,2 +0,0 @@ -tablename = -filekeys = V£DATA,V£CDC \ No newline at end of file From 59b2a7814123fdf7ffe60d07dc03b23981937105 Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Thu, 4 Apr 2024 09:35:28 +0200 Subject: [PATCH 32/35] Simple patch for SQL script building --- sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt b/sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt index cecce72..211729d 100644 --- a/sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt +++ b/sql/src/main/kotlin/com/smeup/dbnative/sql/Native2SQLAdapter.kt @@ -374,7 +374,7 @@ class Native2SQL(val fileMetadata: FileMetadata) { } } } - return Pair(queries.joinToString(" UNION ") + getSQLOrderByClause(), replacements) + return Pair(queries.joinToString(" UNION ") + " " + getSQLOrderByClause(), replacements) } } From 9da72d65c3140d2d975602895e56813acfc98a42 Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Thu, 11 Apr 2024 17:31:29 +0200 Subject: [PATCH 33/35] Patch for insert and delete with postgres DBM --- sql/src/main/kotlin/com/smeup/dbnative/sql/SQLUtils.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLUtils.kt b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLUtils.kt index 49f22c5..b87cac8 100644 --- a/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLUtils.kt +++ b/sql/src/main/kotlin/com/smeup/dbnative/sql/SQLUtils.kt @@ -24,20 +24,20 @@ import com.smeup.dbnative.file.RecordField fun String.insertSQL(record: Record): String { val names = record.keys.joinToString { "\"" + it + "\"" } val questionMarks = record.keys.joinToString { "?" } - return "INSERT INTO $this ($names) VALUES($questionMarks)" + return "INSERT INTO \"$this\" ($names) VALUES($questionMarks)" } fun String.updateSQL(record: Record): String { val namesAndQuestionMarks = record.keys.joinToString { "\"$it\" = ?" } val wheres = record.keys.toList() val comparations = List(record.size) { Comparison.EQ } - return "UPDATE $this SET $namesAndQuestionMarks ${whereSQL(wheres, comparations)}" + return "UPDATE \"$this\" SET $namesAndQuestionMarks ${whereSQL(wheres, comparations)}" } fun String.deleteSQL(record: Record): String { val wheres = record.keys.toList() val comparations = List(record.size) { Comparison.EQ } - return "DELETE FROM $this ${whereSQL(wheres, comparations)}" + return "DELETE FROM \"$this\" ${whereSQL(wheres, comparations)}" } fun orderBySQL(keysNames: List, reverse: Boolean = false): String = From a3eb6739bc90f2863c38d6601f2d3458ad688fa4 Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Tue, 14 May 2024 15:41:41 +0200 Subject: [PATCH 34/35] Add support for H2 embedded DBMS (for tests compatible with Postgres) --- sql/pom.xml | 7 +++++++ .../kotlin/com/smeup/dbnative/sql/utils/SQLDBTestUtils.kt | 8 ++++++++ 2 files changed, 15 insertions(+) diff --git a/sql/pom.xml b/sql/pom.xml index ee6b316..23bce63 100644 --- a/sql/pom.xml +++ b/sql/pom.xml @@ -64,6 +64,13 @@ postgresql 42.7.3 + + com.h2database + h2 + 2.2.224 + test + + net.sf.jt400 diff --git a/sql/src/test/kotlin/com/smeup/dbnative/sql/utils/SQLDBTestUtils.kt b/sql/src/test/kotlin/com/smeup/dbnative/sql/utils/SQLDBTestUtils.kt index 1c6ef0e..5406868 100644 --- a/sql/src/test/kotlin/com/smeup/dbnative/sql/utils/SQLDBTestUtils.kt +++ b/sql/src/test/kotlin/com/smeup/dbnative/sql/utils/SQLDBTestUtils.kt @@ -76,6 +76,14 @@ enum class TestSQLDBType( password = "root"), destroyDatabase = { dbaConnection -> dbaConnection.prepareStatement("DROP SCHEMA PUBLIC CASCADE").use { it.execute() } } ), + // Added H2 embedded DB with postgres compability (for tests) + H2SQLDB(ConnectionConfig( + fileName= "*", + url = "jdbc:h2:~/$DATABASE_NAME;MODE=PostgreSQL", + user = "sa", + password = ""), + destroyDatabase = { dbaConnection -> dbaConnection.prepareStatement("DROP SCHEMA PUBLIC CASCADE").use { it.execute() } } + ), DB2_400(ConnectionConfig( fileName= "*", driver = "com.ibm.as400.access.AS400JDBCDriver", From 0efe99402fda0b401a065f1df9dae2dbebd4567f Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Tue, 14 May 2024 15:54:18 +0200 Subject: [PATCH 35/35] New version 1.4.0 --- base/pom.xml | 2 +- distribution/pom.xml | 2 +- jt400/pom.xml | 2 +- manager/pom.xml | 2 +- nosql/pom.xml | 2 +- pom.xml | 2 +- sql/pom.xml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/base/pom.xml b/base/pom.xml index f224150..3a3d3a3 100644 --- a/base/pom.xml +++ b/base/pom.xml @@ -33,7 +33,7 @@ io.github.smeup.reload reload - develop-SNAPSHOT + 1.4.0 base diff --git a/distribution/pom.xml b/distribution/pom.xml index fa21773..1028326 100644 --- a/distribution/pom.xml +++ b/distribution/pom.xml @@ -25,7 +25,7 @@ reload io.github.smeup.reload - develop-SNAPSHOT + 1.4.0 distribution diff --git a/jt400/pom.xml b/jt400/pom.xml index bb3c562..da4c41b 100644 --- a/jt400/pom.xml +++ b/jt400/pom.xml @@ -31,7 +31,7 @@ io.github.smeup.reload reload - develop-SNAPSHOT + 1.4.0 jt400 diff --git a/manager/pom.xml b/manager/pom.xml index fe6f95b..f5ce88e 100644 --- a/manager/pom.xml +++ b/manager/pom.xml @@ -25,7 +25,7 @@ io.github.smeup.reload reload - develop-SNAPSHOT + 1.4.0 manager diff --git a/nosql/pom.xml b/nosql/pom.xml index 68cc3b8..a8a1a58 100644 --- a/nosql/pom.xml +++ b/nosql/pom.xml @@ -26,7 +26,7 @@ io.github.smeup.reload reload - develop-SNAPSHOT + 1.4.0 nosql diff --git a/pom.xml b/pom.xml index 139fa96..cee32bb 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.github.smeup.reload reload - develop-SNAPSHOT + 1.4.0 pom reload diff --git a/sql/pom.xml b/sql/pom.xml index 23bce63..6130cdd 100644 --- a/sql/pom.xml +++ b/sql/pom.xml @@ -25,7 +25,7 @@ io.github.smeup.reload reload - develop-SNAPSHOT + 1.4.0 sql