diff --git a/.github/workflows/build-timestamped-master.yml b/.github/workflows/build-timestamped-master.yml index ae7e73a..a8865cf 100644 --- a/.github/workflows/build-timestamped-master.yml +++ b/.github/workflows/build-timestamped-master.yml @@ -17,11 +17,11 @@ jobs: if: github.repository_owner == 'ballerina-platform' steps: - uses: actions/checkout@v2 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v2 with: distribution: 'temurin' - java-version: 17.0.7 + java-version: 21.0.3 - name: Change to Timestamped Version run: | initialVersion=$((grep -w 'version' | cut -d= -f2) < gradle.properties ) diff --git a/.github/workflows/build-with-bal-test-graalvm.yml b/.github/workflows/build-with-bal-test-graalvm.yml index aced9a4..1a9fd9c 100644 --- a/.github/workflows/build-with-bal-test-graalvm.yml +++ b/.github/workflows/build-with-bal-test-graalvm.yml @@ -30,7 +30,7 @@ jobs: call_stdlib_workflow: name: Run StdLib Workflow if: ${{ github.event_name != 'schedule' || (github.event_name == 'schedule' && github.repository_owner == 'ballerina-platform') }} - uses: ballerina-platform/ballerina-library/.github/workflows/build-with-bal-test-graalvm-template.yml@main + uses: ballerina-platform/ballerina-library/.github/workflows/build-with-bal-test-graalvm-template.yml@java21 with: lang_tag: ${{ inputs.lang_tag }} lang_version: ${{ inputs.lang_version }} diff --git a/.github/workflows/central-publish.yml b/.github/workflows/central-publish.yml index 11922b5..ebe213e 100644 --- a/.github/workflows/central-publish.yml +++ b/.github/workflows/central-publish.yml @@ -15,7 +15,7 @@ jobs: call_workflow: name: Run Central Publish Workflow if: ${{ github.repository_owner == 'ballerina-platform' }} - uses: ballerina-platform/ballerina-library/.github/workflows/central-publish-template.yml@main + uses: ballerina-platform/ballerina-library/.github/workflows/central-publish-template.yml@java21 secrets: inherit with: environment: ${{ github.event.inputs.environment }} diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index ad204e6..711ede6 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -11,11 +11,11 @@ jobs: if: github.repository_owner == 'ballerina-platform' steps: - uses: actions/checkout@v2 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v2 with: distribution: 'temurin' - java-version: 17.0.7 + java-version: 21.0.3 - name: Build with Gradle env: packageUser: ${{ github.actor }} diff --git a/.github/workflows/publish-snapshot-nexus.yml b/.github/workflows/publish-snapshot-nexus.yml index b13aaea..e9d7cba 100644 --- a/.github/workflows/publish-snapshot-nexus.yml +++ b/.github/workflows/publish-snapshot-nexus.yml @@ -9,11 +9,11 @@ jobs: if: github.repository_owner == 'ballerina-platform' steps: - uses: actions/checkout@v2 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v2 with: distribution: 'temurin' - java-version: 17.0.7 + java-version: 21.0.3 - name: Build with Gradle env: packageUser: ${{ secrets.BALLERINA_BOT_USERNAME }} diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index c22a0b9..e0de6a6 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -10,6 +10,6 @@ jobs: call_workflow: name: Run PR Build Workflow if: ${{ github.repository_owner == 'ballerina-platform' }} - uses: ballerina-platform/ballerina-library/.github/workflows/pull-request-build-template.yml@main + uses: ballerina-platform/ballerina-library/.github/workflows/pull-request-build-template.yml@java21 with: additional-windows-test-flags: "-x test" diff --git a/.github/workflows/trivy-scan.yml b/.github/workflows/trivy-scan.yml index 458aab5..d91a5f3 100644 --- a/.github/workflows/trivy-scan.yml +++ b/.github/workflows/trivy-scan.yml @@ -9,5 +9,5 @@ jobs: call_workflow: name: Run Trivy Scan Workflow if: ${{ github.repository_owner == 'ballerina-platform' }} - uses: ballerina-platform/ballerina-library/.github/workflows/trivy-scan-template.yml@main + uses: ballerina-platform/ballerina-library/.github/workflows/trivy-scan-template.yml@java21 secrets: inherit diff --git a/README.md b/README.md index 5c0d736..e7a657f 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ This repository only contains the source code for the package. ### Set up the prerequisites -1. Download and install Java SE Development Kit (JDK) version 17 (from one of the following locations). +1. Download and install Java SE Development Kit (JDK) version 21 (from one of the following locations). * [Oracle](https://www.oracle.com/java/technologies/downloads/) * [OpenJDK](https://adoptium.net/) diff --git a/ballerina/Ballerina.toml b/ballerina/Ballerina.toml index aefa18f..bb536dd 100644 --- a/ballerina/Ballerina.toml +++ b/ballerina/Ballerina.toml @@ -7,24 +7,24 @@ keywords = ["persist", "sql", "mysql", "mssql", "sql-server"] repository = "https://github.com/ballerina-platform/module-ballerinax-persist.sql" icon = "icon.png" license = ["Apache-2.0"] -distribution = "2201.10.0" +distribution = "2201.10.0-20241011-161100-51978649" -[platform.java17] +[platform.java21] graalvmCompatible = true -[[platform.java17.dependency]] +[[platform.java21.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" version = "1.4.0" path = "../native/build/libs/persist.sql-native-1.4.0.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist-native" version = "1.4.0" path = "./lib/persist-native-1.4.0.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] groupId = "io.ballerina.stdlib" artifactId = "sql-native" version = "1.14.0" diff --git a/ballerina/Dependencies.toml b/ballerina/Dependencies.toml index a237821..bee9b21 100644 --- a/ballerina/Dependencies.toml +++ b/ballerina/Dependencies.toml @@ -5,7 +5,7 @@ [ballerina] dependencies-toml-version = "2" -distribution-version = "2201.10.0" +distribution-version = "2201.10.0-20241011-161100-51978649" [[package]] org = "ballerina" @@ -66,7 +66,7 @@ dependencies = [ [[package]] org = "ballerina" name = "http" -version = "2.12.0" +version = "2.13.0" scope = "testOnly" dependencies = [ {org = "ballerina", name = "auth"}, @@ -366,7 +366,7 @@ dependencies = [ [[package]] org = "ballerinai" name = "transaction" -version = "0.0.0" +version = "1.10.1" scope = "testOnly" dependencies = [ {org = "ballerina", name = "cache"}, @@ -453,7 +453,7 @@ modules = [ [[package]] org = "ballerinax" name = "mysql.driver" -version = "1.6.0" +version = "1.7.1" scope = "testOnly" modules = [ {org = "ballerinax", packageName = "mysql.driver", moduleName = "mysql.driver"} diff --git a/build-config/resources/Ballerina.toml b/build-config/resources/Ballerina.toml index 1efa371..a91e7d0 100644 --- a/build-config/resources/Ballerina.toml +++ b/build-config/resources/Ballerina.toml @@ -7,24 +7,24 @@ keywords = ["persist", "sql", "mysql", "mssql", "sql-server"] repository = "https://github.com/ballerina-platform/module-ballerinax-persist.sql" icon = "icon.png" license = ["Apache-2.0"] -distribution = "2201.10.0" +distribution = "2201.10.0-20241011-161100-51978649" -[platform.java17] +[platform.java21] graalvmCompatible = true -[[platform.java17.dependency]] +[[platform.java21.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" version = "@toml.version@" path = "../native/build/libs/persist.sql-native-@project.version@.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist-native" version = "@persist.version@" path = "./lib/persist-native-@persist.native.version@.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] groupId = "io.ballerina.stdlib" artifactId = "sql-native" version = "@sql.native.version@" diff --git a/compiler-plugin-test/build.gradle b/compiler-plugin-test/build.gradle index ed4850a..6644bc1 100644 --- a/compiler-plugin-test/build.gradle +++ b/compiler-plugin-test/build.gradle @@ -77,8 +77,11 @@ jacocoTestReport { } spotbugsMain { - effort "max" - reportLevel "low" + def classLoader = plugins["com.github.spotbugs"].class.classLoader + def SpotBugsConfidence = classLoader.findLoadedClass("com.github.spotbugs.snom.Confidence") + def SpotBugsEffort = classLoader.findLoadedClass("com.github.spotbugs.snom.Effort") + effort = SpotBugsEffort.MAX + reportLevel = SpotBugsConfidence.LOW reportsDir = file("$project.buildDir/reports/spotbugs") reports { html.enabled true diff --git a/compiler-plugin/build.gradle b/compiler-plugin/build.gradle index 4166d00..0f57951 100644 --- a/compiler-plugin/build.gradle +++ b/compiler-plugin/build.gradle @@ -51,8 +51,11 @@ checkstyle { checkstyleMain.dependsOn(":checkstyle:downloadCheckstyleRuleFiles") spotbugsMain { - effort "max" - reportLevel "low" + def classLoader = plugins["com.github.spotbugs"].class.classLoader + def SpotBugsConfidence = classLoader.findLoadedClass("com.github.spotbugs.snom.Confidence") + def SpotBugsEffort = classLoader.findLoadedClass("com.github.spotbugs.snom.Effort") + effort = SpotBugsEffort.MAX + reportLevel = SpotBugsConfidence.LOW reportsDir = file("$project.buildDir/reports/spotbugs") reports { html.enabled true diff --git a/gradle.properties b/gradle.properties index 5cfa3f7..d4e6a80 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ version=1.4.1-SNAPSHOT puppycrawlCheckstyleVersion=10.12.1 checkstyleToolVersion=10.12.1 -githubSpotbugsVersion=5.0.14 +githubSpotbugsVersion=6.0.18 githubJohnrengelmanShadowVersion=8.1.1 underCouchDownloadVersion=5.4.0 researchgateReleaseVersion=2.8.0 @@ -12,63 +12,63 @@ gsonVersion=2.10 ballerinaGradlePluginVersion=2.0.1 jacocoVersion=0.8.10 -ballerinaLangVersion=2201.10.0 +ballerinaLangVersion=2201.10.0-20241011-161100-51978649 # Direct Dependencies # Level 01 -stdlibIoVersion=1.6.1 -stdlibTimeVersion=2.4.0 -stdlibUrlVersion=2.4.0 +stdlibIoVersion=1.6.2-20240928-084100-656404f +stdlibTimeVersion=2.5.1-20240930-120200-e59222b +stdlibUrlVersion=2.4.1-20240930-120200-b7fb9e1 # Level 02 -stdlibLogVersion=2.10.0 -stdlibOsVersion=1.8.0 -stdlibPersistVersion=1.4.0 +stdlibLogVersion=2.10.1-20240930-154200-5ab2aa4 +stdlibOsVersion=1.8.1-20241001-120600-dd1626e +stdlibPersistVersion=1.4.1-20241001-120600-2395f0f # Level 03 -stdlibFileVersion=1.10.0 +stdlibFileVersion=1.10.1-20241007-160900-03f7b64 # Level 05 -stdlibHttpVersion=2.12.0 +stdlibHttpVersion=2.13.0-20241029-110700-30ed05b # Level 07 -stdlibSqlVersion=1.14.0 +stdlibSqlVersion=1.14.2-20241028-114300-2672942 # Ballerina external dependency -stdlibH2DriverVersion=1.1.0 -stdlibMysqlDriverVersion=1.6.0 -stdlibMssqlDriverVersion=1.6.0 -stdlibPostgresqlDriverVersion=1.5.1 +stdlibH2DriverVersion=1.1.1-20241029-101900-1c0e6d6 +stdlibMysqlDriverVersion=1.7.1-20241029-084000-27ab4f3 +stdlibMssqlDriverVersion=1.6.1-20241106-145800-4b72adb +stdlibPostgresqlDriverVersion=1.5.2-20241106-162800-582e4be # Ballerinax Observer -observeVersion=1.3.0 -observeInternalVersion=1.3.0 +observeVersion=1.3.1-20241007-161000-645452d +observeInternalVersion=1.3.1-20241015-172900-cdc3cb3 # Transitive Dependencies #Level 02 -stdlibConstraintVersion=1.5.0 -stdlibCryptoVersion=2.7.2 -stdlibTaskVersion=2.5.0 +stdlibConstraintVersion=1.5.1-20240930-123400-5ecd396 +stdlibCryptoVersion=2.7.3-20240930-132000-5ecc9ab +stdlibTaskVersion=2.5.1-20241002-145700-5bdb843 # Level 03 -stdlibCacheVersion=3.8.0 -stdlibMimeVersion=2.10.0 -stdlibUuidVersion=1.8.0 +stdlibCacheVersion=3.8.1-20241007-154900-63f4403 +stdlibMimeVersion=2.10.1-20241009-141200-8b6c9f0 +stdlibUuidVersion=1.8.1-20241009-134600-a05012b # Level 04 -stdlibAuthVersion=2.12.0 -stdlibJwtVersion=2.13.0 -stdlibOAuth2Version=2.12.0 +stdlibAuthVersion=2.12.1-20241010-130800-733dbef +stdlibJwtVersion=2.13.1-20241010-123600-5ea6a94 +stdlibOAuth2Version=2.12.1-20241029-084800-d7ba9e5 # Level 06 -stdlibTransactionVersion=1.10.0 +stdlibTransactionVersion=1.10.1-20241021-105400-f7e16a8 # Test Dependencies -stdlibMysqlVersion=1.13.0 -stdlibMssqlVersion=1.13.0 -stdlibPostgresqlVersion=1.13.0 -stdlibJdbcVersion=1.12.0 +stdlibMysqlVersion=1.13.2-20240929-114700-5b8f54c +stdlibMssqlVersion=1.13.2-20241109-095800-f1487c0 +stdlibPostgresqlVersion=1.13.2-20241109-095900-cd7d96a +stdlibJdbcVersion=1.12.2-20241112-200300-c77e1bc # Enabled publishing insecure checksums, due to fail to publish to maven central # Refer https://github.com/gradle/gradle/issues/11308 diff --git a/native/build.gradle b/native/build.gradle index 4e15f80..4b3c6bd 100644 --- a/native/build.gradle +++ b/native/build.gradle @@ -43,7 +43,7 @@ tasks.withType(JavaCompile) { options.encoding = 'UTF-8' } -sourceCompatibility = JavaVersion.VERSION_17 +sourceCompatibility = JavaVersion.VERSION_21 test { testLogging { @@ -60,9 +60,12 @@ test { } spotbugsMain { + def classLoader = plugins["com.github.spotbugs"].class.classLoader + def SpotBugsConfidence = classLoader.findLoadedClass("com.github.spotbugs.snom.Confidence") + def SpotBugsEffort = classLoader.findLoadedClass("com.github.spotbugs.snom.Effort") + effort = SpotBugsEffort.MAX + reportLevel = SpotBugsConfidence.LOW ignoreFailures = true - effort = "max" - reportLevel = "low" reportsDir = file("$project.buildDir/reports/spotbugs") def excludeFile = file("${rootDir}/build-config/spotbugs-exclude.xml") if (excludeFile.exists()) { diff --git a/native/src/main/java/io/ballerina/stdlib/persist/sql/Handler.java b/native/src/main/java/io/ballerina/stdlib/persist/sql/Handler.java new file mode 100644 index 0000000..cd1357c --- /dev/null +++ b/native/src/main/java/io/ballerina/stdlib/persist/sql/Handler.java @@ -0,0 +1,9 @@ +package io.ballerina.stdlib.persist.sql; + +import io.ballerina.runtime.api.values.BError; + +public interface Handler { + void notifySuccess(Object result); + + void notifyFailure(BError bError); +} diff --git a/native/src/main/java/io/ballerina/stdlib/persist/sql/ModuleUtils.java b/native/src/main/java/io/ballerina/stdlib/persist/sql/ModuleUtils.java index 7ca7e25..4fa6ab5 100644 --- a/native/src/main/java/io/ballerina/stdlib/persist/sql/ModuleUtils.java +++ b/native/src/main/java/io/ballerina/stdlib/persist/sql/ModuleUtils.java @@ -20,6 +20,9 @@ import io.ballerina.runtime.api.Environment; import io.ballerina.runtime.api.Module; +import io.ballerina.runtime.api.creators.ErrorCreator; + +import java.util.concurrent.CompletableFuture; /** * Utility functions relevant to module operations. @@ -40,4 +43,12 @@ public static void setModule(Environment env) { public static Module getModule() { return sqlModule; } + + public static Object getResult(CompletableFuture balFuture) { + try { + return balFuture.get(); + } catch (Throwable throwable) { + throw ErrorCreator.createError(throwable); + } + } } diff --git a/native/src/main/java/io/ballerina/stdlib/persist/sql/datastore/SQLProcessor.java b/native/src/main/java/io/ballerina/stdlib/persist/sql/datastore/SQLProcessor.java index 942441e..1489244 100644 --- a/native/src/main/java/io/ballerina/stdlib/persist/sql/datastore/SQLProcessor.java +++ b/native/src/main/java/io/ballerina/stdlib/persist/sql/datastore/SQLProcessor.java @@ -19,16 +19,11 @@ package io.ballerina.stdlib.persist.sql.datastore; import io.ballerina.runtime.api.Environment; -import io.ballerina.runtime.api.Future; import io.ballerina.runtime.api.PredefinedTypes; -import io.ballerina.runtime.api.async.Callback; import io.ballerina.runtime.api.constants.RuntimeConstants; import io.ballerina.runtime.api.creators.TypeCreator; import io.ballerina.runtime.api.creators.ValueCreator; -import io.ballerina.runtime.api.types.ErrorType; import io.ballerina.runtime.api.types.RecordType; -import io.ballerina.runtime.api.types.StreamType; -import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.utils.TypeUtils; import io.ballerina.runtime.api.values.BArray; import io.ballerina.runtime.api.values.BError; @@ -40,12 +35,12 @@ import io.ballerina.runtime.transactions.TransactionLocalContext; import io.ballerina.runtime.transactions.TransactionResourceManager; import io.ballerina.stdlib.persist.Constants; -import io.ballerina.stdlib.persist.ModuleUtils; +import io.ballerina.stdlib.persist.sql.Handler; import io.ballerina.stdlib.persist.sql.Utils; import java.util.Map; +import java.util.concurrent.CompletableFuture; -import static io.ballerina.stdlib.persist.Constants.ERROR; import static io.ballerina.stdlib.persist.Constants.KEY_FIELDS; import static io.ballerina.stdlib.persist.ErrorGenerator.wrapError; import static io.ballerina.stdlib.persist.Utils.getEntity; @@ -58,6 +53,7 @@ import static io.ballerina.stdlib.persist.sql.Constants.SQL_EXECUTE_METHOD; import static io.ballerina.stdlib.persist.sql.Constants.SQL_QUERY_METHOD; import static io.ballerina.stdlib.persist.sql.ModuleUtils.getModule; +import static io.ballerina.stdlib.persist.sql.ModuleUtils.getResult; import static io.ballerina.stdlib.persist.sql.Utils.createPersistNativeSQLStream; import static io.ballerina.stdlib.persist.sql.Utils.wrapSQLError; @@ -82,8 +78,6 @@ static BStream query(Environment env, BObject client, BTypedesc targetType, BObj RecordType recordTypeWithIdFields = getRecordTypeWithKeyFields(keyFields, recordType); BTypedesc targetTypeWithIdFields = ValueCreator.createTypedescValue(recordTypeWithIdFields); - StreamType streamTypeWithIdFields = TypeCreator.createStreamType(recordTypeWithIdFields, - PredefinedTypes.TYPE_NULL); Map trxContextProperties = getTransactionContextProperties(); String strandName = env.getStrandName().isPresent() ? env.getStrandName().get() : null; @@ -93,37 +87,44 @@ static BStream query(Environment env, BObject client, BTypedesc targetType, BObj BArray includes = metadata[1]; BArray typeDescriptions = metadata[2]; - Future balFuture = env.markAsync(); - env.getRuntime().invokeMethodAsyncSequentially( - // Call `SQLClient.runReadQuery( - // typedesc rowType, string[] fields = [], string[] include = [] - // )` - // which returns `stream|persist:Error` - - persistClient, Constants.RUN_READ_QUERY_METHOD, strandName, env.getStrandMetadata(), new Callback() { - @Override - public void notifySuccess(Object o) { - if (o instanceof BStream) { // stream - BStream sqlStream = (BStream) o; - balFuture.complete(Utils.createPersistSQLStreamValue(sqlStream, targetType, fields, - includes, typeDescriptions, persistClient, null)); - } else { // persist:Error - balFuture.complete(Utils.createPersistSQLStreamValue(null, targetType, fields, includes, - typeDescriptions, persistClient, (BError) o)); - } - } - - @Override - public void notifyFailure(BError bError) { + CompletableFuture balFuture = new CompletableFuture<>(); + Thread.startVirtualThread(() -> { + Handler handler = new Handler() { + @Override + public void notifySuccess(Object o) { + if (o instanceof BStream) { // stream + BStream sqlStream = (BStream) o; + balFuture.complete(Utils.createPersistSQLStreamValue(sqlStream, targetType, fields, + includes, typeDescriptions, persistClient, null)); + } else { // persist:Error balFuture.complete(Utils.createPersistSQLStreamValue(null, targetType, fields, includes, - typeDescriptions, persistClient, wrapError(bError))); + typeDescriptions, persistClient, (BError) o)); } - }, trxContextProperties, streamTypeWithIdFields, - targetTypeWithIdFields, true, fields, true, includes, true, whereClause, true, orderByClause, - true, limitClause, true, groupByClause, true - ); - - return null; + } + + @Override + public void notifyFailure(BError bError) { + balFuture.complete(Utils.createPersistSQLStreamValue(null, targetType, fields, includes, + typeDescriptions, persistClient, wrapError(bError))); + } + }; + try { + Object result = env.getRuntime().startNonIsolatedWorker( + // Call `SQLClient.runReadQuery( + // typedesc rowType, string[] fields = [], string[] include = [] + // )` + // which returns `stream|persist:Error` + + persistClient, Constants.RUN_READ_QUERY_METHOD, strandName, env.getStrandMetadata(), + trxContextProperties, targetTypeWithIdFields, fields, includes, whereClause, + orderByClause, limitClause, groupByClause + ).get(); + handler.notifySuccess(result); + } catch (BError bError) { + handler.notifyFailure(bError); + } + }); + return (BStream) getResult(balFuture); } static Object queryOne(Environment env, BObject client, BArray path, BTypedesc targetType) { @@ -140,8 +141,6 @@ static Object queryOne(Environment env, BObject client, BArray path, BTypedesc t RecordType recordTypeWithIdFields = getRecordTypeWithKeyFields(keyFields, recordType); BTypedesc targetTypeWithIdFields = ValueCreator.createTypedescValue(recordTypeWithIdFields); - ErrorType persistErrorType = TypeCreator.createErrorType(ERROR, ModuleUtils.getModule()); - Type unionType = TypeCreator.createUnionType(recordTypeWithIdFields, persistErrorType); BArray[] metadata = getMetadata(recordType); BArray fields = metadata[0]; @@ -150,31 +149,38 @@ static Object queryOne(Environment env, BObject client, BArray path, BTypedesc t Object key = getKey(env, path); - Future balFuture = env.markAsync(); - env.getRuntime().invokeMethodAsyncSequentially( - // Call `SQLClient.runReadByKeyQuery( - // typedesc rowType, typedesc rowTypeWithIdFields, anydata key, - // string[] fields = [], string[] include = [], typedesc[] typeDescriptions = [] - // )` - // which returns `record {}|persist:Error` - - getPersistClient(client, entity), Constants.RUN_READ_BY_KEY_QUERY_METHOD, strandName, - env.getStrandMetadata(), new Callback() { - @Override - public void notifySuccess(Object o) { - balFuture.complete(o); - } - - @Override - public void notifyFailure(BError bError) { - balFuture.complete(wrapError(bError)); - } - }, trxContextProperties, unionType, - targetType, true, targetTypeWithIdFields, true, key, true, fields, true, includes, true, - typeDescriptions, true - ); - - return null; + CompletableFuture balFuture = new CompletableFuture<>(); + Thread.startVirtualThread(() -> { + Handler handler = new Handler() { + @Override + public void notifySuccess(Object o) { + balFuture.complete(o); + } + + @Override + public void notifyFailure(BError bError) { + balFuture.complete(wrapError(bError)); + } + }; + try { + Object result = env.getRuntime().startNonIsolatedWorker( + // Call `SQLClient.runReadByKeyQuery( + // typedesc rowType, typedesc rowTypeWithIdFields, anydata key, + // string[] fields = [], string[] include = [], typedesc[] typeDescriptions = [] + // )` + // which returns `record {}|persist:Error` + + getPersistClient(client, entity), Constants.RUN_READ_BY_KEY_QUERY_METHOD, strandName, + env.getStrandMetadata(), trxContextProperties, + targetType, targetTypeWithIdFields, key, fields, includes, + typeDescriptions + ).get(); + handler.notifySuccess(result); + } catch (BError bError) { + handler.notifyFailure(bError); + } + }); + return getResult(balFuture); } static BStream queryNativeSQL(Environment env, BObject client, BObject paramSQLString, @@ -193,81 +199,94 @@ private static BStream queryNativeSQLBal(Environment env, BObject client, BObjec // This method will return `stream` BObject dbClient = (BObject) client.get(DB_CLIENT); - RecordType recordType = (RecordType) targetType.getDescribingType(); - StreamType streamType = TypeCreator.createStreamType(recordType, PredefinedTypes.TYPE_NULL); TransactionResourceManager trxResourceManager = TransactionResourceManager.getInstance(); TransactionLocalContext currentTrxContext = trxResourceManager.getCurrentTransactionContext(); - Map properties = null; - if (currentTrxContext != null) { - properties = Map.of(RuntimeConstants.CURRENT_TRANSACTION_CONTEXT_PROPERTY, currentTrxContext); - } - - Future balFuture = env.markAsync(); - env.getRuntime().invokeMethodAsyncSequentially( - // Call `sqlClient.query(paramSQLString, targetType)` which returns `stream` - - dbClient, SQL_QUERY_METHOD, null, env.getStrandMetadata(), new Callback() { - @Override - public void notifySuccess(Object o) { - // returned type is `stream` - BStream sqlStream = (BStream) o; - BObject persistNativeStream = createPersistNativeSQLStream(sqlStream, null); - RecordType streamConstraint = - (RecordType) TypeUtils.getReferredType(targetType.getDescribingType()); - balFuture.complete( - ValueCreator.createStreamValue(TypeCreator.createStreamType(streamConstraint, - PredefinedTypes.TYPE_NULL), persistNativeStream) - ); - } - @Override - public void notifyFailure(BError bError) { // can only be hit on a panic - BObject errorStream = Utils.createPersistNativeSQLStream(null, bError); - balFuture.complete(errorStream); - } - }, properties, streamType, paramSQLString, true, targetType, true - ); - - return null; + CompletableFuture balFuture = new CompletableFuture<>(); + Thread.startVirtualThread(() -> { + Map properties = null; + if (currentTrxContext != null) { + properties = Map.of(RuntimeConstants.CURRENT_TRANSACTION_CONTEXT_PROPERTY, currentTrxContext); + } + Handler handler = new Handler() { + @Override + public void notifySuccess(Object o) { + // returned type is `stream` + BStream sqlStream = (BStream) o; + BObject persistNativeStream = createPersistNativeSQLStream(sqlStream, null); + RecordType streamConstraint = + (RecordType) TypeUtils.getReferredType(targetType.getDescribingType()); + balFuture.complete( + ValueCreator.createStreamValue(TypeCreator.createStreamType(streamConstraint, + PredefinedTypes.TYPE_NULL), persistNativeStream) + ); + } + + @Override + public void notifyFailure(BError bError) { // can only be hit on a panic + BObject errorStream = Utils.createPersistNativeSQLStream(null, bError); + balFuture.complete(errorStream); + } + }; + try { + Object result = env.getRuntime().startNonIsolatedWorker( + // Call `sqlClient.query(paramSQLString, targetType)` which returns + // `stream` + + dbClient, SQL_QUERY_METHOD, null, env.getStrandMetadata(), properties, paramSQLString, + targetType + ).get(); + handler.notifySuccess(result); + } catch (BError bError) { + handler.notifyFailure(bError); + } + }); + return (BStream) getResult(balFuture); } private static Object executeNativeSQLBal(Environment env, BObject client, BObject paramSQLString) { BObject dbClient = (BObject) client.get(DB_CLIENT); - RecordType persistExecutionResultType = TypeCreator.createRecordType( - io.ballerina.stdlib.persist.sql.Constants.PERSIST_EXECUTION_RESULT, getModule(), 0, true, 0); TransactionResourceManager trxResourceManager = TransactionResourceManager.getInstance(); TransactionLocalContext currentTrxContext = trxResourceManager.getCurrentTransactionContext(); - Map properties = null; - if (currentTrxContext != null) { - properties = Map.of(RuntimeConstants.CURRENT_TRANSACTION_CONTEXT_PROPERTY, currentTrxContext); - } - - Future balFuture = env.markAsync(); - env.getRuntime().invokeMethodAsyncSequentially( - // Call `sqlClient.execute(paramSQLString)` which returns `sql:ExecutionResult|sql:Error` - - dbClient, SQL_EXECUTE_METHOD, null, env.getStrandMetadata(), new Callback() { - @Override - public void notifySuccess(Object o) { - if (o instanceof BMap) { // returned type is `sql:ExecutionResult` - BMap persistExecutionResult = - ValueCreator.createRecordValue(getModule(), - io.ballerina.stdlib.persist.sql.Constants.PERSIST_EXECUTION_RESULT, - (BMap) o); - balFuture.complete(persistExecutionResult); - } else if (o instanceof BError) { // returned type is `sql:Error` - BError persistError = wrapSQLError((BError) o); - balFuture.complete(persistError); - } - } - @Override - public void notifyFailure(BError bError) { // can only be hit on a panic - BError persistError = wrapError(bError); + CompletableFuture balFuture = new CompletableFuture<>(); + Thread.startVirtualThread(() -> { + Map properties = null; + if (currentTrxContext != null) { + properties = Map.of(RuntimeConstants.CURRENT_TRANSACTION_CONTEXT_PROPERTY, currentTrxContext); + } + Handler handler = new Handler() { + @Override + public void notifySuccess(Object o) { + if (o instanceof BMap) { // returned type is `sql:ExecutionResult` + BMap persistExecutionResult = + ValueCreator.createRecordValue(getModule(), + io.ballerina.stdlib.persist.sql.Constants.PERSIST_EXECUTION_RESULT, + (BMap) o); + balFuture.complete(persistExecutionResult); + } else if (o instanceof BError) { // returned type is `sql:Error` + BError persistError = wrapSQLError((BError) o); balFuture.complete(persistError); } - }, properties, persistExecutionResultType, paramSQLString, true); - - return null; + } + + @Override + public void notifyFailure(BError bError) { // can only be hit on a panic + BError persistError = wrapError(bError); + balFuture.complete(persistError); + } + }; + try { + env.getRuntime().startNonIsolatedWorker( + // Call `sqlClient.execute(paramSQLString)` which returns `sql:ExecutionResult|sql:Error` + + dbClient, SQL_EXECUTE_METHOD, null, env.getStrandMetadata(), properties, + paramSQLString).get(); + handler.notifySuccess(balFuture); + } catch (BError bError) { + handler.notifyFailure(bError); + } + }); + return getResult(balFuture); } }