diff --git a/.github/workflows/build-timestamped-master.yml b/.github/workflows/build-timestamped-master.yml index 82fa97d..860dc22 100644 --- a/.github/workflows/build-timestamped-master.yml +++ b/.github/workflows/build-timestamped-master.yml @@ -16,12 +16,12 @@ jobs: runs-on: ubuntu-latest if: github.repository_owner == 'ballerina-platform' steps: - - uses: actions/checkout@v3 - - name: Set up JDK 17 + - uses: actions/checkout@v2 + - name: Set up JDK 21 uses: actions/setup-java@v3 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/publish-release.yml b/.github/workflows/publish-release.yml index cc436dc..697ff20 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@v3 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v3 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 4e2930f..fc9c8c3 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@v3 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v4 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/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 6a51f11..58a351e 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.1" path = "../native/build/libs/persist.sql-native-1.4.1.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 7b8b005..d3fc0d6 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/build.gradle b/build.gradle index 2d62704..7010181 100644 --- a/build.gradle +++ b/build.gradle @@ -84,6 +84,7 @@ subprojects { ballerinaStdLibs "io.ballerina.stdlib:uuid-ballerina:${stdlibUuidVersion}" ballerinaStdLibs "io.ballerina.stdlib:cache-ballerina:${stdlibCacheVersion}" ballerinaStdLibs "io.ballerina.stdlib:oauth2-ballerina:${stdlibOAuth2Version}" + ballerinaStdLibs "io.ballerina.lib:data.jsondata-ballerina:${stdlibDataJsonDataVersion}" ballerinaStdLibs "io.ballerina.stdlib:auth-ballerina:${stdlibAuthVersion}" ballerinaStdLibs "io.ballerina.stdlib:jwt-ballerina:${stdlibJwtVersion}" ballerinaStdLibs "io.ballerina.stdlib:http-ballerina:${stdlibHttpVersion}" 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 30829f1..4611658 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ version=1.4.2-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,64 @@ gsonVersion=2.10 ballerinaGradlePluginVersion=2.0.1 jacocoVersion=0.8.10 -ballerinaLangVersion=2201.10.0 +ballerinaLangVersion=2201.11.0-20241117-133400-a3054b77 # Direct Dependencies # Level 01 -stdlibIoVersion=1.6.1 -stdlibTimeVersion=2.4.0 -stdlibUrlVersion=2.4.0 +stdlibIoVersion=1.6.2-20241112-233100-995cf5f +stdlibTimeVersion=2.6.0-20241113-073800-201b904 +stdlibUrlVersion=2.4.1-20241113-073900-335ff51 # Level 02 -stdlibLogVersion=2.10.0 -stdlibOsVersion=1.8.0 -stdlibPersistVersion=1.4.0 +stdlibLogVersion=2.10.1-20241113-120000-4577868 +stdlibOsVersion=1.8.1-20241113-122000-cca973b +stdlibPersistVersion=1.4.1-20241113-122000-306cc63 # Level 03 -stdlibFileVersion=1.10.0 +stdlibFileVersion=1.10.1-20241113-151700-e1a2e38 # Level 05 -stdlibHttpVersion=2.12.0 +stdlibHttpVersion=2.13.0-20241114-182900-7e9f66a # Level 07 -stdlibSqlVersion=1.14.0 +stdlibSqlVersion=1.15.0-20241116-124800-0bc6a40 # Ballerina external dependency -stdlibH2DriverVersion=1.1.0 -stdlibMysqlDriverVersion=1.6.0 -stdlibMssqlDriverVersion=1.6.0 -stdlibPostgresqlDriverVersion=1.5.1 +stdlibH2DriverVersion=1.1.1-20241116-205700-cf03680 +stdlibMysqlDriverVersion=1.7.1-20241116-205100-72cd8ab +stdlibMssqlDriverVersion=1.6.1-20241116-205000-d3351e2 +stdlibPostgresqlDriverVersion=1.5.2-20241116-204700-582e4be # Ballerinax Observer -observeVersion=1.3.0 -observeInternalVersion=1.3.0 +observeVersion=1.4.0-20241113-092000-b83ae74 +observeInternalVersion=1.3.1-20241113-101700-265054d # Transitive Dependencies #Level 02 -stdlibConstraintVersion=1.5.0 -stdlibCryptoVersion=2.7.2 -stdlibTaskVersion=2.5.0 +stdlibConstraintVersion=1.6.0-20241113-090900-d276ad5 +stdlibCryptoVersion=2.7.3-20241113-081400-d015a39 +stdlibTaskVersion=2.5.1-20241113-123500-f905281 # Level 03 -stdlibCacheVersion=3.8.0 -stdlibMimeVersion=2.10.0 -stdlibUuidVersion=1.8.0 +stdlibCacheVersion=3.8.1-20241113-125700-b75a1bf +stdlibMimeVersion=2.10.2-20241113-154200-d953747 +stdlibUuidVersion=1.8.1-20241113-154400-443c67b # Level 04 -stdlibAuthVersion=2.12.0 -stdlibJwtVersion=2.13.0 -stdlibOAuth2Version=2.12.0 +stdlibAuthVersion=2.12.1-20241113-162300-ded40eb +stdlibJwtVersion=2.13.1-20241113-162400-b59ccfa +stdlibOAuth2Version=2.12.1-20241113-162400-4c6ddfe +stdlibDataJsonDataVersion=0.3.0-20241114-143900-285d739 # Level 06 -stdlibTransactionVersion=1.10.0 +stdlibTransactionVersion=1.10.1-20241116-112500-189a4e5 # Test Dependencies -stdlibMysqlVersion=1.13.0 -stdlibMssqlVersion=1.13.0 -stdlibPostgresqlVersion=1.13.0 -stdlibJdbcVersion=1.12.0 +stdlibMysqlVersion=1.13.2-20241116-211000-539dff6 +stdlibMssqlVersion=1.13.2-20241116-222300-cb5ec9c +stdlibPostgresqlVersion=1.13.3-20241116-222400-f6d72ae +stdlibJdbcVersion=1.12.2-20241116-224900-893e2b1 # 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/ModuleUtils.java b/native/src/main/java/io/ballerina/stdlib/persist/sql/ModuleUtils.java index 7ca7e25..c8bb2af 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,10 @@ import io.ballerina.runtime.api.Environment; import io.ballerina.runtime.api.Module; +import io.ballerina.runtime.api.creators.ErrorCreator; +import io.ballerina.runtime.api.values.BError; + +import java.util.concurrent.CompletableFuture; /** * Utility functions relevant to module operations. @@ -40,4 +44,17 @@ public static void setModule(Environment env) { public static Module getModule() { return sqlModule; } + + public static Object getResult(CompletableFuture balFuture) { + try { + return balFuture.get(); + } catch (BError error) { + throw error; + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw ErrorCreator.createError(e); + } catch (Throwable throwable) { + throw ErrorCreator.createError(throwable); + } + } } diff --git a/native/src/main/java/io/ballerina/stdlib/persist/sql/Utils.java b/native/src/main/java/io/ballerina/stdlib/persist/sql/Utils.java index ad750dd..6202b14 100644 --- a/native/src/main/java/io/ballerina/stdlib/persist/sql/Utils.java +++ b/native/src/main/java/io/ballerina/stdlib/persist/sql/Utils.java @@ -18,9 +18,9 @@ package io.ballerina.stdlib.persist.sql; -import io.ballerina.runtime.api.PredefinedTypes; import io.ballerina.runtime.api.creators.TypeCreator; import io.ballerina.runtime.api.creators.ValueCreator; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.RecordType; import io.ballerina.runtime.api.utils.TypeUtils; import io.ballerina.runtime.api.values.BArray; 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..9662b99 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,12 @@ 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.concurrent.StrandMetadata; 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.PredefinedTypes; 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 +36,10 @@ 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.Utils; import java.util.Map; -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; @@ -55,6 +49,7 @@ import static io.ballerina.stdlib.persist.Utils.getRecordTypeWithKeyFields; import static io.ballerina.stdlib.persist.Utils.getTransactionContextProperties; import static io.ballerina.stdlib.persist.sql.Constants.DB_CLIENT; +import static io.ballerina.stdlib.persist.sql.Constants.PERSIST_EXECUTION_RESULT; 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; @@ -82,48 +77,34 @@ 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; - BArray[] metadata = getMetadata(recordType); BArray fields = metadata[0]; 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) { - balFuture.complete(Utils.createPersistSQLStreamValue(null, targetType, fields, includes, - typeDescriptions, persistClient, wrapError(bError))); - } - }, trxContextProperties, streamTypeWithIdFields, - targetTypeWithIdFields, true, fields, true, includes, true, whereClause, true, orderByClause, - true, limitClause, true, groupByClause, true - ); - - return null; + return env.yieldAndRun(() -> { + try { + Object result = env.getRuntime().callMethod( + // Call `SQLClient.runReadQuery( + // typedesc rowType, string[] fields = [], string[] include = [] + // )` + // which returns `stream|persist:Error` + persistClient, Constants.RUN_READ_QUERY_METHOD, new StrandMetadata(false, trxContextProperties), + targetTypeWithIdFields, fields, includes, whereClause, + orderByClause, limitClause, groupByClause); + if (result instanceof BStream bStream) { // stream + return Utils.createPersistSQLStreamValue(bStream, targetType, fields, includes, typeDescriptions, + persistClient, null); + } + // persist:Error + return Utils.createPersistSQLStreamValue(null, targetType, fields, includes, typeDescriptions, + persistClient, (BError) result); + } catch (BError bError) { + return Utils.createPersistSQLStreamValue(null, targetType, fields, includes, typeDescriptions, + persistClient, wrapError(bError)); + } + }); } static Object queryOne(Environment env, BObject client, BArray path, BTypedesc targetType) { @@ -136,12 +117,8 @@ static Object queryOne(Environment env, BObject client, BArray path, BTypedesc t RecordType recordType = (RecordType) targetType.getDescribingType(); Map trxContextProperties = getTransactionContextProperties(); - String strandName = env.getStrandName().isPresent() ? env.getStrandName().get() : null; - 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]; @@ -149,32 +126,21 @@ static Object queryOne(Environment env, BObject client, BArray path, BTypedesc t BArray typeDescriptions = metadata[2]; 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; + return env.yieldAndRun(() -> { + try { + return env.getRuntime().callMethod( + // 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, + new StrandMetadata(false, trxContextProperties), targetType, targetTypeWithIdFields, key, + fields, includes, typeDescriptions); + } catch (BError bError) { + return wrapError(bError); + } + }); } static BStream queryNativeSQL(Environment env, BObject client, BObject paramSQLString, @@ -193,81 +159,55 @@ 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; + return (BStream) env.yieldAndRun(() -> { + try { + Map properties = null; + if (currentTrxContext != null) { + properties = Map.of(RuntimeConstants.CURRENT_TRANSACTION_CONTEXT_PROPERTY, currentTrxContext); + } + Object result = env.getRuntime().callMethod( + // Call `sqlClient.query(paramSQLString, targetType)` which returns + // `stream` + dbClient, SQL_QUERY_METHOD, new StrandMetadata(false, properties), paramSQLString, + targetType); + // returned type is `stream` + BStream sqlStream = (BStream) result; + BObject persistNativeStream = createPersistNativeSQLStream(sqlStream, null); + RecordType streamConstraint = + (RecordType) TypeUtils.getReferredType(targetType.getDescribingType()); + return ValueCreator.createStreamValue(TypeCreator.createStreamType(streamConstraint, + PredefinedTypes.TYPE_NULL), persistNativeStream); + } catch (BError bError) { + return Utils.createPersistNativeSQLStream(null, bError); + } + }); } 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); - balFuture.complete(persistError); - } - }, properties, persistExecutionResultType, paramSQLString, true); - return null; + return env.yieldAndRun(() -> { + Map properties = null; + if (currentTrxContext != null) { + properties = Map.of(RuntimeConstants.CURRENT_TRANSACTION_CONTEXT_PROPERTY, currentTrxContext); + } + try { + Object result = env.getRuntime().callMethod( + // Call `sqlClient.execute(paramSQLString)` which returns `sql:ExecutionResult|sql:Error` + dbClient, SQL_EXECUTE_METHOD, new StrandMetadata(false, properties), paramSQLString); + if (result instanceof BMap map) { // returned type is `sql:ExecutionResult` + return ValueCreator.createRecordValue(getModule(), PERSIST_EXECUTION_RESULT, (BMap) map); + } + return wrapSQLError((BError) result); + } catch (BError bError) { + return bError; + } + }); } }