diff --git a/.gitignore b/.gitignore index de1a364b9..d20c88065 100644 --- a/.gitignore +++ b/.gitignore @@ -24,7 +24,9 @@ hs_err_pid* build .gradle/ -target + +/target/ +!persist-cli-tests/src/resources/test-src/**/target/ # IDEA Files .idea/ @@ -44,3 +46,6 @@ bin/ # Ballerina velocity.log* *Ballerina.lock + +# Jar Dependency Versions +version.properties diff --git a/changelog.md b/changelog.md index 4b4d400e3..9b12e65ea 100644 --- a/changelog.md +++ b/changelog.md @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - [Added support for PostgreSQL as a datasource](https://github.com/ballerina-platform/ballerina-standard-library/issues/5829) - [Integrate the persist code generation to the bal build command](https://github.com/ballerina-platform/ballerina-library/issues/5784) +- [Added introspection support for MySQL databases](https://github.com/ballerina-platform/ballerina-library/issues/6014) +- [Added advanced annotation support for SQL databases](https://github.com/ballerina-platform/ballerina-library/issues/6013) ## [1.2.1] - 2021-11-21 diff --git a/docs/spec/spec.md b/docs/spec/spec.md index f33bdde56..218758872 100644 --- a/docs/spec/spec.md +++ b/docs/spec/spec.md @@ -22,6 +22,7 @@ The conforming implementation of the specification is released and included in t 2. [Initializing Persistence Layer in Bal Project](#2-initializing-the-bal-project-with-persistence-layer) 3. [Generating Persistence Derived Types, Clients, and Database Schema](#3-generating-persistence-derived-types-and-clients) 4. [Push Persistence Schema to the Data Provider](#4-push-persistence-schema-to-the-data-provider) +5. [Pull Persistence Schema from the Data Provider](#5-pull-persistence-schema-from-the-data-provider) ## 1. Overview This specification elaborates on the `Persist CLI Tool` commands. @@ -206,3 +207,33 @@ Behaviour of the `push` command, - User should add the relevant configuration to the Ballerina.toml file. - The user should have initiated the persistence layer in the project and executed the `generate` command to generate the SQL script. - If the user invokes the command twice, it will not fail. It will rerun the SQL script against the database. + +## 5. Pull Persistence Schema from the Data Provider + +```bash +bal persist pull --datastore mysql --host localhost --port 3306 --user root --database persist +``` +| Command Parameter | Description | Mandatory | Default Value | +|:-----------------:|:-------------------------------------------------------------------------------------:|:---------:|:-------------:| +| --datastore | used to indicate the preferred database client. Currently, only 'mysql' is supported. | No | mysql | +| --host | used to indicate the database host | Yes | None | +| --port | used to indicate the database port | No | 3306 | +| --user | used to indicate the database user | Yes | None | +| --database | used to indicate the database name | Yes | None | + +This command will introspect the schema of the database and create a `model.bal` file with the entities and relations based on the schema of the database. The database configuration should be provided as command-line arguments. + +This command should execute within a Ballerina project. + +The `persist` directory is created if it is not already present. If a `model.bal` file is already present in the `persist` directory, it will prompt the user to confirm overwriting the existing `model.bal` file. + +Running the `pull` command will, +1. Create a `model.bal` file with the entities and relations based on the introspected schema of the database. +2. Not change the schema of the database in any way. + +Behaviour of the `pull` command, +- User should invoke the command within a Ballerina project. +- User should provide the relevant database configuration as command-line arguments. +- The database password is not provided as a command-line argument. The user will be prompted to enter the password. +- If the user invokes the command while a `model.bal` file exists in the `persist` directory, it will prompt the user to confirm overwriting the existing `model.bal` file. +- The user must execute the `generate` command to generate the derived types and client API after running the `pull` command in order to use the client API in the project. diff --git a/examples/build.gradle b/examples/build.gradle index 2e5f3dcd3..95e82a583 100644 --- a/examples/build.gradle +++ b/examples/build.gradle @@ -24,6 +24,7 @@ description = 'Ballerina - Persist Examples' def ballerinaDist = "${project.buildDir}/ballerina-distribution" def examples = ["medical-center", "rainier"] +def introspectionExamples = ["hospital"] configurations { balTools @@ -124,6 +125,14 @@ task copyTestResources() { } } } + copy { + introspectionExamples.each { example -> + into buildDir + into("generated-examples/${example}/") { + from "${example}" + } + } + } } } @@ -248,6 +257,26 @@ task generateInMemoryExamples { } } +task generateIntrospectionExamples { + doLast { + introspectionExamples.each { example -> + try { + exec { + workingDir "${project.projectDir}/build/generated-examples/${example}" + if (!Os.isFamily(Os.FAMILY_WINDOWS)) { + commandLine 'sh', '-c', "${ballerinaDist}/bin/bal persist generate --datastore=mysql --module=entities" + } else { + commandLine 'cmd', '/c', "${ballerinaDist}/bin/bal.bat persist generate --datastore=mysql --module=entities" + } + } + } catch (Exception e) { + println("Example '${example}' Generation failed: " + e.message) + throw e + } + } + } +} + // task generateGSheetExamples { // doLast { // examples.each { example -> @@ -306,13 +335,13 @@ def checkExecResult(executionResult, failText, standardOutput) { task startTestDockerContainer(type: Exec) { if (!Os.isFamily(Os.FAMILY_WINDOWS)) { def standardOutput = new ByteArrayOutputStream() - commandLine 'sh', '-c', 'docker run --platform linux/amd64 --rm -d --name ballerina-persist-tools-example -e MYSQL_ROOT_PASSWORD="Test123#" -p 3308:3306 -t mysql:8.0.21' + commandLine 'sh', '-c', 'docker run --platform linux/amd64 --rm -d --name ballerina-persist-tools-example -e MYSQL_ROOT_PASSWORD="Test123#" -e MYSQL_DATABASE="hospital" -p 3308:3306 -t mysql:8.0.21' def healthCheck = 1 def counter = 0 doLast { checkExecResult(executionResult, 'Error', standardOutput) while (healthCheck != 0 && counter < 12) { - sleep(60 * 1000) + sleep(30 * 1000) healthCheck = checkTestDockerContainerStatus('ballerina-persist-tools-example') counter = counter + 1 } @@ -406,6 +435,47 @@ task testInMemoryExamples { } } +task testIntrospectionExamples { + dependsOn(startTestDockerContainer) + doLast { + introspectionExamples.each { example -> + try { + if (!Os.isFamily(Os.FAMILY_WINDOWS)) { + //this part is not necessary. this is added so that the build will not fail due to the issue with + //mysql connector for ballerina requiring a 'first login' on a different mysql client. This is a + //temporary fix until the issue is resolved. + try { + exec { + workingDir "${project.projectDir}/build/generated-examples/${example}" + commandLine 'sh', '-c', "${ballerinaDist}/bin/bal persist pull --host localhost --database nonexistentdb --user root --port 3308" + standardInput = new ByteArrayInputStream("Test123#\ny\n".getBytes()) + } + } catch (Exception ignored) {} + exec { + workingDir "${project.projectDir}/build/generated-examples/${example}" + commandLine 'sh', '-c', "${ballerinaDist}/bin/bal test" + } + } else { + try { + exec { + workingDir "${project.projectDir}/build/generated-examples/${example}" + commandLine 'cmd', '/c', "${ballerinaDist}/bin/bal.bat persist pull --host localhost --database hris --user root --port 3308" + standardInput = new ByteArrayInputStream("Test123#\ny\n".getBytes()) + } + } catch (Exception ignored) {} + exec { + workingDir "${project.projectDir}/build/generated-examples/${example}" + commandLine 'cmd', '/c', "${ballerinaDist}/bin/bal.bat test" + } + } + } catch (Exception e) { + println("Example '${example}' Tests failed: " + e.message) + throw e + } + } + } +} + task automateGSheetTable { doLast { try { @@ -450,6 +520,7 @@ copyPersistTool.dependsOn ":persist-cli:build" copyTestResources.dependsOn copyPersistTool initInMemoryExamples.dependsOn copyTestResources +generateIntrospectionExamples.dependsOn copyTestResources generateInMemoryExamples.dependsOn initInMemoryExamples testInMemoryExamples.dependsOn generateInMemoryExamples @@ -457,6 +528,7 @@ initDbExamples.dependsOn testInMemoryExamples generateDbExamples.dependsOn initDbExamples pushExamples.dependsOn generateDbExamples testDbExamples.dependsOn pushExamples +testIntrospectionExamples.dependsOn generateIntrospectionExamples // initGSheetExamples.dependsOn testDbExamples // generateGSheetExamples.dependsOn initGSheetExamples @@ -465,5 +537,6 @@ testDbExamples.dependsOn pushExamples build.dependsOn testInMemoryExamples build.dependsOn testDbExamples +build.dependsOn testIntrospectionExamples //build.dependsOn testGSheetExamples build.finalizedBy stopTestDockerContainer diff --git a/examples/hospital/Ballerina.toml b/examples/hospital/Ballerina.toml new file mode 100644 index 000000000..18b35e571 --- /dev/null +++ b/examples/hospital/Ballerina.toml @@ -0,0 +1,16 @@ +[package] +org = "wso2" +name = "Demo" +version = "0.1.0" +distribution = "2201.8.4" + +[build-options] +observabilityIncluded = true + +[[platform.java17.repository]] +id="wso2-nexus" +url = "https://maven.wso2.org/nexus/content/groups/public/" + +[[platform.java17.repository]] +id="wso2-nexus-snapshot" +url = "https://maven.wso2.org/nexus/content/repositories/snapshots/" diff --git a/examples/hospital/Dependencies.toml b/examples/hospital/Dependencies.toml new file mode 100644 index 000000000..3551d7b66 --- /dev/null +++ b/examples/hospital/Dependencies.toml @@ -0,0 +1,395 @@ +# AUTO-GENERATED FILE. DO NOT MODIFY. + +# This file is auto-generated by Ballerina for managing dependency versions. +# It should not be modified by hand. + +[ballerina] +dependencies-toml-version = "2" +distribution-version = "2201.9.0-20240229-103900-a949e6d4" + +[[package]] +org = "ballerina" +name = "auth" +version = "2.10.0" +dependencies = [ + {org = "ballerina", name = "crypto"}, + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.array"}, + {org = "ballerina", name = "lang.string"}, + {org = "ballerina", name = "log"} +] + +[[package]] +org = "ballerina" +name = "cache" +version = "3.7.1" +dependencies = [ + {org = "ballerina", name = "constraint"}, + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "task"}, + {org = "ballerina", name = "time"} +] + +[[package]] +org = "ballerina" +name = "constraint" +version = "1.5.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] + +[[package]] +org = "ballerina" +name = "crypto" +version = "2.6.2" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "time"} +] + +[[package]] +org = "ballerina" +name = "file" +version = "1.9.0" +dependencies = [ + {org = "ballerina", name = "io"}, + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "os"}, + {org = "ballerina", name = "time"} +] + +[[package]] +org = "ballerina" +name = "http" +version = "2.10.10" +dependencies = [ + {org = "ballerina", name = "auth"}, + {org = "ballerina", name = "cache"}, + {org = "ballerina", name = "constraint"}, + {org = "ballerina", name = "crypto"}, + {org = "ballerina", name = "file"}, + {org = "ballerina", name = "io"}, + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "jwt"}, + {org = "ballerina", name = "lang.array"}, + {org = "ballerina", name = "lang.decimal"}, + {org = "ballerina", name = "lang.int"}, + {org = "ballerina", name = "lang.regexp"}, + {org = "ballerina", name = "lang.runtime"}, + {org = "ballerina", name = "lang.string"}, + {org = "ballerina", name = "lang.value"}, + {org = "ballerina", name = "log"}, + {org = "ballerina", name = "mime"}, + {org = "ballerina", name = "oauth2"}, + {org = "ballerina", name = "observe"}, + {org = "ballerina", name = "time"}, + {org = "ballerina", name = "url"} +] +modules = [ + {org = "ballerina", packageName = "http", moduleName = "http"}, + {org = "ballerina", packageName = "http", moduleName = "http.httpscerr"} +] + +[[package]] +org = "ballerina" +name = "io" +version = "1.6.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.value"} +] + +[[package]] +org = "ballerina" +name = "jballerina.java" +version = "0.0.0" +modules = [ + {org = "ballerina", packageName = "jballerina.java", moduleName = "jballerina.java"} +] + +[[package]] +org = "ballerina" +name = "jwt" +version = "2.10.0" +dependencies = [ + {org = "ballerina", name = "cache"}, + {org = "ballerina", name = "crypto"}, + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.int"}, + {org = "ballerina", name = "lang.string"}, + {org = "ballerina", name = "log"}, + {org = "ballerina", name = "time"} +] + +[[package]] +org = "ballerina" +name = "lang.__internal" +version = "0.0.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.object"} +] + +[[package]] +org = "ballerina" +name = "lang.array" +version = "0.0.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.__internal"} +] + +[[package]] +org = "ballerina" +name = "lang.decimal" +version = "0.0.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] + +[[package]] +org = "ballerina" +name = "lang.error" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] + +[[package]] +org = "ballerina" +name = "lang.int" +version = "0.0.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.__internal"}, + {org = "ballerina", name = "lang.object"} +] + +[[package]] +org = "ballerina" +name = "lang.object" +version = "0.0.0" + +[[package]] +org = "ballerina" +name = "lang.regexp" +version = "0.0.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] + +[[package]] +org = "ballerina" +name = "lang.runtime" +version = "0.0.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] + +[[package]] +org = "ballerina" +name = "lang.string" +version = "0.0.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.regexp"} +] + +[[package]] +org = "ballerina" +name = "lang.value" +version = "0.0.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] + +[[package]] +org = "ballerina" +name = "log" +version = "2.9.0" +dependencies = [ + {org = "ballerina", name = "io"}, + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.value"}, + {org = "ballerina", name = "observe"} +] + +[[package]] +org = "ballerina" +name = "mime" +version = "2.9.0" +dependencies = [ + {org = "ballerina", name = "io"}, + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.int"} +] + +[[package]] +org = "ballerina" +name = "oauth2" +version = "2.10.0" +dependencies = [ + {org = "ballerina", name = "cache"}, + {org = "ballerina", name = "crypto"}, + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "log"}, + {org = "ballerina", name = "time"}, + {org = "ballerina", name = "url"} +] + +[[package]] +org = "ballerina" +name = "observe" +version = "1.2.2" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] + +[[package]] +org = "ballerina" +name = "os" +version = "1.8.0" +dependencies = [ + {org = "ballerina", name = "io"}, + {org = "ballerina", name = "jballerina.java"} +] + +[[package]] +org = "ballerina" +name = "persist" +version = "1.3.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] +modules = [ + {org = "ballerina", packageName = "persist", moduleName = "persist"} +] + +[[package]] +org = "ballerina" +name = "sql" +version = "1.12.0" +dependencies = [ + {org = "ballerina", name = "io"}, + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.object"}, + {org = "ballerina", name = "time"} +] +modules = [ + {org = "ballerina", packageName = "sql", moduleName = "sql"} +] + +[[package]] +org = "ballerina" +name = "task" +version = "2.5.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "time"} +] + +[[package]] +org = "ballerina" +name = "test" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.array"}, + {org = "ballerina", name = "lang.error"} +] +modules = [ + {org = "ballerina", packageName = "test", moduleName = "test"} +] + +[[package]] +org = "ballerina" +name = "time" +version = "2.4.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] +modules = [ + {org = "ballerina", packageName = "time", moduleName = "time"} +] + +[[package]] +org = "ballerina" +name = "url" +version = "2.4.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] + +[[package]] +org = "ballerinai" +name = "observe" +version = "0.0.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "observe"} +] +modules = [ + {org = "ballerinai", packageName = "observe", moduleName = "observe"} +] + +[[package]] +org = "ballerinax" +name = "mysql" +version = "1.11.0" +dependencies = [ + {org = "ballerina", name = "crypto"}, + {org = "ballerina", name = "io"}, + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "sql"}, + {org = "ballerina", name = "time"} +] +modules = [ + {org = "ballerinax", packageName = "mysql", moduleName = "mysql"} +] + +[[package]] +org = "ballerinax" +name = "mysql.driver" +version = "1.6.0" +modules = [ + {org = "ballerinax", packageName = "mysql.driver", moduleName = "mysql.driver"} +] + +[[package]] +org = "ballerinax" +name = "persist.sql" +version = "1.3.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "log"}, + {org = "ballerina", name = "persist"}, + {org = "ballerina", name = "sql"}, + {org = "ballerina", name = "time"} +] +modules = [ + {org = "ballerinax", packageName = "persist.sql", moduleName = "persist.sql"} +] + +[[package]] +org = "haritha" +name = "Demo" +version = "0.1.0" +dependencies = [ + {org = "ballerina", name = "http"}, + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "persist"}, + {org = "ballerina", name = "sql"}, + {org = "ballerina", name = "test"}, + {org = "ballerina", name = "time"}, + {org = "ballerinai", name = "observe"}, + {org = "ballerinax", name = "mysql"}, + {org = "ballerinax", name = "mysql.driver"}, + {org = "ballerinax", name = "persist.sql"} +] +modules = [ + {org = "haritha", packageName = "Demo", moduleName = "Demo"}, + {org = "haritha", packageName = "Demo", moduleName = "Demo.entities"} +] + diff --git a/examples/hospital/main.bal b/examples/hospital/main.bal new file mode 100644 index 000000000..9b95cf920 --- /dev/null +++ b/examples/hospital/main.bal @@ -0,0 +1,193 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import Demo.entities; + +import ballerina/http; +import ballerina/persist; +import ballerina/time; + +public type Doctor record {| + readonly int id; + string name; + string specialty; +|}; + +type Appointment record {| + int id; + int doctorId; + time:Civil appointmentTime; + entities:AppointmentStatus status; + record {| + int id; + string name; + string phoneNumber; + |} patient; +|}; + +type PatientAppointment record {| + int id; + int patientId; + time:Civil appointmentTime; + entities:AppointmentStatus status; + record {| + int id; + string name; + string specialty; + |} doctor; +|}; + +type PatientCreated record {| + *http:Created; +|}; + +service /hospital on new http:Listener(9090) { + private final entities:Client dbClient; + + // Initialize the service + function init() returns error? { + self.dbClient = check new (); + } + + // Define the resource to handle POST requests + resource function post doctors(entities:DoctorInsert doctor) returns http:InternalServerError & readonly|http:Created & readonly|http:Conflict & readonly { + int[]|persist:Error result = self.dbClient->/doctors.post([doctor]); + if result is persist:Error { + if result is persist:AlreadyExistsError { + return http:CONFLICT; + } + return http:INTERNAL_SERVER_ERROR; + } + return http:CREATED; + } + + // Define the resource to handle POST requests for patients + resource function post patients(entities:PatientInsert patient) returns http:InternalServerError & readonly|PatientCreated|http:Conflict & readonly { + int[]|persist:Error result = self.dbClient->/patients.post([patient]); + if result is persist:Error { + return http:INTERNAL_SERVER_ERROR; + } + return { + body: { + insertedId: result[0] + } + }; + } + + // Define the resource to handle POST requests for appointments + resource function post appointments(entities:AppointmentInsert appointment) returns http:InternalServerError & readonly|http:Created & readonly|http:Conflict & readonly { + int[]|persist:Error result = self.dbClient->/appointments.post([appointment]); + if result is persist:Error { + if result is persist:AlreadyExistsError { + return http:CONFLICT; + } + return http:INTERNAL_SERVER_ERROR; + } + return http:CREATED; + } + + // Define the resource to handle GET requests for doctors + resource function get doctors() returns Doctor[]|error { + stream doctors = self.dbClient->/doctors.get(); + return from Doctor doctor in doctors + select doctor; + } + + // Define the resource to handle GET requests for doctors by id as path param and date as query params + resource function get doctors/[int id]/appointments(int year, int month, int day) returns Appointment[]|error { + stream appointments = self.dbClient->/appointments(); + return from Appointment appointment in appointments + where appointment.doctorId == id && + appointment.appointmentTime.year == year && + appointment.appointmentTime.month == month && + appointment.appointmentTime.day == day + select appointment; + + } + + // Define the resource to handle GET requests for appointments for patients by id + resource function get patients/[int id]/appointments() returns PatientAppointment[]|error { + stream appointments = self.dbClient->/appointments(); + return from PatientAppointment appointment in appointments + where appointment.patientId == id + select appointment; + } + + // Define the resource to handle GET requests for patients by id + resource function get patients/[int id]() returns http:InternalServerError & readonly|http:NotFound & readonly|entities:Patient { + entities:Patient|persist:Error result = self.dbClient->/patients/[id]; + if result is persist:Error { + if result is persist:NotFoundError { + return http:NOT_FOUND; + } + return http:INTERNAL_SERVER_ERROR; + } + return result; + } + + // Define the resource to handle PATCH requests for appointment by id + resource function patch appointments/[int id](@http:Payload entities:AppointmentStatus status) returns http:InternalServerError & readonly|http:NotFound & readonly|http:NoContent & readonly { + entities:Appointment|persist:Error result = self.dbClient->/appointments/[id].put({status}); + if result is persist:Error { + if result is persist:NotFoundError { + return http:NOT_FOUND; + } + return http:INTERNAL_SERVER_ERROR; + } + return http:NO_CONTENT; + } + + // Define the resource to handle DELETE requests for patient's appointments passing patient id as path param and date as query params + resource function delete patients/[int id]/appointments(int year, int month, int day) returns http:InternalServerError & readonly|http:NoContent & readonly|http:NotFound & readonly { + stream appointments = self.dbClient->/appointments; + entities:Appointment[]|persist:Error result = from entities:Appointment appointment in appointments + where appointment.patientId == id + && appointment.appointmentTime.year == year + && appointment.appointmentTime.month == month + && appointment.appointmentTime.day == day + select appointment; + if result is persist:Error { + if result is persist:NotFoundError { + return http:NOT_FOUND; + } + return http:INTERNAL_SERVER_ERROR; + } + foreach entities:Appointment appointment in result { + entities:Appointment|persist:Error deleteResult = self.dbClient->/appointments/[appointment.id].delete(); + if deleteResult is persist:Error { + return http:INTERNAL_SERVER_ERROR; + } + } + + return http:NO_CONTENT; + } + + resource function delete patients/[int id]() returns http:NoContent | http:InternalServerError { + entities:Patient|persist:Error result = self.dbClient->/patients/[id].delete(); + if result is persist:Error { + return http:INTERNAL_SERVER_ERROR; + } + return http:NO_CONTENT; + } + + resource function delete doctors/[int id]() returns http:NoContent | http:InternalServerError { + entities:Doctor|persist:Error result = self.dbClient->/doctors/[id].delete(); + if result is persist:Error { + return http:INTERNAL_SERVER_ERROR; + } + return http:NO_CONTENT; + } +} diff --git a/examples/hospital/persist/model.bal b/examples/hospital/persist/model.bal new file mode 100644 index 000000000..534fee3f7 --- /dev/null +++ b/examples/hospital/persist/model.bal @@ -0,0 +1,76 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerina/time; +import ballerinax/persist.sql; + +public enum AppointmentStatus { + SCHEDULED = "SCHEDULED", + STARTED = "STARTED", + ENDED = "ENDED" +} + +public enum PatientGender { + MALE = "MALE", + FEMALE = "FEMALE" +} + +@sql:Mapping {name: "appointment"} +public type Appointment record {| + readonly int id; + @sql:UniqueIndex {names: ["reason_index"]} + string reason; + time:Civil appointmentTime; + AppointmentStatus status; + @sql:Mapping {name: "patient_id"} + @sql:Index {names: ["patientId"]} + int patientId; + @sql:Index {names: ["doctorId"]} + int doctorId; + @sql:Relation {refs: ["patientId"]} + Patient patient; + @sql:Relation {refs: ["doctorId"]} + Doctor doctor; +|}; + +@sql:Mapping {name: "patients"} +public type Patient record {| + @sql:Mapping {name: "ID"} + @sql:Generated + readonly int id; + string name; + int age; + @sql:Mapping {name: "ADDRESS"} + string address; + @sql:Char {length: 10} + string phoneNumber; + PatientGender gender; + Appointment[] appointments; +|}; + +public type Doctor record {| + readonly int id; + string name; + @sql:Index {names: ["specialty_index"]} + string specialty; + @sql:Mapping {name: "phone_number"} + string phoneNumber; + @sql:Decimal {precision: [10, 2]} + decimal? salary; + Appointment[] appointments; +|}; + diff --git a/examples/hospital/tests/Config.toml b/examples/hospital/tests/Config.toml new file mode 100644 index 000000000..08cc566db --- /dev/null +++ b/examples/hospital/tests/Config.toml @@ -0,0 +1,12 @@ +host = "localhost" +port = 3308 +user = "root" +password = "Test123#" +database = "hospital" + +[Demo.entities] +host = "localhost" +port = 3308 +user = "root" +password = "Test123#" +database = "hospital" diff --git a/examples/hospital/tests/demo_test.bal b/examples/hospital/tests/demo_test.bal new file mode 100644 index 000000000..e8cefc5e3 --- /dev/null +++ b/examples/hospital/tests/demo_test.bal @@ -0,0 +1,288 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/test; +import ballerina/http; +import Demo.entities; +import ballerinax/mysql; + +http:Client hospitalEndpoint = check new("http://localhost:9090/hospital"); +configurable int port = ?; +configurable string host = ?; +configurable string user = ?; +configurable string database = ?; +configurable string password = ?; +configurable mysql:Options & readonly connectionOptions = {}; + +@test:BeforeSuite +function initDatabase() returns error? { + mysql:Client dbClient = check new (host = host, user = user, password = password, port = port, options = connectionOptions); + _ = check dbClient->execute(`DROP DATABASE IF EXISTS hospital`); + _ = check dbClient->execute(`CREATE DATABASE hospital`); + _ = check dbClient->execute(`USE hospital`); + _ = check dbClient->execute(`CREATE TABLE Doctor ( + id INT NOT NULL, + name VARCHAR(191) NOT NULL, + specialty VARCHAR(191) NOT NULL, + phone_number VARCHAR(191) NOT NULL, + salary DECIMAL(10,2), + PRIMARY KEY(id) + )`); + _ = check dbClient->execute(`CREATE TABLE patients ( + ID INT AUTO_INCREMENT, + name VARCHAR(191) NOT NULL, + age INT NOT NULL, + ADDRESS VARCHAR(191) NOT NULL, + phoneNumber CHAR(10) NOT NULL, + gender ENUM('MALE', 'FEMALE') NOT NULL, + PRIMARY KEY(ID) + )`); + _ = check dbClient->execute(`CREATE TABLE appointment ( + id INT NOT NULL, + reason VARCHAR(191) NOT NULL, + appointmentTime DATETIME NOT NULL, + status ENUM('SCHEDULED', 'STARTED', 'ENDED') NOT NULL, + patient_id INT NOT NULL, + FOREIGN KEY(patient_id) REFERENCES patients(ID), + doctorId INT NOT NULL, + FOREIGN KEY(doctorId) REFERENCES Doctor(id), + PRIMARY KEY(id) + )`); + _ = check dbClient->execute(`CREATE INDEX patientId ON appointment (patient_id)`); + _ = check dbClient->execute(`CREATE INDEX doctorId ON appointment (doctorId)`); + _ = check dbClient->execute(`CREATE UNIQUE INDEX reason_index ON appointment (reason)`); + _ = check dbClient->execute(`CREATE INDEX specialty_index ON Doctor (specialty)`); + _ = check dbClient.close(); +} + +@test:Config{} +function testCreatePatient() returns error? { + entities:PatientInsert patient = { + name: "John Doe", + age: 30, + phoneNumber: "0771690000", + gender: "MALE", + address: "123, Main Street, Colombo 05" + }; + http:Response result = check hospitalEndpoint->/patients.post(patient); + test:assertEquals(result.statusCode, 201, "Status code should be 201"); + test:assertEquals(result.getJsonPayload(), {"insertedId":1}, "Inserted Patient ID should be 1"); +} + +@test:Config{} +function testCreateDoctor() returns error? { + entities:DoctorInsert doctor = { + id: 1, + name: "Doctor Mouse", + specialty: "Physician", + phoneNumber: "077100100", + salary: 20000 + }; + http:Response result = check hospitalEndpoint->/doctors.post(doctor); + test:assertEquals(result.statusCode, 201, "Status code should be 201"); +} + +@test:Config{ + dependsOn: [testCreateDoctor] +} +function testCreateDoctorAlreadyExists() returns error? { + entities:DoctorInsert doctor = { + id: 1, + name: "Doctor Mouse", + specialty: "Physician", + phoneNumber: "077100100", + salary: 20000 + }; + http:Response result = check hospitalEndpoint->/doctors.post(doctor); + test:assertEquals(result.statusCode, 409, "Status code should be 409"); +} + +@test:Config{ + dependsOn: [testCreatePatient, testCreateDoctor] +} +function testCreateAppointment() returns error? { + entities:AppointmentInsert appointment = { + id: 1, + patientId: 1, + doctorId: 1, + appointmentTime: {year: 2023, month: 7, day: 1, hour: 10, minute: 30}, + status: "SCHEDULED", + reason: "Headache" + }; + http:Response result = check hospitalEndpoint->/appointments.post(appointment); + test:assertEquals(result.statusCode, 201, "Status code should be 201"); +} + +@test:Config{ + dependsOn: [testCreatePatient, testCreateDoctor, testCreateAppointment] +} +function testCreateAppointmentAlreadyExists() returns error? { + entities:AppointmentInsert appointment = { + id: 1, + patientId: 1, + doctorId: 1, + appointmentTime: {year: 2023, month: 7, day: 1, hour: 10, minute: 30}, + status: "SCHEDULED", + reason: "Headache" + }; + http:Response result = check hospitalEndpoint->/appointments.post(appointment); + test:assertEquals(result.statusCode, 409, "Status code should be 409"); +} + +@test:Config{ + dependsOn: [testCreateDoctor] +} +function testGetDoctors() returns error? { + http:Response result = check hospitalEndpoint->/doctors.get(); + test:assertEquals(result.statusCode, 200, "Status code should be 200"); + test:assertEquals(result.getJsonPayload(), [{"id":1,"name":"Doctor Mouse","specialty":"Physician"}], "Doctor details should be returned"); +} + +@test:Config{ + dependsOn: [testCreatePatient] +} +function testGetPatientById() returns error? { + http:Response result = check hospitalEndpoint->/patients/[1]; + test:assertEquals(result.statusCode, 200, "Status code should be 200"); + test:assertEquals(result.getJsonPayload(), {"id":1, "name": "John Doe", "age": 30, "address": "123, Main Street, Colombo 05", "phoneNumber":"0771690000", "gender":"MALE"}, "Patient details should be returned"); +} + +@test:Config{} +function testGetPatientNotFound() returns error? { + http:Response result = check hospitalEndpoint->/patients/[50]; + test:assertEquals(result.statusCode, 404, "Status code should be 404"); +} + +@test:Config{ + dependsOn: [testCreateAppointment] +} +function testGetAppointmentByDoctor() returns error? { + http:Response result = check hospitalEndpoint->/doctors/[1]/appointments(year=2023, month=7, day=1); + test:assertEquals(result.statusCode, 200, "Status code should be 200"); + test:assertEquals(result.getJsonPayload(), [ + { + "id": 1, + "doctorId": 1, + "appointmentTime": { + "year": 2023, + "month": 7, + "day": 1, + "hour": 10, + "minute": 30, + "second": 0 + }, + "status": "SCHEDULED", + "patient": { + "id": 1, + "name": "John Doe", + "phoneNumber": "0771690000" + } + } + ], "Appointment details should be returned"); + http:Response result2 = check hospitalEndpoint->/doctors/[5]/appointments(year=2023, month=7, day=1); + test:assertEquals(result2.statusCode, 200, "Status code should be 200"); + test:assertEquals(result2.getJsonPayload(), [], "Appointment details should be empty"); +} + +@test:Config{ + dependsOn: [testCreateAppointment] +} +function testGetAppointmentByPatient() returns error? { + http:Response result = check hospitalEndpoint->/patients/[1]/appointments; + test:assertEquals(result.statusCode, 200, "Status code should be 200"); + test:assertEquals(result.getJsonPayload(), [ + { + "id": 1, + "patientId": 1, + "appointmentTime": { + "year": 2023, + "month": 7, + "day": 1, + "hour": 10, + "minute": 30, + "second": 0 + }, + "status": "SCHEDULED", + "doctor": { + "id": 1, + "name": "Doctor Mouse", + "specialty": "Physician" + } + } + ], "Appointment details should be returned"); + http:Response result2 = check hospitalEndpoint->/patients/[5]/appointments; + test:assertEquals(result2.statusCode, 200, "Status code should be 200"); + test:assertEquals(result2.getJsonPayload(), [], "Appointment details should be empty"); +} + +@test:Config{ + dependsOn: [testCreateAppointment, testGetAppointmentByDoctor, testGetAppointmentByPatient] +} +function testPatchAppointment() returns error? { + http:Response result = check hospitalEndpoint->/appointments/[1].patch("STARTED"); + test:assertEquals(result.statusCode, 204, "Status code should be 204"); + http:Response result2 = check hospitalEndpoint->/patients/[1]/appointments; + test:assertEquals(result2.statusCode, 200, "Status code should be 200"); + test:assertEquals(result2.getJsonPayload(), [ + { + "id": 1, + "patientId": 1, + "appointmentTime": { + "year": 2023, + "month": 7, + "day": 1, + "hour": 10, + "minute": 30, + "second": 0 + }, + "status": "STARTED", + "doctor": { + "id": 1, + "name": "Doctor Mouse", + "specialty": "Physician" + } + } + ], "Appointment details should be returned"); + http:Response result3 = check hospitalEndpoint->/appointments/[10].patch("STARTED"); + test:assertEquals(result3.statusCode, 404, "Status code should be 404"); +} + +@test:Config{ + dependsOn: [testCreateAppointment, testGetAppointmentByDoctor, testGetAppointmentByPatient, testPatchAppointment] +} +function testDeleteAppointmentByPatientId() returns error? { + http:Response result = check hospitalEndpoint->/patients/[1]/appointments.delete(year=2023, month=7, day=1); + test:assertEquals(result.statusCode, 204, "Status code should be 204"); + http:Response result2 = check hospitalEndpoint->/patients/[1]/appointments; + test:assertEquals(result2.statusCode, 200, "Status code should be 200"); + test:assertEquals(result2.getJsonPayload(), [], "Appointment details should be empty"); +} + +@test:Config{ + dependsOn: [testGetPatientById, testDeleteAppointmentByPatientId] +} +function testDeletePatient() returns error? { + http:Response result = check hospitalEndpoint->/patients/[1].delete(); + test:assertEquals(result.statusCode, 204, "Status code should be 204"); +} + +@test:Config{ + dependsOn: [testGetDoctors, testDeleteAppointmentByPatientId] +} +function testDeleteDoctor() returns error? { + http:Response result = check hospitalEndpoint->/doctors/[1].delete(); + test:assertEquals(result.statusCode, 204, "Status code should be 204"); +} diff --git a/gradle.properties b/gradle.properties index 1bbc336e9..5eee0ef49 100644 --- a/gradle.properties +++ b/gradle.properties @@ -48,22 +48,22 @@ stdlibHttpVersion=2.10.4 stdlibSqlVersion=1.11.1 # Level 09 -stdlibPersistVersion=1.3.0-20240301-141700-02872be +stdlibPersistVersion=1.3.0-20240311-220000-f31520a # Level 10 -stdlibPersistSqlVersion=1.2.2-20231206-130200-881839f +stdlibPersistSqlVersion=1.3.0-20240312-224600-ecf3ece stdlibPersistInmemoryVersion=1.2.0 stdlibPersistGoogleSheetVersion=1.2.0 # Persist native jar maven dependencies -persistSqlNativeVersion=1.2.2-SNAPSHOT +persistSqlNativeVersion=1.3.0-SNAPSHOT persistInMemoryNativeVersion=1.2.0 persistGoogleSheetsNativeVersion=1.2.0 # Test Dependencies # Dependency of mysql should be the previous update versions stdlibMysqlVersion=1.11.0 -stdlibMysqlDriverVersion=1.4.1 +stdlibMysqlDriverVersion=1.6.0 # Ballerinax Observe observeVersion=1.2.0 diff --git a/persist-cli-tests/build.gradle b/persist-cli-tests/build.gradle index 9247b8032..803ec7e07 100644 --- a/persist-cli-tests/build.gradle +++ b/persist-cli-tests/build.gradle @@ -213,7 +213,7 @@ task startTestDockerContainer(type: Exec) { doLast { checkExecResult(executionResult, 'Error', standardOutput) while (healthCheck != 0 && counter < 12) { - sleep(60 * 1000) + sleep(30 * 1000) healthCheck = checkTestDockerContainerStatus('ballerina-persist-tools') counter = counter + 1 } @@ -253,7 +253,7 @@ task startMSSQLTestDockerContainer(type: Exec) { doLast { checkExecResult(executionResult, 'Error', standardOutput) while (healthCheck != 0 && counter < 12) { - sleep(60 * 1000) + sleep(30 * 1000) healthCheck = checkMSSQLTestDockerContainerStatus('ballerina-persist-tools-mssql') counter = counter + 1 } @@ -306,7 +306,7 @@ task startPostgreSQLTestDockerContainer(type: Exec) { doLast { checkExecResult(executionResult, 'Error', standardOutput) while (healthCheck != 0 && counter < 12) { - sleep(5 * 1000) + sleep(30 * 1000) healthCheck = checkPostgreSQLTestDockerContainerStatus("ballerina-persist-tools-postgresql") counter = counter + 1; } diff --git a/persist-cli-tests/src/test/java/io/ballerina/persist/tools/ToolingDbPullTest.java b/persist-cli-tests/src/test/java/io/ballerina/persist/tools/ToolingDbPullTest.java new file mode 100644 index 000000000..3d6be581e --- /dev/null +++ b/persist-cli-tests/src/test/java/io/ballerina/persist/tools/ToolingDbPullTest.java @@ -0,0 +1,408 @@ +/* + * Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you 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 + * + * http://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 io.ballerina.persist.tools; + +import io.ballerina.persist.BalException; +import io.ballerina.persist.cmd.Pull; +import io.ballerina.persist.configuration.DatabaseConfiguration; +import jdk.jfr.Description; +import org.junit.jupiter.api.condition.OS; +import org.testng.annotations.Test; +import picocli.CommandLine; + + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Path; +import java.nio.file.Paths; + +import static io.ballerina.persist.tools.utils.DatabaseTestUtils.createFromDatabaseScript; +import static io.ballerina.persist.tools.utils.GeneratedSourcesTestUtils.assertGeneratedSources; + +public class ToolingDbPullTest { + private static final String GENERATED_SOURCES_DIRECTORY = Paths.get("build", "generated-sources") + .toString(); + + private static final DatabaseConfiguration databaseConfig; + + static { + try { + databaseConfig = new DatabaseConfiguration("localhost", "root", "Test123#", + "3307", "persist"); + } catch (BalException e) { + throw new RuntimeException(e); + } + } + + @Test(enabled = true) + @Description("Test the command line args for pull command.") + public void pullTestArgs() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, + InstantiationException, IllegalAccessException { + String subDir = "tool_test_pull_23"; + Class persistClass = Class.forName("io.ballerina.persist.cmd.Pull"); + + // datastore is empty + Path path = Paths.get(GENERATED_SOURCES_DIRECTORY, subDir); + Pull persistCmd1 = (Pull) persistClass.getDeclaredConstructor(String.class).newInstance(path.toAbsolutePath() + .toString()); + new CommandLine(persistCmd1).parseArgs("--datastore", ""); + new CommandLine(persistCmd1).parseArgs("--host", "localhost"); + new CommandLine(persistCmd1).parseArgs("--port", "3307"); + new CommandLine(persistCmd1).parseArgs("--user", "root"); + new CommandLine(persistCmd1).parseArgs("--database", "persist"); + persistCmd1.execute(); + assertGeneratedSources(subDir); + + // host is empty + Pull persistCmd2 = (Pull) persistClass.getDeclaredConstructor(String.class).newInstance(path.toAbsolutePath() + .toString()); + new CommandLine(persistCmd2).parseArgs("--datastore", "mysql"); + new CommandLine(persistCmd2).parseArgs("--host", ""); + new CommandLine(persistCmd2).parseArgs("--port", "3307"); + new CommandLine(persistCmd2).parseArgs("--user", "root"); + new CommandLine(persistCmd2).parseArgs("--database", "persist"); + persistCmd2.execute(); + assertGeneratedSources(subDir); + + // port is empty + Pull persistCmd3 = (Pull) persistClass.getDeclaredConstructor(String.class).newInstance(path.toAbsolutePath() + .toString()); + new CommandLine(persistCmd3).parseArgs("--datastore", "mysql"); + new CommandLine(persistCmd3).parseArgs("--host", "localhost"); + new CommandLine(persistCmd3).parseArgs("--port", ""); + new CommandLine(persistCmd3).parseArgs("--user", "root"); + new CommandLine(persistCmd3).parseArgs("--database", "persist"); + persistCmd3.execute(); + assertGeneratedSources(subDir); + + // user is empty + Pull persistCmd4 = (Pull) persistClass.getDeclaredConstructor(String.class).newInstance(path.toAbsolutePath() + .toString()); + new CommandLine(persistCmd4).parseArgs("--datastore", "mysql"); + new CommandLine(persistCmd4).parseArgs("--host", "localhost"); + new CommandLine(persistCmd4).parseArgs("--port", "3307"); + new CommandLine(persistCmd4).parseArgs("--user", ""); + new CommandLine(persistCmd4).parseArgs("--database", "persist"); + persistCmd4.execute(); + assertGeneratedSources(subDir); + + // database is empty + Pull persistCmd5 = (Pull) persistClass.getDeclaredConstructor(String.class).newInstance(path.toAbsolutePath() + .toString()); + new CommandLine(persistCmd5).parseArgs("--datastore", "mysql"); + new CommandLine(persistCmd5).parseArgs("--host", "localhost"); + new CommandLine(persistCmd5).parseArgs("--port", "3307"); + new CommandLine(persistCmd5).parseArgs("--user", "root"); + new CommandLine(persistCmd5).parseArgs("--database", ""); + persistCmd5.execute(); + assertGeneratedSources(subDir); + + // host is not provided + Pull persistCmd6 = (Pull) persistClass.getDeclaredConstructor(String.class).newInstance(path.toAbsolutePath() + .toString()); + new CommandLine(persistCmd6).parseArgs("--datastore", "mysql"); + new CommandLine(persistCmd6).parseArgs("--port", "3307"); + new CommandLine(persistCmd6).parseArgs("--user", "root"); + new CommandLine(persistCmd6).parseArgs("--database", "persist"); + persistCmd6.execute(); + assertGeneratedSources(subDir); + + // user is not provided + Pull persistCmd7 = (Pull) persistClass.getDeclaredConstructor(String.class).newInstance(path.toAbsolutePath() + .toString()); + new CommandLine(persistCmd7).parseArgs("--datastore", "mysql"); + new CommandLine(persistCmd7).parseArgs("--host", "localhost"); + new CommandLine(persistCmd7).parseArgs("--port", "3307"); + new CommandLine(persistCmd7).parseArgs("--database", "persist"); + persistCmd7.execute(); + assertGeneratedSources(subDir); + + // database is not provided + Pull persistCmd8 = (Pull) persistClass.getDeclaredConstructor(String.class).newInstance(path.toAbsolutePath() + .toString()); + new CommandLine(persistCmd8).parseArgs("--datastore", "mysql"); + new CommandLine(persistCmd8).parseArgs("--host", "localhost"); + new CommandLine(persistCmd8).parseArgs("--port", "3307"); + new CommandLine(persistCmd8).parseArgs("--user", "root"); + persistCmd8.execute(); + assertGeneratedSources(subDir); + + // invalid port number (not a number) + Pull persistCmd9 = (Pull) persistClass.getDeclaredConstructor(String.class).newInstance(path.toAbsolutePath() + .toString()); + new CommandLine(persistCmd9).parseArgs("--datastore", "mysql"); + new CommandLine(persistCmd9).parseArgs("--host", "localhost"); + new CommandLine(persistCmd9).parseArgs("--port", "lkj"); + new CommandLine(persistCmd9).parseArgs("--user", "root"); + new CommandLine(persistCmd9).parseArgs("--database", "persist"); + persistCmd9.execute(); + assertGeneratedSources(subDir); + + // invalid port number (number, but invalid) + Pull persistCmd10 = (Pull) persistClass.getDeclaredConstructor(String.class).newInstance(path.toAbsolutePath() + .toString()); + new CommandLine(persistCmd10).parseArgs("--datastore", "mysql"); + new CommandLine(persistCmd10).parseArgs("--host", "localhost"); + new CommandLine(persistCmd10).parseArgs("--port", "69000"); + new CommandLine(persistCmd10).parseArgs("--user", "root"); + new CommandLine(persistCmd10).parseArgs("--database", "persist"); + persistCmd10.execute(); + assertGeneratedSources(subDir); + + // invalid database name + Pull persistCmd11 = (Pull) persistClass.getDeclaredConstructor(String.class).newInstance(path.toAbsolutePath() + .toString()); + new CommandLine(persistCmd11).parseArgs("--datastore", "mysql"); + new CommandLine(persistCmd11).parseArgs("--host", "localhost"); + new CommandLine(persistCmd11).parseArgs("--port", "3307"); + new CommandLine(persistCmd11).parseArgs("--user", "root"); + new CommandLine(persistCmd11).parseArgs("--database", "8persist"); + persistCmd11.execute(); + assertGeneratedSources(subDir); + + // no args given + Pull persistCmd12 = (Pull) persistClass.getDeclaredConstructor(String.class).newInstance(path.toAbsolutePath() + .toString()); + persistCmd12.execute(); + assertGeneratedSources(subDir); + } + + @Test(enabled = true) + @Description("Create a model.bal file consisting of one Entity with no annotations and not null fields.") + public void pullTestMysqlBasic() throws BalException { + runIntrospectionTest("tool_test_pull_1_mysql"); + } + + @Test(enabled = true) + @Description("Create a model.bal file consisting of one Entity with no annotations and one nullable field.") + public void pullTestMysqlNullableField() throws BalException { + runIntrospectionTest("tool_test_pull_2_mysql"); + } + + @Test(enabled = true) + @Description("Create a model.bal file consisting of two Entities with a one to many relation.") + public void pullTestMysqlOneToMany() throws BalException { + runIntrospectionTest("tool_test_pull_3_mysql"); + } + + @Test(enabled = true) + @Description("Introspection when a model.bal file already exists and continue.") + public void pullTestMysqlModelFileExistsContinue() throws BalException { + if (OS.WINDOWS.isCurrentOs()) { + return; + } + String subDir = "tool_test_pull_4_mysql"; + createFromDatabaseScript(subDir, "mysql", databaseConfig); + executeDefaultPullCommand(subDir, "y\n"); + assertGeneratedSources(subDir); + } + + @Test(enabled = true) + @Description("Introspection when a model.bal file already exists and abort.") + public void pullTestMysqlModelFileExistsAbort() throws BalException { + if (OS.WINDOWS.isCurrentOs()) { + return; + } + String subDir = "tool_test_pull_5_mysql"; + createFromDatabaseScript(subDir, "mysql", databaseConfig); + executeDefaultPullCommand(subDir, "n\n"); + assertGeneratedSources(subDir); + } + + @Test(enabled = true) + @Description("Create a model.bal file consisting of two Entities with a one to one relation " + + "by making foreign key unique.") + public void pullTestMysqlOneToOneUniqueKey() throws BalException { + runIntrospectionTest("tool_test_pull_6_mysql"); + } + + @Test(enabled = true) + @Description("Create a model.bal file consisting of two Entities with a one to one relation by " + + "making foreign key primary.") + public void pullTestMysqlOneToOnePrimaryKey() throws BalException { + runIntrospectionTest("tool_test_pull_7_mysql"); + } + + @Test(enabled = true) + @Description("Create a model.bal file consisting of two Entities with a one to many relation by " + + "making foreign key a partial key.") + public void pullTestMysqlPartialPrimaryKey() throws BalException { + runIntrospectionTest("tool_test_pull_8_mysql"); + } + + @Test(enabled = true) + @Description("Create a model.bal file three Entities with two one to many relations.") + public void pullTestMysqlMultipleRelations() throws BalException { + runIntrospectionTest("tool_test_pull_9_mysql"); + } + + @Test(enabled = true) + @Description("Create a model.bal file consisting of name mapping annotations.") + public void pullTestMysqlNameMappingAnnotation() throws BalException { + runIntrospectionTest("tool_test_pull_10_mysql"); + } + + @Test(enabled = true) + @Description("Create a model.bal file consisting of type mapping annotations Char, VarChar and Decimal.") + public void pullTestMysqlTypeMappingAnnotation() throws BalException { + runIntrospectionTest("tool_test_pull_11_mysql"); + } + + @Test(enabled = true) + @Description("Create a model.bal file consisting of unique index annotation.") + public void pullTestMysqlUniqueIndexAnnotation() throws BalException { + runIntrospectionTest("tool_test_pull_12_mysql"); + } + + @Test(enabled = true) + @Description("Create a model.bal file consisting of index annotation.") + public void pullTestMysqlIndexAnnotation() throws BalException { + runIntrospectionTest("tool_test_pull_13_mysql"); + } + + @Test(enabled = true) + @Description("Create a model.bal file consisting of multiple relations between same entities.") + public void pullTestMysqlMultipleRelationsBetweenSameEntities() throws BalException { + runIntrospectionTest("tool_test_pull_14_mysql"); + } + + @Test(enabled = true) + @Description("Create a model.bal file consisting of multiple unique indexes on same column.") + public void pullTestMysqlMultipleUniqueIndexes() throws BalException { + runIntrospectionTest("tool_test_pull_15_mysql"); + } + + @Test(enabled = true) + @Description("Create a model.bal file consisting of multiple indexes on same column.") + public void pullTestMysqlMultipleIndexes() throws BalException { + runIntrospectionTest("tool_test_pull_16_mysql"); + } + + @Test(enabled = true) + @Description("Create a model.bal file consisting of a one to many relation with composite foreign key.") + public void pullTestCompositeForeignKeys() throws BalException { + runIntrospectionTest("tool_test_pull_17_mysql"); + } + + @Test(enabled = true) + @Description("Create a model.bal file consisting of an entity with self-referenced relation.") + public void pullTestSelfReferencedRelation() throws BalException { + runIntrospectionTest("tool_test_pull_18_mysql"); + } + + @Test(enabled = true) + @Description("Create a model.bal file consisting of two relations which cross-reference each other.") + public void pullTestCrossReferencedRelations() throws BalException { + runIntrospectionTest("tool_test_pull_19_mysql"); + } + + @Test(enabled = true) + @Description("Create a model.bal file consisting of keyword field names which are to be escaped.") + public void pullTestEscapedFieldNames() throws BalException { + runIntrospectionTest("tool_test_pull_20_mysql"); + } + + @Test(enabled = true) + @Description("When the database does not contain any tables.") + public void pullTestNoTablesInDatabase() throws BalException { + runIntrospectionTest("tool_test_pull_21_mysql"); + } + + @Test(enabled = true) + @Description("When the database does not exist.") + public void pullTestDatabaseDoesNotExist() throws BalException { + runIntrospectionTest("tool_test_pull_22_mysql"); + } + + @Test(enabled = true) + @Description("Create a model.bal file consisting of a generated primary key field.") + public void pullTestWithGeneratedId() throws BalException { + runIntrospectionTest("tool_test_pull_24_mysql"); + } + + @Test(enabled = true) + @Description("Create a model.bal file consisting of a blob type field.") + public void pullTestWithBlobTypeField() throws BalException { + runIntrospectionTest("tool_test_pull_25_mysql"); + } + + private static void runIntrospectionTest(String subDir) throws BalException { + if (OS.WINDOWS.isCurrentOs()) { + return; + } + createFromDatabaseScript(subDir, "mysql", databaseConfig); + executeDefaultPullCommand(subDir); + assertGeneratedSources(subDir); + } + + + private static void executeDefaultPullCommand(String subDir) throws BalException { + try { + Class persistClass = Class.forName("io.ballerina.persist.cmd.Pull"); + Pull persistCmd = (Pull) persistClass.getDeclaredConstructor(String.class). + newInstance(Paths.get(GENERATED_SOURCES_DIRECTORY, subDir).toAbsolutePath().toString()); + new CommandLine(persistCmd).parseArgs("--datastore", "mysql"); + new CommandLine(persistCmd).parseArgs("--host", "localhost"); + new CommandLine(persistCmd).parseArgs("--port", "3307"); + new CommandLine(persistCmd).parseArgs("--user", "root"); + new CommandLine(persistCmd).parseArgs("--database", "persist"); + String password = databaseConfig.getPassword() + "\n"; + InputStream originalSystemIn = System.in; + try (InputStream inputStream = new ByteArrayInputStream(password.getBytes(StandardCharsets.UTF_8))) { + System.setIn(inputStream); + persistCmd.execute(); + } finally { + System.setIn(originalSystemIn); + } + System.setIn(originalSystemIn); + } catch (RuntimeException e) { + throw new RuntimeException("Error occurred while executing pull command: " + e.getMessage()); + } catch (Exception e) { + throw new BalException("Error occurred while executing pull command: " + e.getMessage()); + } + } + + private static void executeDefaultPullCommand(String subDir, String simulatedInput) throws BalException { + try { + Class persistClass = Class.forName("io.ballerina.persist.cmd.Pull"); + Pull persistCmd = (Pull) persistClass.getDeclaredConstructor(String.class). + newInstance(Paths.get(GENERATED_SOURCES_DIRECTORY, subDir).toAbsolutePath().toString()); + new CommandLine(persistCmd).parseArgs("--datastore", "mysql"); + new CommandLine(persistCmd).parseArgs("--host", databaseConfig.getHost()); + new CommandLine(persistCmd).parseArgs("--port", String.valueOf(databaseConfig.getPort())); + new CommandLine(persistCmd).parseArgs("--user", databaseConfig.getUsername()); + new CommandLine(persistCmd).parseArgs("--database", databaseConfig.getDatabase()); + InputStream originalSystemIn = System.in; + String passwordAndSimulatedInput = databaseConfig.getPassword() + "\n" + simulatedInput; + try (InputStream inputStream = new ByteArrayInputStream(passwordAndSimulatedInput + .getBytes(StandardCharsets.UTF_8))) { + System.setIn(inputStream); + persistCmd.execute(); + } finally { + System.setIn(originalSystemIn); + } + } catch (RuntimeException e) { + throw new RuntimeException("Error occurred while executing pull command: " + e.getMessage()); + } catch (Exception e) { + throw new BalException("Error occurred while executing pull command: " + e.getMessage()); + } + } +} + diff --git a/persist-cli-tests/src/test/java/io/ballerina/persist/tools/ToolingGenerateTest.java b/persist-cli-tests/src/test/java/io/ballerina/persist/tools/ToolingGenerateTest.java index 6a7f8b7ef..fb5802682 100644 --- a/persist-cli-tests/src/test/java/io/ballerina/persist/tools/ToolingGenerateTest.java +++ b/persist-cli-tests/src/test/java/io/ballerina/persist/tools/ToolingGenerateTest.java @@ -514,4 +514,167 @@ public void testInit() { executeCommand("tool_test_init_1", INIT); assertGeneratedSources("tool_test_init_1"); } + + @Test + @Description("The model has a relation with relation annotation") + public void testGenerateEntitiesWithRelationAnnotations() { + executeGenerateCommand("tool_test_generate_72", "mysql", "entities"); + assertGeneratedSources("tool_test_generate_72"); + } + + @Test(enabled = true) + @Description("The model has Mapping annotations on entities") + public void testGenerateEntitiesWithMappingAnnotations() { + executeGenerateCommand("tool_test_generate_73", "mysql", "entities"); + assertGeneratedSources("tool_test_generate_73"); + } + + @Test(enabled = true) + @Description("The model has Mapping annotations on foreign keys.") + public void testGenerateEntitiesWithMappingAnnotationOnForeignKeys() { + executeGenerateCommand("tool_test_generate_74", "mysql", "entities"); + assertGeneratedSources("tool_test_generate_74"); + } + + @Test(enabled = true) + @Description("The model has type mapping annotations Char, VarChar and Decimal") + public void testGenerateEntitiesWithTypeMappingAnnotations() { + executeGenerateCommand("tool_test_generate_75", "mysql", "entities"); + assertGeneratedSources("tool_test_generate_75"); + } + + @Test(enabled = true) + @Description("The model has a unique index on a field") + public void testGenerateEntitiesWithUniqueIndexesOnOneField() { + executeGenerateCommand("tool_test_generate_76", "mysql", "entities"); + assertGeneratedSources("tool_test_generate_76"); + } + + @Test(enabled = true) + @Description("The model has a single unique index on two fields") + public void testGenerateEntitiesSameUniqueIndexOnTwoFields() { + executeGenerateCommand("tool_test_generate_77", "mysql", "entities"); + assertGeneratedSources("tool_test_generate_77"); + } + + @Test(enabled = true) + @Description("The model has a single Index on two fields") + public void testGenerateEntitiesSameIndexOnTwoFields() { + executeGenerateCommand("tool_test_generate_78", "mysql", "entities"); + assertGeneratedSources("tool_test_generate_78"); + } + + @Test(enabled = true) + @Description("The model has an entity whose id field is renamed") + public void testGenerateEntitiesWithRenamedIdField() { + executeGenerateCommand("tool_test_generate_79", "mysql", "entities"); + assertGeneratedSources("tool_test_generate_79"); + } + + @Test(enabled = true) + @Description("The model has a renamed Id field and a renamed foreign key") + public void testGenerateEntitiesWithRenamedIdFieldAndForeignKey() { + executeGenerateCommand("tool_test_generate_80", "mysql", "entities"); + assertGeneratedSources("tool_test_generate_80"); + } + + @Test(enabled = true) + @Description("The model has a relation with a composite foreign key") + public void testGenerateEntitiesCompositeForeignKey() { + executeGenerateCommand("tool_test_generate_81", "mysql", "entities"); + assertGeneratedSources("tool_test_generate_81"); + } + + @Test(enabled = true) + @Description("The model has a relation with a composite foreign key with one key renamed") + public void testGenerateEntitiesRenamedCompositeForeignKeyPartial() { + executeGenerateCommand("tool_test_generate_82", "mysql", "entities"); + assertGeneratedSources("tool_test_generate_82"); + } + + @Test(enabled = true) + @Description("The model has a relation with a composite foreign key with both keys renamed") + public void testGenerateEntitiesRenamedCompositeForeignKey() { + executeGenerateCommand("tool_test_generate_83", "mysql", "entities"); + assertGeneratedSources("tool_test_generate_83"); + } + + @Test(enabled = true) + @Description("The model has a relation with a composite foreign key with both keys renamed along with part " + + "of primary key") + public void testGenerateEntitiesCompositeForeignKeyWithRenamedKeysPartial() { + executeGenerateCommand("tool_test_generate_84", "mysql", "entities"); + assertGeneratedSources("tool_test_generate_84"); + } + + @Test(enabled = true) + @Description("The model has a relation with a composite foreign key with both keys renamed along with primary keys") + public void testGenerateEntitiesCompositeForeignKeyWithRenamedKeys() { + executeGenerateCommand("tool_test_generate_85", "mysql", "entities"); + assertGeneratedSources("tool_test_generate_85"); + } + + @Test(enabled = true) + @Description("The model has an Entity with auto generated index on a field") + public void testGenerateEntitiesWithAutoGeneratedIndex() { + executeGenerateCommand("tool_test_generate_86", "mysql", "entities"); + assertGeneratedSources("tool_test_generate_86"); + } + + @Test(enabled = true) + @Description("The model has an Entity with auto generated index on a field") + public void testGenerateEntitiesWithAutoGeneratedUniqueIndex() { + executeGenerateCommand("tool_test_generate_87", "mysql", "entities"); + assertGeneratedSources("tool_test_generate_87"); + } + + @Test(enabled = true) + @Description("The model has Entities with both index types on same field") + public void testGenerateEntitiesWithBothIndexTypesOnSameField() { + executeGenerateCommand("tool_test_generate_88", "mysql", "entities"); + assertGeneratedSources("tool_test_generate_88"); + } + + @Test(enabled = true) + @Description("The model has Entities with both index types on same field and one with a name") + public void testGenerateEntitiesWithBothIndexTypesAndOneWithAName() { + executeGenerateCommand("tool_test_generate_89", "mysql", "entities"); + assertGeneratedSources("tool_test_generate_89"); + } + + @Test(enabled = true) + @Description("The model has Entity with auto generated ID field") + public void testGenerateEntityWithAutoGeneratedId() { + executeGenerateCommand("tool_test_generate_90", "mysql", "entities"); + assertGeneratedSources("tool_test_generate_90"); + } + + @Test(enabled = true) + @Description("The model has Entity with auto generated ID field with a relation") + public void testGenerateEntityWithAutoGeneratedIdWithRelation() { + executeGenerateCommand("tool_test_generate_91", "mysql", "entities"); + assertGeneratedSources("tool_test_generate_91"); + } + + @Test(enabled = true) + @Description("The model has Entity with auto generated ID field with a renamed relation") + public void testGenerateEntityWithAutoGeneratedIdWithRenamedRelation() { + executeGenerateCommand("tool_test_generate_92", "mysql", "entities"); + assertGeneratedSources("tool_test_generate_92"); + } + + @Test(enabled = true) + @Description("The model has multiple relations with relation annotations") + public void testGenerateEntitiesWithMultipleRelationsOnSame() { + executeGenerateCommand("tool_test_generate_93", "mysql", "entities"); + assertGeneratedSources("tool_test_generate_93"); + } + + @Test(enabled = true) + @Description("The model has multiple relations with relation annotations and renamed foreign keys") + public void testGenerateEntitiesWithMultipleRenamedRelationsOnSame() { + executeGenerateCommand("tool_test_generate_94", "mysql", "entities"); + assertGeneratedSources("tool_test_generate_94"); + } + } diff --git a/persist-cli-tests/src/test/java/io/ballerina/persist/tools/utils/DatabaseTestUtils.java b/persist-cli-tests/src/test/java/io/ballerina/persist/tools/utils/DatabaseTestUtils.java index 0f5c144c6..d71406b0f 100644 --- a/persist-cli-tests/src/test/java/io/ballerina/persist/tools/utils/DatabaseTestUtils.java +++ b/persist-cli-tests/src/test/java/io/ballerina/persist/tools/utils/DatabaseTestUtils.java @@ -20,11 +20,15 @@ import io.ballerina.persist.BalException; import io.ballerina.persist.PersistToolsConstants; +import io.ballerina.persist.configuration.DatabaseConfiguration; import io.ballerina.persist.configuration.PersistConfiguration; import io.ballerina.persist.nodegenerator.syntax.utils.TomlSyntaxUtils; import org.testng.Assert; +import java.io.IOException; import java.io.PrintStream; +import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; import java.sql.Connection; import java.sql.DatabaseMetaData; @@ -32,10 +36,12 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.sql.Statement; import java.util.ArrayList; import java.util.Locale; import static io.ballerina.persist.tools.utils.GeneratedSourcesTestUtils.GENERATED_SOURCES_DIRECTORY; +import static io.ballerina.persist.tools.utils.GeneratedSourcesTestUtils.INPUT_RESOURCES_DIRECTORY; import static io.ballerina.projects.util.ProjectConstants.BALLERINA_TOML; /** @@ -194,4 +200,37 @@ private static void validateTable(Connection connection, PersistTable persistTab columns.getString(nullable)); } } + + public static void createFromDatabaseScript(String packageName, String datasource, + DatabaseConfiguration dbConfig) { + Path sourcePath = Paths.get(INPUT_RESOURCES_DIRECTORY, packageName); + + String url; + if (datasource.equals(PersistToolsConstants.SupportedDataSources.MSSQL_DB)) { + url = String.format("jdbc:sqlserver://%s:%s", dbConfig.getHost(), dbConfig.getPort()); + } else if (datasource.equals(PersistToolsConstants.SupportedDataSources.POSTGRESQL_DB)) { + url = String.format("jdbc:postgresql://%s:%s/", dbConfig.getHost(), dbConfig.getPort()); + } else { + url = String.format("jdbc:mysql://%s:%s", dbConfig.getHost(), dbConfig.getPort()); + } + + try (Connection connection = DriverManager.getConnection(url, dbConfig.getUsername(), dbConfig.getPassword())) { + Path scriptFilePath = sourcePath.resolve("script.sql"); + //15 lines skipped to avoid license headers + String scriptContent = Files.lines(scriptFilePath).skip(15).reduce("", String::concat); + try (Statement statement = connection.createStatement()) { + String sql = scriptContent.replace("\r\n", "\n"); + String[] statements = sql.split(";"); + for (String statementStr : statements) { + statement.addBatch(statementStr); + } + statement.executeBatch(); + } + } catch (SQLException e) { + errStream.println("Failed to create database connection: " + e.getMessage()); + } catch (IOException e) { + throw new RuntimeException(e); + } + + } } diff --git a/persist-cli-tests/src/test/java/io/ballerina/persist/tools/utils/GeneratedSourcesTestUtils.java b/persist-cli-tests/src/test/java/io/ballerina/persist/tools/utils/GeneratedSourcesTestUtils.java index e374854a3..b7e3d3f69 100644 --- a/persist-cli-tests/src/test/java/io/ballerina/persist/tools/utils/GeneratedSourcesTestUtils.java +++ b/persist-cli-tests/src/test/java/io/ballerina/persist/tools/utils/GeneratedSourcesTestUtils.java @@ -23,6 +23,7 @@ import io.ballerina.persist.cmd.Init; import io.ballerina.persist.cmd.Migrate; import io.ballerina.persist.cmd.PersistCmd; +import io.ballerina.persist.cmd.Pull; import io.ballerina.persist.cmd.Push; import io.ballerina.projects.Package; import io.ballerina.projects.PackageCompilation; @@ -45,6 +46,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; + /** * persist tool test Utils. */ @@ -58,12 +60,18 @@ public enum Command { ADD, GENERATE, DB_PUSH, - MIGRATE + MIGRATE, + PULL } private static final PrintStream errStream = System.err; - public static final String GENERATED_SOURCES_DIRECTORY = Paths.get("build", "generated-sources").toString(); - public static final Path RESOURCES_EXPECTED_OUTPUT = Paths.get("src", "test", "resources", "test-src", "output") + public static final String GENERATED_SOURCES_DIRECTORY = Paths.get("build", "generated-sources") + .toString(); + + public static final String INPUT_RESOURCES_DIRECTORY = + Paths.get("src", "test", "resources", "test-src", "input").toString(); + public static final Path RESOURCES_EXPECTED_OUTPUT = + Paths.get("src", "test", "resources", "test-src", "output") .toAbsolutePath(); public static void assertGeneratedSources(String subDir) { @@ -146,7 +154,8 @@ public static void assertAuxiliaryFunctions() { persistCmd.printUsage(cmdLongDesc); String cmdLongDescription = cmdLongDesc.toString(); Assert.assertEquals(initLongDescription.trim().replaceAll(System.lineSeparator(), ""), - "Generate database configurations file inside the Ballerina project ballerina persist init"); + "Generate database configurations file inside the Ballerina project ballerina persist " + + "init"); Assert.assertEquals(cmdLongDescription.trim().replaceAll(System.lineSeparator(), ""), "Perform operations on Ballerina Persistent Layer ballerina persist"); persistCmdInit.execute(); @@ -180,6 +189,11 @@ public static HashMap executeCommand(String subDir, Command cmd) { Push persistCmd = (Push) persistClass.getDeclaredConstructor(String.class) .newInstance(sourcePath.toAbsolutePath().toString()); persistCmd.execute(); + } else if (cmd == Command.PULL) { + persistClass = Class.forName("io.ballerina.persist.cmd.Pull"); + Pull persistCmd = (Pull) persistClass.getDeclaredConstructor(String.class) + .newInstance(sourcePath.toAbsolutePath().toString()); + persistCmd.execute(); } else { persistClass = Class.forName("io.ballerina.persist.cmd.Migrate"); Migrate persistCmd = (Migrate) persistClass.getDeclaredConstructor(String.class) @@ -267,4 +281,5 @@ private static String readContent(Path filePath) { } return content.replaceAll(System.lineSeparator(), ""); } + } diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_72/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_72/Ballerina.toml new file mode 100644 index 000000000..e5a20725c --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_72/Ballerina.toml @@ -0,0 +1,8 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_72" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_72/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_72/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_72/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_72/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_72/persist/model.bal new file mode 100644 index 000000000..dd5db5ebf --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_72/persist/model.bal @@ -0,0 +1,42 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User owner; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_73/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_73/Ballerina.toml new file mode 100644 index 000000000..5fede2542 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_73/Ballerina.toml @@ -0,0 +1,8 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_73" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_73/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_73/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_73/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_73/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_73/persist/model.bal new file mode 100644 index 000000000..603e60956 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_73/persist/model.bal @@ -0,0 +1,44 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; + Car[] cars; +|}; + +@sql:Mapping {name: "cars"} +public type Car record {| + readonly int id; + string name; + @sql:Mapping {name: "MODEL"} + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User owner; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_74/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_74/Ballerina.toml new file mode 100644 index 000000000..2bcf6468f --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_74/Ballerina.toml @@ -0,0 +1,8 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_74" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_74/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_74/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_74/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_74/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_74/persist/model.bal new file mode 100644 index 000000000..b1132ba9a --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_74/persist/model.bal @@ -0,0 +1,45 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; + Car[] cars; +|}; + +@sql:Mapping {name: "cars"} +public type Car record {| + readonly int id; + string name; + @sql:Mapping {name: "MODEL"} + string model; + @sql:Mapping {name: "OWNER_ID"} + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_75/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_75/Ballerina.toml new file mode 100644 index 000000000..069f29f40 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_75/Ballerina.toml @@ -0,0 +1,8 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_75" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_75/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_75/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_75/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_75/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_75/persist/model.bal new file mode 100644 index 000000000..c46361007 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_75/persist/model.bal @@ -0,0 +1,45 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + @sql:VarChar {length: 12} + string nic; + @sql:Decimal {precision: [10, 2]} + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + @sql:Char {length: 10} + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_76/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_76/Ballerina.toml new file mode 100644 index 000000000..169bc75b6 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_76/Ballerina.toml @@ -0,0 +1,8 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_76" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_76/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_76/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_76/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_76/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_76/persist/model.bal new file mode 100644 index 000000000..3bc86840f --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_76/persist/model.bal @@ -0,0 +1,43 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + @sql:UniqueIndex {names: ["nic_index"]} + string nic; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_77/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_77/Ballerina.toml new file mode 100644 index 000000000..60f535f1a --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_77/Ballerina.toml @@ -0,0 +1,8 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_77" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_77/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_77/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_77/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_77/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_77/persist/model.bal new file mode 100644 index 000000000..1f81476d4 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_77/persist/model.bal @@ -0,0 +1,44 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + @sql:UniqueIndex {names: ["user_index"]} + readonly int id; + string name; + UserGender gender; + @sql:UniqueIndex {names: ["user_index"]} + string nic; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_78/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_78/Ballerina.toml new file mode 100644 index 000000000..f35b1cf3b --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_78/Ballerina.toml @@ -0,0 +1,8 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_78" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_78/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_78/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_78/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_78/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_78/persist/model.bal new file mode 100644 index 000000000..fd547e035 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_78/persist/model.bal @@ -0,0 +1,44 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + @sql:Index {names: ["user_index"]} + readonly int id; + string name; + UserGender gender; + @sql:Index {names: ["user_index"]} + string nic; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_79/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_79/Ballerina.toml new file mode 100644 index 000000000..f97643f83 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_79/Ballerina.toml @@ -0,0 +1,8 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_79" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_79/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_79/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_79/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_79/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_79/persist/model.bal new file mode 100644 index 000000000..90b8803a3 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_79/persist/model.bal @@ -0,0 +1,44 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +@sql:Mapping {name: "USERS"} +public type User record {| + @sql:Mapping {name: "ID"} + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_80/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_80/Ballerina.toml new file mode 100644 index 000000000..7c1ead284 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_80/Ballerina.toml @@ -0,0 +1,8 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_80" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_80/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_80/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_80/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_80/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_80/persist/model.bal new file mode 100644 index 000000000..06fa197db --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_80/persist/model.bal @@ -0,0 +1,45 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +@sql:Mapping {name: "USERS"} +public type User record {| + @sql:Mapping {name: "ID"} + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Mapping {name: "OWNER_ID"} + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_81/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_81/Ballerina.toml new file mode 100644 index 000000000..b13e306e5 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_81/Ballerina.toml @@ -0,0 +1,8 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_81" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_81/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_81/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_81/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_81/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_81/persist/model.bal new file mode 100644 index 000000000..30c27be35 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_81/persist/model.bal @@ -0,0 +1,44 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + readonly string nic; + string name; + UserGender gender; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Index {names: ["ownerNic"]} + string ownerNic; + @sql:Relation {refs: ["ownerId", "ownerNic"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_82/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_82/Ballerina.toml new file mode 100644 index 000000000..e5f86a883 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_82/Ballerina.toml @@ -0,0 +1,8 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_82" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_82/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_82/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_82/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_82/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_82/persist/model.bal new file mode 100644 index 000000000..d1e7eaa4c --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_82/persist/model.bal @@ -0,0 +1,45 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + readonly string nic; + string name; + UserGender gender; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Mapping {name: "OWNER_NIC"} + @sql:Index {names: ["ownerNic"]} + string ownerNic; + @sql:Relation {refs: ["ownerId", "ownerNic"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_83/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_83/Ballerina.toml new file mode 100644 index 000000000..0b4ec719c --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_83/Ballerina.toml @@ -0,0 +1,8 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_83" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_83/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_83/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_83/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_83/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_83/persist/model.bal new file mode 100644 index 000000000..041af492b --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_83/persist/model.bal @@ -0,0 +1,46 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + readonly string nic; + string name; + UserGender gender; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Mapping {name: "OWNER_ID"} + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Mapping {name: "OWNER_NIC"} + @sql:Index {names: ["ownerNic"]} + string ownerNic; + @sql:Relation {refs: ["ownerId", "ownerNic"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_84/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_84/Ballerina.toml new file mode 100644 index 000000000..7148b8d99 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_84/Ballerina.toml @@ -0,0 +1,8 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_84" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_84/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_84/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_84/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_84/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_84/persist/model.bal new file mode 100644 index 000000000..ae34a6372 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_84/persist/model.bal @@ -0,0 +1,47 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + @sql:Mapping {name: "NIC"} + readonly string nic; + string name; + UserGender gender; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Mapping {name: "OWNER_ID"} + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Mapping {name: "OWNER_NIC"} + @sql:Index {names: ["ownerNic"]} + string ownerNic; + @sql:Relation {refs: ["ownerId", "ownerNic"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_85/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_85/Ballerina.toml new file mode 100644 index 000000000..0b66b57b3 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_85/Ballerina.toml @@ -0,0 +1,8 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_85" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_85/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_85/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_85/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_85/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_85/persist/model.bal new file mode 100644 index 000000000..ab69a9da5 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_85/persist/model.bal @@ -0,0 +1,48 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + @sql:Mapping {name: "ID"} + readonly int id; + @sql:Mapping {name: "NIC"} + readonly string nic; + string name; + UserGender gender; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Mapping {name: "OWNER_ID"} + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Mapping {name: "OWNER_NIC"} + @sql:Index {names: ["ownerNic"]} + string ownerNic; + @sql:Relation {refs: ["ownerId", "ownerNic"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_86/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_86/Ballerina.toml new file mode 100644 index 000000000..088ffe452 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_86/Ballerina.toml @@ -0,0 +1,8 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_86" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_86/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_86/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_86/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_86/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_86/persist/model.bal new file mode 100644 index 000000000..b095c3e11 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_86/persist/model.bal @@ -0,0 +1,43 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + @sql:Index + string nic; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_87/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_87/Ballerina.toml new file mode 100644 index 000000000..9bcd042c2 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_87/Ballerina.toml @@ -0,0 +1,8 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_87" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_87/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_87/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_87/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_87/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_87/persist/model.bal new file mode 100644 index 000000000..734abd0c7 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_87/persist/model.bal @@ -0,0 +1,43 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + @sql:UniqueIndex + string nic; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_88/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_88/Ballerina.toml new file mode 100644 index 000000000..08fcbd96b --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_88/Ballerina.toml @@ -0,0 +1,8 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_88" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_88/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_88/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_88/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_88/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_88/persist/model.bal new file mode 100644 index 000000000..5b5bdfbf0 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_88/persist/model.bal @@ -0,0 +1,44 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + @sql:Index + @sql:UniqueIndex + string nic; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_89/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_89/Ballerina.toml new file mode 100644 index 000000000..c57673414 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_89/Ballerina.toml @@ -0,0 +1,8 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_89" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_89/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_89/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_89/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_89/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_89/persist/model.bal new file mode 100644 index 000000000..961e07b23 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_89/persist/model.bal @@ -0,0 +1,45 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + @sql:UniqueIndex {names: ["unique_user"]} + readonly int id; + string name; + UserGender gender; + @sql:Index + @sql:UniqueIndex {names: ["unique_nic", "unique_user"]} + string nic; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_90/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_90/Ballerina.toml new file mode 100644 index 000000000..ff4bbf9b2 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_90/Ballerina.toml @@ -0,0 +1,8 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_90" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_90/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_90/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_90/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_90/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_90/persist/model.bal new file mode 100644 index 000000000..9a7e5aace --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_90/persist/model.bal @@ -0,0 +1,33 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + @sql:Generated + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_91/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_91/Ballerina.toml new file mode 100644 index 000000000..461384317 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_91/Ballerina.toml @@ -0,0 +1,8 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_91" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_91/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_91/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_91/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_91/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_91/persist/model.bal new file mode 100644 index 000000000..93dc60276 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_91/persist/model.bal @@ -0,0 +1,43 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + @sql:Generated + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_92/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_92/Ballerina.toml new file mode 100644 index 000000000..a2b29d323 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_92/Ballerina.toml @@ -0,0 +1,8 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_92" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_92/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_92/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_92/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_92/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_92/persist/model.bal new file mode 100644 index 000000000..b50ec64c9 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_92/persist/model.bal @@ -0,0 +1,44 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + @sql:Mapping {name: "ID"} + @sql:Generated + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_93/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_93/Ballerina.toml new file mode 100644 index 000000000..b6ea7858a --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_93/Ballerina.toml @@ -0,0 +1,8 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_93" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_93/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_93/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_93/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_93/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_93/persist/model.bal new file mode 100644 index 000000000..34068b66c --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_93/persist/model.bal @@ -0,0 +1,44 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; + Car[] cars; + Car? drives; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User owner; + User driver; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_94/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_94/Ballerina.toml new file mode 100644 index 000000000..3498ad5ee --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_94/Ballerina.toml @@ -0,0 +1,8 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_94" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_94/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_94/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_94/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_94/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_94/persist/model.bal new file mode 100644 index 000000000..95cc426d9 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_generate_94/persist/model.bal @@ -0,0 +1,47 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; + Car[] cars; + Car? drives; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User owner; + @sql:Mapping {name: "DRIVER_ID"} + int driverId; + @sql:Relation {refs: ["driverId"]} + User driver; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_10_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_10_mysql/Ballerina.toml new file mode 100644 index 000000000..a7e235168 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_10_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_10_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_10_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_10_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_10_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_10_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_10_mysql/script.sql new file mode 100644 index 000000000..30d186f44 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_10_mysql/script.sql @@ -0,0 +1,44 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE patients ( + id INT, + name VARCHAR(191) NOT NULL, + GENDER ENUM ('MALE', 'FEMALE') NOT NULL, + NIC VARCHAR(191) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE DOCTOR ( + id INT, + name VARCHAR(191) NOT NULL, + doctor_Specialty VARCHAR(191) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE appointment ( + id INT, + patient_Id INT NOT NULL, + Doctor_Id INT NOT NULL, + date DATE NOT NULL, + PRIMARY KEY (id), + FOREIGN KEY (patient_Id) REFERENCES patients(id), + FOREIGN KEY (Doctor_Id) REFERENCES DOCTOR(id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_11_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_11_mysql/Ballerina.toml new file mode 100644 index 000000000..8c19993e8 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_11_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_11_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_11_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_11_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_11_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_11_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_11_mysql/script.sql new file mode 100644 index 000000000..74bd7d355 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_11_mysql/script.sql @@ -0,0 +1,46 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE Patient ( + id INT, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + nic VARCHAR(12) NOT NULL, + contact CHAR(10) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE Doctor ( + id INT, + name VARCHAR(20) NOT NULL, + specialty VARCHAR(191) NOT NULL, + salary DECIMAL(10,2), + PRIMARY KEY (id) +); + +CREATE TABLE Appointment ( + id INT, + patientId INT NOT NULL, + doctorId INT NOT NULL, + date DATE NOT NULL, + PRIMARY KEY (id), + FOREIGN KEY (patientId) REFERENCES Patient(id), + FOREIGN KEY (doctorId) REFERENCES Doctor(id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_12_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_12_mysql/Ballerina.toml new file mode 100644 index 000000000..74b0043a0 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_12_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_12_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_12_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_12_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_12_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_12_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_12_mysql/script.sql new file mode 100644 index 000000000..e15c8bcb2 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_12_mysql/script.sql @@ -0,0 +1,31 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE User ( + id INT, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + nic VARCHAR(191) NOT NULL, + salary DECIMAL(65,30) NOT NULL, + favColor VARCHAR(191) NOT NULL, + favCar VARCHAR(191) NOT NULL, + UNIQUE INDEX favorite (favColor, favCar), + PRIMARY KEY (id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_13_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_13_mysql/Ballerina.toml new file mode 100644 index 000000000..881ecb37d --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_13_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_13_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_13_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_13_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_13_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_13_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_13_mysql/script.sql new file mode 100644 index 000000000..349076708 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_13_mysql/script.sql @@ -0,0 +1,31 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE User ( + id INT, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + nic VARCHAR(191) NOT NULL, + salary DECIMAL(65,30) NOT NULL, + favColor VARCHAR(191) NOT NULL, + favCar VARCHAR(191) NOT NULL, + INDEX favorite (favColor, favCar), + PRIMARY KEY (id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_14_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_14_mysql/Ballerina.toml new file mode 100644 index 000000000..341989b54 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_14_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_14_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_14_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_14_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_14_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_14_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_14_mysql/script.sql new file mode 100644 index 000000000..85d01c601 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_14_mysql/script.sql @@ -0,0 +1,46 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE Patient ( + id INT, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + nic VARCHAR(191) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE Doctor ( + id INT, + name VARCHAR(191) NOT NULL, + specialty VARCHAR(191) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE Appointment ( + id INT, + patientId INT NOT NULL, + doctorId INT NOT NULL, + assistantId INT NOT NULL, + date DATE NOT NULL, + PRIMARY KEY (id), + FOREIGN KEY (patientId) REFERENCES Patient(id), + FOREIGN KEY (doctorId) REFERENCES Doctor(id), + FOREIGN KEY (assistantId) REFERENCES Doctor(id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_15_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_15_mysql/Ballerina.toml new file mode 100644 index 000000000..630907850 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_15_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_15_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_15_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_15_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_15_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_15_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_15_mysql/script.sql new file mode 100644 index 000000000..4ef2431b4 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_15_mysql/script.sql @@ -0,0 +1,30 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE User ( + id INT, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + nic VARCHAR(191) NOT NULL, + salary DECIMAL(65,30) NOT NULL, + PRIMARY KEY (id), + UNIQUE INDEX user (id,nic), + UNIQUE INDEX user_nic (nic) +); diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_16_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_16_mysql/Ballerina.toml new file mode 100644 index 000000000..7ee00aaba --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_16_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_16_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_16_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_16_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_16_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_16_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_16_mysql/script.sql new file mode 100644 index 000000000..9e29a8002 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_16_mysql/script.sql @@ -0,0 +1,30 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE User ( + id INT, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + nic VARCHAR(191) NOT NULL, + salary DECIMAL(65,30) NOT NULL, + PRIMARY KEY (id), + INDEX user (id,nic), + INDEX user_nic (nic) +); diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_17_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_17_mysql/Ballerina.toml new file mode 100644 index 000000000..9a1bdf7da --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_17_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_17_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_17_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_17_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_17_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_17_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_17_mysql/script.sql new file mode 100644 index 000000000..4ac925f1c --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_17_mysql/script.sql @@ -0,0 +1,38 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE User ( + email VARCHAR(191) NOT NULL, + nic VARCHAR(191) NOT NULL, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + salary DECIMAL(65,30), + PRIMARY KEY (email, nic) +); + +CREATE TABLE Car ( + id INT, + name VARCHAR(191) NOT NULL, + model VARCHAR(191) NOT NULL, + ownerEmail VARCHAR(191) NOT NULL, + ownerNic VARCHAR(191) NOT NULL, + FOREIGN KEY (ownerEmail, ownerNic) REFERENCES User(email,nic), + PRIMARY KEY (id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_18_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_18_mysql/Ballerina.toml new file mode 100644 index 000000000..24778a7c8 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_18_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_18_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_18_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_18_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_18_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_18_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_18_mysql/script.sql new file mode 100644 index 000000000..e58493a4a --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_18_mysql/script.sql @@ -0,0 +1,30 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE Employee ( + id INT, + name VARCHAR(191), + email VARCHAR(191), + age INT, + salary DECIMAL(10,2), + managed_by INT, + PRIMARY KEY (id), + FOREIGN KEY (managed_by) REFERENCES Employee(id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_19_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_19_mysql/Ballerina.toml new file mode 100644 index 000000000..6ad912f38 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_19_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_19_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_19_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_19_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_19_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_19_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_19_mysql/script.sql new file mode 100644 index 000000000..5f91d75db --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_19_mysql/script.sql @@ -0,0 +1,39 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE User ( + id INT, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + salary DECIMAL(65,30), + drives_car INT, + PRIMARY KEY (id) +); + +CREATE TABLE Car ( + id INT, + name VARCHAR(191) NOT NULL, + model VARCHAR(191) NOT NULL, + ownerId INT NOT NULL, + FOREIGN KEY (ownerId) REFERENCES User(id), + PRIMARY KEY (id) +); + +ALTER TABLE User ADD FOREIGN KEY (drives_car) REFERENCES Car(id); diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_1_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_1_mysql/Ballerina.toml new file mode 100644 index 000000000..f7af7cef6 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_1_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_1_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_1_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_1_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_1_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_1_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_1_mysql/script.sql new file mode 100644 index 000000000..eba3731d0 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_1_mysql/script.sql @@ -0,0 +1,28 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE User ( + id INT, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + nic VARCHAR(191) NOT NULL, + salary DECIMAL(65,30) NOT NULL, + PRIMARY KEY (id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_20_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_20_mysql/Ballerina.toml new file mode 100644 index 000000000..4c719365b --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_20_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_20_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_20_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_20_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_20_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_20_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_20_mysql/script.sql new file mode 100644 index 000000000..edb641b1c --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_20_mysql/script.sql @@ -0,0 +1,29 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + + +CREATE TABLE Car ( + id INT, + name VARCHAR(191) NOT NULL, + type VARCHAR (191) NOT NULL, + model VARCHAR(191) NOT NULL, + ownerId INT NOT NULL, + PRIMARY KEY (id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_21_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_21_mysql/Ballerina.toml new file mode 100644 index 000000000..92f6282b8 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_21_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_21_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_21_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_21_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_21_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_21_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_21_mysql/script.sql new file mode 100644 index 000000000..5bfd6bda7 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_21_mysql/script.sql @@ -0,0 +1,19 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_22_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_22_mysql/Ballerina.toml new file mode 100644 index 000000000..53979a76c --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_22_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_22_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_22_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_22_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_22_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_22_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_22_mysql/script.sql new file mode 100644 index 000000000..8fe133e93 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_22_mysql/script.sql @@ -0,0 +1,17 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_23/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_23/Ballerina.toml new file mode 100644 index 000000000..27329268a --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_23/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_23_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_23/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_23/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_23/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_24_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_24_mysql/Ballerina.toml new file mode 100644 index 000000000..cbd9822c9 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_24_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_24_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_24_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_24_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_24_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_24_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_24_mysql/script.sql new file mode 100644 index 000000000..778238087 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_24_mysql/script.sql @@ -0,0 +1,28 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE User ( + id INT AUTO_INCREMENT, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + nic VARCHAR(191) NOT NULL, + salary DECIMAL(65,30) NOT NULL, + PRIMARY KEY (id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_25_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_25_mysql/Ballerina.toml new file mode 100644 index 000000000..2882e8c3b --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_25_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_25_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_25_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_25_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_25_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_25_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_25_mysql/script.sql new file mode 100644 index 000000000..d0a345d95 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_25_mysql/script.sql @@ -0,0 +1,29 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE User ( + id INT, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + nic VARCHAR(191) NOT NULL, + salary DECIMAL(65,30) NOT NULL, + userProfilePic BLOB, + PRIMARY KEY (id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_2_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_2_mysql/Ballerina.toml new file mode 100644 index 000000000..1c0c9ddd6 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_2_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_2_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_2_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_2_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_2_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_2_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_2_mysql/script.sql new file mode 100644 index 000000000..b2dfcf02c --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_2_mysql/script.sql @@ -0,0 +1,28 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE User ( + id INT, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + nic VARCHAR(191) NOT NULL, + salary DECIMAL(65,30), + PRIMARY KEY (id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_3_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_3_mysql/Ballerina.toml new file mode 100644 index 000000000..7cec8b7e5 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_3_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_3_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_3_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_3_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_3_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_3_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_3_mysql/script.sql new file mode 100644 index 000000000..e47632bab --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_3_mysql/script.sql @@ -0,0 +1,37 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE User ( + id INT, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + nic VARCHAR(191) NOT NULL, + salary DECIMAL(65,30), + PRIMARY KEY (id) +); + +CREATE TABLE Car ( + id INT, + name VARCHAR(191) NOT NULL, + model VARCHAR(191) NOT NULL, + ownerId INT NOT NULL, + FOREIGN KEY (ownerId) REFERENCES User(id), + PRIMARY KEY (id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_4_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_4_mysql/Ballerina.toml new file mode 100644 index 000000000..6043641b0 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_4_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_4_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_4_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_4_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_4_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_4_mysql/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_4_mysql/persist/model.bal new file mode 100644 index 000000000..d02cb63ea --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_4_mysql/persist/model.bal @@ -0,0 +1 @@ +import ballerina/persist as _; diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_4_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_4_mysql/script.sql new file mode 100644 index 000000000..e47632bab --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_4_mysql/script.sql @@ -0,0 +1,37 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE User ( + id INT, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + nic VARCHAR(191) NOT NULL, + salary DECIMAL(65,30), + PRIMARY KEY (id) +); + +CREATE TABLE Car ( + id INT, + name VARCHAR(191) NOT NULL, + model VARCHAR(191) NOT NULL, + ownerId INT NOT NULL, + FOREIGN KEY (ownerId) REFERENCES User(id), + PRIMARY KEY (id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_5_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_5_mysql/Ballerina.toml new file mode 100644 index 000000000..23ac92d4b --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_5_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_5_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_5_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_5_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_5_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_5_mysql/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_5_mysql/persist/model.bal new file mode 100644 index 000000000..d02cb63ea --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_5_mysql/persist/model.bal @@ -0,0 +1 @@ +import ballerina/persist as _; diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_5_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_5_mysql/script.sql new file mode 100644 index 000000000..e47632bab --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_5_mysql/script.sql @@ -0,0 +1,37 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE User ( + id INT, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + nic VARCHAR(191) NOT NULL, + salary DECIMAL(65,30), + PRIMARY KEY (id) +); + +CREATE TABLE Car ( + id INT, + name VARCHAR(191) NOT NULL, + model VARCHAR(191) NOT NULL, + ownerId INT NOT NULL, + FOREIGN KEY (ownerId) REFERENCES User(id), + PRIMARY KEY (id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_6_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_6_mysql/Ballerina.toml new file mode 100644 index 000000000..2de97d10e --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_6_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_6_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_6_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_6_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_6_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_6_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_6_mysql/script.sql new file mode 100644 index 000000000..24328ec18 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_6_mysql/script.sql @@ -0,0 +1,37 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE User ( + id INT, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + nic VARCHAR(191) NOT NULL, + salary DECIMAL(65,30), + PRIMARY KEY (id) +); + +CREATE TABLE Car ( + id INT, + name VARCHAR(191) NOT NULL, + model VARCHAR(191) NOT NULL, + ownerId INT UNIQUE NOT NULL, + FOREIGN KEY (ownerId) REFERENCES User(id), + PRIMARY KEY (id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_7_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_7_mysql/Ballerina.toml new file mode 100644 index 000000000..6430c335a --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_7_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_7_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_7_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_7_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_7_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_7_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_7_mysql/script.sql new file mode 100644 index 000000000..a4ca49238 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_7_mysql/script.sql @@ -0,0 +1,35 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE User ( + id INT, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + nic VARCHAR(191) NOT NULL, + salary DECIMAL(65,30), + PRIMARY KEY (id) +); + +CREATE TABLE Phone ( + user_id INT, + number VARCHAR(191) NOT NULL, + PRIMARY KEY (user_id), + FOREIGN KEY (user_id) REFERENCES User(id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_8_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_8_mysql/Ballerina.toml new file mode 100644 index 000000000..2e9b80f0e --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_8_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_8_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_8_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_8_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_8_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_8_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_8_mysql/script.sql new file mode 100644 index 000000000..4f74c6fe4 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_8_mysql/script.sql @@ -0,0 +1,35 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE User ( + id INT, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + nic VARCHAR(191) NOT NULL, + salary DECIMAL(65,30), + PRIMARY KEY (id) +); + +CREATE TABLE Phone ( + user_id INT, + number VARCHAR(191) NOT NULL, + PRIMARY KEY (user_id, number), + FOREIGN KEY (user_id) REFERENCES User(id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_9_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_9_mysql/Ballerina.toml new file mode 100644 index 000000000..502f55df5 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_9_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_9_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_9_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_9_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_9_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_9_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_9_mysql/script.sql new file mode 100644 index 000000000..1ef720a31 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/input/tool_test_pull_9_mysql/script.sql @@ -0,0 +1,44 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE Patient ( + id INT, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + nic VARCHAR(191) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE Doctor ( + id INT, + name VARCHAR(191) NOT NULL, + specialty VARCHAR(191) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE Appointment ( + id INT, + patientId INT NOT NULL, + doctorId INT NOT NULL, + date DATE NOT NULL, + PRIMARY KEY (id), + FOREIGN KEY (patientId) REFERENCES Patient(id), + FOREIGN KEY (doctorId) REFERENCES Doctor(id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_add_1/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_add_1/Ballerina.toml index bcf02d120..1c95bf38b 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_add_1/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_add_1/Ballerina.toml @@ -23,5 +23,5 @@ filePath = "persist/model.bal" [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_add_13/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_add_13/Ballerina.toml index 5dd8e8347..d5cfd93f7 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_add_13/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_add_13/Ballerina.toml @@ -16,5 +16,5 @@ filePath = "persist/model.bal" [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_add_14/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_add_14/Ballerina.toml index 222a211c3..545ff6752 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_add_14/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_add_14/Ballerina.toml @@ -16,5 +16,5 @@ filePath = "persist/model.bal" [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_add_3/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_add_3/Ballerina.toml index 78925aca6..6a51c6771 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_add_3/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_add_3/Ballerina.toml @@ -23,5 +23,5 @@ filePath = "persist/model.bal" [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_add_5/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_add_5/Ballerina.toml index e20d3bdcf..396b31b4c 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_add_5/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_add_5/Ballerina.toml @@ -23,5 +23,5 @@ filePath = "persist/model.bal" [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_add_7/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_add_7/Ballerina.toml index adb2ed3c3..bd14de3a9 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_add_7/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_add_7/Ballerina.toml @@ -16,5 +16,5 @@ filePath = "persist/model.bal" [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_add_9/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_add_9/Ballerina.toml index 5b7be2e31..c446d848b 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_add_9/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_add_9/Ballerina.toml @@ -23,5 +23,5 @@ filePath = "persist/model.bal" [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_1/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_1/Ballerina.toml index 30e847435..f4bb96dd3 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_1/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_1/Ballerina.toml @@ -10,5 +10,5 @@ observabilityIncluded = false [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_1/modules/persist_client.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_1/modules/persist_client.bal index d506b6520..98fa1fc5b 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_1/modules/persist_client.bal +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_1/modules/persist_client.bal @@ -37,12 +37,12 @@ public isolated client class Client { "workspace.workspaceId": {relation: {entityName: "workspace", refField: "workspaceId"}}, "workspace.workspaceType": {relation: {entityName: "workspace", refField: "workspaceType"}}, "workspace.locationBuildingCode": {relation: {entityName: "workspace", refField: "locationBuildingCode"}}, - "workspace.workspaceEmpNo": {relation: {entityName: "workspace", refField: "workspaceEmpNo"}} + "workspace.employeeEmpNo": {relation: {entityName: "workspace", refField: "employeeEmpNo"}} }, keyFields: ["empNo"], joinMetadata: { department: {entity: Department, fieldName: "department", refTable: "Department", refColumns: ["deptNo"], joinColumns: ["departmentDeptNo"], 'type: psql:ONE_TO_MANY}, - workspace: {entity: Workspace, fieldName: "workspace", refTable: "Workspace", refColumns: ["workspaceEmpNo"], joinColumns: ["empNo"], 'type: psql:ONE_TO_ONE} + workspace: {entity: Workspace, fieldName: "workspace", refTable: "Workspace", refColumns: ["employeeEmpNo"], joinColumns: ["empNo"], 'type: psql:ONE_TO_ONE} } }, [WORKSPACE]: { @@ -52,7 +52,7 @@ public isolated client class Client { workspaceId: {columnName: "workspaceId"}, workspaceType: {columnName: "workspaceType"}, locationBuildingCode: {columnName: "locationBuildingCode"}, - workspaceEmpNo: {columnName: "workspaceEmpNo"}, + employeeEmpNo: {columnName: "employeeEmpNo"}, "location.buildingCode": {relation: {entityName: "location", refField: "buildingCode"}}, "location.city": {relation: {entityName: "location", refField: "city"}}, "location.state": {relation: {entityName: "location", refField: "state"}}, @@ -69,7 +69,7 @@ public isolated client class Client { keyFields: ["workspaceId"], joinMetadata: { location: {entity: Building, fieldName: "location", refTable: "Building", refColumns: ["buildingCode"], joinColumns: ["locationBuildingCode"], 'type: psql:ONE_TO_MANY}, - employee: {entity: Employee, fieldName: "employee", refTable: "Employee", refColumns: ["empNo"], joinColumns: ["workspaceEmpNo"], 'type: psql:ONE_TO_ONE} + employee: {entity: Employee, fieldName: "employee", refTable: "Employee", refColumns: ["empNo"], joinColumns: ["employeeEmpNo"], 'type: psql:ONE_TO_ONE} } }, [BUILDING]: { @@ -84,7 +84,7 @@ public isolated client class Client { "workspaces[].workspaceId": {relation: {entityName: "workspaces", refField: "workspaceId"}}, "workspaces[].workspaceType": {relation: {entityName: "workspaces", refField: "workspaceType"}}, "workspaces[].locationBuildingCode": {relation: {entityName: "workspaces", refField: "locationBuildingCode"}}, - "workspaces[].workspaceEmpNo": {relation: {entityName: "workspaces", refField: "workspaceEmpNo"}} + "workspaces[].employeeEmpNo": {relation: {entityName: "workspaces", refField: "employeeEmpNo"}} }, keyFields: ["buildingCode"], joinMetadata: {workspaces: {entity: Workspace, fieldName: "workspaces", refTable: "Workspace", refColumns: ["locationBuildingCode"], joinColumns: ["buildingCode"], 'type: psql:MANY_TO_ONE}} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_1/modules/persist_types.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_1/modules/persist_types.bal index e01ae034a..ce718dc8e 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_1/modules/persist_types.bal +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_1/modules/persist_types.bal @@ -56,14 +56,14 @@ public type Workspace record {| readonly string workspaceId; string workspaceType; string locationBuildingCode; - string workspaceEmpNo; + string employeeEmpNo; |}; public type WorkspaceOptionalized record {| string workspaceId?; string workspaceType?; string locationBuildingCode?; - string workspaceEmpNo?; + string employeeEmpNo?; |}; public type WorkspaceWithRelations record {| @@ -79,7 +79,7 @@ public type WorkspaceInsert Workspace; public type WorkspaceUpdate record {| string workspaceType?; string locationBuildingCode?; - string workspaceEmpNo?; + string employeeEmpNo?; |}; public type Building record {| diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_1/modules/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_1/modules/script.sql index 77f7f940d..ba7ced356 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_1/modules/script.sql +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_1/modules/script.sql @@ -40,7 +40,7 @@ CREATE TABLE `Workspace` ( `workspaceType` VARCHAR(191) NOT NULL, `locationBuildingCode` VARCHAR(191) NOT NULL, FOREIGN KEY(`locationBuildingCode`) REFERENCES `Building`(`buildingCode`), - `workspaceEmpNo` VARCHAR(191) UNIQUE NOT NULL, - FOREIGN KEY(`workspaceEmpNo`) REFERENCES `Employee`(`empNo`), + `employeeEmpNo` VARCHAR(191) UNIQUE NOT NULL, + FOREIGN KEY(`employeeEmpNo`) REFERENCES `Employee`(`empNo`), PRIMARY KEY(`workspaceId`) ); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_11/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_11/Ballerina.toml index 2ef2b4ee8..a1d93cbbc 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_11/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_11/Ballerina.toml @@ -10,5 +10,5 @@ observabilityIncluded = true [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_12/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_12/Ballerina.toml index 0fc20dcb1..4d1362945 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_12/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_12/Ballerina.toml @@ -10,5 +10,5 @@ observabilityIncluded = true [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_13/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_13/Ballerina.toml index 30b3b2a60..b82614884 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_13/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_13/Ballerina.toml @@ -10,5 +10,5 @@ observabilityIncluded = false [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_16/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_16/Ballerina.toml index 8172ddf33..28f5ba5fb 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_16/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_16/Ballerina.toml @@ -10,5 +10,5 @@ observabilityIncluded = false [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_17/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_17/Ballerina.toml index 9f7173789..049b4f415 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_17/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_17/Ballerina.toml @@ -10,5 +10,5 @@ observabilityIncluded = false [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_19/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_19/Ballerina.toml index d1fc68bd4..adb556404 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_19/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_19/Ballerina.toml @@ -10,5 +10,5 @@ observabilityIncluded = false [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_2/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_2/Ballerina.toml index 8784cd577..de3f4c3e5 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_2/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_2/Ballerina.toml @@ -10,5 +10,5 @@ observabilityIncluded = false [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_22/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_22/Ballerina.toml index bf036e223..951406052 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_22/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_22/Ballerina.toml @@ -10,5 +10,5 @@ observabilityIncluded = false [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_24/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_24/Ballerina.toml index 44da7dfa8..e65987ea4 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_24/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_24/Ballerina.toml @@ -10,5 +10,5 @@ observabilityIncluded = false [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_25/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_25/Ballerina.toml index 646ed499b..c48382b8e 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_25/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_25/Ballerina.toml @@ -10,5 +10,5 @@ observabilityIncluded = false [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_26/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_26/Ballerina.toml index 4e0f7ffb2..2317bc76b 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_26/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_26/Ballerina.toml @@ -10,5 +10,5 @@ observabilityIncluded = false [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_27/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_27/Ballerina.toml index 39360d132..586d541e3 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_27/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_27/Ballerina.toml @@ -10,5 +10,5 @@ observabilityIncluded = false [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_28/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_28/Ballerina.toml index bcc5a4ff7..cf6311cf2 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_28/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_28/Ballerina.toml @@ -10,4 +10,4 @@ observabilityIncluded = false [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_29/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_29/Ballerina.toml index 96b1d7757..b738253d0 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_29/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_29/Ballerina.toml @@ -10,5 +10,5 @@ observabilityIncluded = false [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_3/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_3/Ballerina.toml index 72d20c777..f1454ebdb 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_3/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_3/Ballerina.toml @@ -10,5 +10,5 @@ observabilityIncluded = false [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_31/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_31/Ballerina.toml index 1604a44e7..9fb503c3e 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_31/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_31/Ballerina.toml @@ -7,5 +7,5 @@ distribution = "2201.3.0" [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_33/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_33/Ballerina.toml index 533f74b94..5b5c51ddb 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_33/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_33/Ballerina.toml @@ -7,5 +7,5 @@ distribution = "2201.3.0" [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_34/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_34/Ballerina.toml index 9445ff3c8..301f85b7a 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_34/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_34/Ballerina.toml @@ -10,5 +10,5 @@ observabilityIncluded = false [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_35/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_35/Ballerina.toml index 49675c385..ba2a209a7 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_35/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_35/Ballerina.toml @@ -10,5 +10,5 @@ observabilityIncluded = false [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_36/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_36/Ballerina.toml index 126a69c89..cafb4470e 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_36/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_36/Ballerina.toml @@ -10,5 +10,5 @@ observabilityIncluded = false [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_37/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_37/Ballerina.toml index e2e6379d4..d3d88fba3 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_37/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_37/Ballerina.toml @@ -10,5 +10,5 @@ observabilityIncluded = false [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_39/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_39/Ballerina.toml index 871fc0f21..2909bf52c 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_39/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_39/Ballerina.toml @@ -10,5 +10,5 @@ observabilityIncluded = false [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_40/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_40/Ballerina.toml index addb95eaa..e396d5bdc 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_40/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_40/Ballerina.toml @@ -10,5 +10,5 @@ observabilityIncluded = false [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_41/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_41/Ballerina.toml index 4b0159640..c218d988e 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_41/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_41/Ballerina.toml @@ -10,4 +10,4 @@ observabilityIncluded = false [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_46/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_46/Ballerina.toml index 3d350f143..40417c295 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_46/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_46/Ballerina.toml @@ -10,5 +10,5 @@ observabilityIncluded = false [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_5/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_5/Ballerina.toml index 1c5578aa3..a9ad4a30f 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_5/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_5/Ballerina.toml @@ -10,5 +10,5 @@ observabilityIncluded = false [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_50/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_50/Ballerina.toml index 2a7521436..b3903430d 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_50/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_50/Ballerina.toml @@ -10,5 +10,4 @@ observabilityIncluded = false [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" - +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_50/persist_client.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_50/persist_client.bal index b391425a9..f8d696011 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_50/persist_client.bal +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_50/persist_client.bal @@ -35,12 +35,12 @@ public isolated client class Client { "workspace.workspaceId": {relation: {entityName: "workspace", refField: "workspaceId"}}, "workspace.workspaceType": {relation: {entityName: "workspace", refField: "workspaceType"}}, "workspace.locationBuildingCode": {relation: {entityName: "workspace", refField: "locationBuildingCode"}}, - "workspace.workspaceEmpNo": {relation: {entityName: "workspace", refField: "workspaceEmpNo"}} + "workspace.employeeEmpNo": {relation: {entityName: "workspace", refField: "employeeEmpNo"}} }, keyFields: ["empNo"], joinMetadata: { department: {entity: Department, fieldName: "department", refTable: "Department", refColumns: ["deptNo"], joinColumns: ["departmentDeptNo"], 'type: psql:ONE_TO_MANY}, - workspace: {entity: Workspace, fieldName: "workspace", refTable: "Workspace", refColumns: ["workspaceEmpNo"], joinColumns: ["empNo"], 'type: psql:ONE_TO_ONE} + workspace: {entity: Workspace, fieldName: "workspace", refTable: "Workspace", refColumns: ["employeeEmpNo"], joinColumns: ["empNo"], 'type: psql:ONE_TO_ONE} } }, [WORKSPACE]: { @@ -50,7 +50,7 @@ public isolated client class Client { workspaceId: {columnName: "workspaceId"}, workspaceType: {columnName: "workspaceType"}, locationBuildingCode: {columnName: "locationBuildingCode"}, - workspaceEmpNo: {columnName: "workspaceEmpNo"}, + employeeEmpNo: {columnName: "employeeEmpNo"}, "location.buildingCode": {relation: {entityName: "location", refField: "buildingCode"}}, "location.city": {relation: {entityName: "location", refField: "city"}}, "location.state": {relation: {entityName: "location", refField: "state"}}, @@ -65,7 +65,7 @@ public isolated client class Client { keyFields: ["workspaceId"], joinMetadata: { location: {entity: Building, fieldName: "location", refTable: "Building", refColumns: ["buildingCode"], joinColumns: ["locationBuildingCode"], 'type: psql:ONE_TO_MANY}, - employee: {entity: Employee, fieldName: "employee", refTable: "Employee", refColumns: ["empNo"], joinColumns: ["workspaceEmpNo"], 'type: psql:ONE_TO_ONE} + employee: {entity: Employee, fieldName: "employee", refTable: "Employee", refColumns: ["empNo"], joinColumns: ["employeeEmpNo"], 'type: psql:ONE_TO_ONE} } }, [BUILDING]: { @@ -80,7 +80,7 @@ public isolated client class Client { "workspaces[].workspaceId": {relation: {entityName: "workspaces", refField: "workspaceId"}}, "workspaces[].workspaceType": {relation: {entityName: "workspaces", refField: "workspaceType"}}, "workspaces[].locationBuildingCode": {relation: {entityName: "workspaces", refField: "locationBuildingCode"}}, - "workspaces[].workspaceEmpNo": {relation: {entityName: "workspaces", refField: "workspaceEmpNo"}} + "workspaces[].employeeEmpNo": {relation: {entityName: "workspaces", refField: "employeeEmpNo"}} }, keyFields: ["buildingCode"], joinMetadata: {workspaces: {entity: Workspace, fieldName: "workspaces", refTable: "Workspace", refColumns: ["locationBuildingCode"], joinColumns: ["buildingCode"], 'type: psql:MANY_TO_ONE}} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_50/persist_types.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_50/persist_types.bal index 2df4d85d2..3a9d46064 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_50/persist_types.bal +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_50/persist_types.bal @@ -57,14 +57,14 @@ public type Workspace record {| readonly string workspaceId; WorkspaceType workspaceType; string locationBuildingCode; - string workspaceEmpNo; + string employeeEmpNo; |}; public type WorkspaceOptionalized record {| string workspaceId?; WorkspaceType workspaceType?; string locationBuildingCode?; - string workspaceEmpNo?; + string employeeEmpNo?; |}; public type WorkspaceWithRelations record {| @@ -80,7 +80,7 @@ public type WorkspaceInsert Workspace; public type WorkspaceUpdate record {| WorkspaceType workspaceType?; string locationBuildingCode?; - string workspaceEmpNo?; + string employeeEmpNo?; |}; public type Building record {| diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_50/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_50/script.sql index 5317cf128..b6995a349 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_50/script.sql +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_50/script.sql @@ -38,7 +38,7 @@ CREATE TABLE `Workspace` ( `workspaceType` ENUM('C', 'OFFICE', 'MR') NOT NULL, `locationBuildingCode` VARCHAR(191) NOT NULL, FOREIGN KEY(`locationBuildingCode`) REFERENCES `Building`(`buildingCode`), - `workspaceEmpNo` VARCHAR(191) UNIQUE NOT NULL, - FOREIGN KEY(`workspaceEmpNo`) REFERENCES `Employee`(`empNo`), + `employeeEmpNo` VARCHAR(191) UNIQUE NOT NULL, + FOREIGN KEY(`employeeEmpNo`) REFERENCES `Employee`(`empNo`), PRIMARY KEY(`workspaceId`) ); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_51/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_51/Ballerina.toml index 9540f31b3..9a88ee6c5 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_51/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_51/Ballerina.toml @@ -10,5 +10,5 @@ observabilityIncluded = false [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_51/persist_client.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_51/persist_client.bal index 0b3f1e214..6c38c05ac 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_51/persist_client.bal +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_51/persist_client.bal @@ -37,12 +37,12 @@ public isolated client class Client { "workspace.workspaceId": {relation: {entityName: "workspace", refField: "workspaceId"}}, "workspace.workspaceType": {relation: {entityName: "workspace", refField: "workspaceType"}}, "workspace.locationBuildingCode": {relation: {entityName: "workspace", refField: "locationBuildingCode"}}, - "workspace.workspaceEmpNo": {relation: {entityName: "workspace", refField: "workspaceEmpNo"}} + "workspace.employeeEmpNo": {relation: {entityName: "workspace", refField: "employeeEmpNo"}} }, keyFields: ["empNo"], joinMetadata: { department: {entity: Department, fieldName: "department", refTable: "Department", refColumns: ["deptNo"], joinColumns: ["departmentDeptNo"], 'type: psql:ONE_TO_MANY}, - workspace: {entity: Workspace, fieldName: "workspace", refTable: "Workspace", refColumns: ["workspaceEmpNo"], joinColumns: ["empNo"], 'type: psql:ONE_TO_ONE} + workspace: {entity: Workspace, fieldName: "workspace", refTable: "Workspace", refColumns: ["employeeEmpNo"], joinColumns: ["empNo"], 'type: psql:ONE_TO_ONE} } }, [WORKSPACE]: { @@ -52,7 +52,7 @@ public isolated client class Client { workspaceId: {columnName: "workspaceId"}, workspaceType: {columnName: "workspaceType"}, locationBuildingCode: {columnName: "locationBuildingCode"}, - workspaceEmpNo: {columnName: "workspaceEmpNo"}, + employeeEmpNo: {columnName: "employeeEmpNo"}, "location.buildingCode": {relation: {entityName: "location", refField: "buildingCode"}}, "location.city": {relation: {entityName: "location", refField: "city"}}, "location.state": {relation: {entityName: "location", refField: "state"}}, @@ -69,7 +69,7 @@ public isolated client class Client { keyFields: ["workspaceId"], joinMetadata: { location: {entity: Building, fieldName: "location", refTable: "Building", refColumns: ["buildingCode"], joinColumns: ["locationBuildingCode"], 'type: psql:ONE_TO_MANY}, - employee: {entity: Employee, fieldName: "employee", refTable: "Employee", refColumns: ["empNo"], joinColumns: ["workspaceEmpNo"], 'type: psql:ONE_TO_ONE} + employee: {entity: Employee, fieldName: "employee", refTable: "Employee", refColumns: ["empNo"], joinColumns: ["employeeEmpNo"], 'type: psql:ONE_TO_ONE} } }, [BUILDING]: { @@ -84,7 +84,7 @@ public isolated client class Client { "workspaces[].workspaceId": {relation: {entityName: "workspaces", refField: "workspaceId"}}, "workspaces[].workspaceType": {relation: {entityName: "workspaces", refField: "workspaceType"}}, "workspaces[].locationBuildingCode": {relation: {entityName: "workspaces", refField: "locationBuildingCode"}}, - "workspaces[].workspaceEmpNo": {relation: {entityName: "workspaces", refField: "workspaceEmpNo"}} + "workspaces[].employeeEmpNo": {relation: {entityName: "workspaces", refField: "employeeEmpNo"}} }, keyFields: ["buildingCode"], joinMetadata: {workspaces: {entity: Workspace, fieldName: "workspaces", refTable: "Workspace", refColumns: ["locationBuildingCode"], joinColumns: ["buildingCode"], 'type: psql:MANY_TO_ONE}} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_51/persist_types.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_51/persist_types.bal index d9ce4dee2..848f660ce 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_51/persist_types.bal +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_51/persist_types.bal @@ -63,14 +63,14 @@ public type Workspace record {| readonly string workspaceId; WorkspaceType workspaceType; string locationBuildingCode; - string workspaceEmpNo; + string employeeEmpNo; |}; public type WorkspaceOptionalized record {| string workspaceId?; WorkspaceType workspaceType?; string locationBuildingCode?; - string workspaceEmpNo?; + string employeeEmpNo?; |}; public type WorkspaceWithRelations record {| @@ -86,7 +86,7 @@ public type WorkspaceInsert Workspace; public type WorkspaceUpdate record {| WorkspaceType workspaceType?; string locationBuildingCode?; - string workspaceEmpNo?; + string employeeEmpNo?; |}; public type Building record {| diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_51/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_51/script.sql index d5c86a279..51e11faa5 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_51/script.sql +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_51/script.sql @@ -40,7 +40,7 @@ CREATE TABLE `Workspace` ( `workspaceType` ENUM('C', 'OFFICE', 'MR') NOT NULL, `locationBuildingCode` VARCHAR(191) NOT NULL, FOREIGN KEY(`locationBuildingCode`) REFERENCES `Building`(`buildingCode`), - `workspaceEmpNo` VARCHAR(191) UNIQUE NOT NULL, - FOREIGN KEY(`workspaceEmpNo`) REFERENCES `Employee`(`empNo`), + `employeeEmpNo` VARCHAR(191) UNIQUE NOT NULL, + FOREIGN KEY(`employeeEmpNo`) REFERENCES `Employee`(`empNo`), PRIMARY KEY(`workspaceId`) ); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_52_in_memory/modules/entities/persist_client.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_52_in_memory/modules/entities/persist_client.bal index 407bf2c82..43d5ea7be 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_52_in_memory/modules/entities/persist_client.bal +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_52_in_memory/modules/entities/persist_client.bal @@ -298,7 +298,7 @@ isolated function queryWorkspaces(string[] fields) returns stream persistClients; + + private final record {|psql:SQLMetadata...;|} & readonly metadata = { + [USER]: { + entityName: "User", + tableName: "User", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + gender: {columnName: "gender"}, + nic: {columnName: "nic"}, + salary: {columnName: "salary"}, + "cars[].id": {relation: {entityName: "cars", refField: "id"}}, + "cars[].name": {relation: {entityName: "cars", refField: "name"}}, + "cars[].model": {relation: {entityName: "cars", refField: "model"}}, + "cars[].ownerId": {relation: {entityName: "cars", refField: "ownerId"}} + }, + keyFields: ["id"], + joinMetadata: {cars: {entity: Car, fieldName: "cars", refTable: "Car", refColumns: ["ownerId"], joinColumns: ["id"], 'type: psql:MANY_TO_ONE}} + }, + [CAR]: { + entityName: "Car", + tableName: "Car", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + model: {columnName: "model"}, + ownerId: {columnName: "ownerId"}, + "owner.id": {relation: {entityName: "owner", refField: "id"}}, + "owner.name": {relation: {entityName: "owner", refField: "name"}}, + "owner.gender": {relation: {entityName: "owner", refField: "gender"}}, + "owner.nic": {relation: {entityName: "owner", refField: "nic"}}, + "owner.salary": {relation: {entityName: "owner", refField: "salary"}} + }, + keyFields: ["id"], + joinMetadata: {owner: {entity: User, fieldName: "owner", refTable: "User", refColumns: ["id"], joinColumns: ["ownerId"], 'type: psql:ONE_TO_MANY}} + } + }; + + public isolated function init() returns persist:Error? { + mysql:Client|error dbClient = new (host = host, user = user, password = password, database = database, port = port, options = connectionOptions); + if dbClient is error { + return error(dbClient.message()); + } + self.dbClient = dbClient; + self.persistClients = { + [USER]: check new (dbClient, self.metadata.get(USER), psql:MYSQL_SPECIFICS), + [CAR]: check new (dbClient, self.metadata.get(CAR), psql:MYSQL_SPECIFICS) + }; + } + + isolated resource function get users(UserTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get users/[int id](UserTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post users(UserInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from UserInsert inserted in data + select inserted.id; + } + + isolated resource function put users/[int id](UserUpdate value) returns User|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/users/[id].get(); + } + + isolated resource function delete users/[int id]() returns User|persist:Error { + User result = check self->/users/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + isolated resource function get cars(CarTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get cars/[int id](CarTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post cars(CarInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from CarInsert inserted in data + select inserted.id; + } + + isolated resource function put cars/[int id](CarUpdate value) returns Car|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/cars/[id].get(); + } + + isolated resource function delete cars/[int id]() returns Car|persist:Error { + Car result = check self->/cars/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + remote isolated function queryNativeSQL(sql:ParameterizedQuery sqlQuery, typedesc rowType = <>) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + remote isolated function executeNativeSQL(sql:ParameterizedQuery sqlQuery) returns psql:ExecutionResult|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + public isolated function close() returns persist:Error? { + error? result = self.dbClient.close(); + if result is error { + return error(result.message()); + } + return result; + } +} + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_72/modules/entities/persist_db_config.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_72/modules/entities/persist_db_config.bal new file mode 100644 index 000000000..aedfe37e0 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_72/modules/entities/persist_db_config.bal @@ -0,0 +1,12 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer. +// It should not be modified by hand. +import ballerinax/mysql; + +configurable int port = ?; +configurable string host = ?; +configurable string user = ?; +configurable string database = ?; +configurable string password = ?; +configurable mysql:Options & readonly connectionOptions = {}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_72/modules/entities/persist_types.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_72/modules/entities/persist_types.bal new file mode 100644 index 000000000..30b1fd89e --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_72/modules/entities/persist_types.bal @@ -0,0 +1,71 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. + +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; +|}; + +public type UserOptionalized record {| + int id?; + string name?; + UserGender gender?; + string nic?; + decimal? salary?; +|}; + +public type UserWithRelations record {| + *UserOptionalized; + CarOptionalized[] cars?; +|}; + +public type UserTargetType typedesc; + +public type UserInsert User; + +public type UserUpdate record {| + string name?; + UserGender gender?; + string nic?; + decimal? salary?; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + int ownerId; +|}; + +public type CarOptionalized record {| + int id?; + string name?; + string model?; + int ownerId?; +|}; + +public type CarWithRelations record {| + *CarOptionalized; + UserOptionalized owner?; +|}; + +public type CarTargetType typedesc; + +public type CarInsert Car; + +public type CarUpdate record {| + string name?; + string model?; + int ownerId?; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_72/modules/entities/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_72/modules/entities/script.sql new file mode 100644 index 000000000..b601362b0 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_72/modules/entities/script.sql @@ -0,0 +1,28 @@ +-- AUTO-GENERATED FILE. + +-- This file is an auto-generated file by Ballerina persistence layer for model. +-- Please verify the generated scripts and execute them against the target DB server. + +DROP TABLE IF EXISTS `Car`; +DROP TABLE IF EXISTS `User`; + +CREATE TABLE `User` ( + `id` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `gender` ENUM('MALE', 'FEMALE') NOT NULL, + `nic` VARCHAR(191) NOT NULL, + `salary` DECIMAL(65,30), + PRIMARY KEY(`id`) +); + +CREATE TABLE `Car` ( + `id` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `model` VARCHAR(191) NOT NULL, + `ownerId` INT NOT NULL, + FOREIGN KEY(`ownerId`) REFERENCES `User`(`id`), + PRIMARY KEY(`id`) +); + + +CREATE INDEX `ownerId` ON `Car` (`ownerId`); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_72/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_72/persist/model.bal new file mode 100644 index 000000000..dd5db5ebf --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_72/persist/model.bal @@ -0,0 +1,42 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User owner; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_72/target/Persist.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_72/target/Persist.toml new file mode 100644 index 000000000..d9d952872 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_72/target/Persist.toml @@ -0,0 +1,3 @@ +[[tool.persist]] +options.datastore = "mysql" +module = "tool_test_generate_72.entities" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_73/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_73/Ballerina.toml new file mode 100644 index 000000000..8f540342c --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_73/Ballerina.toml @@ -0,0 +1,14 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_73" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +groupId = "io.ballerina.stdlib" +artifactId = "persist.sql-native" +version = "1.3.0-SNAPSHOT" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_73/Config.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_73/Config.toml new file mode 100644 index 000000000..940f4eee7 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_73/Config.toml @@ -0,0 +1,7 @@ +[tool_test_generate_73.entities] +host = "localhost" +port = 3306 +user = "root" +password = "" +database = "" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_73/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_73/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_73/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_73/modules/entities/persist_client.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_73/modules/entities/persist_client.bal new file mode 100644 index 000000000..2db07507c --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_73/modules/entities/persist_client.bal @@ -0,0 +1,164 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. +import ballerina/jballerina.java; +import ballerina/persist; +import ballerina/sql; +import ballerinax/mysql; +import ballerinax/mysql.driver as _; +import ballerinax/persist.sql as psql; + +const USER = "users"; +const CAR = "cars"; + +public isolated client class Client { + *persist:AbstractPersistClient; + + private final mysql:Client dbClient; + + private final map persistClients; + + private final record {|psql:SQLMetadata...;|} & readonly metadata = { + [USER]: { + entityName: "User", + tableName: "User", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + gender: {columnName: "gender"}, + nic: {columnName: "nic"}, + salary: {columnName: "salary"}, + "cars[].id": {relation: {entityName: "cars", refField: "id"}}, + "cars[].name": {relation: {entityName: "cars", refField: "name"}}, + "cars[].model": {relation: {entityName: "cars", refField: "model"}}, + "cars[].ownerId": {relation: {entityName: "cars", refField: "ownerId"}} + }, + keyFields: ["id"], + joinMetadata: {cars: {entity: Car, fieldName: "cars", refTable: "cars", refColumns: ["ownerId"], joinColumns: ["id"], 'type: psql:MANY_TO_ONE}} + }, + [CAR]: { + entityName: "Car", + tableName: "cars", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + model: {columnName: "MODEL"}, + ownerId: {columnName: "ownerId"}, + "owner.id": {relation: {entityName: "owner", refField: "id"}}, + "owner.name": {relation: {entityName: "owner", refField: "name"}}, + "owner.gender": {relation: {entityName: "owner", refField: "gender"}}, + "owner.nic": {relation: {entityName: "owner", refField: "nic"}}, + "owner.salary": {relation: {entityName: "owner", refField: "salary"}} + }, + keyFields: ["id"], + joinMetadata: {owner: {entity: User, fieldName: "owner", refTable: "User", refColumns: ["id"], joinColumns: ["ownerId"], 'type: psql:ONE_TO_MANY}} + } + }; + + public isolated function init() returns persist:Error? { + mysql:Client|error dbClient = new (host = host, user = user, password = password, database = database, port = port, options = connectionOptions); + if dbClient is error { + return error(dbClient.message()); + } + self.dbClient = dbClient; + self.persistClients = { + [USER]: check new (dbClient, self.metadata.get(USER), psql:MYSQL_SPECIFICS), + [CAR]: check new (dbClient, self.metadata.get(CAR), psql:MYSQL_SPECIFICS) + }; + } + + isolated resource function get users(UserTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get users/[int id](UserTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post users(UserInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from UserInsert inserted in data + select inserted.id; + } + + isolated resource function put users/[int id](UserUpdate value) returns User|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/users/[id].get(); + } + + isolated resource function delete users/[int id]() returns User|persist:Error { + User result = check self->/users/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + isolated resource function get cars(CarTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get cars/[int id](CarTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post cars(CarInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from CarInsert inserted in data + select inserted.id; + } + + isolated resource function put cars/[int id](CarUpdate value) returns Car|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/cars/[id].get(); + } + + isolated resource function delete cars/[int id]() returns Car|persist:Error { + Car result = check self->/cars/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + remote isolated function queryNativeSQL(sql:ParameterizedQuery sqlQuery, typedesc rowType = <>) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + remote isolated function executeNativeSQL(sql:ParameterizedQuery sqlQuery) returns psql:ExecutionResult|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + public isolated function close() returns persist:Error? { + error? result = self.dbClient.close(); + if result is error { + return error(result.message()); + } + return result; + } +} + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_73/modules/entities/persist_db_config.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_73/modules/entities/persist_db_config.bal new file mode 100644 index 000000000..aedfe37e0 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_73/modules/entities/persist_db_config.bal @@ -0,0 +1,12 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer. +// It should not be modified by hand. +import ballerinax/mysql; + +configurable int port = ?; +configurable string host = ?; +configurable string user = ?; +configurable string database = ?; +configurable string password = ?; +configurable mysql:Options & readonly connectionOptions = {}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_73/modules/entities/persist_types.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_73/modules/entities/persist_types.bal new file mode 100644 index 000000000..30b1fd89e --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_73/modules/entities/persist_types.bal @@ -0,0 +1,71 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. + +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; +|}; + +public type UserOptionalized record {| + int id?; + string name?; + UserGender gender?; + string nic?; + decimal? salary?; +|}; + +public type UserWithRelations record {| + *UserOptionalized; + CarOptionalized[] cars?; +|}; + +public type UserTargetType typedesc; + +public type UserInsert User; + +public type UserUpdate record {| + string name?; + UserGender gender?; + string nic?; + decimal? salary?; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + int ownerId; +|}; + +public type CarOptionalized record {| + int id?; + string name?; + string model?; + int ownerId?; +|}; + +public type CarWithRelations record {| + *CarOptionalized; + UserOptionalized owner?; +|}; + +public type CarTargetType typedesc; + +public type CarInsert Car; + +public type CarUpdate record {| + string name?; + string model?; + int ownerId?; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_73/modules/entities/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_73/modules/entities/script.sql new file mode 100644 index 000000000..6268c8bf1 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_73/modules/entities/script.sql @@ -0,0 +1,28 @@ +-- AUTO-GENERATED FILE. + +-- This file is an auto-generated file by Ballerina persistence layer for model. +-- Please verify the generated scripts and execute them against the target DB server. + +DROP TABLE IF EXISTS `cars`; +DROP TABLE IF EXISTS `User`; + +CREATE TABLE `User` ( + `id` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `gender` ENUM('MALE', 'FEMALE') NOT NULL, + `nic` VARCHAR(191) NOT NULL, + `salary` DECIMAL(65,30), + PRIMARY KEY(`id`) +); + +CREATE TABLE `cars` ( + `id` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `MODEL` VARCHAR(191) NOT NULL, + `ownerId` INT NOT NULL, + FOREIGN KEY(`ownerId`) REFERENCES `User`(`id`), + PRIMARY KEY(`id`) +); + + +CREATE INDEX `ownerId` ON `cars` (`ownerId`); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_73/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_73/persist/model.bal new file mode 100644 index 000000000..603e60956 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_73/persist/model.bal @@ -0,0 +1,44 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; + Car[] cars; +|}; + +@sql:Mapping {name: "cars"} +public type Car record {| + readonly int id; + string name; + @sql:Mapping {name: "MODEL"} + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User owner; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_73/target/Persist.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_73/target/Persist.toml new file mode 100644 index 000000000..bbab03b78 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_73/target/Persist.toml @@ -0,0 +1,3 @@ +[[tool.persist]] +options.datastore = "mysql" +module = "tool_test_generate_73.entities" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_74/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_74/Ballerina.toml new file mode 100644 index 000000000..d1c0a50d9 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_74/Ballerina.toml @@ -0,0 +1,14 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_74" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +groupId = "io.ballerina.stdlib" +artifactId = "persist.sql-native" +version = "1.3.0-SNAPSHOT" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_74/Config.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_74/Config.toml new file mode 100644 index 000000000..b8ab46b3b --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_74/Config.toml @@ -0,0 +1,7 @@ +[tool_test_generate_74.entities] +host = "localhost" +port = 3306 +user = "root" +password = "" +database = "" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_74/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_74/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_74/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_74/modules/entities/persist_client.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_74/modules/entities/persist_client.bal new file mode 100644 index 000000000..2336002e3 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_74/modules/entities/persist_client.bal @@ -0,0 +1,164 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. +import ballerina/jballerina.java; +import ballerina/persist; +import ballerina/sql; +import ballerinax/mysql; +import ballerinax/mysql.driver as _; +import ballerinax/persist.sql as psql; + +const USER = "users"; +const CAR = "cars"; + +public isolated client class Client { + *persist:AbstractPersistClient; + + private final mysql:Client dbClient; + + private final map persistClients; + + private final record {|psql:SQLMetadata...;|} & readonly metadata = { + [USER]: { + entityName: "User", + tableName: "User", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + gender: {columnName: "gender"}, + nic: {columnName: "nic"}, + salary: {columnName: "salary"}, + "cars[].id": {relation: {entityName: "cars", refField: "id"}}, + "cars[].name": {relation: {entityName: "cars", refField: "name"}}, + "cars[].model": {relation: {entityName: "cars", refField: "model"}}, + "cars[].ownerId": {relation: {entityName: "cars", refField: "ownerId"}} + }, + keyFields: ["id"], + joinMetadata: {cars: {entity: Car, fieldName: "cars", refTable: "cars", refColumns: ["OWNER_ID"], joinColumns: ["id"], 'type: psql:MANY_TO_ONE}} + }, + [CAR]: { + entityName: "Car", + tableName: "cars", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + model: {columnName: "MODEL"}, + ownerId: {columnName: "OWNER_ID"}, + "user.id": {relation: {entityName: "user", refField: "id"}}, + "user.name": {relation: {entityName: "user", refField: "name"}}, + "user.gender": {relation: {entityName: "user", refField: "gender"}}, + "user.nic": {relation: {entityName: "user", refField: "nic"}}, + "user.salary": {relation: {entityName: "user", refField: "salary"}} + }, + keyFields: ["id"], + joinMetadata: {user: {entity: User, fieldName: "user", refTable: "User", refColumns: ["id"], joinColumns: ["OWNER_ID"], 'type: psql:ONE_TO_MANY}} + } + }; + + public isolated function init() returns persist:Error? { + mysql:Client|error dbClient = new (host = host, user = user, password = password, database = database, port = port, options = connectionOptions); + if dbClient is error { + return error(dbClient.message()); + } + self.dbClient = dbClient; + self.persistClients = { + [USER]: check new (dbClient, self.metadata.get(USER), psql:MYSQL_SPECIFICS), + [CAR]: check new (dbClient, self.metadata.get(CAR), psql:MYSQL_SPECIFICS) + }; + } + + isolated resource function get users(UserTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get users/[int id](UserTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post users(UserInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from UserInsert inserted in data + select inserted.id; + } + + isolated resource function put users/[int id](UserUpdate value) returns User|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/users/[id].get(); + } + + isolated resource function delete users/[int id]() returns User|persist:Error { + User result = check self->/users/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + isolated resource function get cars(CarTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get cars/[int id](CarTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post cars(CarInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from CarInsert inserted in data + select inserted.id; + } + + isolated resource function put cars/[int id](CarUpdate value) returns Car|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/cars/[id].get(); + } + + isolated resource function delete cars/[int id]() returns Car|persist:Error { + Car result = check self->/cars/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + remote isolated function queryNativeSQL(sql:ParameterizedQuery sqlQuery, typedesc rowType = <>) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + remote isolated function executeNativeSQL(sql:ParameterizedQuery sqlQuery) returns psql:ExecutionResult|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + public isolated function close() returns persist:Error? { + error? result = self.dbClient.close(); + if result is error { + return error(result.message()); + } + return result; + } +} + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_74/modules/entities/persist_db_config.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_74/modules/entities/persist_db_config.bal new file mode 100644 index 000000000..aedfe37e0 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_74/modules/entities/persist_db_config.bal @@ -0,0 +1,12 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer. +// It should not be modified by hand. +import ballerinax/mysql; + +configurable int port = ?; +configurable string host = ?; +configurable string user = ?; +configurable string database = ?; +configurable string password = ?; +configurable mysql:Options & readonly connectionOptions = {}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_74/modules/entities/persist_types.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_74/modules/entities/persist_types.bal new file mode 100644 index 000000000..c5cca4c1a --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_74/modules/entities/persist_types.bal @@ -0,0 +1,71 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. + +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; +|}; + +public type UserOptionalized record {| + int id?; + string name?; + UserGender gender?; + string nic?; + decimal? salary?; +|}; + +public type UserWithRelations record {| + *UserOptionalized; + CarOptionalized[] cars?; +|}; + +public type UserTargetType typedesc; + +public type UserInsert User; + +public type UserUpdate record {| + string name?; + UserGender gender?; + string nic?; + decimal? salary?; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + int ownerId; +|}; + +public type CarOptionalized record {| + int id?; + string name?; + string model?; + int ownerId?; +|}; + +public type CarWithRelations record {| + *CarOptionalized; + UserOptionalized user?; +|}; + +public type CarTargetType typedesc; + +public type CarInsert Car; + +public type CarUpdate record {| + string name?; + string model?; + int ownerId?; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_74/modules/entities/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_74/modules/entities/script.sql new file mode 100644 index 000000000..33d5a0740 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_74/modules/entities/script.sql @@ -0,0 +1,28 @@ +-- AUTO-GENERATED FILE. + +-- This file is an auto-generated file by Ballerina persistence layer for model. +-- Please verify the generated scripts and execute them against the target DB server. + +DROP TABLE IF EXISTS `cars`; +DROP TABLE IF EXISTS `User`; + +CREATE TABLE `User` ( + `id` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `gender` ENUM('MALE', 'FEMALE') NOT NULL, + `nic` VARCHAR(191) NOT NULL, + `salary` DECIMAL(65,30), + PRIMARY KEY(`id`) +); + +CREATE TABLE `cars` ( + `id` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `MODEL` VARCHAR(191) NOT NULL, + `OWNER_ID` INT NOT NULL, + FOREIGN KEY(`OWNER_ID`) REFERENCES `User`(`id`), + PRIMARY KEY(`id`) +); + + +CREATE INDEX `ownerId` ON `cars` (`OWNER_ID`); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_74/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_74/persist/model.bal new file mode 100644 index 000000000..b1132ba9a --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_74/persist/model.bal @@ -0,0 +1,45 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; + Car[] cars; +|}; + +@sql:Mapping {name: "cars"} +public type Car record {| + readonly int id; + string name; + @sql:Mapping {name: "MODEL"} + string model; + @sql:Mapping {name: "OWNER_ID"} + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_74/target/Persist.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_74/target/Persist.toml new file mode 100644 index 000000000..25907a28b --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_74/target/Persist.toml @@ -0,0 +1,3 @@ +[[tool.persist]] +options.datastore = "mysql" +module = "tool_test_generate_74.entities" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_75/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_75/Ballerina.toml new file mode 100644 index 000000000..98f2cc8cd --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_75/Ballerina.toml @@ -0,0 +1,14 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_75" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +groupId = "io.ballerina.stdlib" +artifactId = "persist.sql-native" +version = "1.3.0-SNAPSHOT" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_75/Config.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_75/Config.toml new file mode 100644 index 000000000..9fa882f57 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_75/Config.toml @@ -0,0 +1,7 @@ +[tool_test_generate_75.entities] +host = "localhost" +port = 3306 +user = "root" +password = "" +database = "" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_75/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_75/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_75/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_75/modules/entities/persist_client.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_75/modules/entities/persist_client.bal new file mode 100644 index 000000000..1d8ef11e8 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_75/modules/entities/persist_client.bal @@ -0,0 +1,164 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. +import ballerina/jballerina.java; +import ballerina/persist; +import ballerina/sql; +import ballerinax/mysql; +import ballerinax/mysql.driver as _; +import ballerinax/persist.sql as psql; + +const USER = "users"; +const CAR = "cars"; + +public isolated client class Client { + *persist:AbstractPersistClient; + + private final mysql:Client dbClient; + + private final map persistClients; + + private final record {|psql:SQLMetadata...;|} & readonly metadata = { + [USER]: { + entityName: "User", + tableName: "User", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + gender: {columnName: "gender"}, + nic: {columnName: "nic"}, + salary: {columnName: "salary"}, + "cars[].id": {relation: {entityName: "cars", refField: "id"}}, + "cars[].name": {relation: {entityName: "cars", refField: "name"}}, + "cars[].model": {relation: {entityName: "cars", refField: "model"}}, + "cars[].ownerId": {relation: {entityName: "cars", refField: "ownerId"}} + }, + keyFields: ["id"], + joinMetadata: {cars: {entity: Car, fieldName: "cars", refTable: "Car", refColumns: ["ownerId"], joinColumns: ["id"], 'type: psql:MANY_TO_ONE}} + }, + [CAR]: { + entityName: "Car", + tableName: "Car", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + model: {columnName: "model"}, + ownerId: {columnName: "ownerId"}, + "user.id": {relation: {entityName: "user", refField: "id"}}, + "user.name": {relation: {entityName: "user", refField: "name"}}, + "user.gender": {relation: {entityName: "user", refField: "gender"}}, + "user.nic": {relation: {entityName: "user", refField: "nic"}}, + "user.salary": {relation: {entityName: "user", refField: "salary"}} + }, + keyFields: ["id"], + joinMetadata: {user: {entity: User, fieldName: "user", refTable: "User", refColumns: ["id"], joinColumns: ["ownerId"], 'type: psql:ONE_TO_MANY}} + } + }; + + public isolated function init() returns persist:Error? { + mysql:Client|error dbClient = new (host = host, user = user, password = password, database = database, port = port, options = connectionOptions); + if dbClient is error { + return error(dbClient.message()); + } + self.dbClient = dbClient; + self.persistClients = { + [USER]: check new (dbClient, self.metadata.get(USER), psql:MYSQL_SPECIFICS), + [CAR]: check new (dbClient, self.metadata.get(CAR), psql:MYSQL_SPECIFICS) + }; + } + + isolated resource function get users(UserTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get users/[int id](UserTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post users(UserInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from UserInsert inserted in data + select inserted.id; + } + + isolated resource function put users/[int id](UserUpdate value) returns User|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/users/[id].get(); + } + + isolated resource function delete users/[int id]() returns User|persist:Error { + User result = check self->/users/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + isolated resource function get cars(CarTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get cars/[int id](CarTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post cars(CarInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from CarInsert inserted in data + select inserted.id; + } + + isolated resource function put cars/[int id](CarUpdate value) returns Car|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/cars/[id].get(); + } + + isolated resource function delete cars/[int id]() returns Car|persist:Error { + Car result = check self->/cars/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + remote isolated function queryNativeSQL(sql:ParameterizedQuery sqlQuery, typedesc rowType = <>) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + remote isolated function executeNativeSQL(sql:ParameterizedQuery sqlQuery) returns psql:ExecutionResult|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + public isolated function close() returns persist:Error? { + error? result = self.dbClient.close(); + if result is error { + return error(result.message()); + } + return result; + } +} + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_75/modules/entities/persist_db_config.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_75/modules/entities/persist_db_config.bal new file mode 100644 index 000000000..aedfe37e0 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_75/modules/entities/persist_db_config.bal @@ -0,0 +1,12 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer. +// It should not be modified by hand. +import ballerinax/mysql; + +configurable int port = ?; +configurable string host = ?; +configurable string user = ?; +configurable string database = ?; +configurable string password = ?; +configurable mysql:Options & readonly connectionOptions = {}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_75/modules/entities/persist_types.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_75/modules/entities/persist_types.bal new file mode 100644 index 000000000..c5cca4c1a --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_75/modules/entities/persist_types.bal @@ -0,0 +1,71 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. + +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; +|}; + +public type UserOptionalized record {| + int id?; + string name?; + UserGender gender?; + string nic?; + decimal? salary?; +|}; + +public type UserWithRelations record {| + *UserOptionalized; + CarOptionalized[] cars?; +|}; + +public type UserTargetType typedesc; + +public type UserInsert User; + +public type UserUpdate record {| + string name?; + UserGender gender?; + string nic?; + decimal? salary?; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + int ownerId; +|}; + +public type CarOptionalized record {| + int id?; + string name?; + string model?; + int ownerId?; +|}; + +public type CarWithRelations record {| + *CarOptionalized; + UserOptionalized user?; +|}; + +public type CarTargetType typedesc; + +public type CarInsert Car; + +public type CarUpdate record {| + string name?; + string model?; + int ownerId?; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_75/modules/entities/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_75/modules/entities/script.sql new file mode 100644 index 000000000..0c824f913 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_75/modules/entities/script.sql @@ -0,0 +1,28 @@ +-- AUTO-GENERATED FILE. + +-- This file is an auto-generated file by Ballerina persistence layer for model. +-- Please verify the generated scripts and execute them against the target DB server. + +DROP TABLE IF EXISTS `Car`; +DROP TABLE IF EXISTS `User`; + +CREATE TABLE `User` ( + `id` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `gender` ENUM('MALE', 'FEMALE') NOT NULL, + `nic` VARCHAR(12) NOT NULL, + `salary` DECIMAL(10,2), + PRIMARY KEY(`id`) +); + +CREATE TABLE `Car` ( + `id` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `model` CHAR(10) NOT NULL, + `ownerId` INT NOT NULL, + FOREIGN KEY(`ownerId`) REFERENCES `User`(`id`), + PRIMARY KEY(`id`) +); + + +CREATE INDEX `ownerId` ON `Car` (`ownerId`); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_75/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_75/persist/model.bal new file mode 100644 index 000000000..c46361007 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_75/persist/model.bal @@ -0,0 +1,45 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + @sql:VarChar {length: 12} + string nic; + @sql:Decimal {precision: [10, 2]} + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + @sql:Char {length: 10} + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_75/target/Persist.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_75/target/Persist.toml new file mode 100644 index 000000000..f6a529b39 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_75/target/Persist.toml @@ -0,0 +1,3 @@ +[[tool.persist]] +options.datastore = "mysql" +module = "tool_test_generate_75.entities" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_76/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_76/Ballerina.toml new file mode 100644 index 000000000..db42139a7 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_76/Ballerina.toml @@ -0,0 +1,14 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_76" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +groupId = "io.ballerina.stdlib" +artifactId = "persist.sql-native" +version = "1.3.0-SNAPSHOT" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_76/Config.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_76/Config.toml new file mode 100644 index 000000000..40fe1d741 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_76/Config.toml @@ -0,0 +1,7 @@ +[tool_test_generate_76.entities] +host = "localhost" +port = 3306 +user = "root" +password = "" +database = "" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_76/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_76/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_76/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_76/modules/entities/persist_client.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_76/modules/entities/persist_client.bal new file mode 100644 index 000000000..1d8ef11e8 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_76/modules/entities/persist_client.bal @@ -0,0 +1,164 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. +import ballerina/jballerina.java; +import ballerina/persist; +import ballerina/sql; +import ballerinax/mysql; +import ballerinax/mysql.driver as _; +import ballerinax/persist.sql as psql; + +const USER = "users"; +const CAR = "cars"; + +public isolated client class Client { + *persist:AbstractPersistClient; + + private final mysql:Client dbClient; + + private final map persistClients; + + private final record {|psql:SQLMetadata...;|} & readonly metadata = { + [USER]: { + entityName: "User", + tableName: "User", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + gender: {columnName: "gender"}, + nic: {columnName: "nic"}, + salary: {columnName: "salary"}, + "cars[].id": {relation: {entityName: "cars", refField: "id"}}, + "cars[].name": {relation: {entityName: "cars", refField: "name"}}, + "cars[].model": {relation: {entityName: "cars", refField: "model"}}, + "cars[].ownerId": {relation: {entityName: "cars", refField: "ownerId"}} + }, + keyFields: ["id"], + joinMetadata: {cars: {entity: Car, fieldName: "cars", refTable: "Car", refColumns: ["ownerId"], joinColumns: ["id"], 'type: psql:MANY_TO_ONE}} + }, + [CAR]: { + entityName: "Car", + tableName: "Car", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + model: {columnName: "model"}, + ownerId: {columnName: "ownerId"}, + "user.id": {relation: {entityName: "user", refField: "id"}}, + "user.name": {relation: {entityName: "user", refField: "name"}}, + "user.gender": {relation: {entityName: "user", refField: "gender"}}, + "user.nic": {relation: {entityName: "user", refField: "nic"}}, + "user.salary": {relation: {entityName: "user", refField: "salary"}} + }, + keyFields: ["id"], + joinMetadata: {user: {entity: User, fieldName: "user", refTable: "User", refColumns: ["id"], joinColumns: ["ownerId"], 'type: psql:ONE_TO_MANY}} + } + }; + + public isolated function init() returns persist:Error? { + mysql:Client|error dbClient = new (host = host, user = user, password = password, database = database, port = port, options = connectionOptions); + if dbClient is error { + return error(dbClient.message()); + } + self.dbClient = dbClient; + self.persistClients = { + [USER]: check new (dbClient, self.metadata.get(USER), psql:MYSQL_SPECIFICS), + [CAR]: check new (dbClient, self.metadata.get(CAR), psql:MYSQL_SPECIFICS) + }; + } + + isolated resource function get users(UserTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get users/[int id](UserTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post users(UserInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from UserInsert inserted in data + select inserted.id; + } + + isolated resource function put users/[int id](UserUpdate value) returns User|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/users/[id].get(); + } + + isolated resource function delete users/[int id]() returns User|persist:Error { + User result = check self->/users/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + isolated resource function get cars(CarTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get cars/[int id](CarTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post cars(CarInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from CarInsert inserted in data + select inserted.id; + } + + isolated resource function put cars/[int id](CarUpdate value) returns Car|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/cars/[id].get(); + } + + isolated resource function delete cars/[int id]() returns Car|persist:Error { + Car result = check self->/cars/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + remote isolated function queryNativeSQL(sql:ParameterizedQuery sqlQuery, typedesc rowType = <>) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + remote isolated function executeNativeSQL(sql:ParameterizedQuery sqlQuery) returns psql:ExecutionResult|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + public isolated function close() returns persist:Error? { + error? result = self.dbClient.close(); + if result is error { + return error(result.message()); + } + return result; + } +} + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_76/modules/entities/persist_db_config.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_76/modules/entities/persist_db_config.bal new file mode 100644 index 000000000..aedfe37e0 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_76/modules/entities/persist_db_config.bal @@ -0,0 +1,12 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer. +// It should not be modified by hand. +import ballerinax/mysql; + +configurable int port = ?; +configurable string host = ?; +configurable string user = ?; +configurable string database = ?; +configurable string password = ?; +configurable mysql:Options & readonly connectionOptions = {}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_76/modules/entities/persist_types.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_76/modules/entities/persist_types.bal new file mode 100644 index 000000000..c5cca4c1a --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_76/modules/entities/persist_types.bal @@ -0,0 +1,71 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. + +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; +|}; + +public type UserOptionalized record {| + int id?; + string name?; + UserGender gender?; + string nic?; + decimal? salary?; +|}; + +public type UserWithRelations record {| + *UserOptionalized; + CarOptionalized[] cars?; +|}; + +public type UserTargetType typedesc; + +public type UserInsert User; + +public type UserUpdate record {| + string name?; + UserGender gender?; + string nic?; + decimal? salary?; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + int ownerId; +|}; + +public type CarOptionalized record {| + int id?; + string name?; + string model?; + int ownerId?; +|}; + +public type CarWithRelations record {| + *CarOptionalized; + UserOptionalized user?; +|}; + +public type CarTargetType typedesc; + +public type CarInsert Car; + +public type CarUpdate record {| + string name?; + string model?; + int ownerId?; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_76/modules/entities/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_76/modules/entities/script.sql new file mode 100644 index 000000000..efda90d19 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_76/modules/entities/script.sql @@ -0,0 +1,29 @@ +-- AUTO-GENERATED FILE. + +-- This file is an auto-generated file by Ballerina persistence layer for model. +-- Please verify the generated scripts and execute them against the target DB server. + +DROP TABLE IF EXISTS `Car`; +DROP TABLE IF EXISTS `User`; + +CREATE TABLE `User` ( + `id` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `gender` ENUM('MALE', 'FEMALE') NOT NULL, + `nic` VARCHAR(191) NOT NULL, + `salary` DECIMAL(65,30), + PRIMARY KEY(`id`) +); + +CREATE TABLE `Car` ( + `id` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `model` VARCHAR(191) NOT NULL, + `ownerId` INT NOT NULL, + FOREIGN KEY(`ownerId`) REFERENCES `User`(`id`), + PRIMARY KEY(`id`) +); + + +CREATE UNIQUE INDEX `nic_index` ON `User` (`nic`); +CREATE INDEX `ownerId` ON `Car` (`ownerId`); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_76/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_76/persist/model.bal new file mode 100644 index 000000000..3bc86840f --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_76/persist/model.bal @@ -0,0 +1,43 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + @sql:UniqueIndex {names: ["nic_index"]} + string nic; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_76/target/Persist.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_76/target/Persist.toml new file mode 100644 index 000000000..c721c2fed --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_76/target/Persist.toml @@ -0,0 +1,3 @@ +[[tool.persist]] +options.datastore = "mysql" +module = "tool_test_generate_76.entities" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_77/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_77/Ballerina.toml new file mode 100644 index 000000000..657685bcd --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_77/Ballerina.toml @@ -0,0 +1,14 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_77" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +groupId = "io.ballerina.stdlib" +artifactId = "persist.sql-native" +version = "1.3.0-SNAPSHOT" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_77/Config.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_77/Config.toml new file mode 100644 index 000000000..bb1840f18 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_77/Config.toml @@ -0,0 +1,7 @@ +[tool_test_generate_77.entities] +host = "localhost" +port = 3306 +user = "root" +password = "" +database = "" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_77/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_77/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_77/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_77/modules/entities/persist_client.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_77/modules/entities/persist_client.bal new file mode 100644 index 000000000..1d8ef11e8 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_77/modules/entities/persist_client.bal @@ -0,0 +1,164 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. +import ballerina/jballerina.java; +import ballerina/persist; +import ballerina/sql; +import ballerinax/mysql; +import ballerinax/mysql.driver as _; +import ballerinax/persist.sql as psql; + +const USER = "users"; +const CAR = "cars"; + +public isolated client class Client { + *persist:AbstractPersistClient; + + private final mysql:Client dbClient; + + private final map persistClients; + + private final record {|psql:SQLMetadata...;|} & readonly metadata = { + [USER]: { + entityName: "User", + tableName: "User", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + gender: {columnName: "gender"}, + nic: {columnName: "nic"}, + salary: {columnName: "salary"}, + "cars[].id": {relation: {entityName: "cars", refField: "id"}}, + "cars[].name": {relation: {entityName: "cars", refField: "name"}}, + "cars[].model": {relation: {entityName: "cars", refField: "model"}}, + "cars[].ownerId": {relation: {entityName: "cars", refField: "ownerId"}} + }, + keyFields: ["id"], + joinMetadata: {cars: {entity: Car, fieldName: "cars", refTable: "Car", refColumns: ["ownerId"], joinColumns: ["id"], 'type: psql:MANY_TO_ONE}} + }, + [CAR]: { + entityName: "Car", + tableName: "Car", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + model: {columnName: "model"}, + ownerId: {columnName: "ownerId"}, + "user.id": {relation: {entityName: "user", refField: "id"}}, + "user.name": {relation: {entityName: "user", refField: "name"}}, + "user.gender": {relation: {entityName: "user", refField: "gender"}}, + "user.nic": {relation: {entityName: "user", refField: "nic"}}, + "user.salary": {relation: {entityName: "user", refField: "salary"}} + }, + keyFields: ["id"], + joinMetadata: {user: {entity: User, fieldName: "user", refTable: "User", refColumns: ["id"], joinColumns: ["ownerId"], 'type: psql:ONE_TO_MANY}} + } + }; + + public isolated function init() returns persist:Error? { + mysql:Client|error dbClient = new (host = host, user = user, password = password, database = database, port = port, options = connectionOptions); + if dbClient is error { + return error(dbClient.message()); + } + self.dbClient = dbClient; + self.persistClients = { + [USER]: check new (dbClient, self.metadata.get(USER), psql:MYSQL_SPECIFICS), + [CAR]: check new (dbClient, self.metadata.get(CAR), psql:MYSQL_SPECIFICS) + }; + } + + isolated resource function get users(UserTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get users/[int id](UserTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post users(UserInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from UserInsert inserted in data + select inserted.id; + } + + isolated resource function put users/[int id](UserUpdate value) returns User|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/users/[id].get(); + } + + isolated resource function delete users/[int id]() returns User|persist:Error { + User result = check self->/users/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + isolated resource function get cars(CarTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get cars/[int id](CarTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post cars(CarInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from CarInsert inserted in data + select inserted.id; + } + + isolated resource function put cars/[int id](CarUpdate value) returns Car|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/cars/[id].get(); + } + + isolated resource function delete cars/[int id]() returns Car|persist:Error { + Car result = check self->/cars/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + remote isolated function queryNativeSQL(sql:ParameterizedQuery sqlQuery, typedesc rowType = <>) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + remote isolated function executeNativeSQL(sql:ParameterizedQuery sqlQuery) returns psql:ExecutionResult|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + public isolated function close() returns persist:Error? { + error? result = self.dbClient.close(); + if result is error { + return error(result.message()); + } + return result; + } +} + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_77/modules/entities/persist_db_config.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_77/modules/entities/persist_db_config.bal new file mode 100644 index 000000000..aedfe37e0 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_77/modules/entities/persist_db_config.bal @@ -0,0 +1,12 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer. +// It should not be modified by hand. +import ballerinax/mysql; + +configurable int port = ?; +configurable string host = ?; +configurable string user = ?; +configurable string database = ?; +configurable string password = ?; +configurable mysql:Options & readonly connectionOptions = {}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_77/modules/entities/persist_types.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_77/modules/entities/persist_types.bal new file mode 100644 index 000000000..c5cca4c1a --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_77/modules/entities/persist_types.bal @@ -0,0 +1,71 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. + +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; +|}; + +public type UserOptionalized record {| + int id?; + string name?; + UserGender gender?; + string nic?; + decimal? salary?; +|}; + +public type UserWithRelations record {| + *UserOptionalized; + CarOptionalized[] cars?; +|}; + +public type UserTargetType typedesc; + +public type UserInsert User; + +public type UserUpdate record {| + string name?; + UserGender gender?; + string nic?; + decimal? salary?; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + int ownerId; +|}; + +public type CarOptionalized record {| + int id?; + string name?; + string model?; + int ownerId?; +|}; + +public type CarWithRelations record {| + *CarOptionalized; + UserOptionalized user?; +|}; + +public type CarTargetType typedesc; + +public type CarInsert Car; + +public type CarUpdate record {| + string name?; + string model?; + int ownerId?; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_77/modules/entities/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_77/modules/entities/script.sql new file mode 100644 index 000000000..bd8a8903d --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_77/modules/entities/script.sql @@ -0,0 +1,29 @@ +-- AUTO-GENERATED FILE. + +-- This file is an auto-generated file by Ballerina persistence layer for model. +-- Please verify the generated scripts and execute them against the target DB server. + +DROP TABLE IF EXISTS `Car`; +DROP TABLE IF EXISTS `User`; + +CREATE TABLE `User` ( + `id` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `gender` ENUM('MALE', 'FEMALE') NOT NULL, + `nic` VARCHAR(191) NOT NULL, + `salary` DECIMAL(65,30), + PRIMARY KEY(`id`) +); + +CREATE TABLE `Car` ( + `id` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `model` VARCHAR(191) NOT NULL, + `ownerId` INT NOT NULL, + FOREIGN KEY(`ownerId`) REFERENCES `User`(`id`), + PRIMARY KEY(`id`) +); + + +CREATE UNIQUE INDEX `user_index` ON `User` (`id`, `nic`); +CREATE INDEX `ownerId` ON `Car` (`ownerId`); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_77/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_77/persist/model.bal new file mode 100644 index 000000000..1f81476d4 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_77/persist/model.bal @@ -0,0 +1,44 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + @sql:UniqueIndex {names: ["user_index"]} + readonly int id; + string name; + UserGender gender; + @sql:UniqueIndex {names: ["user_index"]} + string nic; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_77/target/Persist.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_77/target/Persist.toml new file mode 100644 index 000000000..9267772f3 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_77/target/Persist.toml @@ -0,0 +1,3 @@ +[[tool.persist]] +options.datastore = "mysql" +module = "tool_test_generate_77.entities" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_78/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_78/Ballerina.toml new file mode 100644 index 000000000..f17e99865 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_78/Ballerina.toml @@ -0,0 +1,14 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_78" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +groupId = "io.ballerina.stdlib" +artifactId = "persist.sql-native" +version = "1.3.0-SNAPSHOT" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_78/Config.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_78/Config.toml new file mode 100644 index 000000000..5168f7ff3 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_78/Config.toml @@ -0,0 +1,7 @@ +[tool_test_generate_78.entities] +host = "localhost" +port = 3306 +user = "root" +password = "" +database = "" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_78/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_78/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_78/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_78/modules/entities/persist_client.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_78/modules/entities/persist_client.bal new file mode 100644 index 000000000..1d8ef11e8 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_78/modules/entities/persist_client.bal @@ -0,0 +1,164 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. +import ballerina/jballerina.java; +import ballerina/persist; +import ballerina/sql; +import ballerinax/mysql; +import ballerinax/mysql.driver as _; +import ballerinax/persist.sql as psql; + +const USER = "users"; +const CAR = "cars"; + +public isolated client class Client { + *persist:AbstractPersistClient; + + private final mysql:Client dbClient; + + private final map persistClients; + + private final record {|psql:SQLMetadata...;|} & readonly metadata = { + [USER]: { + entityName: "User", + tableName: "User", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + gender: {columnName: "gender"}, + nic: {columnName: "nic"}, + salary: {columnName: "salary"}, + "cars[].id": {relation: {entityName: "cars", refField: "id"}}, + "cars[].name": {relation: {entityName: "cars", refField: "name"}}, + "cars[].model": {relation: {entityName: "cars", refField: "model"}}, + "cars[].ownerId": {relation: {entityName: "cars", refField: "ownerId"}} + }, + keyFields: ["id"], + joinMetadata: {cars: {entity: Car, fieldName: "cars", refTable: "Car", refColumns: ["ownerId"], joinColumns: ["id"], 'type: psql:MANY_TO_ONE}} + }, + [CAR]: { + entityName: "Car", + tableName: "Car", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + model: {columnName: "model"}, + ownerId: {columnName: "ownerId"}, + "user.id": {relation: {entityName: "user", refField: "id"}}, + "user.name": {relation: {entityName: "user", refField: "name"}}, + "user.gender": {relation: {entityName: "user", refField: "gender"}}, + "user.nic": {relation: {entityName: "user", refField: "nic"}}, + "user.salary": {relation: {entityName: "user", refField: "salary"}} + }, + keyFields: ["id"], + joinMetadata: {user: {entity: User, fieldName: "user", refTable: "User", refColumns: ["id"], joinColumns: ["ownerId"], 'type: psql:ONE_TO_MANY}} + } + }; + + public isolated function init() returns persist:Error? { + mysql:Client|error dbClient = new (host = host, user = user, password = password, database = database, port = port, options = connectionOptions); + if dbClient is error { + return error(dbClient.message()); + } + self.dbClient = dbClient; + self.persistClients = { + [USER]: check new (dbClient, self.metadata.get(USER), psql:MYSQL_SPECIFICS), + [CAR]: check new (dbClient, self.metadata.get(CAR), psql:MYSQL_SPECIFICS) + }; + } + + isolated resource function get users(UserTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get users/[int id](UserTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post users(UserInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from UserInsert inserted in data + select inserted.id; + } + + isolated resource function put users/[int id](UserUpdate value) returns User|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/users/[id].get(); + } + + isolated resource function delete users/[int id]() returns User|persist:Error { + User result = check self->/users/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + isolated resource function get cars(CarTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get cars/[int id](CarTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post cars(CarInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from CarInsert inserted in data + select inserted.id; + } + + isolated resource function put cars/[int id](CarUpdate value) returns Car|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/cars/[id].get(); + } + + isolated resource function delete cars/[int id]() returns Car|persist:Error { + Car result = check self->/cars/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + remote isolated function queryNativeSQL(sql:ParameterizedQuery sqlQuery, typedesc rowType = <>) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + remote isolated function executeNativeSQL(sql:ParameterizedQuery sqlQuery) returns psql:ExecutionResult|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + public isolated function close() returns persist:Error? { + error? result = self.dbClient.close(); + if result is error { + return error(result.message()); + } + return result; + } +} + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_78/modules/entities/persist_db_config.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_78/modules/entities/persist_db_config.bal new file mode 100644 index 000000000..aedfe37e0 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_78/modules/entities/persist_db_config.bal @@ -0,0 +1,12 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer. +// It should not be modified by hand. +import ballerinax/mysql; + +configurable int port = ?; +configurable string host = ?; +configurable string user = ?; +configurable string database = ?; +configurable string password = ?; +configurable mysql:Options & readonly connectionOptions = {}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_78/modules/entities/persist_types.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_78/modules/entities/persist_types.bal new file mode 100644 index 000000000..c5cca4c1a --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_78/modules/entities/persist_types.bal @@ -0,0 +1,71 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. + +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; +|}; + +public type UserOptionalized record {| + int id?; + string name?; + UserGender gender?; + string nic?; + decimal? salary?; +|}; + +public type UserWithRelations record {| + *UserOptionalized; + CarOptionalized[] cars?; +|}; + +public type UserTargetType typedesc; + +public type UserInsert User; + +public type UserUpdate record {| + string name?; + UserGender gender?; + string nic?; + decimal? salary?; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + int ownerId; +|}; + +public type CarOptionalized record {| + int id?; + string name?; + string model?; + int ownerId?; +|}; + +public type CarWithRelations record {| + *CarOptionalized; + UserOptionalized user?; +|}; + +public type CarTargetType typedesc; + +public type CarInsert Car; + +public type CarUpdate record {| + string name?; + string model?; + int ownerId?; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_78/modules/entities/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_78/modules/entities/script.sql new file mode 100644 index 000000000..db4a4f363 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_78/modules/entities/script.sql @@ -0,0 +1,29 @@ +-- AUTO-GENERATED FILE. + +-- This file is an auto-generated file by Ballerina persistence layer for model. +-- Please verify the generated scripts and execute them against the target DB server. + +DROP TABLE IF EXISTS `Car`; +DROP TABLE IF EXISTS `User`; + +CREATE TABLE `User` ( + `id` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `gender` ENUM('MALE', 'FEMALE') NOT NULL, + `nic` VARCHAR(191) NOT NULL, + `salary` DECIMAL(65,30), + PRIMARY KEY(`id`) +); + +CREATE TABLE `Car` ( + `id` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `model` VARCHAR(191) NOT NULL, + `ownerId` INT NOT NULL, + FOREIGN KEY(`ownerId`) REFERENCES `User`(`id`), + PRIMARY KEY(`id`) +); + + +CREATE INDEX `user_index` ON `User` (`id`, `nic`); +CREATE INDEX `ownerId` ON `Car` (`ownerId`); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_78/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_78/persist/model.bal new file mode 100644 index 000000000..fd547e035 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_78/persist/model.bal @@ -0,0 +1,44 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + @sql:Index {names: ["user_index"]} + readonly int id; + string name; + UserGender gender; + @sql:Index {names: ["user_index"]} + string nic; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_78/target/Persist.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_78/target/Persist.toml new file mode 100644 index 000000000..f5f1b02dc --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_78/target/Persist.toml @@ -0,0 +1,3 @@ +[[tool.persist]] +options.datastore = "mysql" +module = "tool_test_generate_78.entities" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_79/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_79/Ballerina.toml new file mode 100644 index 000000000..678546f22 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_79/Ballerina.toml @@ -0,0 +1,14 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_79" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +groupId = "io.ballerina.stdlib" +artifactId = "persist.sql-native" +version = "1.3.0-SNAPSHOT" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_79/Config.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_79/Config.toml new file mode 100644 index 000000000..3463ce5bc --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_79/Config.toml @@ -0,0 +1,7 @@ +[tool_test_generate_79.entities] +host = "localhost" +port = 3306 +user = "root" +password = "" +database = "" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_79/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_79/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_79/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_79/modules/entities/persist_client.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_79/modules/entities/persist_client.bal new file mode 100644 index 000000000..0a4782adf --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_79/modules/entities/persist_client.bal @@ -0,0 +1,164 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. +import ballerina/jballerina.java; +import ballerina/persist; +import ballerina/sql; +import ballerinax/mysql; +import ballerinax/mysql.driver as _; +import ballerinax/persist.sql as psql; + +const USER = "users"; +const CAR = "cars"; + +public isolated client class Client { + *persist:AbstractPersistClient; + + private final mysql:Client dbClient; + + private final map persistClients; + + private final record {|psql:SQLMetadata...;|} & readonly metadata = { + [USER]: { + entityName: "User", + tableName: "USERS", + fieldMetadata: { + id: {columnName: "ID"}, + name: {columnName: "name"}, + gender: {columnName: "gender"}, + nic: {columnName: "nic"}, + salary: {columnName: "salary"}, + "cars[].id": {relation: {entityName: "cars", refField: "id"}}, + "cars[].name": {relation: {entityName: "cars", refField: "name"}}, + "cars[].model": {relation: {entityName: "cars", refField: "model"}}, + "cars[].ownerId": {relation: {entityName: "cars", refField: "ownerId"}} + }, + keyFields: ["id"], + joinMetadata: {cars: {entity: Car, fieldName: "cars", refTable: "Car", refColumns: ["ownerId"], joinColumns: ["ID"], 'type: psql:MANY_TO_ONE}} + }, + [CAR]: { + entityName: "Car", + tableName: "Car", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + model: {columnName: "model"}, + ownerId: {columnName: "ownerId"}, + "user.id": {relation: {entityName: "user", refField: "id"}}, + "user.name": {relation: {entityName: "user", refField: "name"}}, + "user.gender": {relation: {entityName: "user", refField: "gender"}}, + "user.nic": {relation: {entityName: "user", refField: "nic"}}, + "user.salary": {relation: {entityName: "user", refField: "salary"}} + }, + keyFields: ["id"], + joinMetadata: {user: {entity: User, fieldName: "user", refTable: "USERS", refColumns: ["ID"], joinColumns: ["ownerId"], 'type: psql:ONE_TO_MANY}} + } + }; + + public isolated function init() returns persist:Error? { + mysql:Client|error dbClient = new (host = host, user = user, password = password, database = database, port = port, options = connectionOptions); + if dbClient is error { + return error(dbClient.message()); + } + self.dbClient = dbClient; + self.persistClients = { + [USER]: check new (dbClient, self.metadata.get(USER), psql:MYSQL_SPECIFICS), + [CAR]: check new (dbClient, self.metadata.get(CAR), psql:MYSQL_SPECIFICS) + }; + } + + isolated resource function get users(UserTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get users/[int id](UserTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post users(UserInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from UserInsert inserted in data + select inserted.id; + } + + isolated resource function put users/[int id](UserUpdate value) returns User|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/users/[id].get(); + } + + isolated resource function delete users/[int id]() returns User|persist:Error { + User result = check self->/users/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + isolated resource function get cars(CarTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get cars/[int id](CarTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post cars(CarInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from CarInsert inserted in data + select inserted.id; + } + + isolated resource function put cars/[int id](CarUpdate value) returns Car|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/cars/[id].get(); + } + + isolated resource function delete cars/[int id]() returns Car|persist:Error { + Car result = check self->/cars/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + remote isolated function queryNativeSQL(sql:ParameterizedQuery sqlQuery, typedesc rowType = <>) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + remote isolated function executeNativeSQL(sql:ParameterizedQuery sqlQuery) returns psql:ExecutionResult|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + public isolated function close() returns persist:Error? { + error? result = self.dbClient.close(); + if result is error { + return error(result.message()); + } + return result; + } +} + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_79/modules/entities/persist_db_config.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_79/modules/entities/persist_db_config.bal new file mode 100644 index 000000000..aedfe37e0 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_79/modules/entities/persist_db_config.bal @@ -0,0 +1,12 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer. +// It should not be modified by hand. +import ballerinax/mysql; + +configurable int port = ?; +configurable string host = ?; +configurable string user = ?; +configurable string database = ?; +configurable string password = ?; +configurable mysql:Options & readonly connectionOptions = {}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_79/modules/entities/persist_types.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_79/modules/entities/persist_types.bal new file mode 100644 index 000000000..c5cca4c1a --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_79/modules/entities/persist_types.bal @@ -0,0 +1,71 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. + +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; +|}; + +public type UserOptionalized record {| + int id?; + string name?; + UserGender gender?; + string nic?; + decimal? salary?; +|}; + +public type UserWithRelations record {| + *UserOptionalized; + CarOptionalized[] cars?; +|}; + +public type UserTargetType typedesc; + +public type UserInsert User; + +public type UserUpdate record {| + string name?; + UserGender gender?; + string nic?; + decimal? salary?; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + int ownerId; +|}; + +public type CarOptionalized record {| + int id?; + string name?; + string model?; + int ownerId?; +|}; + +public type CarWithRelations record {| + *CarOptionalized; + UserOptionalized user?; +|}; + +public type CarTargetType typedesc; + +public type CarInsert Car; + +public type CarUpdate record {| + string name?; + string model?; + int ownerId?; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_79/modules/entities/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_79/modules/entities/script.sql new file mode 100644 index 000000000..46defe3f3 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_79/modules/entities/script.sql @@ -0,0 +1,28 @@ +-- AUTO-GENERATED FILE. + +-- This file is an auto-generated file by Ballerina persistence layer for model. +-- Please verify the generated scripts and execute them against the target DB server. + +DROP TABLE IF EXISTS `Car`; +DROP TABLE IF EXISTS `USERS`; + +CREATE TABLE `USERS` ( + `ID` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `gender` ENUM('MALE', 'FEMALE') NOT NULL, + `nic` VARCHAR(191) NOT NULL, + `salary` DECIMAL(65,30), + PRIMARY KEY(`ID`) +); + +CREATE TABLE `Car` ( + `id` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `model` VARCHAR(191) NOT NULL, + `ownerId` INT NOT NULL, + FOREIGN KEY(`ownerId`) REFERENCES `USERS`(`ID`), + PRIMARY KEY(`id`) +); + + +CREATE INDEX `ownerId` ON `Car` (`ownerId`); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_79/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_79/persist/model.bal new file mode 100644 index 000000000..90b8803a3 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_79/persist/model.bal @@ -0,0 +1,44 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +@sql:Mapping {name: "USERS"} +public type User record {| + @sql:Mapping {name: "ID"} + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_79/target/Persist.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_79/target/Persist.toml new file mode 100644 index 000000000..6a727b1df --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_79/target/Persist.toml @@ -0,0 +1,3 @@ +[[tool.persist]] +options.datastore = "mysql" +module = "tool_test_generate_79.entities" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_8/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_8/Ballerina.toml index 912e3c449..8797e9489 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_8/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_8/Ballerina.toml @@ -10,5 +10,4 @@ observabilityIncluded = false [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" - +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_80/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_80/Ballerina.toml new file mode 100644 index 000000000..be03582e4 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_80/Ballerina.toml @@ -0,0 +1,14 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_80" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +groupId = "io.ballerina.stdlib" +artifactId = "persist.sql-native" +version = "1.3.0-SNAPSHOT" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_80/Config.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_80/Config.toml new file mode 100644 index 000000000..f2904990e --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_80/Config.toml @@ -0,0 +1,7 @@ +[tool_test_generate_80.entities] +host = "localhost" +port = 3306 +user = "root" +password = "" +database = "" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_80/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_80/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_80/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_80/modules/entities/persist_client.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_80/modules/entities/persist_client.bal new file mode 100644 index 000000000..5861fc85a --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_80/modules/entities/persist_client.bal @@ -0,0 +1,164 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. +import ballerina/jballerina.java; +import ballerina/persist; +import ballerina/sql; +import ballerinax/mysql; +import ballerinax/mysql.driver as _; +import ballerinax/persist.sql as psql; + +const USER = "users"; +const CAR = "cars"; + +public isolated client class Client { + *persist:AbstractPersistClient; + + private final mysql:Client dbClient; + + private final map persistClients; + + private final record {|psql:SQLMetadata...;|} & readonly metadata = { + [USER]: { + entityName: "User", + tableName: "USERS", + fieldMetadata: { + id: {columnName: "ID"}, + name: {columnName: "name"}, + gender: {columnName: "gender"}, + nic: {columnName: "nic"}, + salary: {columnName: "salary"}, + "cars[].id": {relation: {entityName: "cars", refField: "id"}}, + "cars[].name": {relation: {entityName: "cars", refField: "name"}}, + "cars[].model": {relation: {entityName: "cars", refField: "model"}}, + "cars[].ownerId": {relation: {entityName: "cars", refField: "ownerId"}} + }, + keyFields: ["id"], + joinMetadata: {cars: {entity: Car, fieldName: "cars", refTable: "Car", refColumns: ["OWNER_ID"], joinColumns: ["ID"], 'type: psql:MANY_TO_ONE}} + }, + [CAR]: { + entityName: "Car", + tableName: "Car", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + model: {columnName: "model"}, + ownerId: {columnName: "OWNER_ID"}, + "user.id": {relation: {entityName: "user", refField: "id"}}, + "user.name": {relation: {entityName: "user", refField: "name"}}, + "user.gender": {relation: {entityName: "user", refField: "gender"}}, + "user.nic": {relation: {entityName: "user", refField: "nic"}}, + "user.salary": {relation: {entityName: "user", refField: "salary"}} + }, + keyFields: ["id"], + joinMetadata: {user: {entity: User, fieldName: "user", refTable: "USERS", refColumns: ["ID"], joinColumns: ["OWNER_ID"], 'type: psql:ONE_TO_MANY}} + } + }; + + public isolated function init() returns persist:Error? { + mysql:Client|error dbClient = new (host = host, user = user, password = password, database = database, port = port, options = connectionOptions); + if dbClient is error { + return error(dbClient.message()); + } + self.dbClient = dbClient; + self.persistClients = { + [USER]: check new (dbClient, self.metadata.get(USER), psql:MYSQL_SPECIFICS), + [CAR]: check new (dbClient, self.metadata.get(CAR), psql:MYSQL_SPECIFICS) + }; + } + + isolated resource function get users(UserTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get users/[int id](UserTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post users(UserInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from UserInsert inserted in data + select inserted.id; + } + + isolated resource function put users/[int id](UserUpdate value) returns User|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/users/[id].get(); + } + + isolated resource function delete users/[int id]() returns User|persist:Error { + User result = check self->/users/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + isolated resource function get cars(CarTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get cars/[int id](CarTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post cars(CarInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from CarInsert inserted in data + select inserted.id; + } + + isolated resource function put cars/[int id](CarUpdate value) returns Car|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/cars/[id].get(); + } + + isolated resource function delete cars/[int id]() returns Car|persist:Error { + Car result = check self->/cars/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + remote isolated function queryNativeSQL(sql:ParameterizedQuery sqlQuery, typedesc rowType = <>) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + remote isolated function executeNativeSQL(sql:ParameterizedQuery sqlQuery) returns psql:ExecutionResult|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + public isolated function close() returns persist:Error? { + error? result = self.dbClient.close(); + if result is error { + return error(result.message()); + } + return result; + } +} + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_80/modules/entities/persist_db_config.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_80/modules/entities/persist_db_config.bal new file mode 100644 index 000000000..aedfe37e0 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_80/modules/entities/persist_db_config.bal @@ -0,0 +1,12 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer. +// It should not be modified by hand. +import ballerinax/mysql; + +configurable int port = ?; +configurable string host = ?; +configurable string user = ?; +configurable string database = ?; +configurable string password = ?; +configurable mysql:Options & readonly connectionOptions = {}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_80/modules/entities/persist_types.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_80/modules/entities/persist_types.bal new file mode 100644 index 000000000..c5cca4c1a --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_80/modules/entities/persist_types.bal @@ -0,0 +1,71 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. + +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; +|}; + +public type UserOptionalized record {| + int id?; + string name?; + UserGender gender?; + string nic?; + decimal? salary?; +|}; + +public type UserWithRelations record {| + *UserOptionalized; + CarOptionalized[] cars?; +|}; + +public type UserTargetType typedesc; + +public type UserInsert User; + +public type UserUpdate record {| + string name?; + UserGender gender?; + string nic?; + decimal? salary?; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + int ownerId; +|}; + +public type CarOptionalized record {| + int id?; + string name?; + string model?; + int ownerId?; +|}; + +public type CarWithRelations record {| + *CarOptionalized; + UserOptionalized user?; +|}; + +public type CarTargetType typedesc; + +public type CarInsert Car; + +public type CarUpdate record {| + string name?; + string model?; + int ownerId?; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_80/modules/entities/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_80/modules/entities/script.sql new file mode 100644 index 000000000..c51f8fe0d --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_80/modules/entities/script.sql @@ -0,0 +1,28 @@ +-- AUTO-GENERATED FILE. + +-- This file is an auto-generated file by Ballerina persistence layer for model. +-- Please verify the generated scripts and execute them against the target DB server. + +DROP TABLE IF EXISTS `Car`; +DROP TABLE IF EXISTS `USERS`; + +CREATE TABLE `USERS` ( + `ID` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `gender` ENUM('MALE', 'FEMALE') NOT NULL, + `nic` VARCHAR(191) NOT NULL, + `salary` DECIMAL(65,30), + PRIMARY KEY(`ID`) +); + +CREATE TABLE `Car` ( + `id` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `model` VARCHAR(191) NOT NULL, + `OWNER_ID` INT NOT NULL, + FOREIGN KEY(`OWNER_ID`) REFERENCES `USERS`(`ID`), + PRIMARY KEY(`id`) +); + + +CREATE INDEX `ownerId` ON `Car` (`OWNER_ID`); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_80/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_80/persist/model.bal new file mode 100644 index 000000000..06fa197db --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_80/persist/model.bal @@ -0,0 +1,45 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +@sql:Mapping {name: "USERS"} +public type User record {| + @sql:Mapping {name: "ID"} + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Mapping {name: "OWNER_ID"} + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_80/target/Persist.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_80/target/Persist.toml new file mode 100644 index 000000000..e6f4c407e --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_80/target/Persist.toml @@ -0,0 +1,3 @@ +[[tool.persist]] +options.datastore = "mysql" +module = "tool_test_generate_80.entities" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_81/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_81/Ballerina.toml new file mode 100644 index 000000000..4c15ca01e --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_81/Ballerina.toml @@ -0,0 +1,14 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_81" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +groupId = "io.ballerina.stdlib" +artifactId = "persist.sql-native" +version = "1.3.0-SNAPSHOT" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_81/Config.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_81/Config.toml new file mode 100644 index 000000000..a983eb370 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_81/Config.toml @@ -0,0 +1,7 @@ +[tool_test_generate_81.entities] +host = "localhost" +port = 3306 +user = "root" +password = "" +database = "" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_81/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_81/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_81/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_81/modules/entities/persist_client.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_81/modules/entities/persist_client.bal new file mode 100644 index 000000000..b27aed3ed --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_81/modules/entities/persist_client.bal @@ -0,0 +1,166 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. +import ballerina/jballerina.java; +import ballerina/persist; +import ballerina/sql; +import ballerinax/mysql; +import ballerinax/mysql.driver as _; +import ballerinax/persist.sql as psql; + +const USER = "users"; +const CAR = "cars"; + +public isolated client class Client { + *persist:AbstractPersistClient; + + private final mysql:Client dbClient; + + private final map persistClients; + + private final record {|psql:SQLMetadata...;|} & readonly metadata = { + [USER]: { + entityName: "User", + tableName: "User", + fieldMetadata: { + id: {columnName: "id"}, + nic: {columnName: "nic"}, + name: {columnName: "name"}, + gender: {columnName: "gender"}, + salary: {columnName: "salary"}, + "cars[].id": {relation: {entityName: "cars", refField: "id"}}, + "cars[].name": {relation: {entityName: "cars", refField: "name"}}, + "cars[].model": {relation: {entityName: "cars", refField: "model"}}, + "cars[].ownerId": {relation: {entityName: "cars", refField: "ownerId"}}, + "cars[].ownerNic": {relation: {entityName: "cars", refField: "ownerNic"}} + }, + keyFields: ["id", "nic"], + joinMetadata: {cars: {entity: Car, fieldName: "cars", refTable: "Car", refColumns: ["ownerId", "ownerNic"], joinColumns: ["id", "nic"], 'type: psql:MANY_TO_ONE}} + }, + [CAR]: { + entityName: "Car", + tableName: "Car", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + model: {columnName: "model"}, + ownerId: {columnName: "ownerId"}, + ownerNic: {columnName: "ownerNic"}, + "user.id": {relation: {entityName: "user", refField: "id"}}, + "user.nic": {relation: {entityName: "user", refField: "nic"}}, + "user.name": {relation: {entityName: "user", refField: "name"}}, + "user.gender": {relation: {entityName: "user", refField: "gender"}}, + "user.salary": {relation: {entityName: "user", refField: "salary"}} + }, + keyFields: ["id"], + joinMetadata: {user: {entity: User, fieldName: "user", refTable: "User", refColumns: ["id", "nic"], joinColumns: ["ownerId", "ownerNic"], 'type: psql:ONE_TO_MANY}} + } + }; + + public isolated function init() returns persist:Error? { + mysql:Client|error dbClient = new (host = host, user = user, password = password, database = database, port = port, options = connectionOptions); + if dbClient is error { + return error(dbClient.message()); + } + self.dbClient = dbClient; + self.persistClients = { + [USER]: check new (dbClient, self.metadata.get(USER), psql:MYSQL_SPECIFICS), + [CAR]: check new (dbClient, self.metadata.get(CAR), psql:MYSQL_SPECIFICS) + }; + } + + isolated resource function get users(UserTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get users/[int id]/[string nic](UserTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post users(UserInsert[] data) returns [int, string][]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from UserInsert inserted in data + select [inserted.id, inserted.nic]; + } + + isolated resource function put users/[int id]/[string nic](UserUpdate value) returns User|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runUpdateQuery({"id": id, "nic": nic}, value); + return self->/users/[id]/[nic].get(); + } + + isolated resource function delete users/[int id]/[string nic]() returns User|persist:Error { + User result = check self->/users/[id]/[nic].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runDeleteQuery({"id": id, "nic": nic}); + return result; + } + + isolated resource function get cars(CarTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get cars/[int id](CarTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post cars(CarInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from CarInsert inserted in data + select inserted.id; + } + + isolated resource function put cars/[int id](CarUpdate value) returns Car|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/cars/[id].get(); + } + + isolated resource function delete cars/[int id]() returns Car|persist:Error { + Car result = check self->/cars/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + remote isolated function queryNativeSQL(sql:ParameterizedQuery sqlQuery, typedesc rowType = <>) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + remote isolated function executeNativeSQL(sql:ParameterizedQuery sqlQuery) returns psql:ExecutionResult|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + public isolated function close() returns persist:Error? { + error? result = self.dbClient.close(); + if result is error { + return error(result.message()); + } + return result; + } +} + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_81/modules/entities/persist_db_config.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_81/modules/entities/persist_db_config.bal new file mode 100644 index 000000000..aedfe37e0 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_81/modules/entities/persist_db_config.bal @@ -0,0 +1,12 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer. +// It should not be modified by hand. +import ballerinax/mysql; + +configurable int port = ?; +configurable string host = ?; +configurable string user = ?; +configurable string database = ?; +configurable string password = ?; +configurable mysql:Options & readonly connectionOptions = {}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_81/modules/entities/persist_types.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_81/modules/entities/persist_types.bal new file mode 100644 index 000000000..ab94b2786 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_81/modules/entities/persist_types.bal @@ -0,0 +1,73 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. + +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + readonly string nic; + string name; + UserGender gender; + decimal? salary; +|}; + +public type UserOptionalized record {| + int id?; + string nic?; + string name?; + UserGender gender?; + decimal? salary?; +|}; + +public type UserWithRelations record {| + *UserOptionalized; + CarOptionalized[] cars?; +|}; + +public type UserTargetType typedesc; + +public type UserInsert User; + +public type UserUpdate record {| + string name?; + UserGender gender?; + decimal? salary?; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + int ownerId; + string ownerNic; +|}; + +public type CarOptionalized record {| + int id?; + string name?; + string model?; + int ownerId?; + string ownerNic?; +|}; + +public type CarWithRelations record {| + *CarOptionalized; + UserOptionalized user?; +|}; + +public type CarTargetType typedesc; + +public type CarInsert Car; + +public type CarUpdate record {| + string name?; + string model?; + int ownerId?; + string ownerNic?; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_81/modules/entities/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_81/modules/entities/script.sql new file mode 100644 index 000000000..011b40505 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_81/modules/entities/script.sql @@ -0,0 +1,30 @@ +-- AUTO-GENERATED FILE. + +-- This file is an auto-generated file by Ballerina persistence layer for model. +-- Please verify the generated scripts and execute them against the target DB server. + +DROP TABLE IF EXISTS `Car`; +DROP TABLE IF EXISTS `User`; + +CREATE TABLE `User` ( + `id` INT NOT NULL, + `nic` VARCHAR(191) NOT NULL, + `name` VARCHAR(191) NOT NULL, + `gender` ENUM('MALE', 'FEMALE') NOT NULL, + `salary` DECIMAL(65,30), + PRIMARY KEY(`id`,`nic`) +); + +CREATE TABLE `Car` ( + `id` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `model` VARCHAR(191) NOT NULL, + `ownerId` INT NOT NULL, + `ownerNic` VARCHAR(191) NOT NULL, + FOREIGN KEY(`ownerId`, `ownerNic`) REFERENCES `User`(`id`, `nic`), + PRIMARY KEY(`id`) +); + + +CREATE INDEX `ownerId` ON `Car` (`ownerId`); +CREATE INDEX `ownerNic` ON `Car` (`ownerNic`); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_81/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_81/persist/model.bal new file mode 100644 index 000000000..30c27be35 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_81/persist/model.bal @@ -0,0 +1,44 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + readonly string nic; + string name; + UserGender gender; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Index {names: ["ownerNic"]} + string ownerNic; + @sql:Relation {refs: ["ownerId", "ownerNic"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_81/target/Persist.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_81/target/Persist.toml new file mode 100644 index 000000000..fa2599f36 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_81/target/Persist.toml @@ -0,0 +1,3 @@ +[[tool.persist]] +options.datastore = "mysql" +module = "tool_test_generate_81.entities" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_82/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_82/Ballerina.toml new file mode 100644 index 000000000..4d2da0cfd --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_82/Ballerina.toml @@ -0,0 +1,14 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_82" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +groupId = "io.ballerina.stdlib" +artifactId = "persist.sql-native" +version = "1.3.0-SNAPSHOT" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_82/Config.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_82/Config.toml new file mode 100644 index 000000000..1fa885e80 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_82/Config.toml @@ -0,0 +1,7 @@ +[tool_test_generate_82.entities] +host = "localhost" +port = 3306 +user = "root" +password = "" +database = "" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_82/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_82/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_82/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_82/modules/entities/persist_client.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_82/modules/entities/persist_client.bal new file mode 100644 index 000000000..b3282aa45 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_82/modules/entities/persist_client.bal @@ -0,0 +1,166 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. +import ballerina/jballerina.java; +import ballerina/persist; +import ballerina/sql; +import ballerinax/mysql; +import ballerinax/mysql.driver as _; +import ballerinax/persist.sql as psql; + +const USER = "users"; +const CAR = "cars"; + +public isolated client class Client { + *persist:AbstractPersistClient; + + private final mysql:Client dbClient; + + private final map persistClients; + + private final record {|psql:SQLMetadata...;|} & readonly metadata = { + [USER]: { + entityName: "User", + tableName: "User", + fieldMetadata: { + id: {columnName: "id"}, + nic: {columnName: "nic"}, + name: {columnName: "name"}, + gender: {columnName: "gender"}, + salary: {columnName: "salary"}, + "cars[].id": {relation: {entityName: "cars", refField: "id"}}, + "cars[].name": {relation: {entityName: "cars", refField: "name"}}, + "cars[].model": {relation: {entityName: "cars", refField: "model"}}, + "cars[].ownerId": {relation: {entityName: "cars", refField: "ownerId"}}, + "cars[].ownerNic": {relation: {entityName: "cars", refField: "ownerNic"}} + }, + keyFields: ["id", "nic"], + joinMetadata: {cars: {entity: Car, fieldName: "cars", refTable: "Car", refColumns: ["ownerId", "OWNER_NIC"], joinColumns: ["id", "nic"], 'type: psql:MANY_TO_ONE}} + }, + [CAR]: { + entityName: "Car", + tableName: "Car", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + model: {columnName: "model"}, + ownerId: {columnName: "ownerId"}, + ownerNic: {columnName: "OWNER_NIC"}, + "user.id": {relation: {entityName: "user", refField: "id"}}, + "user.nic": {relation: {entityName: "user", refField: "nic"}}, + "user.name": {relation: {entityName: "user", refField: "name"}}, + "user.gender": {relation: {entityName: "user", refField: "gender"}}, + "user.salary": {relation: {entityName: "user", refField: "salary"}} + }, + keyFields: ["id"], + joinMetadata: {user: {entity: User, fieldName: "user", refTable: "User", refColumns: ["id", "nic"], joinColumns: ["ownerId", "OWNER_NIC"], 'type: psql:ONE_TO_MANY}} + } + }; + + public isolated function init() returns persist:Error? { + mysql:Client|error dbClient = new (host = host, user = user, password = password, database = database, port = port, options = connectionOptions); + if dbClient is error { + return error(dbClient.message()); + } + self.dbClient = dbClient; + self.persistClients = { + [USER]: check new (dbClient, self.metadata.get(USER), psql:MYSQL_SPECIFICS), + [CAR]: check new (dbClient, self.metadata.get(CAR), psql:MYSQL_SPECIFICS) + }; + } + + isolated resource function get users(UserTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get users/[int id]/[string nic](UserTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post users(UserInsert[] data) returns [int, string][]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from UserInsert inserted in data + select [inserted.id, inserted.nic]; + } + + isolated resource function put users/[int id]/[string nic](UserUpdate value) returns User|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runUpdateQuery({"id": id, "nic": nic}, value); + return self->/users/[id]/[nic].get(); + } + + isolated resource function delete users/[int id]/[string nic]() returns User|persist:Error { + User result = check self->/users/[id]/[nic].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runDeleteQuery({"id": id, "nic": nic}); + return result; + } + + isolated resource function get cars(CarTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get cars/[int id](CarTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post cars(CarInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from CarInsert inserted in data + select inserted.id; + } + + isolated resource function put cars/[int id](CarUpdate value) returns Car|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/cars/[id].get(); + } + + isolated resource function delete cars/[int id]() returns Car|persist:Error { + Car result = check self->/cars/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + remote isolated function queryNativeSQL(sql:ParameterizedQuery sqlQuery, typedesc rowType = <>) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + remote isolated function executeNativeSQL(sql:ParameterizedQuery sqlQuery) returns psql:ExecutionResult|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + public isolated function close() returns persist:Error? { + error? result = self.dbClient.close(); + if result is error { + return error(result.message()); + } + return result; + } +} + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_82/modules/entities/persist_db_config.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_82/modules/entities/persist_db_config.bal new file mode 100644 index 000000000..aedfe37e0 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_82/modules/entities/persist_db_config.bal @@ -0,0 +1,12 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer. +// It should not be modified by hand. +import ballerinax/mysql; + +configurable int port = ?; +configurable string host = ?; +configurable string user = ?; +configurable string database = ?; +configurable string password = ?; +configurable mysql:Options & readonly connectionOptions = {}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_82/modules/entities/persist_types.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_82/modules/entities/persist_types.bal new file mode 100644 index 000000000..ab94b2786 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_82/modules/entities/persist_types.bal @@ -0,0 +1,73 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. + +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + readonly string nic; + string name; + UserGender gender; + decimal? salary; +|}; + +public type UserOptionalized record {| + int id?; + string nic?; + string name?; + UserGender gender?; + decimal? salary?; +|}; + +public type UserWithRelations record {| + *UserOptionalized; + CarOptionalized[] cars?; +|}; + +public type UserTargetType typedesc; + +public type UserInsert User; + +public type UserUpdate record {| + string name?; + UserGender gender?; + decimal? salary?; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + int ownerId; + string ownerNic; +|}; + +public type CarOptionalized record {| + int id?; + string name?; + string model?; + int ownerId?; + string ownerNic?; +|}; + +public type CarWithRelations record {| + *CarOptionalized; + UserOptionalized user?; +|}; + +public type CarTargetType typedesc; + +public type CarInsert Car; + +public type CarUpdate record {| + string name?; + string model?; + int ownerId?; + string ownerNic?; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_82/modules/entities/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_82/modules/entities/script.sql new file mode 100644 index 000000000..ac1492256 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_82/modules/entities/script.sql @@ -0,0 +1,30 @@ +-- AUTO-GENERATED FILE. + +-- This file is an auto-generated file by Ballerina persistence layer for model. +-- Please verify the generated scripts and execute them against the target DB server. + +DROP TABLE IF EXISTS `Car`; +DROP TABLE IF EXISTS `User`; + +CREATE TABLE `User` ( + `id` INT NOT NULL, + `nic` VARCHAR(191) NOT NULL, + `name` VARCHAR(191) NOT NULL, + `gender` ENUM('MALE', 'FEMALE') NOT NULL, + `salary` DECIMAL(65,30), + PRIMARY KEY(`id`,`nic`) +); + +CREATE TABLE `Car` ( + `id` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `model` VARCHAR(191) NOT NULL, + `ownerId` INT NOT NULL, + `OWNER_NIC` VARCHAR(191) NOT NULL, + FOREIGN KEY(`ownerId`, `OWNER_NIC`) REFERENCES `User`(`id`, `nic`), + PRIMARY KEY(`id`) +); + + +CREATE INDEX `ownerId` ON `Car` (`ownerId`); +CREATE INDEX `ownerNic` ON `Car` (`OWNER_NIC`); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_82/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_82/persist/model.bal new file mode 100644 index 000000000..d1e7eaa4c --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_82/persist/model.bal @@ -0,0 +1,45 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + readonly string nic; + string name; + UserGender gender; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Mapping {name: "OWNER_NIC"} + @sql:Index {names: ["ownerNic"]} + string ownerNic; + @sql:Relation {refs: ["ownerId", "ownerNic"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_82/target/Persist.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_82/target/Persist.toml new file mode 100644 index 000000000..f640e6a43 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_82/target/Persist.toml @@ -0,0 +1,3 @@ +[[tool.persist]] +options.datastore = "mysql" +module = "tool_test_generate_82.entities" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_83/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_83/Ballerina.toml new file mode 100644 index 000000000..5b6c32463 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_83/Ballerina.toml @@ -0,0 +1,14 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_83" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +groupId = "io.ballerina.stdlib" +artifactId = "persist.sql-native" +version = "1.3.0-SNAPSHOT" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_83/Config.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_83/Config.toml new file mode 100644 index 000000000..b395fdb63 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_83/Config.toml @@ -0,0 +1,7 @@ +[tool_test_generate_83.entities] +host = "localhost" +port = 3306 +user = "root" +password = "" +database = "" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_83/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_83/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_83/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_83/modules/entities/persist_client.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_83/modules/entities/persist_client.bal new file mode 100644 index 000000000..d87f9cfd0 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_83/modules/entities/persist_client.bal @@ -0,0 +1,166 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. +import ballerina/jballerina.java; +import ballerina/persist; +import ballerina/sql; +import ballerinax/mysql; +import ballerinax/mysql.driver as _; +import ballerinax/persist.sql as psql; + +const USER = "users"; +const CAR = "cars"; + +public isolated client class Client { + *persist:AbstractPersistClient; + + private final mysql:Client dbClient; + + private final map persistClients; + + private final record {|psql:SQLMetadata...;|} & readonly metadata = { + [USER]: { + entityName: "User", + tableName: "User", + fieldMetadata: { + id: {columnName: "id"}, + nic: {columnName: "nic"}, + name: {columnName: "name"}, + gender: {columnName: "gender"}, + salary: {columnName: "salary"}, + "cars[].id": {relation: {entityName: "cars", refField: "id"}}, + "cars[].name": {relation: {entityName: "cars", refField: "name"}}, + "cars[].model": {relation: {entityName: "cars", refField: "model"}}, + "cars[].ownerId": {relation: {entityName: "cars", refField: "ownerId"}}, + "cars[].ownerNic": {relation: {entityName: "cars", refField: "ownerNic"}} + }, + keyFields: ["id", "nic"], + joinMetadata: {cars: {entity: Car, fieldName: "cars", refTable: "Car", refColumns: ["OWNER_ID", "OWNER_NIC"], joinColumns: ["id", "nic"], 'type: psql:MANY_TO_ONE}} + }, + [CAR]: { + entityName: "Car", + tableName: "Car", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + model: {columnName: "model"}, + ownerId: {columnName: "OWNER_ID"}, + ownerNic: {columnName: "OWNER_NIC"}, + "user.id": {relation: {entityName: "user", refField: "id"}}, + "user.nic": {relation: {entityName: "user", refField: "nic"}}, + "user.name": {relation: {entityName: "user", refField: "name"}}, + "user.gender": {relation: {entityName: "user", refField: "gender"}}, + "user.salary": {relation: {entityName: "user", refField: "salary"}} + }, + keyFields: ["id"], + joinMetadata: {user: {entity: User, fieldName: "user", refTable: "User", refColumns: ["id", "nic"], joinColumns: ["OWNER_ID", "OWNER_NIC"], 'type: psql:ONE_TO_MANY}} + } + }; + + public isolated function init() returns persist:Error? { + mysql:Client|error dbClient = new (host = host, user = user, password = password, database = database, port = port, options = connectionOptions); + if dbClient is error { + return error(dbClient.message()); + } + self.dbClient = dbClient; + self.persistClients = { + [USER]: check new (dbClient, self.metadata.get(USER), psql:MYSQL_SPECIFICS), + [CAR]: check new (dbClient, self.metadata.get(CAR), psql:MYSQL_SPECIFICS) + }; + } + + isolated resource function get users(UserTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get users/[int id]/[string nic](UserTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post users(UserInsert[] data) returns [int, string][]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from UserInsert inserted in data + select [inserted.id, inserted.nic]; + } + + isolated resource function put users/[int id]/[string nic](UserUpdate value) returns User|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runUpdateQuery({"id": id, "nic": nic}, value); + return self->/users/[id]/[nic].get(); + } + + isolated resource function delete users/[int id]/[string nic]() returns User|persist:Error { + User result = check self->/users/[id]/[nic].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runDeleteQuery({"id": id, "nic": nic}); + return result; + } + + isolated resource function get cars(CarTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get cars/[int id](CarTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post cars(CarInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from CarInsert inserted in data + select inserted.id; + } + + isolated resource function put cars/[int id](CarUpdate value) returns Car|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/cars/[id].get(); + } + + isolated resource function delete cars/[int id]() returns Car|persist:Error { + Car result = check self->/cars/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + remote isolated function queryNativeSQL(sql:ParameterizedQuery sqlQuery, typedesc rowType = <>) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + remote isolated function executeNativeSQL(sql:ParameterizedQuery sqlQuery) returns psql:ExecutionResult|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + public isolated function close() returns persist:Error? { + error? result = self.dbClient.close(); + if result is error { + return error(result.message()); + } + return result; + } +} + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_83/modules/entities/persist_db_config.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_83/modules/entities/persist_db_config.bal new file mode 100644 index 000000000..aedfe37e0 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_83/modules/entities/persist_db_config.bal @@ -0,0 +1,12 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer. +// It should not be modified by hand. +import ballerinax/mysql; + +configurable int port = ?; +configurable string host = ?; +configurable string user = ?; +configurable string database = ?; +configurable string password = ?; +configurable mysql:Options & readonly connectionOptions = {}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_83/modules/entities/persist_types.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_83/modules/entities/persist_types.bal new file mode 100644 index 000000000..ab94b2786 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_83/modules/entities/persist_types.bal @@ -0,0 +1,73 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. + +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + readonly string nic; + string name; + UserGender gender; + decimal? salary; +|}; + +public type UserOptionalized record {| + int id?; + string nic?; + string name?; + UserGender gender?; + decimal? salary?; +|}; + +public type UserWithRelations record {| + *UserOptionalized; + CarOptionalized[] cars?; +|}; + +public type UserTargetType typedesc; + +public type UserInsert User; + +public type UserUpdate record {| + string name?; + UserGender gender?; + decimal? salary?; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + int ownerId; + string ownerNic; +|}; + +public type CarOptionalized record {| + int id?; + string name?; + string model?; + int ownerId?; + string ownerNic?; +|}; + +public type CarWithRelations record {| + *CarOptionalized; + UserOptionalized user?; +|}; + +public type CarTargetType typedesc; + +public type CarInsert Car; + +public type CarUpdate record {| + string name?; + string model?; + int ownerId?; + string ownerNic?; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_83/modules/entities/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_83/modules/entities/script.sql new file mode 100644 index 000000000..11b271763 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_83/modules/entities/script.sql @@ -0,0 +1,30 @@ +-- AUTO-GENERATED FILE. + +-- This file is an auto-generated file by Ballerina persistence layer for model. +-- Please verify the generated scripts and execute them against the target DB server. + +DROP TABLE IF EXISTS `Car`; +DROP TABLE IF EXISTS `User`; + +CREATE TABLE `User` ( + `id` INT NOT NULL, + `nic` VARCHAR(191) NOT NULL, + `name` VARCHAR(191) NOT NULL, + `gender` ENUM('MALE', 'FEMALE') NOT NULL, + `salary` DECIMAL(65,30), + PRIMARY KEY(`id`,`nic`) +); + +CREATE TABLE `Car` ( + `id` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `model` VARCHAR(191) NOT NULL, + `OWNER_ID` INT NOT NULL, + `OWNER_NIC` VARCHAR(191) NOT NULL, + FOREIGN KEY(`OWNER_ID`, `OWNER_NIC`) REFERENCES `User`(`id`, `nic`), + PRIMARY KEY(`id`) +); + + +CREATE INDEX `ownerId` ON `Car` (`OWNER_ID`); +CREATE INDEX `ownerNic` ON `Car` (`OWNER_NIC`); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_83/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_83/persist/model.bal new file mode 100644 index 000000000..041af492b --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_83/persist/model.bal @@ -0,0 +1,46 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + readonly string nic; + string name; + UserGender gender; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Mapping {name: "OWNER_ID"} + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Mapping {name: "OWNER_NIC"} + @sql:Index {names: ["ownerNic"]} + string ownerNic; + @sql:Relation {refs: ["ownerId", "ownerNic"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_83/target/Persist.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_83/target/Persist.toml new file mode 100644 index 000000000..2339aa1ea --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_83/target/Persist.toml @@ -0,0 +1,3 @@ +[[tool.persist]] +options.datastore = "mysql" +module = "tool_test_generate_83.entities" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_84/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_84/Ballerina.toml new file mode 100644 index 000000000..39d9f8609 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_84/Ballerina.toml @@ -0,0 +1,14 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_84" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +groupId = "io.ballerina.stdlib" +artifactId = "persist.sql-native" +version = "1.3.0-SNAPSHOT" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_84/Config.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_84/Config.toml new file mode 100644 index 000000000..2e50bc4e2 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_84/Config.toml @@ -0,0 +1,7 @@ +[tool_test_generate_84.entities] +host = "localhost" +port = 3306 +user = "root" +password = "" +database = "" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_84/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_84/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_84/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_84/modules/entities/persist_client.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_84/modules/entities/persist_client.bal new file mode 100644 index 000000000..f129ebc6b --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_84/modules/entities/persist_client.bal @@ -0,0 +1,166 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. +import ballerina/jballerina.java; +import ballerina/persist; +import ballerina/sql; +import ballerinax/mysql; +import ballerinax/mysql.driver as _; +import ballerinax/persist.sql as psql; + +const USER = "users"; +const CAR = "cars"; + +public isolated client class Client { + *persist:AbstractPersistClient; + + private final mysql:Client dbClient; + + private final map persistClients; + + private final record {|psql:SQLMetadata...;|} & readonly metadata = { + [USER]: { + entityName: "User", + tableName: "User", + fieldMetadata: { + id: {columnName: "id"}, + nic: {columnName: "NIC"}, + name: {columnName: "name"}, + gender: {columnName: "gender"}, + salary: {columnName: "salary"}, + "cars[].id": {relation: {entityName: "cars", refField: "id"}}, + "cars[].name": {relation: {entityName: "cars", refField: "name"}}, + "cars[].model": {relation: {entityName: "cars", refField: "model"}}, + "cars[].ownerId": {relation: {entityName: "cars", refField: "ownerId"}}, + "cars[].ownerNic": {relation: {entityName: "cars", refField: "ownerNic"}} + }, + keyFields: ["id", "nic"], + joinMetadata: {cars: {entity: Car, fieldName: "cars", refTable: "Car", refColumns: ["OWNER_ID", "OWNER_NIC"], joinColumns: ["id", "NIC"], 'type: psql:MANY_TO_ONE}} + }, + [CAR]: { + entityName: "Car", + tableName: "Car", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + model: {columnName: "model"}, + ownerId: {columnName: "OWNER_ID"}, + ownerNic: {columnName: "OWNER_NIC"}, + "user.id": {relation: {entityName: "user", refField: "id"}}, + "user.nic": {relation: {entityName: "user", refField: "nic"}}, + "user.name": {relation: {entityName: "user", refField: "name"}}, + "user.gender": {relation: {entityName: "user", refField: "gender"}}, + "user.salary": {relation: {entityName: "user", refField: "salary"}} + }, + keyFields: ["id"], + joinMetadata: {user: {entity: User, fieldName: "user", refTable: "User", refColumns: ["id", "NIC"], joinColumns: ["OWNER_ID", "OWNER_NIC"], 'type: psql:ONE_TO_MANY}} + } + }; + + public isolated function init() returns persist:Error? { + mysql:Client|error dbClient = new (host = host, user = user, password = password, database = database, port = port, options = connectionOptions); + if dbClient is error { + return error(dbClient.message()); + } + self.dbClient = dbClient; + self.persistClients = { + [USER]: check new (dbClient, self.metadata.get(USER), psql:MYSQL_SPECIFICS), + [CAR]: check new (dbClient, self.metadata.get(CAR), psql:MYSQL_SPECIFICS) + }; + } + + isolated resource function get users(UserTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get users/[int id]/[string nic](UserTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post users(UserInsert[] data) returns [int, string][]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from UserInsert inserted in data + select [inserted.id, inserted.nic]; + } + + isolated resource function put users/[int id]/[string nic](UserUpdate value) returns User|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runUpdateQuery({"id": id, "nic": nic}, value); + return self->/users/[id]/[nic].get(); + } + + isolated resource function delete users/[int id]/[string nic]() returns User|persist:Error { + User result = check self->/users/[id]/[nic].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runDeleteQuery({"id": id, "nic": nic}); + return result; + } + + isolated resource function get cars(CarTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get cars/[int id](CarTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post cars(CarInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from CarInsert inserted in data + select inserted.id; + } + + isolated resource function put cars/[int id](CarUpdate value) returns Car|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/cars/[id].get(); + } + + isolated resource function delete cars/[int id]() returns Car|persist:Error { + Car result = check self->/cars/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + remote isolated function queryNativeSQL(sql:ParameterizedQuery sqlQuery, typedesc rowType = <>) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + remote isolated function executeNativeSQL(sql:ParameterizedQuery sqlQuery) returns psql:ExecutionResult|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + public isolated function close() returns persist:Error? { + error? result = self.dbClient.close(); + if result is error { + return error(result.message()); + } + return result; + } +} + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_84/modules/entities/persist_db_config.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_84/modules/entities/persist_db_config.bal new file mode 100644 index 000000000..aedfe37e0 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_84/modules/entities/persist_db_config.bal @@ -0,0 +1,12 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer. +// It should not be modified by hand. +import ballerinax/mysql; + +configurable int port = ?; +configurable string host = ?; +configurable string user = ?; +configurable string database = ?; +configurable string password = ?; +configurable mysql:Options & readonly connectionOptions = {}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_84/modules/entities/persist_types.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_84/modules/entities/persist_types.bal new file mode 100644 index 000000000..ab94b2786 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_84/modules/entities/persist_types.bal @@ -0,0 +1,73 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. + +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + readonly string nic; + string name; + UserGender gender; + decimal? salary; +|}; + +public type UserOptionalized record {| + int id?; + string nic?; + string name?; + UserGender gender?; + decimal? salary?; +|}; + +public type UserWithRelations record {| + *UserOptionalized; + CarOptionalized[] cars?; +|}; + +public type UserTargetType typedesc; + +public type UserInsert User; + +public type UserUpdate record {| + string name?; + UserGender gender?; + decimal? salary?; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + int ownerId; + string ownerNic; +|}; + +public type CarOptionalized record {| + int id?; + string name?; + string model?; + int ownerId?; + string ownerNic?; +|}; + +public type CarWithRelations record {| + *CarOptionalized; + UserOptionalized user?; +|}; + +public type CarTargetType typedesc; + +public type CarInsert Car; + +public type CarUpdate record {| + string name?; + string model?; + int ownerId?; + string ownerNic?; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_84/modules/entities/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_84/modules/entities/script.sql new file mode 100644 index 000000000..98da4dcfa --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_84/modules/entities/script.sql @@ -0,0 +1,30 @@ +-- AUTO-GENERATED FILE. + +-- This file is an auto-generated file by Ballerina persistence layer for model. +-- Please verify the generated scripts and execute them against the target DB server. + +DROP TABLE IF EXISTS `Car`; +DROP TABLE IF EXISTS `User`; + +CREATE TABLE `User` ( + `id` INT NOT NULL, + `NIC` VARCHAR(191) NOT NULL, + `name` VARCHAR(191) NOT NULL, + `gender` ENUM('MALE', 'FEMALE') NOT NULL, + `salary` DECIMAL(65,30), + PRIMARY KEY(`id`,`NIC`) +); + +CREATE TABLE `Car` ( + `id` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `model` VARCHAR(191) NOT NULL, + `OWNER_ID` INT NOT NULL, + `OWNER_NIC` VARCHAR(191) NOT NULL, + FOREIGN KEY(`OWNER_ID`, `OWNER_NIC`) REFERENCES `User`(`id`, `NIC`), + PRIMARY KEY(`id`) +); + + +CREATE INDEX `ownerId` ON `Car` (`OWNER_ID`); +CREATE INDEX `ownerNic` ON `Car` (`OWNER_NIC`); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_84/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_84/persist/model.bal new file mode 100644 index 000000000..ae34a6372 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_84/persist/model.bal @@ -0,0 +1,47 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + @sql:Mapping {name: "NIC"} + readonly string nic; + string name; + UserGender gender; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Mapping {name: "OWNER_ID"} + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Mapping {name: "OWNER_NIC"} + @sql:Index {names: ["ownerNic"]} + string ownerNic; + @sql:Relation {refs: ["ownerId", "ownerNic"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_84/target/Persist.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_84/target/Persist.toml new file mode 100644 index 000000000..b5ae72fef --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_84/target/Persist.toml @@ -0,0 +1,3 @@ +[[tool.persist]] +options.datastore = "mysql" +module = "tool_test_generate_84.entities" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_85/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_85/Ballerina.toml new file mode 100644 index 000000000..1109aeb85 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_85/Ballerina.toml @@ -0,0 +1,14 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_85" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +groupId = "io.ballerina.stdlib" +artifactId = "persist.sql-native" +version = "1.3.0-SNAPSHOT" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_85/Config.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_85/Config.toml new file mode 100644 index 000000000..c236e9b52 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_85/Config.toml @@ -0,0 +1,7 @@ +[tool_test_generate_85.entities] +host = "localhost" +port = 3306 +user = "root" +password = "" +database = "" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_85/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_85/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_85/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_85/modules/entities/persist_client.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_85/modules/entities/persist_client.bal new file mode 100644 index 000000000..3249599b5 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_85/modules/entities/persist_client.bal @@ -0,0 +1,166 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. +import ballerina/jballerina.java; +import ballerina/persist; +import ballerina/sql; +import ballerinax/mysql; +import ballerinax/mysql.driver as _; +import ballerinax/persist.sql as psql; + +const USER = "users"; +const CAR = "cars"; + +public isolated client class Client { + *persist:AbstractPersistClient; + + private final mysql:Client dbClient; + + private final map persistClients; + + private final record {|psql:SQLMetadata...;|} & readonly metadata = { + [USER]: { + entityName: "User", + tableName: "User", + fieldMetadata: { + id: {columnName: "ID"}, + nic: {columnName: "NIC"}, + name: {columnName: "name"}, + gender: {columnName: "gender"}, + salary: {columnName: "salary"}, + "cars[].id": {relation: {entityName: "cars", refField: "id"}}, + "cars[].name": {relation: {entityName: "cars", refField: "name"}}, + "cars[].model": {relation: {entityName: "cars", refField: "model"}}, + "cars[].ownerId": {relation: {entityName: "cars", refField: "ownerId"}}, + "cars[].ownerNic": {relation: {entityName: "cars", refField: "ownerNic"}} + }, + keyFields: ["id", "nic"], + joinMetadata: {cars: {entity: Car, fieldName: "cars", refTable: "Car", refColumns: ["OWNER_ID", "OWNER_NIC"], joinColumns: ["ID", "NIC"], 'type: psql:MANY_TO_ONE}} + }, + [CAR]: { + entityName: "Car", + tableName: "Car", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + model: {columnName: "model"}, + ownerId: {columnName: "OWNER_ID"}, + ownerNic: {columnName: "OWNER_NIC"}, + "user.id": {relation: {entityName: "user", refField: "id"}}, + "user.nic": {relation: {entityName: "user", refField: "nic"}}, + "user.name": {relation: {entityName: "user", refField: "name"}}, + "user.gender": {relation: {entityName: "user", refField: "gender"}}, + "user.salary": {relation: {entityName: "user", refField: "salary"}} + }, + keyFields: ["id"], + joinMetadata: {user: {entity: User, fieldName: "user", refTable: "User", refColumns: ["ID", "NIC"], joinColumns: ["OWNER_ID", "OWNER_NIC"], 'type: psql:ONE_TO_MANY}} + } + }; + + public isolated function init() returns persist:Error? { + mysql:Client|error dbClient = new (host = host, user = user, password = password, database = database, port = port, options = connectionOptions); + if dbClient is error { + return error(dbClient.message()); + } + self.dbClient = dbClient; + self.persistClients = { + [USER]: check new (dbClient, self.metadata.get(USER), psql:MYSQL_SPECIFICS), + [CAR]: check new (dbClient, self.metadata.get(CAR), psql:MYSQL_SPECIFICS) + }; + } + + isolated resource function get users(UserTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get users/[int id]/[string nic](UserTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post users(UserInsert[] data) returns [int, string][]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from UserInsert inserted in data + select [inserted.id, inserted.nic]; + } + + isolated resource function put users/[int id]/[string nic](UserUpdate value) returns User|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runUpdateQuery({"id": id, "nic": nic}, value); + return self->/users/[id]/[nic].get(); + } + + isolated resource function delete users/[int id]/[string nic]() returns User|persist:Error { + User result = check self->/users/[id]/[nic].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runDeleteQuery({"id": id, "nic": nic}); + return result; + } + + isolated resource function get cars(CarTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get cars/[int id](CarTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post cars(CarInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from CarInsert inserted in data + select inserted.id; + } + + isolated resource function put cars/[int id](CarUpdate value) returns Car|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/cars/[id].get(); + } + + isolated resource function delete cars/[int id]() returns Car|persist:Error { + Car result = check self->/cars/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + remote isolated function queryNativeSQL(sql:ParameterizedQuery sqlQuery, typedesc rowType = <>) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + remote isolated function executeNativeSQL(sql:ParameterizedQuery sqlQuery) returns psql:ExecutionResult|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + public isolated function close() returns persist:Error? { + error? result = self.dbClient.close(); + if result is error { + return error(result.message()); + } + return result; + } +} + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_85/modules/entities/persist_db_config.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_85/modules/entities/persist_db_config.bal new file mode 100644 index 000000000..aedfe37e0 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_85/modules/entities/persist_db_config.bal @@ -0,0 +1,12 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer. +// It should not be modified by hand. +import ballerinax/mysql; + +configurable int port = ?; +configurable string host = ?; +configurable string user = ?; +configurable string database = ?; +configurable string password = ?; +configurable mysql:Options & readonly connectionOptions = {}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_85/modules/entities/persist_types.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_85/modules/entities/persist_types.bal new file mode 100644 index 000000000..ab94b2786 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_85/modules/entities/persist_types.bal @@ -0,0 +1,73 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. + +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + readonly string nic; + string name; + UserGender gender; + decimal? salary; +|}; + +public type UserOptionalized record {| + int id?; + string nic?; + string name?; + UserGender gender?; + decimal? salary?; +|}; + +public type UserWithRelations record {| + *UserOptionalized; + CarOptionalized[] cars?; +|}; + +public type UserTargetType typedesc; + +public type UserInsert User; + +public type UserUpdate record {| + string name?; + UserGender gender?; + decimal? salary?; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + int ownerId; + string ownerNic; +|}; + +public type CarOptionalized record {| + int id?; + string name?; + string model?; + int ownerId?; + string ownerNic?; +|}; + +public type CarWithRelations record {| + *CarOptionalized; + UserOptionalized user?; +|}; + +public type CarTargetType typedesc; + +public type CarInsert Car; + +public type CarUpdate record {| + string name?; + string model?; + int ownerId?; + string ownerNic?; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_85/modules/entities/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_85/modules/entities/script.sql new file mode 100644 index 000000000..e8cc59278 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_85/modules/entities/script.sql @@ -0,0 +1,30 @@ +-- AUTO-GENERATED FILE. + +-- This file is an auto-generated file by Ballerina persistence layer for model. +-- Please verify the generated scripts and execute them against the target DB server. + +DROP TABLE IF EXISTS `Car`; +DROP TABLE IF EXISTS `User`; + +CREATE TABLE `User` ( + `ID` INT NOT NULL, + `NIC` VARCHAR(191) NOT NULL, + `name` VARCHAR(191) NOT NULL, + `gender` ENUM('MALE', 'FEMALE') NOT NULL, + `salary` DECIMAL(65,30), + PRIMARY KEY(`ID`,`NIC`) +); + +CREATE TABLE `Car` ( + `id` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `model` VARCHAR(191) NOT NULL, + `OWNER_ID` INT NOT NULL, + `OWNER_NIC` VARCHAR(191) NOT NULL, + FOREIGN KEY(`OWNER_ID`, `OWNER_NIC`) REFERENCES `User`(`ID`, `NIC`), + PRIMARY KEY(`id`) +); + + +CREATE INDEX `ownerId` ON `Car` (`OWNER_ID`); +CREATE INDEX `ownerNic` ON `Car` (`OWNER_NIC`); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_85/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_85/persist/model.bal new file mode 100644 index 000000000..ab69a9da5 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_85/persist/model.bal @@ -0,0 +1,48 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + @sql:Mapping {name: "ID"} + readonly int id; + @sql:Mapping {name: "NIC"} + readonly string nic; + string name; + UserGender gender; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Mapping {name: "OWNER_ID"} + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Mapping {name: "OWNER_NIC"} + @sql:Index {names: ["ownerNic"]} + string ownerNic; + @sql:Relation {refs: ["ownerId", "ownerNic"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_85/target/Persist.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_85/target/Persist.toml new file mode 100644 index 000000000..a6a154347 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_85/target/Persist.toml @@ -0,0 +1,3 @@ +[[tool.persist]] +options.datastore = "mysql" +module = "tool_test_generate_85.entities" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_86/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_86/Ballerina.toml new file mode 100644 index 000000000..38c37f398 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_86/Ballerina.toml @@ -0,0 +1,14 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_86" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +groupId = "io.ballerina.stdlib" +artifactId = "persist.sql-native" +version = "1.3.0-SNAPSHOT" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_86/Config.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_86/Config.toml new file mode 100644 index 000000000..acc37c598 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_86/Config.toml @@ -0,0 +1,7 @@ +[tool_test_generate_86.entities] +host = "localhost" +port = 3306 +user = "root" +password = "" +database = "" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_86/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_86/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_86/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_86/modules/entities/persist_client.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_86/modules/entities/persist_client.bal new file mode 100644 index 000000000..1d8ef11e8 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_86/modules/entities/persist_client.bal @@ -0,0 +1,164 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. +import ballerina/jballerina.java; +import ballerina/persist; +import ballerina/sql; +import ballerinax/mysql; +import ballerinax/mysql.driver as _; +import ballerinax/persist.sql as psql; + +const USER = "users"; +const CAR = "cars"; + +public isolated client class Client { + *persist:AbstractPersistClient; + + private final mysql:Client dbClient; + + private final map persistClients; + + private final record {|psql:SQLMetadata...;|} & readonly metadata = { + [USER]: { + entityName: "User", + tableName: "User", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + gender: {columnName: "gender"}, + nic: {columnName: "nic"}, + salary: {columnName: "salary"}, + "cars[].id": {relation: {entityName: "cars", refField: "id"}}, + "cars[].name": {relation: {entityName: "cars", refField: "name"}}, + "cars[].model": {relation: {entityName: "cars", refField: "model"}}, + "cars[].ownerId": {relation: {entityName: "cars", refField: "ownerId"}} + }, + keyFields: ["id"], + joinMetadata: {cars: {entity: Car, fieldName: "cars", refTable: "Car", refColumns: ["ownerId"], joinColumns: ["id"], 'type: psql:MANY_TO_ONE}} + }, + [CAR]: { + entityName: "Car", + tableName: "Car", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + model: {columnName: "model"}, + ownerId: {columnName: "ownerId"}, + "user.id": {relation: {entityName: "user", refField: "id"}}, + "user.name": {relation: {entityName: "user", refField: "name"}}, + "user.gender": {relation: {entityName: "user", refField: "gender"}}, + "user.nic": {relation: {entityName: "user", refField: "nic"}}, + "user.salary": {relation: {entityName: "user", refField: "salary"}} + }, + keyFields: ["id"], + joinMetadata: {user: {entity: User, fieldName: "user", refTable: "User", refColumns: ["id"], joinColumns: ["ownerId"], 'type: psql:ONE_TO_MANY}} + } + }; + + public isolated function init() returns persist:Error? { + mysql:Client|error dbClient = new (host = host, user = user, password = password, database = database, port = port, options = connectionOptions); + if dbClient is error { + return error(dbClient.message()); + } + self.dbClient = dbClient; + self.persistClients = { + [USER]: check new (dbClient, self.metadata.get(USER), psql:MYSQL_SPECIFICS), + [CAR]: check new (dbClient, self.metadata.get(CAR), psql:MYSQL_SPECIFICS) + }; + } + + isolated resource function get users(UserTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get users/[int id](UserTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post users(UserInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from UserInsert inserted in data + select inserted.id; + } + + isolated resource function put users/[int id](UserUpdate value) returns User|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/users/[id].get(); + } + + isolated resource function delete users/[int id]() returns User|persist:Error { + User result = check self->/users/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + isolated resource function get cars(CarTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get cars/[int id](CarTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post cars(CarInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from CarInsert inserted in data + select inserted.id; + } + + isolated resource function put cars/[int id](CarUpdate value) returns Car|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/cars/[id].get(); + } + + isolated resource function delete cars/[int id]() returns Car|persist:Error { + Car result = check self->/cars/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + remote isolated function queryNativeSQL(sql:ParameterizedQuery sqlQuery, typedesc rowType = <>) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + remote isolated function executeNativeSQL(sql:ParameterizedQuery sqlQuery) returns psql:ExecutionResult|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + public isolated function close() returns persist:Error? { + error? result = self.dbClient.close(); + if result is error { + return error(result.message()); + } + return result; + } +} + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_86/modules/entities/persist_db_config.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_86/modules/entities/persist_db_config.bal new file mode 100644 index 000000000..aedfe37e0 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_86/modules/entities/persist_db_config.bal @@ -0,0 +1,12 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer. +// It should not be modified by hand. +import ballerinax/mysql; + +configurable int port = ?; +configurable string host = ?; +configurable string user = ?; +configurable string database = ?; +configurable string password = ?; +configurable mysql:Options & readonly connectionOptions = {}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_86/modules/entities/persist_types.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_86/modules/entities/persist_types.bal new file mode 100644 index 000000000..c5cca4c1a --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_86/modules/entities/persist_types.bal @@ -0,0 +1,71 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. + +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; +|}; + +public type UserOptionalized record {| + int id?; + string name?; + UserGender gender?; + string nic?; + decimal? salary?; +|}; + +public type UserWithRelations record {| + *UserOptionalized; + CarOptionalized[] cars?; +|}; + +public type UserTargetType typedesc; + +public type UserInsert User; + +public type UserUpdate record {| + string name?; + UserGender gender?; + string nic?; + decimal? salary?; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + int ownerId; +|}; + +public type CarOptionalized record {| + int id?; + string name?; + string model?; + int ownerId?; +|}; + +public type CarWithRelations record {| + *CarOptionalized; + UserOptionalized user?; +|}; + +public type CarTargetType typedesc; + +public type CarInsert Car; + +public type CarUpdate record {| + string name?; + string model?; + int ownerId?; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_86/modules/entities/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_86/modules/entities/script.sql new file mode 100644 index 000000000..bc177c45b --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_86/modules/entities/script.sql @@ -0,0 +1,29 @@ +-- AUTO-GENERATED FILE. + +-- This file is an auto-generated file by Ballerina persistence layer for model. +-- Please verify the generated scripts and execute them against the target DB server. + +DROP TABLE IF EXISTS `Car`; +DROP TABLE IF EXISTS `User`; + +CREATE TABLE `User` ( + `id` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `gender` ENUM('MALE', 'FEMALE') NOT NULL, + `nic` VARCHAR(191) NOT NULL, + `salary` DECIMAL(65,30), + PRIMARY KEY(`id`) +); + +CREATE TABLE `Car` ( + `id` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `model` VARCHAR(191) NOT NULL, + `ownerId` INT NOT NULL, + FOREIGN KEY(`ownerId`) REFERENCES `User`(`id`), + PRIMARY KEY(`id`) +); + + +CREATE INDEX `idx_nic` ON `User` (`nic`); +CREATE INDEX `ownerId` ON `Car` (`ownerId`); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_86/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_86/persist/model.bal new file mode 100644 index 000000000..b095c3e11 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_86/persist/model.bal @@ -0,0 +1,43 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + @sql:Index + string nic; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_86/target/Persist.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_86/target/Persist.toml new file mode 100644 index 000000000..1cdf8c0d5 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_86/target/Persist.toml @@ -0,0 +1,3 @@ +[[tool.persist]] +options.datastore = "mysql" +module = "tool_test_generate_86.entities" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_87/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_87/Ballerina.toml new file mode 100644 index 000000000..00439398d --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_87/Ballerina.toml @@ -0,0 +1,14 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_87" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +groupId = "io.ballerina.stdlib" +artifactId = "persist.sql-native" +version = "1.3.0-SNAPSHOT" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_87/Config.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_87/Config.toml new file mode 100644 index 000000000..3f998a839 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_87/Config.toml @@ -0,0 +1,7 @@ +[tool_test_generate_87.entities] +host = "localhost" +port = 3306 +user = "root" +password = "" +database = "" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_87/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_87/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_87/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_87/modules/entities/persist_client.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_87/modules/entities/persist_client.bal new file mode 100644 index 000000000..1d8ef11e8 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_87/modules/entities/persist_client.bal @@ -0,0 +1,164 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. +import ballerina/jballerina.java; +import ballerina/persist; +import ballerina/sql; +import ballerinax/mysql; +import ballerinax/mysql.driver as _; +import ballerinax/persist.sql as psql; + +const USER = "users"; +const CAR = "cars"; + +public isolated client class Client { + *persist:AbstractPersistClient; + + private final mysql:Client dbClient; + + private final map persistClients; + + private final record {|psql:SQLMetadata...;|} & readonly metadata = { + [USER]: { + entityName: "User", + tableName: "User", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + gender: {columnName: "gender"}, + nic: {columnName: "nic"}, + salary: {columnName: "salary"}, + "cars[].id": {relation: {entityName: "cars", refField: "id"}}, + "cars[].name": {relation: {entityName: "cars", refField: "name"}}, + "cars[].model": {relation: {entityName: "cars", refField: "model"}}, + "cars[].ownerId": {relation: {entityName: "cars", refField: "ownerId"}} + }, + keyFields: ["id"], + joinMetadata: {cars: {entity: Car, fieldName: "cars", refTable: "Car", refColumns: ["ownerId"], joinColumns: ["id"], 'type: psql:MANY_TO_ONE}} + }, + [CAR]: { + entityName: "Car", + tableName: "Car", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + model: {columnName: "model"}, + ownerId: {columnName: "ownerId"}, + "user.id": {relation: {entityName: "user", refField: "id"}}, + "user.name": {relation: {entityName: "user", refField: "name"}}, + "user.gender": {relation: {entityName: "user", refField: "gender"}}, + "user.nic": {relation: {entityName: "user", refField: "nic"}}, + "user.salary": {relation: {entityName: "user", refField: "salary"}} + }, + keyFields: ["id"], + joinMetadata: {user: {entity: User, fieldName: "user", refTable: "User", refColumns: ["id"], joinColumns: ["ownerId"], 'type: psql:ONE_TO_MANY}} + } + }; + + public isolated function init() returns persist:Error? { + mysql:Client|error dbClient = new (host = host, user = user, password = password, database = database, port = port, options = connectionOptions); + if dbClient is error { + return error(dbClient.message()); + } + self.dbClient = dbClient; + self.persistClients = { + [USER]: check new (dbClient, self.metadata.get(USER), psql:MYSQL_SPECIFICS), + [CAR]: check new (dbClient, self.metadata.get(CAR), psql:MYSQL_SPECIFICS) + }; + } + + isolated resource function get users(UserTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get users/[int id](UserTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post users(UserInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from UserInsert inserted in data + select inserted.id; + } + + isolated resource function put users/[int id](UserUpdate value) returns User|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/users/[id].get(); + } + + isolated resource function delete users/[int id]() returns User|persist:Error { + User result = check self->/users/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + isolated resource function get cars(CarTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get cars/[int id](CarTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post cars(CarInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from CarInsert inserted in data + select inserted.id; + } + + isolated resource function put cars/[int id](CarUpdate value) returns Car|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/cars/[id].get(); + } + + isolated resource function delete cars/[int id]() returns Car|persist:Error { + Car result = check self->/cars/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + remote isolated function queryNativeSQL(sql:ParameterizedQuery sqlQuery, typedesc rowType = <>) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + remote isolated function executeNativeSQL(sql:ParameterizedQuery sqlQuery) returns psql:ExecutionResult|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + public isolated function close() returns persist:Error? { + error? result = self.dbClient.close(); + if result is error { + return error(result.message()); + } + return result; + } +} + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_87/modules/entities/persist_db_config.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_87/modules/entities/persist_db_config.bal new file mode 100644 index 000000000..aedfe37e0 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_87/modules/entities/persist_db_config.bal @@ -0,0 +1,12 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer. +// It should not be modified by hand. +import ballerinax/mysql; + +configurable int port = ?; +configurable string host = ?; +configurable string user = ?; +configurable string database = ?; +configurable string password = ?; +configurable mysql:Options & readonly connectionOptions = {}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_87/modules/entities/persist_types.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_87/modules/entities/persist_types.bal new file mode 100644 index 000000000..c5cca4c1a --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_87/modules/entities/persist_types.bal @@ -0,0 +1,71 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. + +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; +|}; + +public type UserOptionalized record {| + int id?; + string name?; + UserGender gender?; + string nic?; + decimal? salary?; +|}; + +public type UserWithRelations record {| + *UserOptionalized; + CarOptionalized[] cars?; +|}; + +public type UserTargetType typedesc; + +public type UserInsert User; + +public type UserUpdate record {| + string name?; + UserGender gender?; + string nic?; + decimal? salary?; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + int ownerId; +|}; + +public type CarOptionalized record {| + int id?; + string name?; + string model?; + int ownerId?; +|}; + +public type CarWithRelations record {| + *CarOptionalized; + UserOptionalized user?; +|}; + +public type CarTargetType typedesc; + +public type CarInsert Car; + +public type CarUpdate record {| + string name?; + string model?; + int ownerId?; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_87/modules/entities/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_87/modules/entities/script.sql new file mode 100644 index 000000000..3ecf995cc --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_87/modules/entities/script.sql @@ -0,0 +1,29 @@ +-- AUTO-GENERATED FILE. + +-- This file is an auto-generated file by Ballerina persistence layer for model. +-- Please verify the generated scripts and execute them against the target DB server. + +DROP TABLE IF EXISTS `Car`; +DROP TABLE IF EXISTS `User`; + +CREATE TABLE `User` ( + `id` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `gender` ENUM('MALE', 'FEMALE') NOT NULL, + `nic` VARCHAR(191) NOT NULL, + `salary` DECIMAL(65,30), + PRIMARY KEY(`id`) +); + +CREATE TABLE `Car` ( + `id` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `model` VARCHAR(191) NOT NULL, + `ownerId` INT NOT NULL, + FOREIGN KEY(`ownerId`) REFERENCES `User`(`id`), + PRIMARY KEY(`id`) +); + + +CREATE UNIQUE INDEX `unique_idx_nic` ON `User` (`nic`); +CREATE INDEX `ownerId` ON `Car` (`ownerId`); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_87/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_87/persist/model.bal new file mode 100644 index 000000000..734abd0c7 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_87/persist/model.bal @@ -0,0 +1,43 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + @sql:UniqueIndex + string nic; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_87/target/Persist.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_87/target/Persist.toml new file mode 100644 index 000000000..934428d2e --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_87/target/Persist.toml @@ -0,0 +1,3 @@ +[[tool.persist]] +options.datastore = "mysql" +module = "tool_test_generate_87.entities" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_88/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_88/Ballerina.toml new file mode 100644 index 000000000..731fdcfbc --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_88/Ballerina.toml @@ -0,0 +1,14 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_88" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +groupId = "io.ballerina.stdlib" +artifactId = "persist.sql-native" +version = "1.3.0-SNAPSHOT" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_88/Config.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_88/Config.toml new file mode 100644 index 000000000..18be8b418 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_88/Config.toml @@ -0,0 +1,7 @@ +[tool_test_generate_88.entities] +host = "localhost" +port = 3306 +user = "root" +password = "" +database = "" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_88/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_88/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_88/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_88/modules/entities/persist_client.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_88/modules/entities/persist_client.bal new file mode 100644 index 000000000..1d8ef11e8 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_88/modules/entities/persist_client.bal @@ -0,0 +1,164 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. +import ballerina/jballerina.java; +import ballerina/persist; +import ballerina/sql; +import ballerinax/mysql; +import ballerinax/mysql.driver as _; +import ballerinax/persist.sql as psql; + +const USER = "users"; +const CAR = "cars"; + +public isolated client class Client { + *persist:AbstractPersistClient; + + private final mysql:Client dbClient; + + private final map persistClients; + + private final record {|psql:SQLMetadata...;|} & readonly metadata = { + [USER]: { + entityName: "User", + tableName: "User", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + gender: {columnName: "gender"}, + nic: {columnName: "nic"}, + salary: {columnName: "salary"}, + "cars[].id": {relation: {entityName: "cars", refField: "id"}}, + "cars[].name": {relation: {entityName: "cars", refField: "name"}}, + "cars[].model": {relation: {entityName: "cars", refField: "model"}}, + "cars[].ownerId": {relation: {entityName: "cars", refField: "ownerId"}} + }, + keyFields: ["id"], + joinMetadata: {cars: {entity: Car, fieldName: "cars", refTable: "Car", refColumns: ["ownerId"], joinColumns: ["id"], 'type: psql:MANY_TO_ONE}} + }, + [CAR]: { + entityName: "Car", + tableName: "Car", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + model: {columnName: "model"}, + ownerId: {columnName: "ownerId"}, + "user.id": {relation: {entityName: "user", refField: "id"}}, + "user.name": {relation: {entityName: "user", refField: "name"}}, + "user.gender": {relation: {entityName: "user", refField: "gender"}}, + "user.nic": {relation: {entityName: "user", refField: "nic"}}, + "user.salary": {relation: {entityName: "user", refField: "salary"}} + }, + keyFields: ["id"], + joinMetadata: {user: {entity: User, fieldName: "user", refTable: "User", refColumns: ["id"], joinColumns: ["ownerId"], 'type: psql:ONE_TO_MANY}} + } + }; + + public isolated function init() returns persist:Error? { + mysql:Client|error dbClient = new (host = host, user = user, password = password, database = database, port = port, options = connectionOptions); + if dbClient is error { + return error(dbClient.message()); + } + self.dbClient = dbClient; + self.persistClients = { + [USER]: check new (dbClient, self.metadata.get(USER), psql:MYSQL_SPECIFICS), + [CAR]: check new (dbClient, self.metadata.get(CAR), psql:MYSQL_SPECIFICS) + }; + } + + isolated resource function get users(UserTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get users/[int id](UserTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post users(UserInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from UserInsert inserted in data + select inserted.id; + } + + isolated resource function put users/[int id](UserUpdate value) returns User|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/users/[id].get(); + } + + isolated resource function delete users/[int id]() returns User|persist:Error { + User result = check self->/users/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + isolated resource function get cars(CarTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get cars/[int id](CarTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post cars(CarInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from CarInsert inserted in data + select inserted.id; + } + + isolated resource function put cars/[int id](CarUpdate value) returns Car|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/cars/[id].get(); + } + + isolated resource function delete cars/[int id]() returns Car|persist:Error { + Car result = check self->/cars/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + remote isolated function queryNativeSQL(sql:ParameterizedQuery sqlQuery, typedesc rowType = <>) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + remote isolated function executeNativeSQL(sql:ParameterizedQuery sqlQuery) returns psql:ExecutionResult|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + public isolated function close() returns persist:Error? { + error? result = self.dbClient.close(); + if result is error { + return error(result.message()); + } + return result; + } +} + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_88/modules/entities/persist_db_config.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_88/modules/entities/persist_db_config.bal new file mode 100644 index 000000000..aedfe37e0 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_88/modules/entities/persist_db_config.bal @@ -0,0 +1,12 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer. +// It should not be modified by hand. +import ballerinax/mysql; + +configurable int port = ?; +configurable string host = ?; +configurable string user = ?; +configurable string database = ?; +configurable string password = ?; +configurable mysql:Options & readonly connectionOptions = {}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_88/modules/entities/persist_types.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_88/modules/entities/persist_types.bal new file mode 100644 index 000000000..c5cca4c1a --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_88/modules/entities/persist_types.bal @@ -0,0 +1,71 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. + +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; +|}; + +public type UserOptionalized record {| + int id?; + string name?; + UserGender gender?; + string nic?; + decimal? salary?; +|}; + +public type UserWithRelations record {| + *UserOptionalized; + CarOptionalized[] cars?; +|}; + +public type UserTargetType typedesc; + +public type UserInsert User; + +public type UserUpdate record {| + string name?; + UserGender gender?; + string nic?; + decimal? salary?; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + int ownerId; +|}; + +public type CarOptionalized record {| + int id?; + string name?; + string model?; + int ownerId?; +|}; + +public type CarWithRelations record {| + *CarOptionalized; + UserOptionalized user?; +|}; + +public type CarTargetType typedesc; + +public type CarInsert Car; + +public type CarUpdate record {| + string name?; + string model?; + int ownerId?; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_88/modules/entities/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_88/modules/entities/script.sql new file mode 100644 index 000000000..26b5da296 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_88/modules/entities/script.sql @@ -0,0 +1,30 @@ +-- AUTO-GENERATED FILE. + +-- This file is an auto-generated file by Ballerina persistence layer for model. +-- Please verify the generated scripts and execute them against the target DB server. + +DROP TABLE IF EXISTS `Car`; +DROP TABLE IF EXISTS `User`; + +CREATE TABLE `User` ( + `id` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `gender` ENUM('MALE', 'FEMALE') NOT NULL, + `nic` VARCHAR(191) NOT NULL, + `salary` DECIMAL(65,30), + PRIMARY KEY(`id`) +); + +CREATE TABLE `Car` ( + `id` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `model` VARCHAR(191) NOT NULL, + `ownerId` INT NOT NULL, + FOREIGN KEY(`ownerId`) REFERENCES `User`(`id`), + PRIMARY KEY(`id`) +); + + +CREATE INDEX `idx_nic` ON `User` (`nic`); +CREATE UNIQUE INDEX `unique_idx_nic` ON `User` (`nic`); +CREATE INDEX `ownerId` ON `Car` (`ownerId`); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_88/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_88/persist/model.bal new file mode 100644 index 000000000..5b5bdfbf0 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_88/persist/model.bal @@ -0,0 +1,44 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + @sql:Index + @sql:UniqueIndex + string nic; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_88/target/Persist.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_88/target/Persist.toml new file mode 100644 index 000000000..265d7faba --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_88/target/Persist.toml @@ -0,0 +1,3 @@ +[[tool.persist]] +options.datastore = "mysql" +module = "tool_test_generate_88.entities" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_89/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_89/Ballerina.toml new file mode 100644 index 000000000..bfe334c8b --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_89/Ballerina.toml @@ -0,0 +1,14 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_89" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +groupId = "io.ballerina.stdlib" +artifactId = "persist.sql-native" +version = "1.3.0-SNAPSHOT" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_89/Config.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_89/Config.toml new file mode 100644 index 000000000..908104b55 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_89/Config.toml @@ -0,0 +1,7 @@ +[tool_test_generate_89.entities] +host = "localhost" +port = 3306 +user = "root" +password = "" +database = "" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_89/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_89/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_89/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_89/modules/entities/persist_client.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_89/modules/entities/persist_client.bal new file mode 100644 index 000000000..1d8ef11e8 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_89/modules/entities/persist_client.bal @@ -0,0 +1,164 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. +import ballerina/jballerina.java; +import ballerina/persist; +import ballerina/sql; +import ballerinax/mysql; +import ballerinax/mysql.driver as _; +import ballerinax/persist.sql as psql; + +const USER = "users"; +const CAR = "cars"; + +public isolated client class Client { + *persist:AbstractPersistClient; + + private final mysql:Client dbClient; + + private final map persistClients; + + private final record {|psql:SQLMetadata...;|} & readonly metadata = { + [USER]: { + entityName: "User", + tableName: "User", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + gender: {columnName: "gender"}, + nic: {columnName: "nic"}, + salary: {columnName: "salary"}, + "cars[].id": {relation: {entityName: "cars", refField: "id"}}, + "cars[].name": {relation: {entityName: "cars", refField: "name"}}, + "cars[].model": {relation: {entityName: "cars", refField: "model"}}, + "cars[].ownerId": {relation: {entityName: "cars", refField: "ownerId"}} + }, + keyFields: ["id"], + joinMetadata: {cars: {entity: Car, fieldName: "cars", refTable: "Car", refColumns: ["ownerId"], joinColumns: ["id"], 'type: psql:MANY_TO_ONE}} + }, + [CAR]: { + entityName: "Car", + tableName: "Car", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + model: {columnName: "model"}, + ownerId: {columnName: "ownerId"}, + "user.id": {relation: {entityName: "user", refField: "id"}}, + "user.name": {relation: {entityName: "user", refField: "name"}}, + "user.gender": {relation: {entityName: "user", refField: "gender"}}, + "user.nic": {relation: {entityName: "user", refField: "nic"}}, + "user.salary": {relation: {entityName: "user", refField: "salary"}} + }, + keyFields: ["id"], + joinMetadata: {user: {entity: User, fieldName: "user", refTable: "User", refColumns: ["id"], joinColumns: ["ownerId"], 'type: psql:ONE_TO_MANY}} + } + }; + + public isolated function init() returns persist:Error? { + mysql:Client|error dbClient = new (host = host, user = user, password = password, database = database, port = port, options = connectionOptions); + if dbClient is error { + return error(dbClient.message()); + } + self.dbClient = dbClient; + self.persistClients = { + [USER]: check new (dbClient, self.metadata.get(USER), psql:MYSQL_SPECIFICS), + [CAR]: check new (dbClient, self.metadata.get(CAR), psql:MYSQL_SPECIFICS) + }; + } + + isolated resource function get users(UserTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get users/[int id](UserTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post users(UserInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from UserInsert inserted in data + select inserted.id; + } + + isolated resource function put users/[int id](UserUpdate value) returns User|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/users/[id].get(); + } + + isolated resource function delete users/[int id]() returns User|persist:Error { + User result = check self->/users/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + isolated resource function get cars(CarTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get cars/[int id](CarTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post cars(CarInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from CarInsert inserted in data + select inserted.id; + } + + isolated resource function put cars/[int id](CarUpdate value) returns Car|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/cars/[id].get(); + } + + isolated resource function delete cars/[int id]() returns Car|persist:Error { + Car result = check self->/cars/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + remote isolated function queryNativeSQL(sql:ParameterizedQuery sqlQuery, typedesc rowType = <>) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + remote isolated function executeNativeSQL(sql:ParameterizedQuery sqlQuery) returns psql:ExecutionResult|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + public isolated function close() returns persist:Error? { + error? result = self.dbClient.close(); + if result is error { + return error(result.message()); + } + return result; + } +} + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_89/modules/entities/persist_db_config.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_89/modules/entities/persist_db_config.bal new file mode 100644 index 000000000..aedfe37e0 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_89/modules/entities/persist_db_config.bal @@ -0,0 +1,12 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer. +// It should not be modified by hand. +import ballerinax/mysql; + +configurable int port = ?; +configurable string host = ?; +configurable string user = ?; +configurable string database = ?; +configurable string password = ?; +configurable mysql:Options & readonly connectionOptions = {}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_89/modules/entities/persist_types.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_89/modules/entities/persist_types.bal new file mode 100644 index 000000000..c5cca4c1a --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_89/modules/entities/persist_types.bal @@ -0,0 +1,71 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. + +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; +|}; + +public type UserOptionalized record {| + int id?; + string name?; + UserGender gender?; + string nic?; + decimal? salary?; +|}; + +public type UserWithRelations record {| + *UserOptionalized; + CarOptionalized[] cars?; +|}; + +public type UserTargetType typedesc; + +public type UserInsert User; + +public type UserUpdate record {| + string name?; + UserGender gender?; + string nic?; + decimal? salary?; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + int ownerId; +|}; + +public type CarOptionalized record {| + int id?; + string name?; + string model?; + int ownerId?; +|}; + +public type CarWithRelations record {| + *CarOptionalized; + UserOptionalized user?; +|}; + +public type CarTargetType typedesc; + +public type CarInsert Car; + +public type CarUpdate record {| + string name?; + string model?; + int ownerId?; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_89/modules/entities/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_89/modules/entities/script.sql new file mode 100644 index 000000000..8362c6bfa --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_89/modules/entities/script.sql @@ -0,0 +1,31 @@ +-- AUTO-GENERATED FILE. + +-- This file is an auto-generated file by Ballerina persistence layer for model. +-- Please verify the generated scripts and execute them against the target DB server. + +DROP TABLE IF EXISTS `Car`; +DROP TABLE IF EXISTS `User`; + +CREATE TABLE `User` ( + `id` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `gender` ENUM('MALE', 'FEMALE') NOT NULL, + `nic` VARCHAR(191) NOT NULL, + `salary` DECIMAL(65,30), + PRIMARY KEY(`id`) +); + +CREATE TABLE `Car` ( + `id` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `model` VARCHAR(191) NOT NULL, + `ownerId` INT NOT NULL, + FOREIGN KEY(`ownerId`) REFERENCES `User`(`id`), + PRIMARY KEY(`id`) +); + + +CREATE INDEX `idx_nic` ON `User` (`nic`); +CREATE UNIQUE INDEX `unique_user` ON `User` (`id`, `nic`); +CREATE UNIQUE INDEX `unique_nic` ON `User` (`nic`); +CREATE INDEX `ownerId` ON `Car` (`ownerId`); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_89/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_89/persist/model.bal new file mode 100644 index 000000000..961e07b23 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_89/persist/model.bal @@ -0,0 +1,45 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + @sql:UniqueIndex {names: ["unique_user"]} + readonly int id; + string name; + UserGender gender; + @sql:Index + @sql:UniqueIndex {names: ["unique_nic", "unique_user"]} + string nic; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_89/target/Persist.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_89/target/Persist.toml new file mode 100644 index 000000000..25dceb255 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_89/target/Persist.toml @@ -0,0 +1,3 @@ +[[tool.persist]] +options.datastore = "mysql" +module = "tool_test_generate_89.entities" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_9/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_9/Ballerina.toml index 9ab05bab9..a7a9bd0d3 100644 --- a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_9/Ballerina.toml +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_9/Ballerina.toml @@ -10,5 +10,5 @@ observabilityIncluded = false [[platform.java17.dependency]] groupId = "io.ballerina.stdlib" artifactId = "persist.sql-native" -version = "1.2.2-SNAPSHOT" +version = "1.3.0-SNAPSHOT" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_90/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_90/Ballerina.toml new file mode 100644 index 000000000..ffaa4e994 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_90/Ballerina.toml @@ -0,0 +1,14 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_90" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +groupId = "io.ballerina.stdlib" +artifactId = "persist.sql-native" +version = "1.3.0-SNAPSHOT" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_90/Config.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_90/Config.toml new file mode 100644 index 000000000..71eebfd9b --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_90/Config.toml @@ -0,0 +1,7 @@ +[tool_test_generate_90.entities] +host = "localhost" +port = 3306 +user = "root" +password = "" +database = "" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_90/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_90/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_90/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_90/modules/entities/persist_client.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_90/modules/entities/persist_client.bal new file mode 100644 index 000000000..ce64c2045 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_90/modules/entities/persist_client.bal @@ -0,0 +1,100 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. +import ballerina/jballerina.java; +import ballerina/persist; +import ballerina/sql; +import ballerinax/mysql; +import ballerinax/mysql.driver as _; +import ballerinax/persist.sql as psql; + +const USER = "users"; + +public isolated client class Client { + *persist:AbstractPersistClient; + + private final mysql:Client dbClient; + + private final map persistClients; + + private final record {|psql:SQLMetadata...;|} & readonly metadata = { + [USER]: { + entityName: "User", + tableName: "User", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + gender: {columnName: "gender"}, + nic: {columnName: "nic"}, + salary: {columnName: "salary"} + }, + keyFields: ["id"] + } + }; + + public isolated function init() returns persist:Error? { + mysql:Client|error dbClient = new (host = host, user = user, password = password, database = database, port = port, options = connectionOptions); + if dbClient is error { + return error(dbClient.message()); + } + self.dbClient = dbClient; + self.persistClients = {[USER]: check new (dbClient, self.metadata.get(USER), psql:MYSQL_SPECIFICS)}; + } + + isolated resource function get users(UserTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get users/[int id](UserTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post users(UserInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + sql:ExecutionResult[] result = check sqlClient.runBatchInsertQuery(data); + return from sql:ExecutionResult inserted in result + where inserted.lastInsertId != () + select inserted.lastInsertId; + } + + isolated resource function put users/[int id](UserUpdate value) returns User|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/users/[id].get(); + } + + isolated resource function delete users/[int id]() returns User|persist:Error { + User result = check self->/users/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + remote isolated function queryNativeSQL(sql:ParameterizedQuery sqlQuery, typedesc rowType = <>) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + remote isolated function executeNativeSQL(sql:ParameterizedQuery sqlQuery) returns psql:ExecutionResult|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + public isolated function close() returns persist:Error? { + error? result = self.dbClient.close(); + if result is error { + return error(result.message()); + } + return result; + } +} + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_90/modules/entities/persist_db_config.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_90/modules/entities/persist_db_config.bal new file mode 100644 index 000000000..aedfe37e0 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_90/modules/entities/persist_db_config.bal @@ -0,0 +1,12 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer. +// It should not be modified by hand. +import ballerinax/mysql; + +configurable int port = ?; +configurable string host = ?; +configurable string user = ?; +configurable string database = ?; +configurable string password = ?; +configurable mysql:Options & readonly connectionOptions = {}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_90/modules/entities/persist_types.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_90/modules/entities/persist_types.bal new file mode 100644 index 000000000..18f1476b2 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_90/modules/entities/persist_types.bal @@ -0,0 +1,41 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. + +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. + +public enum UserGender { + MALE, + FEMALE +} +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; +|}; + +public type UserOptionalized record {| + int id?; + string name?; + UserGender gender?; + string nic?; + decimal? salary?; +|}; + +public type UserTargetType typedesc; + +public type UserInsert record {| + string name; + UserGender gender; + string nic; + decimal? salary; +|}; + +public type UserUpdate record {| + string name?; + UserGender gender?; + string nic?; + decimal? salary?; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_90/modules/entities/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_90/modules/entities/script.sql new file mode 100644 index 000000000..176452df4 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_90/modules/entities/script.sql @@ -0,0 +1,17 @@ +-- AUTO-GENERATED FILE. + +-- This file is an auto-generated file by Ballerina persistence layer for model. +-- Please verify the generated scripts and execute them against the target DB server. + +DROP TABLE IF EXISTS `User`; + +CREATE TABLE `User` ( + `id` INT AUTO_INCREMENT, + `name` VARCHAR(191) NOT NULL, + `gender` ENUM('MALE', 'FEMALE') NOT NULL, + `nic` VARCHAR(191) NOT NULL, + `salary` DECIMAL(65,30), + PRIMARY KEY(`id`) +); + + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_90/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_90/persist/model.bal new file mode 100644 index 000000000..9a7e5aace --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_90/persist/model.bal @@ -0,0 +1,33 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + @sql:Generated + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_90/target/Persist.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_90/target/Persist.toml new file mode 100644 index 000000000..c89190644 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_90/target/Persist.toml @@ -0,0 +1,3 @@ +[[tool.persist]] +options.datastore = "mysql" +module = "tool_test_generate_90.entities" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_91/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_91/Ballerina.toml new file mode 100644 index 000000000..3a81122d5 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_91/Ballerina.toml @@ -0,0 +1,14 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_91" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +groupId = "io.ballerina.stdlib" +artifactId = "persist.sql-native" +version = "1.3.0-SNAPSHOT" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_91/Config.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_91/Config.toml new file mode 100644 index 000000000..e0e93ed94 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_91/Config.toml @@ -0,0 +1,7 @@ +[tool_test_generate_91.entities] +host = "localhost" +port = 3306 +user = "root" +password = "" +database = "" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_91/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_91/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_91/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_91/modules/entities/persist_client.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_91/modules/entities/persist_client.bal new file mode 100644 index 000000000..c96762719 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_91/modules/entities/persist_client.bal @@ -0,0 +1,165 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. +import ballerina/jballerina.java; +import ballerina/persist; +import ballerina/sql; +import ballerinax/mysql; +import ballerinax/mysql.driver as _; +import ballerinax/persist.sql as psql; + +const USER = "users"; +const CAR = "cars"; + +public isolated client class Client { + *persist:AbstractPersistClient; + + private final mysql:Client dbClient; + + private final map persistClients; + + private final record {|psql:SQLMetadata...;|} & readonly metadata = { + [USER]: { + entityName: "User", + tableName: "User", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + gender: {columnName: "gender"}, + nic: {columnName: "nic"}, + salary: {columnName: "salary"}, + "cars[].id": {relation: {entityName: "cars", refField: "id"}}, + "cars[].name": {relation: {entityName: "cars", refField: "name"}}, + "cars[].model": {relation: {entityName: "cars", refField: "model"}}, + "cars[].ownerId": {relation: {entityName: "cars", refField: "ownerId"}} + }, + keyFields: ["id"], + joinMetadata: {cars: {entity: Car, fieldName: "cars", refTable: "Car", refColumns: ["ownerId"], joinColumns: ["id"], 'type: psql:MANY_TO_ONE}} + }, + [CAR]: { + entityName: "Car", + tableName: "Car", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + model: {columnName: "model"}, + ownerId: {columnName: "ownerId"}, + "user.id": {relation: {entityName: "user", refField: "id"}}, + "user.name": {relation: {entityName: "user", refField: "name"}}, + "user.gender": {relation: {entityName: "user", refField: "gender"}}, + "user.nic": {relation: {entityName: "user", refField: "nic"}}, + "user.salary": {relation: {entityName: "user", refField: "salary"}} + }, + keyFields: ["id"], + joinMetadata: {user: {entity: User, fieldName: "user", refTable: "User", refColumns: ["id"], joinColumns: ["ownerId"], 'type: psql:ONE_TO_MANY}} + } + }; + + public isolated function init() returns persist:Error? { + mysql:Client|error dbClient = new (host = host, user = user, password = password, database = database, port = port, options = connectionOptions); + if dbClient is error { + return error(dbClient.message()); + } + self.dbClient = dbClient; + self.persistClients = { + [USER]: check new (dbClient, self.metadata.get(USER), psql:MYSQL_SPECIFICS), + [CAR]: check new (dbClient, self.metadata.get(CAR), psql:MYSQL_SPECIFICS) + }; + } + + isolated resource function get users(UserTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get users/[int id](UserTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post users(UserInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + sql:ExecutionResult[] result = check sqlClient.runBatchInsertQuery(data); + return from sql:ExecutionResult inserted in result + where inserted.lastInsertId != () + select inserted.lastInsertId; + } + + isolated resource function put users/[int id](UserUpdate value) returns User|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/users/[id].get(); + } + + isolated resource function delete users/[int id]() returns User|persist:Error { + User result = check self->/users/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + isolated resource function get cars(CarTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get cars/[int id](CarTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post cars(CarInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from CarInsert inserted in data + select inserted.id; + } + + isolated resource function put cars/[int id](CarUpdate value) returns Car|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/cars/[id].get(); + } + + isolated resource function delete cars/[int id]() returns Car|persist:Error { + Car result = check self->/cars/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + remote isolated function queryNativeSQL(sql:ParameterizedQuery sqlQuery, typedesc rowType = <>) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + remote isolated function executeNativeSQL(sql:ParameterizedQuery sqlQuery) returns psql:ExecutionResult|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + public isolated function close() returns persist:Error? { + error? result = self.dbClient.close(); + if result is error { + return error(result.message()); + } + return result; + } +} + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_91/modules/entities/persist_db_config.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_91/modules/entities/persist_db_config.bal new file mode 100644 index 000000000..aedfe37e0 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_91/modules/entities/persist_db_config.bal @@ -0,0 +1,12 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer. +// It should not be modified by hand. +import ballerinax/mysql; + +configurable int port = ?; +configurable string host = ?; +configurable string user = ?; +configurable string database = ?; +configurable string password = ?; +configurable mysql:Options & readonly connectionOptions = {}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_91/modules/entities/persist_types.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_91/modules/entities/persist_types.bal new file mode 100644 index 000000000..0da736f85 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_91/modules/entities/persist_types.bal @@ -0,0 +1,76 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. + +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; +|}; + +public type UserOptionalized record {| + int id?; + string name?; + UserGender gender?; + string nic?; + decimal? salary?; +|}; + +public type UserWithRelations record {| + *UserOptionalized; + CarOptionalized[] cars?; +|}; + +public type UserTargetType typedesc; + +public type UserInsert record {| + string name; + UserGender gender; + string nic; + decimal? salary; +|}; + +public type UserUpdate record {| + string name?; + UserGender gender?; + string nic?; + decimal? salary?; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + int ownerId; +|}; + +public type CarOptionalized record {| + int id?; + string name?; + string model?; + int ownerId?; +|}; + +public type CarWithRelations record {| + *CarOptionalized; + UserOptionalized user?; +|}; + +public type CarTargetType typedesc; + +public type CarInsert Car; + +public type CarUpdate record {| + string name?; + string model?; + int ownerId?; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_91/modules/entities/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_91/modules/entities/script.sql new file mode 100644 index 000000000..4d6961a5b --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_91/modules/entities/script.sql @@ -0,0 +1,28 @@ +-- AUTO-GENERATED FILE. + +-- This file is an auto-generated file by Ballerina persistence layer for model. +-- Please verify the generated scripts and execute them against the target DB server. + +DROP TABLE IF EXISTS `Car`; +DROP TABLE IF EXISTS `User`; + +CREATE TABLE `User` ( + `id` INT AUTO_INCREMENT, + `name` VARCHAR(191) NOT NULL, + `gender` ENUM('MALE', 'FEMALE') NOT NULL, + `nic` VARCHAR(191) NOT NULL, + `salary` DECIMAL(65,30), + PRIMARY KEY(`id`) +); + +CREATE TABLE `Car` ( + `id` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `model` VARCHAR(191) NOT NULL, + `ownerId` INT NOT NULL, + FOREIGN KEY(`ownerId`) REFERENCES `User`(`id`), + PRIMARY KEY(`id`) +); + + +CREATE INDEX `ownerId` ON `Car` (`ownerId`); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_91/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_91/persist/model.bal new file mode 100644 index 000000000..93dc60276 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_91/persist/model.bal @@ -0,0 +1,43 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + @sql:Generated + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_91/target/Persist.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_91/target/Persist.toml new file mode 100644 index 000000000..489b75ef4 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_91/target/Persist.toml @@ -0,0 +1,3 @@ +[[tool.persist]] +options.datastore = "mysql" +module = "tool_test_generate_91.entities" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_92/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_92/Ballerina.toml new file mode 100644 index 000000000..67a3659be --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_92/Ballerina.toml @@ -0,0 +1,14 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_92" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +groupId = "io.ballerina.stdlib" +artifactId = "persist.sql-native" +version = "1.3.0-SNAPSHOT" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_92/Config.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_92/Config.toml new file mode 100644 index 000000000..8340b6cc5 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_92/Config.toml @@ -0,0 +1,7 @@ +[tool_test_generate_92.entities] +host = "localhost" +port = 3306 +user = "root" +password = "" +database = "" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_92/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_92/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_92/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_92/modules/entities/persist_client.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_92/modules/entities/persist_client.bal new file mode 100644 index 000000000..d7df0f21d --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_92/modules/entities/persist_client.bal @@ -0,0 +1,165 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. +import ballerina/jballerina.java; +import ballerina/persist; +import ballerina/sql; +import ballerinax/mysql; +import ballerinax/mysql.driver as _; +import ballerinax/persist.sql as psql; + +const USER = "users"; +const CAR = "cars"; + +public isolated client class Client { + *persist:AbstractPersistClient; + + private final mysql:Client dbClient; + + private final map persistClients; + + private final record {|psql:SQLMetadata...;|} & readonly metadata = { + [USER]: { + entityName: "User", + tableName: "User", + fieldMetadata: { + id: {columnName: "ID"}, + name: {columnName: "name"}, + gender: {columnName: "gender"}, + nic: {columnName: "nic"}, + salary: {columnName: "salary"}, + "cars[].id": {relation: {entityName: "cars", refField: "id"}}, + "cars[].name": {relation: {entityName: "cars", refField: "name"}}, + "cars[].model": {relation: {entityName: "cars", refField: "model"}}, + "cars[].ownerId": {relation: {entityName: "cars", refField: "ownerId"}} + }, + keyFields: ["id"], + joinMetadata: {cars: {entity: Car, fieldName: "cars", refTable: "Car", refColumns: ["ownerId"], joinColumns: ["ID"], 'type: psql:MANY_TO_ONE}} + }, + [CAR]: { + entityName: "Car", + tableName: "Car", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + model: {columnName: "model"}, + ownerId: {columnName: "ownerId"}, + "user.id": {relation: {entityName: "user", refField: "id"}}, + "user.name": {relation: {entityName: "user", refField: "name"}}, + "user.gender": {relation: {entityName: "user", refField: "gender"}}, + "user.nic": {relation: {entityName: "user", refField: "nic"}}, + "user.salary": {relation: {entityName: "user", refField: "salary"}} + }, + keyFields: ["id"], + joinMetadata: {user: {entity: User, fieldName: "user", refTable: "User", refColumns: ["ID"], joinColumns: ["ownerId"], 'type: psql:ONE_TO_MANY}} + } + }; + + public isolated function init() returns persist:Error? { + mysql:Client|error dbClient = new (host = host, user = user, password = password, database = database, port = port, options = connectionOptions); + if dbClient is error { + return error(dbClient.message()); + } + self.dbClient = dbClient; + self.persistClients = { + [USER]: check new (dbClient, self.metadata.get(USER), psql:MYSQL_SPECIFICS), + [CAR]: check new (dbClient, self.metadata.get(CAR), psql:MYSQL_SPECIFICS) + }; + } + + isolated resource function get users(UserTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get users/[int id](UserTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post users(UserInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + sql:ExecutionResult[] result = check sqlClient.runBatchInsertQuery(data); + return from sql:ExecutionResult inserted in result + where inserted.lastInsertId != () + select inserted.lastInsertId; + } + + isolated resource function put users/[int id](UserUpdate value) returns User|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/users/[id].get(); + } + + isolated resource function delete users/[int id]() returns User|persist:Error { + User result = check self->/users/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + isolated resource function get cars(CarTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get cars/[int id](CarTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post cars(CarInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from CarInsert inserted in data + select inserted.id; + } + + isolated resource function put cars/[int id](CarUpdate value) returns Car|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/cars/[id].get(); + } + + isolated resource function delete cars/[int id]() returns Car|persist:Error { + Car result = check self->/cars/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + remote isolated function queryNativeSQL(sql:ParameterizedQuery sqlQuery, typedesc rowType = <>) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + remote isolated function executeNativeSQL(sql:ParameterizedQuery sqlQuery) returns psql:ExecutionResult|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + public isolated function close() returns persist:Error? { + error? result = self.dbClient.close(); + if result is error { + return error(result.message()); + } + return result; + } +} + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_92/modules/entities/persist_db_config.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_92/modules/entities/persist_db_config.bal new file mode 100644 index 000000000..aedfe37e0 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_92/modules/entities/persist_db_config.bal @@ -0,0 +1,12 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer. +// It should not be modified by hand. +import ballerinax/mysql; + +configurable int port = ?; +configurable string host = ?; +configurable string user = ?; +configurable string database = ?; +configurable string password = ?; +configurable mysql:Options & readonly connectionOptions = {}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_92/modules/entities/persist_types.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_92/modules/entities/persist_types.bal new file mode 100644 index 000000000..0da736f85 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_92/modules/entities/persist_types.bal @@ -0,0 +1,76 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. + +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; +|}; + +public type UserOptionalized record {| + int id?; + string name?; + UserGender gender?; + string nic?; + decimal? salary?; +|}; + +public type UserWithRelations record {| + *UserOptionalized; + CarOptionalized[] cars?; +|}; + +public type UserTargetType typedesc; + +public type UserInsert record {| + string name; + UserGender gender; + string nic; + decimal? salary; +|}; + +public type UserUpdate record {| + string name?; + UserGender gender?; + string nic?; + decimal? salary?; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + int ownerId; +|}; + +public type CarOptionalized record {| + int id?; + string name?; + string model?; + int ownerId?; +|}; + +public type CarWithRelations record {| + *CarOptionalized; + UserOptionalized user?; +|}; + +public type CarTargetType typedesc; + +public type CarInsert Car; + +public type CarUpdate record {| + string name?; + string model?; + int ownerId?; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_92/modules/entities/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_92/modules/entities/script.sql new file mode 100644 index 000000000..d907a841b --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_92/modules/entities/script.sql @@ -0,0 +1,28 @@ +-- AUTO-GENERATED FILE. + +-- This file is an auto-generated file by Ballerina persistence layer for model. +-- Please verify the generated scripts and execute them against the target DB server. + +DROP TABLE IF EXISTS `Car`; +DROP TABLE IF EXISTS `User`; + +CREATE TABLE `User` ( + `ID` INT AUTO_INCREMENT, + `name` VARCHAR(191) NOT NULL, + `gender` ENUM('MALE', 'FEMALE') NOT NULL, + `nic` VARCHAR(191) NOT NULL, + `salary` DECIMAL(65,30), + PRIMARY KEY(`ID`) +); + +CREATE TABLE `Car` ( + `id` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `model` VARCHAR(191) NOT NULL, + `ownerId` INT NOT NULL, + FOREIGN KEY(`ownerId`) REFERENCES `User`(`ID`), + PRIMARY KEY(`id`) +); + + +CREATE INDEX `ownerId` ON `Car` (`ownerId`); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_92/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_92/persist/model.bal new file mode 100644 index 000000000..b50ec64c9 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_92/persist/model.bal @@ -0,0 +1,44 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + @sql:Mapping {name: "ID"} + @sql:Generated + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_92/target/Persist.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_92/target/Persist.toml new file mode 100644 index 000000000..b1029067c --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_92/target/Persist.toml @@ -0,0 +1,3 @@ +[[tool.persist]] +options.datastore = "mysql" +module = "tool_test_generate_92.entities" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_93/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_93/Ballerina.toml new file mode 100644 index 000000000..563284848 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_93/Ballerina.toml @@ -0,0 +1,14 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_93" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +groupId = "io.ballerina.stdlib" +artifactId = "persist.sql-native" +version = "1.3.0-SNAPSHOT" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_93/Config.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_93/Config.toml new file mode 100644 index 000000000..ff9cc097e --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_93/Config.toml @@ -0,0 +1,7 @@ +[tool_test_generate_93.entities] +host = "localhost" +port = 3306 +user = "root" +password = "" +database = "" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_93/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_93/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_93/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_93/modules/entities/persist_client.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_93/modules/entities/persist_client.bal new file mode 100644 index 000000000..5973418f8 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_93/modules/entities/persist_client.bal @@ -0,0 +1,182 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. +import ballerina/jballerina.java; +import ballerina/persist; +import ballerina/sql; +import ballerinax/mysql; +import ballerinax/mysql.driver as _; +import ballerinax/persist.sql as psql; + +const USER = "users"; +const CAR = "cars"; + +public isolated client class Client { + *persist:AbstractPersistClient; + + private final mysql:Client dbClient; + + private final map persistClients; + + private final record {|psql:SQLMetadata...;|} & readonly metadata = { + [USER]: { + entityName: "User", + tableName: "User", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + gender: {columnName: "gender"}, + nic: {columnName: "nic"}, + salary: {columnName: "salary"}, + "cars[].id": {relation: {entityName: "cars", refField: "id"}}, + "cars[].name": {relation: {entityName: "cars", refField: "name"}}, + "cars[].model": {relation: {entityName: "cars", refField: "model"}}, + "cars[].ownerId": {relation: {entityName: "cars", refField: "ownerId"}}, + "cars[].driverId": {relation: {entityName: "cars", refField: "driverId"}}, + "drives.id": {relation: {entityName: "drives", refField: "id"}}, + "drives.name": {relation: {entityName: "drives", refField: "name"}}, + "drives.model": {relation: {entityName: "drives", refField: "model"}}, + "drives.ownerId": {relation: {entityName: "drives", refField: "ownerId"}}, + "drives.driverId": {relation: {entityName: "drives", refField: "driverId"}} + }, + keyFields: ["id"], + joinMetadata: { + cars: {entity: Car, fieldName: "cars", refTable: "Car", refColumns: ["ownerId"], joinColumns: ["id"], 'type: psql:MANY_TO_ONE}, + drives: {entity: Car, fieldName: "drives", refTable: "Car", refColumns: ["driverId"], joinColumns: ["id"], 'type: psql:ONE_TO_ONE} + } + }, + [CAR]: { + entityName: "Car", + tableName: "Car", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + model: {columnName: "model"}, + ownerId: {columnName: "ownerId"}, + driverId: {columnName: "driverId"}, + "owner.id": {relation: {entityName: "owner", refField: "id"}}, + "owner.name": {relation: {entityName: "owner", refField: "name"}}, + "owner.gender": {relation: {entityName: "owner", refField: "gender"}}, + "owner.nic": {relation: {entityName: "owner", refField: "nic"}}, + "owner.salary": {relation: {entityName: "owner", refField: "salary"}}, + "driver.id": {relation: {entityName: "driver", refField: "id"}}, + "driver.name": {relation: {entityName: "driver", refField: "name"}}, + "driver.gender": {relation: {entityName: "driver", refField: "gender"}}, + "driver.nic": {relation: {entityName: "driver", refField: "nic"}}, + "driver.salary": {relation: {entityName: "driver", refField: "salary"}} + }, + keyFields: ["id"], + joinMetadata: { + owner: {entity: User, fieldName: "owner", refTable: "User", refColumns: ["id"], joinColumns: ["ownerId"], 'type: psql:ONE_TO_MANY}, + driver: {entity: User, fieldName: "driver", refTable: "User", refColumns: ["id"], joinColumns: ["driverId"], 'type: psql:ONE_TO_MANY} + } + } + }; + + public isolated function init() returns persist:Error? { + mysql:Client|error dbClient = new (host = host, user = user, password = password, database = database, port = port, options = connectionOptions); + if dbClient is error { + return error(dbClient.message()); + } + self.dbClient = dbClient; + self.persistClients = { + [USER]: check new (dbClient, self.metadata.get(USER), psql:MYSQL_SPECIFICS), + [CAR]: check new (dbClient, self.metadata.get(CAR), psql:MYSQL_SPECIFICS) + }; + } + + isolated resource function get users(UserTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get users/[int id](UserTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post users(UserInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from UserInsert inserted in data + select inserted.id; + } + + isolated resource function put users/[int id](UserUpdate value) returns User|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/users/[id].get(); + } + + isolated resource function delete users/[int id]() returns User|persist:Error { + User result = check self->/users/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + isolated resource function get cars(CarTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get cars/[int id](CarTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post cars(CarInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from CarInsert inserted in data + select inserted.id; + } + + isolated resource function put cars/[int id](CarUpdate value) returns Car|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/cars/[id].get(); + } + + isolated resource function delete cars/[int id]() returns Car|persist:Error { + Car result = check self->/cars/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + remote isolated function queryNativeSQL(sql:ParameterizedQuery sqlQuery, typedesc rowType = <>) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + remote isolated function executeNativeSQL(sql:ParameterizedQuery sqlQuery) returns psql:ExecutionResult|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + public isolated function close() returns persist:Error? { + error? result = self.dbClient.close(); + if result is error { + return error(result.message()); + } + return result; + } +} + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_93/modules/entities/persist_db_config.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_93/modules/entities/persist_db_config.bal new file mode 100644 index 000000000..aedfe37e0 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_93/modules/entities/persist_db_config.bal @@ -0,0 +1,12 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer. +// It should not be modified by hand. +import ballerinax/mysql; + +configurable int port = ?; +configurable string host = ?; +configurable string user = ?; +configurable string database = ?; +configurable string password = ?; +configurable mysql:Options & readonly connectionOptions = {}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_93/modules/entities/persist_types.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_93/modules/entities/persist_types.bal new file mode 100644 index 000000000..7631f16d5 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_93/modules/entities/persist_types.bal @@ -0,0 +1,76 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. + +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; +|}; + +public type UserOptionalized record {| + int id?; + string name?; + UserGender gender?; + string nic?; + decimal? salary?; +|}; + +public type UserWithRelations record {| + *UserOptionalized; + CarOptionalized[] cars?; + CarOptionalized drives?; +|}; + +public type UserTargetType typedesc; + +public type UserInsert User; + +public type UserUpdate record {| + string name?; + UserGender gender?; + string nic?; + decimal? salary?; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + int ownerId; + int driverId; +|}; + +public type CarOptionalized record {| + int id?; + string name?; + string model?; + int ownerId?; + int driverId?; +|}; + +public type CarWithRelations record {| + *CarOptionalized; + UserOptionalized owner?; + UserOptionalized driver?; +|}; + +public type CarTargetType typedesc; + +public type CarInsert Car; + +public type CarUpdate record {| + string name?; + string model?; + int ownerId?; + int driverId?; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_93/modules/entities/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_93/modules/entities/script.sql new file mode 100644 index 000000000..2f2f1c005 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_93/modules/entities/script.sql @@ -0,0 +1,30 @@ +-- AUTO-GENERATED FILE. + +-- This file is an auto-generated file by Ballerina persistence layer for model. +-- Please verify the generated scripts and execute them against the target DB server. + +DROP TABLE IF EXISTS `Car`; +DROP TABLE IF EXISTS `User`; + +CREATE TABLE `User` ( + `id` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `gender` ENUM('MALE', 'FEMALE') NOT NULL, + `nic` VARCHAR(191) NOT NULL, + `salary` DECIMAL(65,30), + PRIMARY KEY(`id`) +); + +CREATE TABLE `Car` ( + `id` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `model` VARCHAR(191) NOT NULL, + `ownerId` INT NOT NULL, + FOREIGN KEY(`ownerId`) REFERENCES `User`(`id`), + `driverId` INT NOT NULL, + FOREIGN KEY(`driverId`) REFERENCES `User`(`id`), + PRIMARY KEY(`id`) +); + + +CREATE INDEX `ownerId` ON `Car` (`ownerId`); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_93/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_93/persist/model.bal new file mode 100644 index 000000000..34068b66c --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_93/persist/model.bal @@ -0,0 +1,44 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; + Car[] cars; + Car? drives; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User owner; + User driver; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_93/target/Persist.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_93/target/Persist.toml new file mode 100644 index 000000000..3ee0e9acc --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_93/target/Persist.toml @@ -0,0 +1,3 @@ +[[tool.persist]] +options.datastore = "mysql" +module = "tool_test_generate_93.entities" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_94/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_94/Ballerina.toml new file mode 100644 index 000000000..3b199c62d --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_94/Ballerina.toml @@ -0,0 +1,14 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_generate_94" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +groupId = "io.ballerina.stdlib" +artifactId = "persist.sql-native" +version = "1.3.0-SNAPSHOT" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_94/Config.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_94/Config.toml new file mode 100644 index 000000000..7245b3204 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_94/Config.toml @@ -0,0 +1,7 @@ +[tool_test_generate_94.entities] +host = "localhost" +port = 3306 +user = "root" +password = "" +database = "" + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_94/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_94/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_94/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_94/modules/entities/persist_client.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_94/modules/entities/persist_client.bal new file mode 100644 index 000000000..11f067dc2 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_94/modules/entities/persist_client.bal @@ -0,0 +1,182 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. +import ballerina/jballerina.java; +import ballerina/persist; +import ballerina/sql; +import ballerinax/mysql; +import ballerinax/mysql.driver as _; +import ballerinax/persist.sql as psql; + +const USER = "users"; +const CAR = "cars"; + +public isolated client class Client { + *persist:AbstractPersistClient; + + private final mysql:Client dbClient; + + private final map persistClients; + + private final record {|psql:SQLMetadata...;|} & readonly metadata = { + [USER]: { + entityName: "User", + tableName: "User", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + gender: {columnName: "gender"}, + nic: {columnName: "nic"}, + salary: {columnName: "salary"}, + "cars[].id": {relation: {entityName: "cars", refField: "id"}}, + "cars[].name": {relation: {entityName: "cars", refField: "name"}}, + "cars[].model": {relation: {entityName: "cars", refField: "model"}}, + "cars[].ownerId": {relation: {entityName: "cars", refField: "ownerId"}}, + "cars[].driverId": {relation: {entityName: "cars", refField: "driverId"}}, + "drives.id": {relation: {entityName: "drives", refField: "id"}}, + "drives.name": {relation: {entityName: "drives", refField: "name"}}, + "drives.model": {relation: {entityName: "drives", refField: "model"}}, + "drives.ownerId": {relation: {entityName: "drives", refField: "ownerId"}}, + "drives.driverId": {relation: {entityName: "drives", refField: "driverId"}} + }, + keyFields: ["id"], + joinMetadata: { + cars: {entity: Car, fieldName: "cars", refTable: "Car", refColumns: ["ownerId"], joinColumns: ["id"], 'type: psql:MANY_TO_ONE}, + drives: {entity: Car, fieldName: "drives", refTable: "Car", refColumns: ["DRIVER_ID"], joinColumns: ["id"], 'type: psql:ONE_TO_ONE} + } + }, + [CAR]: { + entityName: "Car", + tableName: "Car", + fieldMetadata: { + id: {columnName: "id"}, + name: {columnName: "name"}, + model: {columnName: "model"}, + ownerId: {columnName: "ownerId"}, + driverId: {columnName: "DRIVER_ID"}, + "owner.id": {relation: {entityName: "owner", refField: "id"}}, + "owner.name": {relation: {entityName: "owner", refField: "name"}}, + "owner.gender": {relation: {entityName: "owner", refField: "gender"}}, + "owner.nic": {relation: {entityName: "owner", refField: "nic"}}, + "owner.salary": {relation: {entityName: "owner", refField: "salary"}}, + "driver.id": {relation: {entityName: "driver", refField: "id"}}, + "driver.name": {relation: {entityName: "driver", refField: "name"}}, + "driver.gender": {relation: {entityName: "driver", refField: "gender"}}, + "driver.nic": {relation: {entityName: "driver", refField: "nic"}}, + "driver.salary": {relation: {entityName: "driver", refField: "salary"}} + }, + keyFields: ["id"], + joinMetadata: { + owner: {entity: User, fieldName: "owner", refTable: "User", refColumns: ["id"], joinColumns: ["ownerId"], 'type: psql:ONE_TO_MANY}, + driver: {entity: User, fieldName: "driver", refTable: "User", refColumns: ["id"], joinColumns: ["DRIVER_ID"], 'type: psql:ONE_TO_MANY} + } + } + }; + + public isolated function init() returns persist:Error? { + mysql:Client|error dbClient = new (host = host, user = user, password = password, database = database, port = port, options = connectionOptions); + if dbClient is error { + return error(dbClient.message()); + } + self.dbClient = dbClient; + self.persistClients = { + [USER]: check new (dbClient, self.metadata.get(USER), psql:MYSQL_SPECIFICS), + [CAR]: check new (dbClient, self.metadata.get(CAR), psql:MYSQL_SPECIFICS) + }; + } + + isolated resource function get users(UserTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get users/[int id](UserTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post users(UserInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from UserInsert inserted in data + select inserted.id; + } + + isolated resource function put users/[int id](UserUpdate value) returns User|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/users/[id].get(); + } + + isolated resource function delete users/[int id]() returns User|persist:Error { + User result = check self->/users/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(USER); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + isolated resource function get cars(CarTargetType targetType = <>, sql:ParameterizedQuery whereClause = ``, sql:ParameterizedQuery orderByClause = ``, sql:ParameterizedQuery limitClause = ``, sql:ParameterizedQuery groupByClause = ``) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "query" + } external; + + isolated resource function get cars/[int id](CarTargetType targetType = <>) returns targetType|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor", + name: "queryOne" + } external; + + isolated resource function post cars(CarInsert[] data) returns int[]|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runBatchInsertQuery(data); + return from CarInsert inserted in data + select inserted.id; + } + + isolated resource function put cars/[int id](CarUpdate value) returns Car|persist:Error { + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runUpdateQuery(id, value); + return self->/cars/[id].get(); + } + + isolated resource function delete cars/[int id]() returns Car|persist:Error { + Car result = check self->/cars/[id].get(); + psql:SQLClient sqlClient; + lock { + sqlClient = self.persistClients.get(CAR); + } + _ = check sqlClient.runDeleteQuery(id); + return result; + } + + remote isolated function queryNativeSQL(sql:ParameterizedQuery sqlQuery, typedesc rowType = <>) returns stream = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + remote isolated function executeNativeSQL(sql:ParameterizedQuery sqlQuery) returns psql:ExecutionResult|persist:Error = @java:Method { + 'class: "io.ballerina.stdlib.persist.sql.datastore.MySQLProcessor" + } external; + + public isolated function close() returns persist:Error? { + error? result = self.dbClient.close(); + if result is error { + return error(result.message()); + } + return result; + } +} + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_94/modules/entities/persist_db_config.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_94/modules/entities/persist_db_config.bal new file mode 100644 index 000000000..aedfe37e0 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_94/modules/entities/persist_db_config.bal @@ -0,0 +1,12 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. +// This file is an auto-generated file by Ballerina persistence layer. +// It should not be modified by hand. +import ballerinax/mysql; + +configurable int port = ?; +configurable string host = ?; +configurable string user = ?; +configurable string database = ?; +configurable string password = ?; +configurable mysql:Options & readonly connectionOptions = {}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_94/modules/entities/persist_types.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_94/modules/entities/persist_types.bal new file mode 100644 index 000000000..7631f16d5 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_94/modules/entities/persist_types.bal @@ -0,0 +1,76 @@ +// AUTO-GENERATED FILE. DO NOT MODIFY. + +// This file is an auto-generated file by Ballerina persistence layer for model. +// It should not be modified by hand. + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; +|}; + +public type UserOptionalized record {| + int id?; + string name?; + UserGender gender?; + string nic?; + decimal? salary?; +|}; + +public type UserWithRelations record {| + *UserOptionalized; + CarOptionalized[] cars?; + CarOptionalized drives?; +|}; + +public type UserTargetType typedesc; + +public type UserInsert User; + +public type UserUpdate record {| + string name?; + UserGender gender?; + string nic?; + decimal? salary?; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + int ownerId; + int driverId; +|}; + +public type CarOptionalized record {| + int id?; + string name?; + string model?; + int ownerId?; + int driverId?; +|}; + +public type CarWithRelations record {| + *CarOptionalized; + UserOptionalized owner?; + UserOptionalized driver?; +|}; + +public type CarTargetType typedesc; + +public type CarInsert Car; + +public type CarUpdate record {| + string name?; + string model?; + int ownerId?; + int driverId?; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_94/modules/entities/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_94/modules/entities/script.sql new file mode 100644 index 000000000..e8971fade --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_94/modules/entities/script.sql @@ -0,0 +1,30 @@ +-- AUTO-GENERATED FILE. + +-- This file is an auto-generated file by Ballerina persistence layer for model. +-- Please verify the generated scripts and execute them against the target DB server. + +DROP TABLE IF EXISTS `Car`; +DROP TABLE IF EXISTS `User`; + +CREATE TABLE `User` ( + `id` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `gender` ENUM('MALE', 'FEMALE') NOT NULL, + `nic` VARCHAR(191) NOT NULL, + `salary` DECIMAL(65,30), + PRIMARY KEY(`id`) +); + +CREATE TABLE `Car` ( + `id` INT NOT NULL, + `name` VARCHAR(191) NOT NULL, + `model` VARCHAR(191) NOT NULL, + `ownerId` INT NOT NULL, + FOREIGN KEY(`ownerId`) REFERENCES `User`(`id`), + `DRIVER_ID` INT NOT NULL, + FOREIGN KEY(`DRIVER_ID`) REFERENCES `User`(`id`), + PRIMARY KEY(`id`) +); + + +CREATE INDEX `ownerId` ON `Car` (`ownerId`); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_94/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_94/persist/model.bal new file mode 100644 index 000000000..95cc426d9 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_94/persist/model.bal @@ -0,0 +1,47 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE, + FEMALE +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; + Car[] cars; + Car? drives; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User owner; + @sql:Mapping {name: "DRIVER_ID"} + int driverId; + @sql:Relation {refs: ["driverId"]} + User driver; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_94/target/Persist.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_94/target/Persist.toml new file mode 100644 index 000000000..a91688085 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_generate_94/target/Persist.toml @@ -0,0 +1,3 @@ +[[tool.persist]] +options.datastore = "mysql" +module = "tool_test_generate_94.entities" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_10_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_10_mysql/Ballerina.toml new file mode 100644 index 000000000..a7e235168 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_10_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_10_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_10_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_10_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_10_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_10_mysql/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_10_mysql/persist/model.bal new file mode 100644 index 000000000..1d17d632b --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_10_mysql/persist/model.bal @@ -0,0 +1,45 @@ +import ballerina/persist as _; +import ballerina/time; +import ballerinax/persist.sql; + +public enum PatientGender { + MALE = "MALE", + FEMALE = "FEMALE" +} + +@sql:Mapping {name: "appointment"} +public type Appointment record {| + readonly int id; + @sql:Mapping {name: "patient_Id"} + @sql:Index {names: ["patient_Id"]} + int patientId; + @sql:Mapping {name: "Doctor_Id"} + @sql:Index {names: ["Doctor_Id"]} + int doctorId; + time:Date date; + @sql:Relation {refs: ["patientId"]} + Patient patient; + @sql:Relation {refs: ["doctorId"]} + Doctor doctor; +|}; + +@sql:Mapping {name: "patients"} +public type Patient record {| + readonly int id; + string name; + @sql:Mapping {name: "GENDER"} + PatientGender gender; + @sql:Mapping {name: "NIC"} + string nic; + Appointment[] appointments; +|}; + +@sql:Mapping {name: "DOCTOR"} +public type Doctor record {| + readonly int id; + string name; + @sql:Mapping {name: "doctor_Specialty"} + string doctorSpecialty; + Appointment[] appointments; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_10_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_10_mysql/script.sql new file mode 100644 index 000000000..30d186f44 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_10_mysql/script.sql @@ -0,0 +1,44 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE patients ( + id INT, + name VARCHAR(191) NOT NULL, + GENDER ENUM ('MALE', 'FEMALE') NOT NULL, + NIC VARCHAR(191) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE DOCTOR ( + id INT, + name VARCHAR(191) NOT NULL, + doctor_Specialty VARCHAR(191) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE appointment ( + id INT, + patient_Id INT NOT NULL, + Doctor_Id INT NOT NULL, + date DATE NOT NULL, + PRIMARY KEY (id), + FOREIGN KEY (patient_Id) REFERENCES patients(id), + FOREIGN KEY (Doctor_Id) REFERENCES DOCTOR(id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_11_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_11_mysql/Ballerina.toml new file mode 100644 index 000000000..8c19993e8 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_11_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_11_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_11_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_11_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_11_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_11_mysql/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_11_mysql/persist/model.bal new file mode 100644 index 000000000..39721b998 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_11_mysql/persist/model.bal @@ -0,0 +1,43 @@ +import ballerina/persist as _; +import ballerina/time; +import ballerinax/persist.sql; + +public enum PatientGender { + MALE = "MALE", + FEMALE = "FEMALE" +} + +public type Appointment record {| + readonly int id; + @sql:Index {names: ["patientId"]} + int patientId; + @sql:Index {names: ["doctorId"]} + int doctorId; + time:Date date; + @sql:Relation {refs: ["patientId"]} + Patient patient; + @sql:Relation {refs: ["doctorId"]} + Doctor doctor; +|}; + +public type Patient record {| + readonly int id; + string name; + PatientGender gender; + @sql:VarChar {length: 12} + string nic; + @sql:Char {length: 10} + string contact; + Appointment[] appointments; +|}; + +public type Doctor record {| + readonly int id; + @sql:VarChar {length: 20} + string name; + string specialty; + @sql:Decimal {precision: [10, 2]} + decimal? salary; + Appointment[] appointments; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_11_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_11_mysql/script.sql new file mode 100644 index 000000000..74bd7d355 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_11_mysql/script.sql @@ -0,0 +1,46 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE Patient ( + id INT, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + nic VARCHAR(12) NOT NULL, + contact CHAR(10) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE Doctor ( + id INT, + name VARCHAR(20) NOT NULL, + specialty VARCHAR(191) NOT NULL, + salary DECIMAL(10,2), + PRIMARY KEY (id) +); + +CREATE TABLE Appointment ( + id INT, + patientId INT NOT NULL, + doctorId INT NOT NULL, + date DATE NOT NULL, + PRIMARY KEY (id), + FOREIGN KEY (patientId) REFERENCES Patient(id), + FOREIGN KEY (doctorId) REFERENCES Doctor(id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_12_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_12_mysql/Ballerina.toml new file mode 100644 index 000000000..74b0043a0 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_12_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_12_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_12_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_12_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_12_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_12_mysql/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_12_mysql/persist/model.bal new file mode 100644 index 000000000..4196cdbf7 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_12_mysql/persist/model.bal @@ -0,0 +1,20 @@ +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE = "MALE", + FEMALE = "FEMALE" +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal salary; + @sql:UniqueIndex {names: ["favorite"]} + string favColor; + @sql:UniqueIndex {names: ["favorite"]} + string favCar; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_12_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_12_mysql/script.sql new file mode 100644 index 000000000..e15c8bcb2 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_12_mysql/script.sql @@ -0,0 +1,31 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE User ( + id INT, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + nic VARCHAR(191) NOT NULL, + salary DECIMAL(65,30) NOT NULL, + favColor VARCHAR(191) NOT NULL, + favCar VARCHAR(191) NOT NULL, + UNIQUE INDEX favorite (favColor, favCar), + PRIMARY KEY (id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_13_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_13_mysql/Ballerina.toml new file mode 100644 index 000000000..881ecb37d --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_13_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_13_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_13_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_13_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_13_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_13_mysql/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_13_mysql/persist/model.bal new file mode 100644 index 000000000..af0838d9c --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_13_mysql/persist/model.bal @@ -0,0 +1,20 @@ +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE = "MALE", + FEMALE = "FEMALE" +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal salary; + @sql:Index {names: ["favorite"]} + string favColor; + @sql:Index {names: ["favorite"]} + string favCar; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_13_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_13_mysql/script.sql new file mode 100644 index 000000000..349076708 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_13_mysql/script.sql @@ -0,0 +1,31 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE User ( + id INT, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + nic VARCHAR(191) NOT NULL, + salary DECIMAL(65,30) NOT NULL, + favColor VARCHAR(191) NOT NULL, + favCar VARCHAR(191) NOT NULL, + INDEX favorite (favColor, favCar), + PRIMARY KEY (id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_14_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_14_mysql/Ballerina.toml new file mode 100644 index 000000000..341989b54 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_14_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_14_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_14_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_14_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_14_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_14_mysql/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_14_mysql/persist/model.bal new file mode 100644 index 000000000..a60ceae46 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_14_mysql/persist/model.bal @@ -0,0 +1,42 @@ +import ballerina/persist as _; +import ballerina/time; +import ballerinax/persist.sql; + +public enum PatientGender { + MALE = "MALE", + FEMALE = "FEMALE" +} + +public type Appointment record {| + readonly int id; + @sql:Index {names: ["patientId"]} + int patientId; + @sql:Index {names: ["doctorId"]} + int doctorId; + @sql:Index {names: ["assistantId"]} + int assistantId; + time:Date date; + @sql:Relation {refs: ["patientId"]} + Patient patient; + @sql:Relation {refs: ["doctorId"]} + Doctor doctor; + @sql:Relation {refs: ["assistantId"]} + Doctor doctor1; +|}; + +public type Patient record {| + readonly int id; + string name; + PatientGender gender; + string nic; + Appointment[] appointments; +|}; + +public type Doctor record {| + readonly int id; + string name; + string specialty; + Appointment[] appointments; + Appointment[] appointments1; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_14_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_14_mysql/script.sql new file mode 100644 index 000000000..85d01c601 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_14_mysql/script.sql @@ -0,0 +1,46 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE Patient ( + id INT, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + nic VARCHAR(191) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE Doctor ( + id INT, + name VARCHAR(191) NOT NULL, + specialty VARCHAR(191) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE Appointment ( + id INT, + patientId INT NOT NULL, + doctorId INT NOT NULL, + assistantId INT NOT NULL, + date DATE NOT NULL, + PRIMARY KEY (id), + FOREIGN KEY (patientId) REFERENCES Patient(id), + FOREIGN KEY (doctorId) REFERENCES Doctor(id), + FOREIGN KEY (assistantId) REFERENCES Doctor(id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_15_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_15_mysql/Ballerina.toml new file mode 100644 index 000000000..630907850 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_15_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_15_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_15_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_15_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_15_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_15_mysql/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_15_mysql/persist/model.bal new file mode 100644 index 000000000..4d7c2d381 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_15_mysql/persist/model.bal @@ -0,0 +1,18 @@ +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE = "MALE", + FEMALE = "FEMALE" +} + +public type User record {| + @sql:UniqueIndex {names: ["user"]} + readonly int id; + string name; + UserGender gender; + @sql:UniqueIndex {names: ["user", "user_nic"]} + string nic; + decimal salary; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_15_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_15_mysql/script.sql new file mode 100644 index 000000000..4ef2431b4 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_15_mysql/script.sql @@ -0,0 +1,30 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE User ( + id INT, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + nic VARCHAR(191) NOT NULL, + salary DECIMAL(65,30) NOT NULL, + PRIMARY KEY (id), + UNIQUE INDEX user (id,nic), + UNIQUE INDEX user_nic (nic) +); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_16_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_16_mysql/Ballerina.toml new file mode 100644 index 000000000..7ee00aaba --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_16_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_16_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_16_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_16_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_16_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_16_mysql/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_16_mysql/persist/model.bal new file mode 100644 index 000000000..a760224cd --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_16_mysql/persist/model.bal @@ -0,0 +1,18 @@ +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE = "MALE", + FEMALE = "FEMALE" +} + +public type User record {| + @sql:Index {names: ["user"]} + readonly int id; + string name; + UserGender gender; + @sql:Index {names: ["user", "user_nic"]} + string nic; + decimal salary; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_16_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_16_mysql/script.sql new file mode 100644 index 000000000..9e29a8002 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_16_mysql/script.sql @@ -0,0 +1,30 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE User ( + id INT, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + nic VARCHAR(191) NOT NULL, + salary DECIMAL(65,30) NOT NULL, + PRIMARY KEY (id), + INDEX user (id,nic), + INDEX user_nic (nic) +); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_17_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_17_mysql/Ballerina.toml new file mode 100644 index 000000000..9a1bdf7da --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_17_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_17_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_17_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_17_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_17_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_17_mysql/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_17_mysql/persist/model.bal new file mode 100644 index 000000000..b8a4939e6 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_17_mysql/persist/model.bal @@ -0,0 +1,29 @@ +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE = "MALE", + FEMALE = "FEMALE" +} + +public type User record {| + readonly string email; + readonly string nic; + string name; + UserGender gender; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Index {names: ["ownerEmail"]} + string ownerEmail; + @sql:Index {names: ["ownerEmail"]} + string ownerNic; + @sql:Relation {refs: ["ownerEmail", "ownerNic"]} + User user; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_17_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_17_mysql/script.sql new file mode 100644 index 000000000..4ac925f1c --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_17_mysql/script.sql @@ -0,0 +1,38 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE User ( + email VARCHAR(191) NOT NULL, + nic VARCHAR(191) NOT NULL, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + salary DECIMAL(65,30), + PRIMARY KEY (email, nic) +); + +CREATE TABLE Car ( + id INT, + name VARCHAR(191) NOT NULL, + model VARCHAR(191) NOT NULL, + ownerEmail VARCHAR(191) NOT NULL, + ownerNic VARCHAR(191) NOT NULL, + FOREIGN KEY (ownerEmail, ownerNic) REFERENCES User(email,nic), + PRIMARY KEY (id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_18_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_18_mysql/Ballerina.toml new file mode 100644 index 000000000..24778a7c8 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_18_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_18_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_18_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_18_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_18_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_18_mysql/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_18_mysql/persist/model.bal new file mode 100644 index 000000000..d3c06963f --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_18_mysql/persist/model.bal @@ -0,0 +1,18 @@ +import ballerina/persist as _; +import ballerinax/persist.sql; + +public type Employee record {| + readonly int id; + string? name; + string? email; + int? age; + @sql:Decimal {precision: [10, 2]} + decimal? salary; + @sql:Mapping {name: "managed_by"} + @sql:Index {names: ["managed_by"]} + int? managedBy; + Employee[] employees; + @sql:Relation {refs: ["managedBy"]} + Employee employee; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_18_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_18_mysql/script.sql new file mode 100644 index 000000000..e58493a4a --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_18_mysql/script.sql @@ -0,0 +1,30 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE Employee ( + id INT, + name VARCHAR(191), + email VARCHAR(191), + age INT, + salary DECIMAL(10,2), + managed_by INT, + PRIMARY KEY (id), + FOREIGN KEY (managed_by) REFERENCES Employee(id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_19_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_19_mysql/Ballerina.toml new file mode 100644 index 000000000..6ad912f38 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_19_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_19_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_19_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_19_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_19_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_19_mysql/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_19_mysql/persist/model.bal new file mode 100644 index 000000000..1064c70bb --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_19_mysql/persist/model.bal @@ -0,0 +1,32 @@ +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE = "MALE", + FEMALE = "FEMALE" +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + decimal? salary; + @sql:Mapping {name: "drives_car"} + @sql:Index {names: ["drives_car"]} + int? drivesCar; + Car[] cars; + @sql:Relation {refs: ["drivesCar"]} + Car car; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User user; + User[] users; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_19_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_19_mysql/script.sql new file mode 100644 index 000000000..5f91d75db --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_19_mysql/script.sql @@ -0,0 +1,39 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE User ( + id INT, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + salary DECIMAL(65,30), + drives_car INT, + PRIMARY KEY (id) +); + +CREATE TABLE Car ( + id INT, + name VARCHAR(191) NOT NULL, + model VARCHAR(191) NOT NULL, + ownerId INT NOT NULL, + FOREIGN KEY (ownerId) REFERENCES User(id), + PRIMARY KEY (id) +); + +ALTER TABLE User ADD FOREIGN KEY (drives_car) REFERENCES Car(id); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_1_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_1_mysql/Ballerina.toml new file mode 100644 index 000000000..f7af7cef6 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_1_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_1_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_1_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_1_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_1_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_1_mysql/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_1_mysql/persist/model.bal new file mode 100644 index 000000000..a2c3aefaf --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_1_mysql/persist/model.bal @@ -0,0 +1,15 @@ +import ballerina/persist as _; + +public enum UserGender { + MALE = "MALE", + FEMALE = "FEMALE" +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal salary; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_1_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_1_mysql/script.sql new file mode 100644 index 000000000..eba3731d0 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_1_mysql/script.sql @@ -0,0 +1,28 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE User ( + id INT, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + nic VARCHAR(191) NOT NULL, + salary DECIMAL(65,30) NOT NULL, + PRIMARY KEY (id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_20_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_20_mysql/Ballerina.toml new file mode 100644 index 000000000..4c719365b --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_20_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_20_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_20_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_20_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_20_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_20_mysql/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_20_mysql/persist/model.bal new file mode 100644 index 000000000..1bc953705 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_20_mysql/persist/model.bal @@ -0,0 +1,10 @@ +import ballerina/persist as _; + +public type Car record {| + readonly int id; + string name; + string 'type; + string model; + int ownerId; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_20_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_20_mysql/script.sql new file mode 100644 index 000000000..edb641b1c --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_20_mysql/script.sql @@ -0,0 +1,29 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + + +CREATE TABLE Car ( + id INT, + name VARCHAR(191) NOT NULL, + type VARCHAR (191) NOT NULL, + model VARCHAR(191) NOT NULL, + ownerId INT NOT NULL, + PRIMARY KEY (id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_21_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_21_mysql/Ballerina.toml new file mode 100644 index 000000000..92f6282b8 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_21_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_21_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_21_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_21_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_21_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_21_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_21_mysql/script.sql new file mode 100644 index 000000000..5bfd6bda7 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_21_mysql/script.sql @@ -0,0 +1,19 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_22_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_22_mysql/Ballerina.toml new file mode 100644 index 000000000..53979a76c --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_22_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_22_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_22_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_22_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_22_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_22_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_22_mysql/script.sql new file mode 100644 index 000000000..8fe133e93 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_22_mysql/script.sql @@ -0,0 +1,17 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_23/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_23/Ballerina.toml new file mode 100644 index 000000000..27329268a --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_23/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_23_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_23/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_23/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_23/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_24_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_24_mysql/Ballerina.toml new file mode 100644 index 000000000..cbd9822c9 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_24_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_24_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_24_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_24_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_24_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_24_mysql/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_24_mysql/persist/model.bal new file mode 100644 index 000000000..6ea9ffcf3 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_24_mysql/persist/model.bal @@ -0,0 +1,17 @@ +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE = "MALE", + FEMALE = "FEMALE" +} + +public type User record {| + @sql:Generated + readonly int id; + string name; + UserGender gender; + string nic; + decimal salary; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_24_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_24_mysql/script.sql new file mode 100644 index 000000000..778238087 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_24_mysql/script.sql @@ -0,0 +1,28 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE User ( + id INT AUTO_INCREMENT, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + nic VARCHAR(191) NOT NULL, + salary DECIMAL(65,30) NOT NULL, + PRIMARY KEY (id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_25_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_25_mysql/Ballerina.toml new file mode 100644 index 000000000..2882e8c3b --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_25_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_25_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_25_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_25_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_25_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_25_mysql/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_25_mysql/persist/model.bal new file mode 100644 index 000000000..9e3f2da47 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_25_mysql/persist/model.bal @@ -0,0 +1,16 @@ +import ballerina/persist as _; + +public enum UserGender { + MALE = "MALE", + FEMALE = "FEMALE" +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal salary; + byte[]? userProfilePic; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_25_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_25_mysql/script.sql new file mode 100644 index 000000000..d0a345d95 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_25_mysql/script.sql @@ -0,0 +1,29 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE User ( + id INT, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + nic VARCHAR(191) NOT NULL, + salary DECIMAL(65,30) NOT NULL, + userProfilePic BLOB, + PRIMARY KEY (id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_2_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_2_mysql/Ballerina.toml new file mode 100644 index 000000000..1c0c9ddd6 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_2_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_2_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_2_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_2_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_2_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_2_mysql/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_2_mysql/persist/model.bal new file mode 100644 index 000000000..f08521d0c --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_2_mysql/persist/model.bal @@ -0,0 +1,15 @@ +import ballerina/persist as _; + +public enum UserGender { + MALE = "MALE", + FEMALE = "FEMALE" +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_2_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_2_mysql/script.sql new file mode 100644 index 000000000..b2dfcf02c --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_2_mysql/script.sql @@ -0,0 +1,28 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE User ( + id INT, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + nic VARCHAR(191) NOT NULL, + salary DECIMAL(65,30), + PRIMARY KEY (id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_3_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_3_mysql/Ballerina.toml new file mode 100644 index 000000000..7cec8b7e5 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_3_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_3_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_3_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_3_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_3_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_3_mysql/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_3_mysql/persist/model.bal new file mode 100644 index 000000000..8fe31eb0f --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_3_mysql/persist/model.bal @@ -0,0 +1,26 @@ +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE = "MALE", + FEMALE = "FEMALE" +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_3_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_3_mysql/script.sql new file mode 100644 index 000000000..e47632bab --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_3_mysql/script.sql @@ -0,0 +1,37 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE User ( + id INT, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + nic VARCHAR(191) NOT NULL, + salary DECIMAL(65,30), + PRIMARY KEY (id) +); + +CREATE TABLE Car ( + id INT, + name VARCHAR(191) NOT NULL, + model VARCHAR(191) NOT NULL, + ownerId INT NOT NULL, + FOREIGN KEY (ownerId) REFERENCES User(id), + PRIMARY KEY (id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_4_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_4_mysql/Ballerina.toml new file mode 100644 index 000000000..6043641b0 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_4_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_4_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_4_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_4_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_4_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_4_mysql/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_4_mysql/persist/model.bal new file mode 100644 index 000000000..8fe31eb0f --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_4_mysql/persist/model.bal @@ -0,0 +1,26 @@ +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE = "MALE", + FEMALE = "FEMALE" +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; + Car[] cars; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:Index {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User user; +|}; diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_4_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_4_mysql/script.sql new file mode 100644 index 000000000..e47632bab --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_4_mysql/script.sql @@ -0,0 +1,37 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE User ( + id INT, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + nic VARCHAR(191) NOT NULL, + salary DECIMAL(65,30), + PRIMARY KEY (id) +); + +CREATE TABLE Car ( + id INT, + name VARCHAR(191) NOT NULL, + model VARCHAR(191) NOT NULL, + ownerId INT NOT NULL, + FOREIGN KEY (ownerId) REFERENCES User(id), + PRIMARY KEY (id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_5_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_5_mysql/Ballerina.toml new file mode 100644 index 000000000..23ac92d4b --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_5_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_5_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_5_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_5_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_5_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_5_mysql/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_5_mysql/persist/model.bal new file mode 100644 index 000000000..65eb21cf7 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_5_mysql/persist/model.bal @@ -0,0 +1 @@ +import ballerina/persist as _; \ No newline at end of file diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_5_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_5_mysql/script.sql new file mode 100644 index 000000000..e47632bab --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_5_mysql/script.sql @@ -0,0 +1,37 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE User ( + id INT, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + nic VARCHAR(191) NOT NULL, + salary DECIMAL(65,30), + PRIMARY KEY (id) +); + +CREATE TABLE Car ( + id INT, + name VARCHAR(191) NOT NULL, + model VARCHAR(191) NOT NULL, + ownerId INT NOT NULL, + FOREIGN KEY (ownerId) REFERENCES User(id), + PRIMARY KEY (id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_6_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_6_mysql/Ballerina.toml new file mode 100644 index 000000000..2de97d10e --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_6_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_6_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_6_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_6_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_6_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_6_mysql/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_6_mysql/persist/model.bal new file mode 100644 index 000000000..573edb1e3 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_6_mysql/persist/model.bal @@ -0,0 +1,27 @@ +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE = "MALE", + FEMALE = "FEMALE" +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; + Car? car; +|}; + +public type Car record {| + readonly int id; + string name; + string model; + @sql:UniqueIndex {names: ["ownerId"]} + int ownerId; + @sql:Relation {refs: ["ownerId"]} + User user; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_6_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_6_mysql/script.sql new file mode 100644 index 000000000..24328ec18 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_6_mysql/script.sql @@ -0,0 +1,37 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE User ( + id INT, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + nic VARCHAR(191) NOT NULL, + salary DECIMAL(65,30), + PRIMARY KEY (id) +); + +CREATE TABLE Car ( + id INT, + name VARCHAR(191) NOT NULL, + model VARCHAR(191) NOT NULL, + ownerId INT UNIQUE NOT NULL, + FOREIGN KEY (ownerId) REFERENCES User(id), + PRIMARY KEY (id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_7_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_7_mysql/Ballerina.toml new file mode 100644 index 000000000..6430c335a --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_7_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_7_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_7_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_7_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_7_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_7_mysql/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_7_mysql/persist/model.bal new file mode 100644 index 000000000..c1a2165c9 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_7_mysql/persist/model.bal @@ -0,0 +1,25 @@ +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE = "MALE", + FEMALE = "FEMALE" +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; + Phone? phone; +|}; + +public type Phone record {| + @sql:Mapping {name: "user_id"} + readonly int userId; + string number; + @sql:Relation {refs: ["userId"]} + User user; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_7_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_7_mysql/script.sql new file mode 100644 index 000000000..a4ca49238 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_7_mysql/script.sql @@ -0,0 +1,35 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE User ( + id INT, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + nic VARCHAR(191) NOT NULL, + salary DECIMAL(65,30), + PRIMARY KEY (id) +); + +CREATE TABLE Phone ( + user_id INT, + number VARCHAR(191) NOT NULL, + PRIMARY KEY (user_id), + FOREIGN KEY (user_id) REFERENCES User(id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_8_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_8_mysql/Ballerina.toml new file mode 100644 index 000000000..2e9b80f0e --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_8_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_8_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_8_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_8_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_8_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_8_mysql/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_8_mysql/persist/model.bal new file mode 100644 index 000000000..072a0ee55 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_8_mysql/persist/model.bal @@ -0,0 +1,25 @@ +import ballerina/persist as _; +import ballerinax/persist.sql; + +public enum UserGender { + MALE = "MALE", + FEMALE = "FEMALE" +} + +public type User record {| + readonly int id; + string name; + UserGender gender; + string nic; + decimal? salary; + Phone[] phones; +|}; + +public type Phone record {| + @sql:Mapping {name: "user_id"} + readonly int userId; + readonly string number; + @sql:Relation {refs: ["userId"]} + User user; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_8_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_8_mysql/script.sql new file mode 100644 index 000000000..4f74c6fe4 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_8_mysql/script.sql @@ -0,0 +1,35 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE User ( + id INT, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + nic VARCHAR(191) NOT NULL, + salary DECIMAL(65,30), + PRIMARY KEY (id) +); + +CREATE TABLE Phone ( + user_id INT, + number VARCHAR(191) NOT NULL, + PRIMARY KEY (user_id, number), + FOREIGN KEY (user_id) REFERENCES User(id) +); diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_9_mysql/Ballerina.toml b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_9_mysql/Ballerina.toml new file mode 100644 index 000000000..502f55df5 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_9_mysql/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +distribution = "2201.8.4" +name = "tool_test_pull_9_mysql" +org = "wso2" +version = "0.1.0" + +[build-options] +observabilityIncluded = true + +[[platform.java17.dependency]] +artifactId = "persist.sql-native" +groupId = "io.ballerina.stdlib" +version = "1.2.0" diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_9_mysql/main.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_9_mysql/main.bal new file mode 100644 index 000000000..eda9833de --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_9_mysql/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +// +// WSO2 LLC. licenses this file to you 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 +// +// http://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. + +import ballerina/io; + +public function main() { + io:println("Hello, World!"); +} diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_9_mysql/persist/model.bal b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_9_mysql/persist/model.bal new file mode 100644 index 000000000..5dc23483a --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_9_mysql/persist/model.bal @@ -0,0 +1,37 @@ +import ballerina/persist as _; +import ballerina/time; +import ballerinax/persist.sql; + +public enum PatientGender { + MALE = "MALE", + FEMALE = "FEMALE" +} + +public type Appointment record {| + readonly int id; + @sql:Index {names: ["patientId"]} + int patientId; + @sql:Index {names: ["doctorId"]} + int doctorId; + time:Date date; + @sql:Relation {refs: ["patientId"]} + Patient patient; + @sql:Relation {refs: ["doctorId"]} + Doctor doctor; +|}; + +public type Patient record {| + readonly int id; + string name; + PatientGender gender; + string nic; + Appointment[] appointments; +|}; + +public type Doctor record {| + readonly int id; + string name; + string specialty; + Appointment[] appointments; +|}; + diff --git a/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_9_mysql/script.sql b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_9_mysql/script.sql new file mode 100644 index 000000000..1ef720a31 --- /dev/null +++ b/persist-cli-tests/src/test/resources/test-src/output/tool_test_pull_9_mysql/script.sql @@ -0,0 +1,44 @@ +-- Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). +-- +-- WSO2 LLC. licenses this file to you 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 +-- +-- http://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. + +DROP DATABASE IF EXISTS persist; +CREATE DATABASE persist; +USE persist; + +CREATE TABLE Patient ( + id INT, + name VARCHAR(191) NOT NULL, + gender ENUM ('MALE', 'FEMALE') NOT NULL, + nic VARCHAR(191) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE Doctor ( + id INT, + name VARCHAR(191) NOT NULL, + specialty VARCHAR(191) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE Appointment ( + id INT, + patientId INT NOT NULL, + doctorId INT NOT NULL, + date DATE NOT NULL, + PRIMARY KEY (id), + FOREIGN KEY (patientId) REFERENCES Patient(id), + FOREIGN KEY (doctorId) REFERENCES Doctor(id) +); diff --git a/persist-cli/src/main/java/io/ballerina/persist/PersistToolsConstants.java b/persist-cli/src/main/java/io/ballerina/persist/PersistToolsConstants.java index d8e142694..72375900d 100644 --- a/persist-cli/src/main/java/io/ballerina/persist/PersistToolsConstants.java +++ b/persist-cli/src/main/java/io/ballerina/persist/PersistToolsConstants.java @@ -64,6 +64,7 @@ private PersistToolsConstants() {} public static final String MSSQL_CONNECTOR_NAME_PREFIX = "mssql-jdbc"; public static final String POSTGRESQL_CONNECTOR_NAME_PREFIX = "postgresql"; public static final String SCHEMA_FILE_NAME = "model"; + public static final Set SUPPORTED_DB_PROVIDERS = Set.of(SupportedDataSources.MYSQL_DB, SupportedDataSources.MSSQL_DB, SupportedDataSources.IN_MEMORY_TABLE, SupportedDataSources.GOOGLE_SHEETS, SupportedDataSources.POSTGRESQL_DB); @@ -100,12 +101,14 @@ private SqlTypes() {} public static final String DOUBLE = "DOUBLE"; public static final String FLOAT = "FLOAT"; public static final String VARCHAR = "VARCHAR"; + public static final String CHAR = "CHAR"; public static final String DATE = "DATE"; public static final String TIME = "TIME"; public static final String TIME_STAMP = "TIMESTAMP"; public static final String DATE_TIME = "DATETIME"; public static final String DATE_TIME2 = "DATETIME2"; public static final String LONG_BLOB = "LONGBLOB"; + public static final String BLOB = "BLOB"; public static final String VARBINARY = "VARBINARY(MAX)"; public static final String BYTEA = "BYTEA"; } diff --git a/persist-cli/src/main/java/io/ballerina/persist/cmd/PersistCmd.java b/persist-cli/src/main/java/io/ballerina/persist/cmd/PersistCmd.java index 91a2cd1aa..0a137604e 100644 --- a/persist-cli/src/main/java/io/ballerina/persist/cmd/PersistCmd.java +++ b/persist-cli/src/main/java/io/ballerina/persist/cmd/PersistCmd.java @@ -34,7 +34,7 @@ @CommandLine.Command( name = "persist", description = "generate database configurations.", - subcommands = {Init.class, Generate.class, Push.class, Migrate.class, Add.class} + subcommands = {Init.class, Generate.class, Push.class, Migrate.class, Add.class, Pull.class} ) public class PersistCmd implements BLauncherCmd { diff --git a/persist-cli/src/main/java/io/ballerina/persist/cmd/Pull.java b/persist-cli/src/main/java/io/ballerina/persist/cmd/Pull.java new file mode 100644 index 000000000..3cbd0aa48 --- /dev/null +++ b/persist-cli/src/main/java/io/ballerina/persist/cmd/Pull.java @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you 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 + * + * http://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 io.ballerina.persist.cmd; + +import io.ballerina.cli.BLauncherCmd; +import io.ballerina.persist.BalException; +import io.ballerina.persist.PersistToolsConstants; +import io.ballerina.persist.configuration.DatabaseConfiguration; +import io.ballerina.persist.configuration.PersistConfiguration; +import io.ballerina.persist.introspect.Introspector; +import io.ballerina.persist.introspect.MySqlIntrospector; +import io.ballerina.persist.models.Module; +import io.ballerina.persist.nodegenerator.DriverResolver; +import io.ballerina.persist.nodegenerator.SourceGenerator; +import io.ballerina.persist.utils.DatabaseConnector; +import io.ballerina.persist.utils.JdbcDriverLoader; +import io.ballerina.projects.Project; +import picocli.CommandLine; + +import java.io.IOException; +import java.io.PrintStream; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.sql.Connection; +import java.sql.Driver; +import java.sql.SQLException; +import java.util.Locale; +import java.util.Scanner; + +import static io.ballerina.persist.PersistToolsConstants.MYSQL_DRIVER_CLASS; +import static io.ballerina.persist.PersistToolsConstants.PERSIST_DIRECTORY; +import static io.ballerina.persist.nodegenerator.syntax.constants.BalSyntaxConstants.JDBC_URL_WITH_DATABASE_MYSQL; +import static io.ballerina.persist.utils.BalProjectUtils.validateBallerinaProject; +import static io.ballerina.persist.utils.BalProjectUtils.validatePullCommandOptions; +import static io.ballerina.persist.utils.DatabaseConnector.readDatabasePassword; + +@CommandLine.Command( + name = "pull", + description = "Create model.bal file according to given database schema") +public class Pull implements BLauncherCmd { + private static final PrintStream errStream = System.err; + + private final String sourcePath; + + private static final String COMMAND_IDENTIFIER = "persist-pull"; + + DatabaseConnector databaseConnector; + + public Pull() { + this(""); + } + + public Pull(String sourcePath) { + this.sourcePath = sourcePath; + } + + @CommandLine.Option(names = {"--datastore"}) + private String datastore = "mysql"; + + @CommandLine.Option(names = {"--host"}) + private String host; + + @CommandLine.Option(names = {"--port"}) + private String port = "3306"; + + @CommandLine.Option(names = {"--user"}) + private String user; + + @CommandLine.Option(names = {"--database"}) + private String database; + + @CommandLine.Option(names = { "-h", "--help" }, hidden = true) + private boolean helpFlag; + + @Override + public void execute() { + Scanner scanner = new Scanner(System.in, StandardCharsets.UTF_8); + if (helpFlag) { + String commandUsageInfo = BLauncherCmd.getCommandUsageInfo(COMMAND_IDENTIFIER); + errStream.println(commandUsageInfo); + return; + } + try { + validatePullCommandOptions(datastore, host, port, user, database); + } catch (BalException e) { + errStream.println("ERROR: invalid option(s): " + System.lineSeparator() + e.getMessage()); + return; + } + + String password = readDatabasePassword(scanner, errStream); + + try { + validateBallerinaProject(Paths.get(this.sourcePath)); + } catch (BalException e) { + errStream.println(e.getMessage()); + return; + } + + if (this.datastore.equals(PersistToolsConstants.SupportedDataSources.MYSQL_DB)) { + this.databaseConnector = new DatabaseConnector(JDBC_URL_WITH_DATABASE_MYSQL, MYSQL_DRIVER_CLASS); + } else { + errStream.printf("ERROR: unsupported data store: '%s'%n", datastore); + return; + } + + Path persistDir = Paths.get(this.sourcePath, PERSIST_DIRECTORY); + if (!Files.exists(persistDir)) { + try { + Files.createDirectory(persistDir.toAbsolutePath()); + } catch (IOException e) { + errStream.println("ERROR: failed to create the persist directory. " + e.getMessage()); + return; + } + } + + boolean modelFile = Files.exists(Path.of(String.valueOf(persistDir), "model.bal")); + if (modelFile) { + String yellowColor = "\u001B[33m"; + String resetColor = "\u001B[0m"; + errStream.print(yellowColor + "[WARNING] A model.bal file already exists. " + + "Continuing would overwrite it. Do you wish to continue? (y/n) " + resetColor); + String input = scanner.nextLine(); + if (!(input.toLowerCase(Locale.ENGLISH).equals("y") || input.toLowerCase(Locale.ENGLISH).equals("yes"))) { + errStream.println("Introspection aborted."); + return; + } + errStream.println("Continuing..."); + } + + PersistConfiguration persistConfigurations = new PersistConfiguration(); + persistConfigurations.setProvider(datastore); + try { + persistConfigurations.setDbConfig(new DatabaseConfiguration(this.host, this.user, password, this.port, + this.database)); + } catch (BalException e) { + errStream.println(e.getMessage()); + return; + } + + Module entityModule; + DriverResolver driverResolver = new DriverResolver(this.sourcePath); + Project driverProject; + try { + driverProject = driverResolver.resolveDriverDependencies(); + } catch (BalException e) { + errStream.println(e.getMessage()); + deleteDriverFile(driverResolver); + return; + } + + try (JdbcDriverLoader driverLoader = databaseConnector.getJdbcDriverLoader(driverProject)) { + Driver driver = databaseConnector.getJdbcDriver(driverLoader); + + try (Connection connection = databaseConnector.getConnection(driver, persistConfigurations, true)) { + + Introspector introspector = new MySqlIntrospector(connection, + persistConfigurations.getDbConfig().getDatabase()); + + entityModule = introspector.introspectDatabase(); + + if (entityModule == null) { + throw new BalException("ERROR: failed to generate entity module."); + } + + } catch (SQLException e) { + errStream.printf("ERROR: database failure. %s%n", e.getMessage()); + deleteDriverFile(driverResolver); + return; + } + } catch (BalException e) { + errStream.printf("ERROR: database introspection failed. %s%n", e.getMessage()); + deleteDriverFile(driverResolver); + return; + } catch (IOException e) { + errStream.printf("ERROR: failed to load the database driver. %s%n", e.getMessage()); + deleteDriverFile(driverResolver); + return; + } + + SourceGenerator sourceGenerator = new SourceGenerator(sourcePath, Paths.get(sourcePath, PERSIST_DIRECTORY), + "Introspect.db", entityModule); + + try { + sourceGenerator.createDbModel(); + } catch (BalException e) { + errStream.printf(String.format("ERROR: failed to generate model for introspected database: %s%n", + e.getMessage())); + deleteDriverFile(driverResolver); + return; + } + + deleteDriverFile(driverResolver); + errStream.println("Introspection complete! The model.bal file created successfully."); + } + + @Override + public String getName() { + return null; + } + + @Override + public void printLongDesc(StringBuilder stringBuilder) { + + } + + @Override + public void printUsage(StringBuilder stringBuilder) { + + } + + @Override + public void setParentCmdParser(CommandLine commandLine) { + + } + + public void deleteDriverFile(DriverResolver driverResolver) { + try { + driverResolver.deleteDriverFile(); + } catch (BalException e) { + errStream.println(e.getMessage()); + } + } +} diff --git a/persist-cli/src/main/java/io/ballerina/persist/configuration/DatabaseConfiguration.java b/persist-cli/src/main/java/io/ballerina/persist/configuration/DatabaseConfiguration.java index 369b7826c..75434cf12 100644 --- a/persist-cli/src/main/java/io/ballerina/persist/configuration/DatabaseConfiguration.java +++ b/persist-cli/src/main/java/io/ballerina/persist/configuration/DatabaseConfiguration.java @@ -34,6 +34,15 @@ public class DatabaseConfiguration { private int port; private String database; + public DatabaseConfiguration(String host, String username, String password, String port, String database) + throws BalException { + this.host = host; + this.username = username; + this.password = password; + this.port = Integer.parseInt(port); + this.database = DataBaseValidationUtils.validateDatabaseInput(database); + } + public DatabaseConfiguration(String modelName, NodeList nodeList) throws BalException { for (KeyValueNode member : nodeList) { diff --git a/persist-cli/src/main/java/io/ballerina/persist/inflector/CaseConverter.java b/persist-cli/src/main/java/io/ballerina/persist/inflector/CaseConverter.java new file mode 100644 index 000000000..12e89c2fb --- /dev/null +++ b/persist-cli/src/main/java/io/ballerina/persist/inflector/CaseConverter.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you 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 + * + * http://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 io.ballerina.persist.inflector; + +import java.util.Arrays; +import java.util.Locale; + +public class CaseConverter { + private CaseConverter() {} + public static String toPascalCase(String word) { + return arrayToPascalCase(split(word)); + } + public static String toCamelCase(String word) { + String pascalsCase = arrayToPascalCase(split(word)); + return pascalsCase.substring(0, 1).toLowerCase(Locale.ENGLISH) + pascalsCase.substring(1); + } + + public static String toSingularPascalCase(String word) { + String[] words = split(word); + words = Arrays.stream(words).map(Singularizer::singularize).toArray(String[]::new); + return arrayToPascalCase(words); + } + + private static String arrayToPascalCase(String[] words) { + StringBuilder result = new StringBuilder(); + for (String item: words) { + if (!item.isEmpty()) { + // Capitalize the first letter of each word + result.append(Character.toUpperCase(item.charAt(0))); + result.append(item.substring(1).toLowerCase(Locale.ENGLISH)); + } + } + return result.toString(); + } + private static String[] split(String value) { + String splitUpperUpperRe = "([\\p{Ll}\\d])(\\p{Lu})"; + String splitLowerUpperRe = "([\\p{Ll}\\d])(\\p{Lu})"; + String splitReplaceValue = "$1\0$2"; + String result = value.replaceAll(splitLowerUpperRe, splitReplaceValue) + .replaceAll(splitUpperUpperRe, splitReplaceValue); + String defaultStripRegexp = "[^\\p{L}\\d]+"; + result = result.replaceAll(defaultStripRegexp, "\0"); + int start = 0; + int end = result.length(); + while (result.charAt(start) == '\0') { + start++; + } + while (result.charAt(end - 1) == '\0') { + end--; + } + return Arrays.stream(result.substring(start, end) + .split("\0")) + .map(String::trim) + .map(String::toLowerCase) + .toArray(String[]::new); + } +} diff --git a/persist-cli/src/main/java/io/ballerina/persist/plural/Pluralizer.java b/persist-cli/src/main/java/io/ballerina/persist/inflector/Pluralizer.java similarity index 97% rename from persist-cli/src/main/java/io/ballerina/persist/plural/Pluralizer.java rename to persist-cli/src/main/java/io/ballerina/persist/inflector/Pluralizer.java index a883dab34..e6c2c530d 100644 --- a/persist-cli/src/main/java/io/ballerina/persist/plural/Pluralizer.java +++ b/persist-cli/src/main/java/io/ballerina/persist/inflector/Pluralizer.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations * under the License. */ -package io.ballerina.persist.plural; +package io.ballerina.persist.inflector; import java.util.regex.Matcher; import java.util.regex.Pattern; diff --git a/persist-cli/src/main/java/io/ballerina/persist/plural/Rules.java b/persist-cli/src/main/java/io/ballerina/persist/inflector/Rules.java similarity index 75% rename from persist-cli/src/main/java/io/ballerina/persist/plural/Rules.java rename to persist-cli/src/main/java/io/ballerina/persist/inflector/Rules.java index bb6923427..951bb98bf 100644 --- a/persist-cli/src/main/java/io/ballerina/persist/plural/Rules.java +++ b/persist-cli/src/main/java/io/ballerina/persist/inflector/Rules.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations * under the License. */ -package io.ballerina.persist.plural; +package io.ballerina.persist.inflector; import java.util.Arrays; import java.util.List; @@ -84,9 +84,14 @@ private Rules() {} {"groove", "grooves"}, {"pickaxe", "pickaxes"}, {"passerby", "passersby"}, - {"canvas", "canvases"} + {"canvas", "canvases"}, + {"mango", "mangoes"} }); + static final String[][] SINGULAR_IRREGULAR_RULES = { + {"have", "have"} + }; + // Pluralization rules. static final String[][] PLURALIZATION_RULES = (new String[][]{ {"[^\u0000-\u007F]$", "$0"}, @@ -118,6 +123,36 @@ private Rules() {} {"s?$", "s"} }); + static final String[][] SINGULARIZATION_RULES = (new String[][]{ + {"(ss)$", "$1"}, + {"(wi|kni|(?:after|half|high|low|mid|non|night|[^\\w]|^)li)ves$", "$1fe"}, + {"(ar|(?:wo|[ae])l|[eo][ao])ves$", "$1f"}, + {"ies$", "y"}, + {"(dg|ss|ois|lk|ok|wn|mb|th|ch|ec|oal|is|ck|ix|sser|ts|wb)ies$", "$1ie"}, + {"\b(l|(?:neck|cross|hog|aun)?t|coll|faer|food|gen|goon|group|hipp|junk|vegg|(?:pork)?p|charl|calor|cut" + + ")ies$", "$1ie"}, + {"\b(mon|smil)ies$", "$1ey"}, + {"\b((?:tit)?m|l)ice$", "$1ouse"}, + {"(seraph|cherub)im$", "$1"}, + {"(x|ch|ss|sh|zz|tto|go|cho|alias|[^aou]us|t[lm]as|gas|(?:her|at|gr)o|[aeiou]ris)(?:es)?$", "$1"}, + {"(analy|diagno|parenthe|progno|synop|the|empha|cri|ne)(?:sis|ses)$", "$1sis"}, + {"(movie|twelve|abuse|e[mn]u)s$", "$1"}, + {"(test)(?:is|es)$", "$1is"}, + {"(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$", "$1us"}, + {"(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|" + + "quor)a$", "$1um"}, + {"(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)a$", "$1on"}, + {"(alumn|alg|vertebr)ae$", "$1a"}, + {"(cod|mur|sil|vert|ind)ices$", "$1ex"}, + {"(matr|append)ices$", "$1ix"}, + {"(pe)(rson|ople)$", "$1rson"}, + {"(child)ren$", "$1"}, + {"(eau)x?$", "$1"}, + {"men$", "man"}, + {"s$", ""}, + }); + + // Uncountable rules. static final List UNCOUNTABLE_RULES = Arrays.asList( // Singular words with no plurals. @@ -139,6 +174,7 @@ private Rules() {} "^[a-z]*measles$", "^[a-z]*o[iu]s$", // "carnivorous" "^[a-z]*pox$", // "chickpox", "smallpox" - "^[a-z]*sheep$" + "^[a-z]*sheep$", + "species" ); } diff --git a/persist-cli/src/main/java/io/ballerina/persist/inflector/Singularizer.java b/persist-cli/src/main/java/io/ballerina/persist/inflector/Singularizer.java new file mode 100644 index 000000000..52a78a2ea --- /dev/null +++ b/persist-cli/src/main/java/io/ballerina/persist/inflector/Singularizer.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you 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 + * + * http://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 io.ballerina.persist.inflector; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Singularizer { + private Singularizer() {} + + public static String singularize(String word) { + for (String rule : Rules.UNCOUNTABLE_RULES) { + if (Pattern.matches(rule, word)) { + return word; + } + } + for (String[] irregularRule: Rules.SINGULAR_IRREGULAR_RULES) { + if (irregularRule[0].equals(word)) { + return word; + } + if (irregularRule[1].equals(word)) { + return irregularRule[0]; + } + } + for (String[] irregularRule: Rules.IRREGULAR_RULES) { + if (irregularRule[0].equals(word)) { + return word; + } + if (irregularRule[1].equals(word)) { + return irregularRule[0]; + } + } + for (String[] singularizationRule: Rules.SINGULARIZATION_RULES) { + Matcher matcher = Pattern.compile(singularizationRule[0]).matcher(word); + if (matcher.find()) { + return matcher.replaceFirst(singularizationRule[1]); + } + } + return word; + } +} diff --git a/persist-cli/src/main/java/io/ballerina/persist/introspect/Introspector.java b/persist-cli/src/main/java/io/ballerina/persist/introspect/Introspector.java new file mode 100644 index 000000000..c990c3fa4 --- /dev/null +++ b/persist-cli/src/main/java/io/ballerina/persist/introspect/Introspector.java @@ -0,0 +1,279 @@ +/* + * Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you 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 + * + * http://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 io.ballerina.persist.introspect; + +import io.ballerina.persist.inflector.CaseConverter; +import io.ballerina.persist.inflector.Pluralizer; +import io.ballerina.persist.introspectiondto.SqlEnum; +import io.ballerina.persist.introspectiondto.SqlForeignKey; +import io.ballerina.persist.introspectiondto.SqlTable; +import io.ballerina.persist.models.Entity; +import io.ballerina.persist.models.EntityField; +import io.ballerina.persist.models.Enum; +import io.ballerina.persist.models.EnumMember; +import io.ballerina.persist.models.Index; +import io.ballerina.persist.models.Module; +import io.ballerina.persist.models.Relation; +import io.ballerina.persist.models.SQLType; +import io.ballerina.persist.utils.ScriptRunner; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static java.lang.Integer.parseInt; + +/** + * Database Introspector class. + * + * + */ +public abstract class Introspector { + + protected final Connection connection; + protected String databaseName; + protected abstract String getTablesQuery(); + protected abstract String getColumnsQuery(String tableName); + protected abstract String getIndexesQuery(String tableName); + protected abstract String getForeignKeysQuery(String tableName); + protected abstract String getEnumsQuery(); + + private List tables; + + private List sqlEnums; + private final Module.Builder moduleBuilder; + + private final Map entityMap; + + private final List sqlForeignKeys; + + public Introspector(Connection connection, String databaseName) { + this.connection = connection; + this.databaseName = databaseName; + this.tables = new ArrayList<>(); + this.entityMap = new HashMap<>(); + this.sqlForeignKeys = new ArrayList<>(); + this.sqlEnums = new ArrayList<>(); + this.moduleBuilder = Module.newBuilder("db"); + } + + public Module introspectDatabase() throws SQLException { + ScriptRunner sr = new ScriptRunner(connection); + this.tables = sr.getSQLTables(this.getTablesQuery()); + this.sqlEnums = sr.getSQLEnums(this.getEnumsQuery()); + for (SqlTable table : tables) { + sr.readColumnsOfSQLTable(table, this.getColumnsQuery(table.getTableName())); + this.sqlForeignKeys.addAll(sr.readForeignKeysOfSQLTable + (table, this.getForeignKeysQuery(table.getTableName()))); + sr.readIndexesOfSQLTable(table, this.getIndexesQuery(table.getTableName())); + } + + mapEnums(); + mapEntities(); + + entityMap.forEach(moduleBuilder::addEntity); + return moduleBuilder.build(); + } + + private void mapEnums() { + this.sqlEnums.forEach(sqlEnum -> { + String enumName = createEnumName(sqlEnum.getEnumTableName(), sqlEnum.getEnumColumnName()); + Enum.Builder enumBuilder = Enum.newBuilder(enumName); + extractEnumValues(sqlEnum.getFullEnumText()) + .forEach(enumValue -> + enumBuilder.addMember(new EnumMember(enumValue.toUpperCase(Locale.ENGLISH), enumValue))); + moduleBuilder.addEnum(enumName, enumBuilder.build()); + }); + } + + private List extractEnumValues(String enumString) { + List enumValues = new ArrayList<>(); + + // Using regex to extract values inside parentheses + Pattern pattern = Pattern.compile("\\((.*?)\\)"); + Matcher matcher = pattern.matcher(enumString); + + if (matcher.find()) { + // Group 1 contains the values inside parentheses + String valuesInsideParentheses = matcher.group(1); + + // Split the values by comma + String[] valuesArray = valuesInsideParentheses.split(","); + Arrays.stream(valuesArray).map(value -> { + value = value.trim(); + value = value.replace("'", ""); + return value.trim(); + }).forEach(enumValues::add); + } + + return enumValues; + } + + private void mapEntities() { + Map entityBuilderMap = new HashMap<>(); + tables.forEach(table -> { + String entityName = CaseConverter.toSingularPascalCase(table.getTableName()); + + Entity.Builder entityBuilder = Entity.newBuilder(entityName); + entityBuilder.setTableName(table.getTableName()); + List keys = new ArrayList<>(); + List fields = new ArrayList<>(); + table.getColumns().forEach(column -> { + EntityField.Builder fieldBuilder = EntityField.newBuilder( + CaseConverter.toCamelCase(column.getColumnName())); + + fieldBuilder.setFieldColumnName(column.getColumnName()); + fieldBuilder.setArrayType(false); + if (Objects.equals(column.getDataType(), "enum")) { + fieldBuilder.setType(createEnumName(table.getTableName(), column.getColumnName())); + } else { + SQLType sqlType = new SQLType( + column.getDataType().toUpperCase(Locale.ENGLISH), + column.getColumnDefault(), + column.getNumericPrecision() != null ? parseInt(column.getNumericPrecision()) : 0, + column.getNumericScale() != null ? parseInt(column.getNumericScale()) : 0, + column.getDatetimePrecision(), + column.getCharacterMaximumLength() != null ? + parseInt(column.getCharacterMaximumLength()) : 0 + ); + + String balType = sqlType.getBalType(); + fieldBuilder.setType(balType); + fieldBuilder.setSqlType(sqlType); + fieldBuilder.setArrayType(sqlType.isArrayType()); + } + + fieldBuilder.setOptionalType(column.getIsNullable().equals("YES")); + fieldBuilder.setIsDbGenerated(column.isDbGenerated()); + + EntityField entityField = fieldBuilder.build(); + entityBuilder.addField(entityField); + fields.add(entityField); + if (column.getIsPrimaryKey()) { + keys.add(entityField); + } + }); + table.getIndexes().forEach(sqlIndex -> { + List indexFields = new ArrayList<>(); + sqlIndex.getColumnNames().forEach(columnName -> fields.forEach(entityField -> { + if (entityField.getFieldColumnName().equals(columnName)) { + indexFields.add(entityField); + } + })); + Index index = new Index(sqlIndex.getIndexName(), indexFields, sqlIndex.getNonUnique().equals("0")); + if (index.isUnique()) { + entityBuilder.addUniqueIndex(index); + } else { + entityBuilder.addIndex(index); + } + }); + entityBuilder.setKeys(keys); + entityBuilderMap.put(entityBuilder.getEntityName(), entityBuilder); + }); + HashMap ownerFieldNames = new HashMap<>(); + HashMap assocFieldNames = new HashMap<>(); + this.sqlForeignKeys.forEach(sqlForeignKey -> { + Entity.Builder ownerEntityBuilder = entityBuilderMap + .get(CaseConverter.toSingularPascalCase(sqlForeignKey.getTableName())); + Entity.Builder assocEntityBuilder = entityBuilderMap + .get(CaseConverter.toSingularPascalCase(sqlForeignKey.getReferencedTableName())); + boolean isReferenceMany = inferRelationshipCardinality + (ownerEntityBuilder.build(), sqlForeignKey) + == Relation.RelationType.MANY; + String assocFieldName = isReferenceMany ? + Pluralizer.pluralize(ownerEntityBuilder.getEntityName().toLowerCase(Locale.ENGLISH)) + : ownerEntityBuilder.getEntityName().toLowerCase(Locale.ENGLISH); + if (assocFieldNames.containsKey(assocEntityBuilder.getEntityName() + assocFieldName)) { + assocFieldNames.put(assocEntityBuilder.getEntityName() + assocFieldName, + assocFieldNames.get(assocEntityBuilder.getEntityName() + assocFieldName) + 1); + assocFieldName = assocFieldName + + assocFieldNames.get(assocEntityBuilder.getEntityName() + assocFieldName); + } else { + assocFieldNames.put(assocEntityBuilder.getEntityName() + assocFieldName, 0); + } + EntityField.Builder assocFieldBuilder = EntityField + .newBuilder(assocFieldName); + assocFieldBuilder.setType(ownerEntityBuilder.getEntityName()); + + String ownerFieldName = assocEntityBuilder.getEntityName().toLowerCase(Locale.ENGLISH); + if (ownerFieldNames.containsKey(ownerEntityBuilder.getEntityName() + ownerFieldName)) { + ownerFieldNames.put(ownerEntityBuilder.getEntityName() + ownerFieldName, + ownerFieldNames.get(ownerEntityBuilder.getEntityName() + ownerFieldName) + 1); + ownerFieldName = ownerFieldName + + ownerFieldNames.get(ownerEntityBuilder.getEntityName() + ownerFieldName); + } else { + ownerFieldNames.put(ownerEntityBuilder.getEntityName() + ownerFieldName, 0); + } + + EntityField.Builder ownerFieldBuilder = EntityField + .newBuilder(ownerFieldName); + ownerFieldBuilder.setType(assocEntityBuilder.getEntityName()); + + assocFieldBuilder.setArrayType(isReferenceMany); + assocFieldBuilder.setOptionalType(!isReferenceMany); + ownerFieldBuilder.setRelationRefs(sqlForeignKey.getColumnNames().stream().map(columnName -> + ownerEntityBuilder.build().getFieldByColumnName(columnName).getFieldName()).toList()); + + EntityField ownerField = ownerFieldBuilder.build(); + + assocEntityBuilder.addField(assocFieldBuilder.build()); + ownerEntityBuilder.addField(ownerField); + }); + + entityBuilderMap.forEach((key, value) -> entityMap.put(key, value.build())); + } + + private String createEnumName(String tableName, String columnName) { + return CaseConverter.toSingularPascalCase(tableName) + CaseConverter.toSingularPascalCase(columnName); + } + + private Relation.RelationType inferRelationshipCardinality(Entity ownerEntity, SqlForeignKey foreignKey) { + List ownerColumns = new ArrayList<>(); + foreignKey.getColumnNames().forEach(columnName -> + ownerColumns.add(ownerEntity.getFieldByColumnName(columnName))); + boolean isUniqueIndexPresent = ownerEntity.getUniqueIndexes().stream() + .anyMatch(index -> areTwoFieldListsEqual(index.getFields(), ownerColumns)); + if (areTwoFieldListsEqual(ownerEntity.getKeys(), ownerColumns)) { + return Relation.RelationType.ONE; + } else if (isUniqueIndexPresent) { + return Relation.RelationType.ONE; + } else { + return Relation.RelationType.MANY; + } + } + + private boolean areTwoFieldListsEqual(List list1, List list2) { + if (list1.size() != list2.size()) { + return false; + } + for (EntityField entityField : list1) { + if (!list2.contains(entityField)) { + return false; + } + } + return true; + } +} diff --git a/persist-cli/src/main/java/io/ballerina/persist/introspect/MySqlIntrospector.java b/persist-cli/src/main/java/io/ballerina/persist/introspect/MySqlIntrospector.java new file mode 100644 index 000000000..5e9d8c180 --- /dev/null +++ b/persist-cli/src/main/java/io/ballerina/persist/introspect/MySqlIntrospector.java @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you 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 + * + * http://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 io.ballerina.persist.introspect; + +import java.sql.Connection; + +public class MySqlIntrospector extends Introspector { + + public MySqlIntrospector(Connection connection, String databaseName) { + super(connection, databaseName); + } + + @Override + public String getTablesQuery() { + String formatQuery = """ + SELECT DISTINCT + table_info.table_name AS table_name, + table_info.create_options AS create_options, + table_info.table_comment AS table_comment + FROM + information_schema.tables AS table_info + JOIN information_schema.columns AS column_info + ON column_info.table_name = table_info.table_name + WHERE + table_info.table_schema= '%s' AND + column_info.table_schema = '%s' AND + table_info.table_type = 'BASE TABLE' + ORDER BY + table_info.table_name; + """; + formatQuery = formatQuery.replace("\r\n", "%n"); + return String.format(formatQuery, this.databaseName, this.databaseName); + } + + @Override + public String getColumnsQuery(String tableName) { + String formatQuery = """ + SELECT + column_name column_name, + data_type data_type, + column_type full_data_type, + character_maximum_length character_maximum_length, + numeric_precision numeric_precision, + numeric_scale numeric_scale, + datetime_precision datetime_precision, + column_default column_default, + is_nullable is_nullable, + extra extra, + table_name table_name, + column_key column_key, + IF(column_comment = '', NULL, column_comment) AS column_comment, + IF(extra = 'auto_increment', 1, 0) AS dbgenerated + FROM + information_schema.columns + WHERE + table_schema = '%s' + AND table_name = '%s' + ORDER BY + ordinal_position ASC; + """; + formatQuery = formatQuery.replace("\r\n", "%n"); + return String.format(formatQuery, this.databaseName, tableName); + } + + @Override + public String getIndexesQuery(String tableName) { + String formatQuery = """ + SELECT + table_name AS table_name, + index_name AS index_name, + column_name AS column_name, + sub_part AS partial, + seq_in_index AS seq_in_index, + collation AS column_order, + non_unique AS non_unique, + index_type AS index_type + FROM + information_schema.statistics + WHERE + table_schema = '%s' + AND table_name = '%s' + AND index_name != 'PRIMARY' + ORDER BY + BINARY index_name, + seq_in_index; + """; + formatQuery = formatQuery.replace("\r\n", "%n"); + return String.format(formatQuery, this.databaseName, tableName); + } + + @Override + public String getForeignKeysQuery(String tableName) { + String formatQuery = """ + SELECT + kcu.constraint_name constraint_name, + kcu.column_name column_name, + kcu.referenced_table_name referenced_table_name, + kcu.referenced_column_name referenced_column_name, + kcu.ordinal_position ordinal_position, + kcu.table_name table_name, + rc.delete_rule delete_rule, + rc.update_rule update_rule + FROM + information_schema.key_column_usage AS kcu + INNER JOIN information_schema.referential_constraints AS rc ON + BINARY kcu.constraint_name = BINARY rc.constraint_name + WHERE + BINARY kcu.table_schema = '%s' + AND rc.constraint_schema = '%s' + AND kcu.table_name = '%s' + AND kcu.referenced_column_name IS NOT NULL + ORDER BY + BINARY kcu.table_schema, + BINARY kcu.table_name, + BINARY kcu.constraint_name, + kcu.ordinal_position; + """; + formatQuery = formatQuery.replace("\r\n", "%n"); + return String.format(formatQuery, this.databaseName, this.databaseName, tableName); + } + + @Override + protected String getEnumsQuery() { + String formatQuery = """ + SELECT + column_name column_name, + data_type data_type, + column_type full_enum_type, + table_name table_name + FROM + information_schema.columns + WHERE + table_schema = '%s' + AND data_type = 'enum' + ORDER BY + ordinal_position ASC; + """; + formatQuery = formatQuery.replace("\r\n", "%n"); + return String.format(formatQuery, this.databaseName); + } + +} diff --git a/persist-cli/src/main/java/io/ballerina/persist/introspectiondto/SqlColumn.java b/persist-cli/src/main/java/io/ballerina/persist/introspectiondto/SqlColumn.java new file mode 100644 index 000000000..88013c43c --- /dev/null +++ b/persist-cli/src/main/java/io/ballerina/persist/introspectiondto/SqlColumn.java @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you 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 + * + * http://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 io.ballerina.persist.introspectiondto; + +public class SqlColumn { + private final String columnName; + private final String tableName; + private final String dataType; + private final String fullDataType; + private final String characterMaximumLength; + private final String numericPrecision; + private final String numericScale; + private final String datetimePrecision; + private final String columnDefault; + private final String isNullable; + private final String extra; + private final String columnComment; + private final boolean isPrimaryKey; + private final boolean isDbGenerated; + + private SqlColumn(String columnName, String tableName, String dataType, String fullDataType, + String characterMaximumLength, String numericPrecision, String numericScale, + String datetimePrecision, String columnDefault, String isNullable, String extra, + String columnComment, Boolean isPrimaryKey, Boolean isDbGenerated) { + this.columnName = columnName; + this.tableName = tableName; + this.dataType = dataType; + this.fullDataType = fullDataType; + this.characterMaximumLength = characterMaximumLength; + this.numericPrecision = numericPrecision; + this.numericScale = numericScale; + this.datetimePrecision = datetimePrecision; + this.columnDefault = columnDefault; + this.isNullable = isNullable; + this.extra = extra; + this.columnComment = columnComment; + this.isPrimaryKey = isPrimaryKey; + this.isDbGenerated = isDbGenerated; + } + + public String getColumnName() { + return columnName; + } + + public String getTableName() { + return tableName; + } + + public String getDataType() { + return dataType; + } + + public String getFullDataType() { + return fullDataType; + } + + public String getCharacterMaximumLength() { + return characterMaximumLength; + } + + public String getNumericPrecision() { + return numericPrecision; + } + + public String getNumericScale() { + return numericScale; + } + + public String getDatetimePrecision() { + return datetimePrecision; + } + + public String getColumnDefault() { + return columnDefault; + } + + public String getIsNullable() { + return isNullable; + } + + public Boolean isDbGenerated() { + return isDbGenerated; + } + + public String getExtra() { + return extra; + } + + public String getColumnComment() { + return columnComment; + } + + public Boolean getIsPrimaryKey() { + return isPrimaryKey; + } + + public static SqlColumn.Builder newBuilder(String columnName) { + return new Builder(columnName); + } + + public static class Builder { + private String columnName; + private String dataType; + private String fullDataType; + private String characterMaximumLength; + private String numericPrecision; + private String numericScale; + private String datetimePrecision; + private String columnDefault; + private String isNullable; + private String extra; + private String columnComment; + private String tableName; + private Boolean isPrimaryKey; + private Boolean isDbGenerated; + + private Builder(String columnName) { + this.columnName = columnName; + } + + public Builder setTableName(String tableName) { + this.tableName = tableName; + return this; + } + + public Builder setDataType(String dataType) { + this.dataType = dataType; + return this; + } + + public Builder setIsDbGenerated(Boolean isDbGenerated) { + this.isDbGenerated = isDbGenerated; + return this; + } + + public Builder setFullDataType(String fullDataType) { + this.fullDataType = fullDataType; + return this; + } + + public Builder setCharacterMaximumLength(String characterMaximumLength) { + this.characterMaximumLength = characterMaximumLength; + return this; + } + + public Builder setNumericPrecision(String numericPrecision) { + this.numericPrecision = numericPrecision; + return this; + } + + public Builder setNumericScale(String numericScale) { + this.numericScale = numericScale; + return this; + } + + public Builder setDatetimePrecision(String datetimePrecision) { + this.datetimePrecision = datetimePrecision; + return this; + } + + public Builder setColumnDefault(String columnDefault) { + this.columnDefault = columnDefault; + return this; + } + + public Builder setIsNullable(String isNullable) { + this.isNullable = isNullable; + return this; + } + + public Builder setExtra(String extra) { + this.extra = extra; + return this; + } + + public Builder setColumnComment(String columnComment) { + this.columnComment = columnComment; + return this; + } + public Builder setIsPrimaryKey(Boolean isPrimaryKey) { + this.isPrimaryKey = isPrimaryKey; + return this; + } + + public SqlColumn build() { + return new SqlColumn(this.columnName, this.tableName, this.dataType, this.fullDataType, + this.characterMaximumLength, this.numericPrecision, this.numericScale, this.datetimePrecision, + this.columnDefault, this.isNullable, this.extra, this.columnComment, this.isPrimaryKey, + this.isDbGenerated); + } + } +} diff --git a/persist-cli/src/main/java/io/ballerina/persist/introspectiondto/SqlEnum.java b/persist-cli/src/main/java/io/ballerina/persist/introspectiondto/SqlEnum.java new file mode 100644 index 000000000..2b941a99a --- /dev/null +++ b/persist-cli/src/main/java/io/ballerina/persist/introspectiondto/SqlEnum.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you 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 + * + * http://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 io.ballerina.persist.introspectiondto; + +public class SqlEnum { + private final String fullEnumText; + private final String enumTableName; + private final String enumColumnName; + + public SqlEnum(String fullEnumText, String enumTableName, String enumColumnName) { + this.fullEnumText = fullEnumText; + this.enumTableName = enumTableName; + this.enumColumnName = enumColumnName; + } + + public String getFullEnumText() { + return fullEnumText; + } + + public String getEnumTableName() { + return enumTableName; + } + + public String getEnumColumnName() { + return enumColumnName; + } + +} diff --git a/persist-cli/src/main/java/io/ballerina/persist/introspectiondto/SqlForeignKey.java b/persist-cli/src/main/java/io/ballerina/persist/introspectiondto/SqlForeignKey.java new file mode 100644 index 000000000..dd3fbb956 --- /dev/null +++ b/persist-cli/src/main/java/io/ballerina/persist/introspectiondto/SqlForeignKey.java @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you 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 + * + * http://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 io.ballerina.persist.introspectiondto; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class SqlForeignKey { + private final String constraintName; + private final String tableName; + private List columnNames; + private final String referencedTableName; + private List referencedColumnNames; + private final String updateRule; + private final String deleteRule; + + public String getConstraintName() { + return constraintName; + } + + public String getTableName() { + return tableName; + } + + public List getColumnNames() { + return Collections.unmodifiableList(columnNames); + } + + public SqlForeignKey(String constraintName, String tableName, List columnNames, String referencedTableName, + List referencedColumnNames, String updateRule, String deleteRule) { + this.constraintName = constraintName; + this.tableName = tableName; + this.columnNames = Collections.unmodifiableList(columnNames); + this.referencedTableName = referencedTableName; + this.referencedColumnNames = Collections.unmodifiableList(referencedColumnNames); + this.updateRule = updateRule; + this.deleteRule = deleteRule; + } + + public String getReferencedTableName() { + return referencedTableName; + } + + public List getReferencedColumnNames() { + return Collections.unmodifiableList(referencedColumnNames); + } + + public String getUpdateRule() { + return updateRule; + } + + public String getDeleteRule() { + return deleteRule; + } + + public void addColumnName(String columnName) { + List newColumnNames = new ArrayList<>(this.columnNames); + newColumnNames.add(columnName); + this.columnNames = Collections.unmodifiableList(newColumnNames); + } + + public void addReferencedColumnName(String referencedColumnName) { + List newReferencedColumnNames = new ArrayList<>(this.referencedColumnNames); + newReferencedColumnNames.add(referencedColumnName); + this.referencedColumnNames = Collections.unmodifiableList(newReferencedColumnNames); + } + public static class Builder { + private final String constraintName; + private String tableName; + private final List columnNames; + private String referencedTableName; + private final List referencedColumnNames; + private String updateRule; + private String deleteRule; + + public static Builder newBuilder(String constraintName) { + return new Builder(constraintName); + + } + + private Builder(String constraintName) { + this.constraintName = constraintName; + this.columnNames = new ArrayList<>(); + this.referencedColumnNames = new ArrayList<>(); + } + + public Builder setTableName(String tableName) { + this.tableName = tableName; + return this; + } + + public Builder addColumnName(String columnName) { + this.columnNames.add(columnName); + return this; + } + + public Builder setReferencedTableName(String referencedTableName) { + this.referencedTableName = referencedTableName; + return this; + } + + public Builder addReferencedColumnName(String referencedColumnName) { + this.referencedColumnNames.add(referencedColumnName); + return this; + } + + public Builder setUpdateRule(String updateRule) { + this.updateRule = updateRule; + return this; + } + + public Builder setDeleteRule(String deleteRule) { + this.deleteRule = deleteRule; + return this; + } + + public SqlForeignKey build() { + return new SqlForeignKey(constraintName, tableName, columnNames, referencedTableName, referencedColumnNames, + updateRule, deleteRule); + } + } +} diff --git a/persist-cli/src/main/java/io/ballerina/persist/introspectiondto/SqlIndex.java b/persist-cli/src/main/java/io/ballerina/persist/introspectiondto/SqlIndex.java new file mode 100644 index 000000000..e04f73439 --- /dev/null +++ b/persist-cli/src/main/java/io/ballerina/persist/introspectiondto/SqlIndex.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you 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 + * + * http://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 io.ballerina.persist.introspectiondto; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class SqlIndex { + private final String tableName; + private final String indexName; + private final List columnNames; + private final String partial; + private final String columnOrder; + private final String nonUnique; + private final String indexType; + + private SqlIndex(String indexName, String tableName, List columnNames, String partial, + String columnOrder, String nonUnique, String indexType) { + this.indexName = indexName; + this.tableName = tableName; + this.columnNames = columnNames; + this.partial = partial; + this.columnOrder = columnOrder; + this.nonUnique = nonUnique; + this.indexType = indexType; + } + + public String getTableName() { + return this.tableName; + } + + public String getIndexName() { + return indexName; + } + + public List getColumnNames() { + return Collections.unmodifiableList(columnNames); + } + + public String getPartial() { + return partial; + } + + public String getColumnOrder() { + return columnOrder; + } + + public String getNonUnique() { + return nonUnique; + } + + public String getIndexType() { + return indexType; + } + + public void addColumnName(String columnName) { + this.columnNames.add(columnName); + } + + public static Builder newBuilder(String indexName) { + return new Builder(indexName); + } + + public static class Builder { + private final String indexName; + private String tableName; + private final List columnNames; + private String partial; + private String columnOrder; + private String nonUnique; + private String indexType; + + public static Builder newBuilder(String indexName) { + return new Builder(indexName); + } + + private Builder(String indexName) { + this.indexName = indexName; + this.columnNames = new ArrayList<>(); + + } + + public Builder setTableName(String tableName) { + this.tableName = tableName; + return this; + } + + public Builder addColumnName(String columnName) { + this.columnNames.add(columnName); + return this; + } + + public Builder setPartial(String partial) { + this.partial = partial; + return this; + } + + public Builder setColumnOrder(String columnOrder) { + this.columnOrder = columnOrder; + return this; + } + + public Builder setNonUnique(String nonUnique) { + this.nonUnique = nonUnique; + return this; + } + + public Builder setIndexType(String indexType) { + this.indexType = indexType; + return this; + } + + public SqlIndex build() { + return new SqlIndex(indexName, tableName, columnNames, partial, + columnOrder, nonUnique, indexType); + } + } +} diff --git a/persist-cli/src/main/java/io/ballerina/persist/introspectiondto/SqlTable.java b/persist-cli/src/main/java/io/ballerina/persist/introspectiondto/SqlTable.java new file mode 100644 index 000000000..7daf7dd67 --- /dev/null +++ b/persist-cli/src/main/java/io/ballerina/persist/introspectiondto/SqlTable.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you 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 + * + * http://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 io.ballerina.persist.introspectiondto; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class SqlTable { + private final String tableName; + private final String createOptions; + private final String tableComment; + private final List columns; + private final List sqlForeignKeys; + + private final List indexes; + + public SqlTable(String tableName, String createOptions, String tableComment) { + this.tableName = tableName; + this.createOptions = createOptions; + this.tableComment = tableComment; + this.columns = new ArrayList<>(); + this.sqlForeignKeys = new ArrayList<>(); + this.indexes = new ArrayList<>(); + } + + public String getTableName() { + return tableName; + } + + public String getCreateOptions() { + return createOptions; + } + + public String getTableComment() { + return tableComment; + } + + public List getColumns() { + return Collections.unmodifiableList(columns); + } + + public List getSqlForeignKeys() { + return Collections.unmodifiableList(sqlForeignKeys); + } + + public List getIndexes() { + return Collections.unmodifiableList(indexes); + } + + public void addColumn(SqlColumn column) { + this.columns.add(column); + } + + public void addForeignKey(SqlForeignKey foreignKey) { + this.sqlForeignKeys.add(foreignKey); + } + + public void addIndex(SqlIndex index) { + this.indexes.add(index); + } + + public static Builder newBuilder(String tableName) { + return new Builder(tableName); + } + + public static class Builder { + private final String tableName; + private String createOptions; + private String tableComment; + + private Builder(String tableName) { + this.tableName = tableName; + } + + public Builder setCreateOptions(String createOptions) { + this.createOptions = createOptions; + return this; + } + + public Builder setTableComment(String tableComment) { + this.tableComment = tableComment; + return this; + } + + public SqlTable build() { + return new SqlTable(tableName, createOptions, + tableComment); + } + } +} diff --git a/persist-cli/src/main/java/io/ballerina/persist/models/Entity.java b/persist-cli/src/main/java/io/ballerina/persist/models/Entity.java index c8327a808..00b442399 100644 --- a/persist-cli/src/main/java/io/ballerina/persist/models/Entity.java +++ b/persist-cli/src/main/java/io/ballerina/persist/models/Entity.java @@ -18,7 +18,7 @@ package io.ballerina.persist.models; -import io.ballerina.persist.plural.Pluralizer; +import io.ballerina.persist.inflector.Pluralizer; import java.util.ArrayList; import java.util.Collections; @@ -33,26 +33,27 @@ public class Entity { private final List keys; - private final String resourceName; - + private final String tableName; private final String entityName; - - private final List fields; - + private List fields; + private final List indexes; + private final List uniqueIndexes; private Entity(String entityName, List keys, - String resourceName, List fields) { + String resourceName, List fields, List indexes, List uniqueIndexes) { this.entityName = entityName; this.keys = Collections.unmodifiableList(keys); - this.resourceName = resourceName; + this.tableName = resourceName; this.fields = Collections.unmodifiableList(fields); + this.indexes = Collections.unmodifiableList(indexes); + this.uniqueIndexes = Collections.unmodifiableList(uniqueIndexes); } public List getKeys() { return this.keys; } - public String getResourceName() { - return this.resourceName; + public String getTableName() { + return this.tableName; } public String getEntityName() { return this.entityName; @@ -62,6 +63,18 @@ public List getFields() { return this.fields; } + public String getClientResourceName() { + return Pluralizer.pluralize(entityName.toLowerCase(Locale.ENGLISH)); + } + + public List getIndexes() { + return this.indexes; + } + + public List getUniqueIndexes() { + return this.uniqueIndexes; + } + public EntityField getFieldByName(String fieldName) { for (EntityField field : fields) { if (field.getFieldName().equals(fieldName)) { @@ -71,22 +84,55 @@ public EntityField getFieldByName(String fieldName) { return null; } + public EntityField getFieldByColumnName(String columnName) { + for (EntityField field : fields) { + if (field.getFieldColumnName().equals(columnName)) { + return field; + } + } + return null; + } + + public boolean shouldTableMappingGenerated() { + if (tableName == null || tableName.isBlank()) { + return false; + } + return !entityName.equals(tableName); + } + + public void removeField(String fieldName) { + List newFields = new ArrayList<>(this.fields); + newFields.removeIf(field -> field.getFieldName().equals(fieldName)); + this.fields = Collections.unmodifiableList(newFields); + } + public static Entity.Builder newBuilder(String entityName) { return new Entity.Builder(entityName); } + /** * Entity Definition.Builder. */ public static class Builder { String entityName; - String resourceName = null; + String tableName = null; List keys; List fieldList = null; + List indexes; + + List uniqueIndexes; + private Builder(String entityName) { this.entityName = entityName; + this.indexes = new ArrayList<>(); + this.uniqueIndexes = new ArrayList<>(); + } + + public void setTableName(String tableName) { + this.tableName = tableName; } public void setKeys(List keys) { @@ -100,12 +146,56 @@ public void addField(EntityField field) { fieldList.add(field); } + public void addIndex(Index index) { + indexes.add(index); + } + + public void upsertIndex(String indexName, EntityField field) { + List fields = new ArrayList<>(); + fields.add(field); + Index existingIndex = this.indexes.stream() + .filter(i -> i.getIndexName().equals(indexName)).findFirst().orElse(null); + if (existingIndex != null) { + existingIndex.addField(field); + } else { + Index index = new Index(indexName, fields, false); + indexes.add(index); + } + } + + public void upsertUniqueIndex(String indexName, EntityField field) { + List fields = new ArrayList<>(); + fields.add(field); + Index existingIndex = this.uniqueIndexes.stream() + .filter(i -> i.getIndexName().equals(indexName)).findFirst().orElse(null); + if (existingIndex != null) { + existingIndex.addField(field); + } else { + Index index = new Index(indexName, fields, true); + uniqueIndexes.add(index); + } + } + + public void addUniqueIndex(Index index) { + uniqueIndexes.add(index); + } + public Entity build() { - if (resourceName == null) { - resourceName = entityName.toLowerCase(Locale.ENGLISH); + return new Entity(entityName, keys, tableName, fieldList, indexes, uniqueIndexes); + } + + public EntityField getFieldByName(String fieldName) { + for (EntityField field : fieldList) { + if (field.getFieldName().equals(fieldName)) { + return field; + } } - resourceName = Pluralizer.pluralize(resourceName); - return new Entity(entityName, keys, resourceName, fieldList); + return null; } + + public String getEntityName() { + return entityName; + } + } } diff --git a/persist-cli/src/main/java/io/ballerina/persist/models/EntityField.java b/persist-cli/src/main/java/io/ballerina/persist/models/EntityField.java index e1b5cd162..152198fd0 100644 --- a/persist-cli/src/main/java/io/ballerina/persist/models/EntityField.java +++ b/persist-cli/src/main/java/io/ballerina/persist/models/EntityField.java @@ -19,9 +19,15 @@ package io.ballerina.persist.models; import io.ballerina.compiler.syntax.tree.AnnotationNode; -import io.ballerina.compiler.syntax.tree.NodeList; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import static io.ballerina.persist.nodegenerator.syntax.constants.BalSyntaxConstants.COLON; +import static io.ballerina.persist.nodegenerator.syntax.constants.BalSyntaxConstants.SINGLE_QUOTE; +import static io.ballerina.persist.nodegenerator.syntax.utils.BalSyntaxUtils.stripEscapeCharacter; +import static io.ballerina.persist.utils.StubUtils.isLiteralName; /** * Client Entity fieldMetaData class. @@ -31,26 +37,41 @@ */ public class EntityField { private final String fieldName; + private final String fieldColumnName; private final String fieldType; + private final SQLType sqlType; private final boolean arrayType; private final boolean optionalType; + + private final boolean isDbGenerated; private Relation relation; private Enum enumValue; - private final NodeList annotationNodes; + private final List annotationNodes; + private final List relationRefs; - EntityField(String fieldName, String fieldType, boolean arrayType, boolean optionalType, - NodeList annotationNodes) { + EntityField(String fieldName, String fieldColumnName, String fieldType, boolean arrayType, boolean optionalType, + List annotationNodes, SQLType sqlType, List relationRefs, + boolean isDbGenerated) { this.fieldName = fieldName; + this.fieldColumnName = fieldColumnName; this.fieldType = fieldType; this.arrayType = arrayType; this.optionalType = optionalType; - this.annotationNodes = annotationNodes; + this.annotationNodes = + Collections.unmodifiableList(annotationNodes != null ? annotationNodes : new ArrayList<>()); + this.sqlType = sqlType; + this.relationRefs = Collections.unmodifiableList(relationRefs != null ? relationRefs : new ArrayList<>()); + this.isDbGenerated = isDbGenerated; } public String getFieldName() { return fieldName; } + public String getFieldColumnName() { + return fieldColumnName; + } + public String getFieldType() { return fieldType; } @@ -59,10 +80,30 @@ public Relation getRelation() { return relation; } - public NodeList getAnnotation() { + public SQLType getSqlType() { + return sqlType; + } + + public List getAnnotation() { return annotationNodes; } + public boolean isDbGenerated() { + return isDbGenerated; + } + + public boolean shouldColumnMappingGenerated() { + if (fieldColumnName == null || fieldColumnName.isBlank()) { + return false; + } + + return !fieldColumnName.equals(stripEscapeCharacter(fieldName)); + } + + public List getRelationRefs() { + return relationRefs; + } + public void setRelation(Relation relation) { this.relation = relation; } @@ -92,13 +133,24 @@ public static EntityField.Builder newBuilder(String fieldName) { */ public static class Builder { String fieldName; + String fieldColumnName; String fieldType; - boolean arrayType = false; - boolean optionalType = false; - private NodeList annotationNodes = null; + private boolean arrayType = false; + private boolean optionalType = false; + + SQLType sqlType; + private List annotationNodes = null; + + private List relationRefs; + + private boolean isDbGenerated = false; Builder(String fieldName) { + if (isLiteralName(fieldName)) { + this.fieldName = SINGLE_QUOTE + fieldName; + return; + } this.fieldName = fieldName; } @@ -109,6 +161,21 @@ public void setType(String fieldType) { this.fieldType = fieldType; } + public void setSqlType(SQLType sqlType) { + this.sqlType = sqlType; + } + public void setFieldColumnName(String fieldColumnName) { + this.fieldColumnName = fieldColumnName; + } + + public void setRelationRefs(List relationRefs) { + this.relationRefs = relationRefs; + } + + public void setIsDbGenerated(boolean isDbGenerated) { + this.isDbGenerated = isDbGenerated; + } + public void setArrayType(boolean arrayType) { this.arrayType = arrayType; @@ -117,12 +184,17 @@ public void setArrayType(boolean arrayType) { public void setOptionalType(boolean optionalType) { this.optionalType = optionalType; } - public void setAnnotation(NodeList annotationNodes) { + public void setAnnotations(List annotationNodes) { this.annotationNodes = annotationNodes; } public EntityField build() { - return new EntityField(fieldName, fieldType, arrayType, optionalType, annotationNodes); + return new EntityField(fieldName, fieldColumnName, fieldType, arrayType, optionalType, annotationNodes, + sqlType, relationRefs, isDbGenerated); + } + + public String getFieldName() { + return fieldName; } } } diff --git a/persist-cli/src/main/java/io/ballerina/persist/models/Enum.java b/persist-cli/src/main/java/io/ballerina/persist/models/Enum.java index 61905b037..152940c7a 100644 --- a/persist-cli/src/main/java/io/ballerina/persist/models/Enum.java +++ b/persist-cli/src/main/java/io/ballerina/persist/models/Enum.java @@ -45,8 +45,8 @@ public List getMembers() { return this.members; } - public static Enum.Builder newBuilder(String entityName) { - return new Enum.Builder(entityName); + public static Enum.Builder newBuilder(String enumName) { + return new Enum.Builder(enumName); } /** diff --git a/persist-cli/src/main/java/io/ballerina/persist/models/Index.java b/persist-cli/src/main/java/io/ballerina/persist/models/Index.java new file mode 100644 index 000000000..64beb43bd --- /dev/null +++ b/persist-cli/src/main/java/io/ballerina/persist/models/Index.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). + * + * WSO2 Inc. licenses this file to you 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 + * + * http://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 io.ballerina.persist.models; + +import java.util.Collections; +import java.util.List; + +public class Index { + private final String indexName; + private List fields; + private boolean unique; + public Index(String indexName, List fields, boolean unique) { + this.indexName = indexName; + this.fields = fields; + this.unique = unique; + } + + public String getIndexName() { + return indexName; + } + + public List getFields() { + return Collections.unmodifiableList(fields); + } + + public void addField(EntityField field) { + fields.add(field); + } + + public boolean isUnique() { + return unique; + } + +} diff --git a/persist-cli/src/main/java/io/ballerina/persist/models/Relation.java b/persist-cli/src/main/java/io/ballerina/persist/models/Relation.java index f3a75c87b..3d0b98788 100644 --- a/persist-cli/src/main/java/io/ballerina/persist/models/Relation.java +++ b/persist-cli/src/main/java/io/ballerina/persist/models/Relation.java @@ -18,6 +18,7 @@ package io.ballerina.persist.models; +import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -45,7 +46,6 @@ public enum RelationType { private RelationType relationType; private Entity assocEntity; - private Relation(List keyColumns, List references, RelationType relationType, Entity assocEntity, boolean owner) { @@ -101,7 +101,7 @@ public static Relation.Builder newBuilder() { */ public static class Builder { List keys = null; - List references = null; + List references = new ArrayList<>(); Entity assocEntity = null; RelationType relationType = RelationType.ONE; @@ -138,12 +138,17 @@ public Relation build() { */ public static class Key { private final String field; + + private final String columnName; private final String reference; + private final String referenceColumnName; private final String type; - public Key(String field, String reference, String type) { + public Key(String field, String columnName, String reference, String referenceColumnName, String type) { this.field = field; + this.columnName = columnName; this.reference = reference; + this.referenceColumnName = referenceColumnName; this.type = type; } @@ -158,5 +163,13 @@ public String getReference() { public String getType() { return type; } + + public String getColumnName() { + return columnName; + } + + public String getReferenceColumnName() { + return referenceColumnName; + } } } diff --git a/persist-cli/src/main/java/io/ballerina/persist/models/SQLType.java b/persist-cli/src/main/java/io/ballerina/persist/models/SQLType.java new file mode 100644 index 000000000..566f03f98 --- /dev/null +++ b/persist-cli/src/main/java/io/ballerina/persist/models/SQLType.java @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you 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 + * + * http://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 io.ballerina.persist.models; + + +import io.ballerina.persist.PersistToolsConstants; + +public class SQLType { + private final String typeName; + protected final String columnDefaultValue; + private final int numericPrecision; + private final int numericScale; + private final String dateTimePrecision; + private final int maxLength; + + public SQLType(String typeName, String columnDefaultValue, int numericPrecision, int numericScale, + String dateTimePrecision, int maxCharLength) { + this.typeName = typeName; + this.columnDefaultValue = columnDefaultValue; + this.numericPrecision = numericPrecision; + this.numericScale = numericScale; + this.dateTimePrecision = dateTimePrecision; + this.maxLength = maxCharLength; + } + + public String getTypeName() { + return typeName; + } + + public String getColumnDefaultValue() { + return columnDefaultValue; + } + + public int getNumericPrecision() { + return numericPrecision; + } + + public int getNumericScale() { + return numericScale; + } + + public String getDateTimePrecisionLevel() { + return dateTimePrecision; + } + + public int getMaxLength() { + return maxLength; + } + + public boolean isArrayType() { + return this.typeName.equals(PersistToolsConstants.SqlTypes.BLOB) || + this.typeName.equals(PersistToolsConstants.SqlTypes.LONG_BLOB); + } + public String getBalType() { + switch (this.typeName) { + + // Ballerina --> int + // MySQL --> INT + // MSSQL --> INT + // PostgreSQL --> INT + case PersistToolsConstants.SqlTypes.INT: + return PersistToolsConstants.BallerinaTypes.INT; + + // Ballerina --> boolean + // MySQL --> BOOLEAN + // MSSQL --> BIT + // PostgreSQL --> BOOLEAN + case PersistToolsConstants.SqlTypes.BIT: + case PersistToolsConstants.SqlTypes.BOOLEAN: + return PersistToolsConstants.BallerinaTypes.BOOLEAN; + + // Ballerina --> decimal + // MySQL --> DECIMAL(65,30) + // MSSQL --> DECIMAL(38,30) + // PostgreSQL --> DECIMAL(65,30) + case PersistToolsConstants.SqlTypes.DECIMAL: + return PersistToolsConstants.BallerinaTypes.DECIMAL; + + // Ballerina --> float + // MySQL --> DOUBLE + // MSSQL --> FLOAT + // PostgreSQL --> FLOAT + case PersistToolsConstants.SqlTypes.DOUBLE: + case PersistToolsConstants.SqlTypes.FLOAT: + return PersistToolsConstants.BallerinaTypes.FLOAT; + + // Ballerina --> time:Date + // MySQL --> DATE + // MSSQL --> DATE + // PostgreSQL --> DATE + case PersistToolsConstants.SqlTypes.DATE: + return PersistToolsConstants.BallerinaTypes.DATE; + + // Ballerina --> time:TimeOfDay + // MySQL --> TIME + // MSSQL --> TIME + // PostgreSQL --> TIME + case PersistToolsConstants.SqlTypes.TIME: + return PersistToolsConstants.BallerinaTypes.TIME_OF_DAY; + + // Ballerina --> time:Utc + // MySQL --> TIMESTAMP + // MSSQL --> DATETIME2 + // PostgreSQL --> TIMESTAMP + case PersistToolsConstants.SqlTypes.TIME_STAMP: + return PersistToolsConstants.BallerinaTypes.UTC; + case PersistToolsConstants.SqlTypes.DATE_TIME2: + case PersistToolsConstants.SqlTypes.DATE_TIME: + return PersistToolsConstants.BallerinaTypes.CIVIL; + + // Ballerina --> string + // MySQL --> VARCHAR + // MSSQL --> VARCHAR + // PostgreSQL --> VARCHAR + case PersistToolsConstants.SqlTypes.VARCHAR: + case PersistToolsConstants.SqlTypes.CHAR: + return PersistToolsConstants.BallerinaTypes.STRING; + + case PersistToolsConstants.SqlTypes.LONG_BLOB: + case PersistToolsConstants.SqlTypes.BLOB: + return PersistToolsConstants.BallerinaTypes.BYTE; + + default: + throw new RuntimeException + ("ERROR: Couldn't find equivalent Ballerina type for the field type: " + this.typeName); + } + } +} diff --git a/persist-cli/src/main/java/io/ballerina/persist/nodegenerator/DriverResolver.java b/persist-cli/src/main/java/io/ballerina/persist/nodegenerator/DriverResolver.java new file mode 100644 index 000000000..24344cea7 --- /dev/null +++ b/persist-cli/src/main/java/io/ballerina/persist/nodegenerator/DriverResolver.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you 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 + * + * http://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 io.ballerina.persist.nodegenerator; + +import io.ballerina.persist.BalException; +import io.ballerina.persist.nodegenerator.syntax.sources.DbModelGenSyntaxTree; +import io.ballerina.persist.utils.BalProjectUtils; +import io.ballerina.projects.Project; +import org.ballerinalang.formatter.core.Formatter; + +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +public class DriverResolver { + + private final Path driverImportFile; + + public DriverResolver(String sourcePath) { + driverImportFile = Paths.get(sourcePath, "persist/driver.bal"); + } + + public Project resolveDriverDependencies() throws BalException { + createDriverImportFile(); + return BalProjectUtils.buildDriverFile(driverImportFile); + } + + private void createDriverImportFile() throws BalException { + DbModelGenSyntaxTree dbModelGenSyntaxTree = new DbModelGenSyntaxTree(); + try { + writeOutputFile + (Formatter.format(dbModelGenSyntaxTree.createInitialDriverImportFile().toSourceCode()), + driverImportFile); + } catch (Exception e) { + throw new BalException("ERROR: failed to create driver import file. " + e.getMessage()); + } + } + private void writeOutputFile(String syntaxTree, Path outPath) throws IOException { + try (PrintWriter writer = new PrintWriter(outPath.toString(), StandardCharsets.UTF_8)) { + writer.println(syntaxTree); + } + } + + public void deleteDriverFile() throws BalException { + try { + Files.deleteIfExists(driverImportFile); + } catch (IOException e) { + throw new BalException("ERROR: failed to delete driver import file. " + e.getMessage()); + } + } + +} diff --git a/persist-cli/src/main/java/io/ballerina/persist/nodegenerator/SourceGenerator.java b/persist-cli/src/main/java/io/ballerina/persist/nodegenerator/SourceGenerator.java index 513d77be5..3ab3a57b1 100644 --- a/persist-cli/src/main/java/io/ballerina/persist/nodegenerator/SourceGenerator.java +++ b/persist-cli/src/main/java/io/ballerina/persist/nodegenerator/SourceGenerator.java @@ -22,6 +22,7 @@ import io.ballerina.persist.PersistToolsConstants; import io.ballerina.persist.models.Module; import io.ballerina.persist.nodegenerator.syntax.constants.BalSyntaxConstants; +import io.ballerina.persist.nodegenerator.syntax.sources.DbModelGenSyntaxTree; import io.ballerina.persist.nodegenerator.syntax.sources.DbSyntaxTree; import io.ballerina.persist.nodegenerator.syntax.sources.GSheetSyntaxTree; import io.ballerina.persist.nodegenerator.syntax.sources.InMemorySyntaxTree; @@ -57,6 +58,7 @@ public class SourceGenerator { private static final String persistTypesBal = "persist_types.bal"; private static final String persistClientBal = "persist_client.bal"; + private static final String persistModelBal = "model.bal"; private static final String NEW_LINE = System.lineSeparator(); private final String sourcePath; private final String moduleNameWithPackageName; @@ -71,6 +73,22 @@ public SourceGenerator(String sourcePath, Path generatedSourceDirPath, String mo this.generatedSourceDirPath = generatedSourceDirPath; } + public void createDbModel() throws BalException { + DbModelGenSyntaxTree dbModelGenSyntaxTree = new DbModelGenSyntaxTree(); + addModelFile(dbModelGenSyntaxTree.getDataModels(entityModule), + this.generatedSourceDirPath.resolve(persistModelBal).toAbsolutePath(), + this.moduleNameWithPackageName); + } + + private void addModelFile(SyntaxTree syntaxTree, Path path, String moduleName) throws BalException { + try { + writeOutputFile(Formatter.format(syntaxTree.toSourceCode()), path); + } catch (FormatterException | IOException e) { + throw new BalException(String.format("could not write the records for the `%s` data model " + + "to the model.bal file.", moduleName) + e.getMessage()); + } + } + public void createDbSources(String datasource) throws BalException { DbSyntaxTree dbSyntaxTree = new DbSyntaxTree(); try { diff --git a/persist-cli/src/main/java/io/ballerina/persist/nodegenerator/syntax/clients/DbClientSyntax.java b/persist-cli/src/main/java/io/ballerina/persist/nodegenerator/syntax/clients/DbClientSyntax.java index 3f03dc1a9..a3ec7285f 100644 --- a/persist-cli/src/main/java/io/ballerina/persist/nodegenerator/syntax/clients/DbClientSyntax.java +++ b/persist-cli/src/main/java/io/ballerina/persist/nodegenerator/syntax/clients/DbClientSyntax.java @@ -149,7 +149,8 @@ public FunctionDefinitionNode getInitFunction(Module entityModule) { @Override public FunctionDefinitionNode getGetFunction(Entity entity) { return (FunctionDefinitionNode) NodeParser.parseObjectMember( - String.format(BalSyntaxConstants.EXTERNAL_SQL_GET_METHOD_TEMPLATE, entity.getResourceName(), + String.format(BalSyntaxConstants.EXTERNAL_SQL_GET_METHOD_TEMPLATE, + entity.getClientResourceName(), entity.getEntityName(), BalSyntaxConstants.SQL, this.nativeClass)); } @@ -184,7 +185,8 @@ public FunctionDefinitionNode getPostFunction(Entity entity) { @Override public FunctionDefinitionNode getPutFunction(Entity entity) { StringBuilder filterKeys = new StringBuilder(BalSyntaxConstants.OPEN_BRACE); - StringBuilder path = new StringBuilder(BalSyntaxConstants.BACK_SLASH + entity.getResourceName()); + StringBuilder path = new StringBuilder(BalSyntaxConstants.BACK_SLASH + + entity.getClientResourceName()); Function update = BalSyntaxUtils.generatePutFunction(entity, filterKeys, path); update.addStatement(NodeParser.parseStatement(BalSyntaxConstants.SQL_CLIENT_DECLARATION)); @@ -212,7 +214,8 @@ public FunctionDefinitionNode getPutFunction(Entity entity) { @Override public FunctionDefinitionNode getDeleteFunction(Entity entity) { StringBuilder filterKeys = new StringBuilder(BalSyntaxConstants.OPEN_BRACE); - StringBuilder path = new StringBuilder(BalSyntaxConstants.BACK_SLASH + entity.getResourceName()); + StringBuilder path = new StringBuilder(BalSyntaxConstants.BACK_SLASH + + entity.getClientResourceName()); Function delete = BalSyntaxUtils.generateDeleteFunction(entity, filterKeys, path); delete.addStatement(NodeParser.parseStatement(String.format(BalSyntaxConstants.GET_OBJECT_QUERY, entity.getEntityName(), path))); @@ -258,7 +261,7 @@ private static Node generateMetadataRecord(Module entityModule) { entityMetaData.append(String.format(BalSyntaxConstants.METADATA_RECORD_ENTITY_NAME_TEMPLATE, BalSyntaxUtils.stripEscapeCharacter(entity.getEntityName()))); entityMetaData.append(String.format(BalSyntaxConstants.METADATA_RECORD_TABLE_NAME_TEMPLATE, - BalSyntaxUtils.stripEscapeCharacter(entity.getEntityName()))); + BalSyntaxUtils.stripEscapeCharacter(entity.getTableName()))); StringBuilder fieldMetaData = new StringBuilder(); StringBuilder associateFieldMetaData = new StringBuilder(); boolean relationsExists = false; @@ -271,11 +274,12 @@ private static Node generateMetadataRecord(Module entityModule) { fieldMetaData.append(BalSyntaxConstants.COMMA_WITH_NEWLINE); } for (Relation.Key key : field.getRelation().getKeyColumns()) { + if (foreignKeyFields.length() != 0) { foreignKeyFields.append(BalSyntaxConstants.COMMA_WITH_NEWLINE); } foreignKeyFields.append(String.format(BalSyntaxConstants.METADATA_RECORD_FIELD_TEMPLATE, - key.getField(), BalSyntaxUtils.stripEscapeCharacter(key.getField()))); + key.getField(), BalSyntaxUtils.stripEscapeCharacter(key.getColumnName()))); } } fieldMetaData.append(foreignKeyFields); @@ -293,16 +297,17 @@ private static Node generateMetadataRecord(Module entityModule) { BalSyntaxUtils.stripEscapeCharacter(associatedEntityField.getFieldName()))); } else { if (associatedEntityField.getRelation().isOwner()) { - for (Relation.Key key : associatedEntityField.getRelation().getKeyColumns()) { - if (associateFieldMetaData.length() != 0) { - associateFieldMetaData.append(BalSyntaxConstants.COMMA_WITH_NEWLINE); + for (Relation.Key key : associatedEntityField.getRelation().getKeyColumns()) { + if (associateFieldMetaData.length() != 0) { + associateFieldMetaData.append(BalSyntaxConstants.COMMA_WITH_NEWLINE); + } + associateFieldMetaData.append(String.format((field.isArrayType() ? + "\"%s[]" : "\"%s") + + BalSyntaxConstants.ASSOCIATED_FIELD_TEMPLATE, + field.getFieldName(), key.getField(), + BalSyntaxUtils.stripEscapeCharacter(field.getFieldName()), + BalSyntaxUtils.stripEscapeCharacter(key.getField()))); } - associateFieldMetaData.append(String.format((field.isArrayType() ? - "\"%s[]" : "\"%s") + BalSyntaxConstants.ASSOCIATED_FIELD_TEMPLATE, - field.getFieldName(), key.getField(), - BalSyntaxUtils.stripEscapeCharacter(field.getFieldName()), - BalSyntaxUtils.stripEscapeCharacter(key.getField()))); - } } } } @@ -311,7 +316,7 @@ private static Node generateMetadataRecord(Module entityModule) { fieldMetaData.append(BalSyntaxConstants.COMMA_WITH_NEWLINE); } fieldMetaData.append(String.format(BalSyntaxConstants.METADATA_RECORD_FIELD_TEMPLATE, - field.getFieldName(), BalSyntaxUtils.stripEscapeCharacter(field.getFieldName()))); + field.getFieldName(), BalSyntaxUtils.stripEscapeCharacter(field.getFieldColumnName()))); } } if (associateFieldMetaData.length() > 1) { @@ -372,13 +377,13 @@ private static String getJoinMetaData(Entity entity) { refColumns.append(BalSyntaxConstants.COMMA); } refColumns.append(String.format(BalSyntaxConstants.COLUMN_ARRAY_ENTRY_TEMPLATE, - BalSyntaxUtils.stripEscapeCharacter(key.getReference()))); + BalSyntaxUtils.stripEscapeCharacter(key.getReferenceColumnName()))); joinColumns.append(String.format(BalSyntaxConstants.COLUMN_ARRAY_ENTRY_TEMPLATE, - BalSyntaxUtils.stripEscapeCharacter(key.getField()))); + BalSyntaxUtils.stripEscapeCharacter(key.getColumnName()))); } joinMetaData.append(String.format(BalSyntaxConstants.JOIN_METADATA_FIELD_TEMPLATE, - entityField.getFieldName(), entityField.getFieldType(), - entityField.getFieldName(), entityField.getFieldType(), refColumns, + entityField.getFieldName(), entityField.getFieldType(), entityField.getFieldName(), + entityField.getRelation().getAssocEntity().getTableName(), refColumns, joinColumns, relationType)); } } @@ -394,6 +399,18 @@ private static void addFunctionBodyToPostResource(Function create, List 1) { @@ -180,7 +180,7 @@ public FunctionDefinitionNode getPutFunction(Entity entity) { @Override public FunctionDefinitionNode getDeleteFunction(Entity entity) { StringBuilder filterKeys = new StringBuilder(BalSyntaxConstants.OPEN_BRACE); - StringBuilder path = new StringBuilder(BalSyntaxConstants.BACK_SLASH + entity.getResourceName()); + StringBuilder path = new StringBuilder(BalSyntaxConstants.BACK_SLASH + entity.getClientResourceName()); Function delete = BalSyntaxUtils.generateDeleteFunction(entity, filterKeys, path); delete.addStatement(NodeParser.parseStatement(String.format(BalSyntaxConstants.GET_OBJECT_QUERY, entity.getEntityName(), path))); @@ -217,7 +217,7 @@ private String generateMetadataRecord(Module entityModule) { String endRange = "A"; boolean hasAssociationMethod = false; String entityName = entity.getEntityName(); - String entityResourceName = entity.getResourceName(); + String entityResourceName = entity.getClientResourceName(); StringBuilder fieldMetaData = new StringBuilder(); StringBuilder associationsMethods = new StringBuilder(); StringBuilder fieldType = new StringBuilder(); @@ -277,7 +277,7 @@ private String generateMetadataRecord(Module entityModule) { associationsMethods.append(BalSyntaxConstants.COMMA_WITH_NEWLINE); } String associateEntityName = BalSyntaxUtils.stripEscapeCharacter(relation. - getAssocEntity().getResourceName()); + getAssocEntity().getClientResourceName()); String associateEntityNameCamelCase = associateEntityName.substring(0, 1). toUpperCase(Locale.ENGLISH) + associateEntityName.substring(1). toLowerCase(Locale.ENGLISH); diff --git a/persist-cli/src/main/java/io/ballerina/persist/nodegenerator/syntax/clients/InMemoryClientSyntax.java b/persist-cli/src/main/java/io/ballerina/persist/nodegenerator/syntax/clients/InMemoryClientSyntax.java index 3dd45bf79..4c2dd4bcf 100644 --- a/persist-cli/src/main/java/io/ballerina/persist/nodegenerator/syntax/clients/InMemoryClientSyntax.java +++ b/persist-cli/src/main/java/io/ballerina/persist/nodegenerator/syntax/clients/InMemoryClientSyntax.java @@ -137,7 +137,7 @@ public FunctionDefinitionNode getPutFunction(Entity entity) { this.primaryKeysTuple = new StringBuilder(); this.primaryKeysRecord = new StringBuilder(); StringBuilder filterKeys = new StringBuilder(BalSyntaxConstants.OPEN_BRACE); - StringBuilder path = new StringBuilder(BalSyntaxConstants.BACK_SLASH + entity.getResourceName()); + StringBuilder path = new StringBuilder(BalSyntaxConstants.BACK_SLASH + entity.getClientResourceName()); EntityField primaryKey; List keys = entity.getKeys(); if (keys.size() == 1) { @@ -164,18 +164,18 @@ public FunctionDefinitionNode getPutFunction(Entity entity) { update.addStatement(NodeParser.parseStatement(BalSyntaxConstants.LOCK)); update.addStatement(NodeParser.parseStatement(BalSyntaxConstants.OPEN_BRACE)); IfElse hasCheck = new IfElse(NodeParser.parseExpression(String.format(BalSyntaxConstants.HAS_NOT_KEY, - entity.getResourceName(), + entity.getClientResourceName(), primaryKeysTuple))); hasCheck.addIfStatement(NodeParser.parseStatement(String.format(BalSyntaxConstants.HAS_NOT_KEY_ERROR, entity.getEntityName(), primaryKeysRecord))); update.addIfElseStatement(hasCheck.getIfElseStatementNode()); String entityNameInLowerCase = entity.getEntityName().toLowerCase(Locale.ENGLISH); update.addStatement(NodeParser.parseStatement(String.format(BalSyntaxConstants.GET_UPDATE_RECORD, - entity.getEntityName(), entityNameInLowerCase, entity.getResourceName(), primaryKeysTuple))); + entity.getEntityName(), entityNameInLowerCase, entity.getClientResourceName(), primaryKeysTuple))); update.addStatement(NodeParser.parseStatement( String.format(BalSyntaxConstants.UPDATE_RECORD_FIELD_VALUE, entityNameInLowerCase))); update.addStatement(NodeParser.parseStatement(String.format(BalSyntaxConstants.PUT_VALUE_TO_MAP, - entity.getResourceName(), entityNameInLowerCase))); + entity.getClientResourceName(), entityNameInLowerCase))); update.addStatement(NodeParser.parseStatement(String.format(BalSyntaxConstants.RETURN_STATEMENT, entity.getEntityName().toLowerCase(Locale.ENGLISH)))); update.addStatement(NodeParser.parseStatement(BalSyntaxConstants.CLOSE_BRACE)); @@ -185,17 +185,17 @@ public FunctionDefinitionNode getPutFunction(Entity entity) { @Override public FunctionDefinitionNode getDeleteFunction(Entity entity) { StringBuilder filterKeys = new StringBuilder(BalSyntaxConstants.OPEN_BRACE); - StringBuilder path = new StringBuilder(BalSyntaxConstants.BACK_SLASH + entity.getResourceName()); + StringBuilder path = new StringBuilder(BalSyntaxConstants.BACK_SLASH + entity.getClientResourceName()); Function delete = BalSyntaxUtils.generateDeleteFunction(entity, path, filterKeys); delete.addStatement(NodeParser.parseStatement(BalSyntaxConstants.LOCK)); delete.addStatement(NodeParser.parseStatement(BalSyntaxConstants.OPEN_BRACE)); IfElse hasCheck = new IfElse(NodeParser.parseExpression(String.format(BalSyntaxConstants.HAS_NOT_KEY, - entity.getResourceName(), primaryKeysTuple))); + entity.getClientResourceName(), primaryKeysTuple))); hasCheck.addIfStatement(NodeParser.parseStatement(String.format(BalSyntaxConstants.HAS_NOT_KEY_ERROR, entity.getEntityName(), primaryKeysRecord))); delete.addIfElseStatement(hasCheck.getIfElseStatementNode()); delete.addStatement(NodeParser.parseStatement(String.format(BalSyntaxConstants.DELETED_OBJECT, - entity.getResourceName(), primaryKeysTuple))); + entity.getClientResourceName(), primaryKeysTuple))); delete.addStatement(NodeParser.parseStatement(BalSyntaxConstants.CLOSE_BRACE)); return delete.getFunctionDefinitionNode(); } @@ -238,10 +238,10 @@ private static void addFunctionBodyToInMemoryPostResource(Function create, List< filterKeysRecord.append(BalSyntaxConstants.CLOSE_BRACE); variableArrayType.append(String.format(BalSyntaxConstants.VARIABLE_TYPE, variableType)); } - forEachStmt.append(String.format(BalSyntaxConstants.HAS_KEY, entity.getResourceName(), filterKeys)); + forEachStmt.append(String.format(BalSyntaxConstants.HAS_KEY, entity.getClientResourceName(), filterKeys)); forEachStmt.append(String.format(BalSyntaxConstants.HAS_KEY_ERROR, entity.getEntityName(), filterKeysRecord)); - forEachStmt.append(String.format("\t" + BalSyntaxConstants.PUT_VALUE_TO_MAP, entity.getResourceName(), + forEachStmt.append(String.format("\t" + BalSyntaxConstants.PUT_VALUE_TO_MAP, entity.getClientResourceName(), "value.clone()")); forEachStmt.append(BalSyntaxConstants.CLOSE_BRACE); forEachStmt.append(String.format(BalSyntaxConstants.PUSH_VALUES, filterKeys)).append("}"); @@ -261,7 +261,7 @@ private static String generateInMemoryMetadataRecord(Module entityModule, Listinserted.lastInsertId;" + System.lineSeparator(); public static final String SELECT_WITH_SPACE = "\t\t\tselect "; public static final String UPDATE_RUN_UPDATE_QUERY = "_ = check sqlClient.runUpdateQuery(%s, value);"; public static final String G_SHEET_UPDATE_RUN_UPDATE_QUERY = "_ = check googleSheetsClient." + @@ -140,6 +147,7 @@ private InheritedTypeReferenceConstants() { public static final String JDBC_URL_WITH_DATABASE_MSSQL = "jdbc:%s://%s:%s;databaseName=%s"; public static final String JDBC_URL_WITH_DATABASE_POSTGRESQL = "jdbc:%s://%s:%s/%s"; public static final String CREATE_DATABASE_SQL_FORMAT_MYSQL = "CREATE DATABASE IF NOT EXISTS %s"; + public static final String DROP_DATABASE_SQL_FORMAT_MYSQL = "DROP DATABASE IF EXISTS %s"; public static final String CREATE_DATABASE_SQL_FORMAT_MSSQL = "IF NOT EXISTS(SELECT name FROM sys.databases WHERE name = '%1$s') CREATE DATABASE %1$s;"; public static final String CREATE_DATABASE_SQL_FORMAT_POSTGRESQL = "CREATE DATABASE %s;"; @@ -248,6 +256,32 @@ private InheritedTypeReferenceConstants() { public static final String CONSTRAINT_ANNOTATION = "@constraint:String {" + System.lineSeparator() + " %s" + System.lineSeparator() + " }"; + + public static final String SQL_DB_MAPPING_ANNOTATION_NAME = "sql:Mapping"; + public static final String SQL_VARCHAR_MAPPING_ANNOTATION_NAME = "sql:VarChar"; + public static final String SQL_CHAR_MAPPING_ANNOTATION_NAME = "sql:Char"; + public static final String SQL_DECIMAL_MAPPING_ANNOTATION_NAME = "sql:Decimal"; + public static final String SQL_RELATION_MAPPING_ANNOTATION_NAME = "sql:Relation"; + public static final String SQL_INDEX_MAPPING_ANNOTATION_NAME = "sql:Index"; + public static final String SQL_UNIQUE_INDEX_MAPPING_ANNOTATION_NAME = "sql:UniqueIndex"; + public static final String SQL_GENERATED_ANNOTATION_NAME = "sql:Generated"; + public static final String SQL_DB_MAPPING_ANNOTATION = + String.format("@%s { name: \"%s\" }", SQL_DB_MAPPING_ANNOTATION_NAME, "%s"); + public static final String SQL_VARCHAR_MAPPING_ANNOTATION = + String.format("@%s { length: %s }", SQL_VARCHAR_MAPPING_ANNOTATION_NAME, "%s"); + public static final String SQL_CHAR_MAPPING_ANNOTATION = + String.format("@%s{ length: %s }", SQL_CHAR_MAPPING_ANNOTATION_NAME, "%s"); + public static final String SQL_DECIMAL_MAPPING_ANNOTATION = + String.format("@%s{ precision: [%s,%s] }", SQL_DECIMAL_MAPPING_ANNOTATION_NAME, "%s", "%s"); + public static final String SQL_RELATION_MAPPING_ANNOTATION = + String.format("@%s{ refs: %s }", SQL_RELATION_MAPPING_ANNOTATION_NAME, "%s"); + public static final String SQL_INDEX_MAPPING_ANNOTATION = + String.format("@%s { names: %s }", SQL_INDEX_MAPPING_ANNOTATION_NAME, "%s"); + public static final String SQL_UNIQUE_INDEX_MAPPING_ANNOTATION = + String.format("@%s { names: %s }", SQL_UNIQUE_INDEX_MAPPING_ANNOTATION_NAME, "%s"); + public static final String SQL_GENERATED_ANNOTATION = String.format("@%s", SQL_GENERATED_ANNOTATION_NAME); + + public static final String FIELD_METADATA_TEMPLATE = "fieldMetadata: {%s}"; public static final String JOIN_METADATA_TEMPLATE = "joinMetadata: {%s}"; diff --git a/persist-cli/src/main/java/io/ballerina/persist/nodegenerator/syntax/sources/DbModelGenSyntaxTree.java b/persist-cli/src/main/java/io/ballerina/persist/nodegenerator/syntax/sources/DbModelGenSyntaxTree.java new file mode 100644 index 000000000..a4358cd1a --- /dev/null +++ b/persist-cli/src/main/java/io/ballerina/persist/nodegenerator/syntax/sources/DbModelGenSyntaxTree.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you 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 + * + * http://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 io.ballerina.persist.nodegenerator.syntax.sources; + + +import io.ballerina.compiler.syntax.tree.SyntaxTree; +import io.ballerina.persist.BalException; +import io.ballerina.persist.models.Module; +import io.ballerina.persist.nodegenerator.syntax.utils.BalSyntaxUtils; + +public class DbModelGenSyntaxTree implements IntrospectSyntaxTree { + + @Override + public SyntaxTree getDataModels(Module entityModule) throws BalException { + if (!entityModule.getEntityMap().values().isEmpty()) { + return BalSyntaxUtils.generateModelSyntaxTree(entityModule); + } + throw new BalException("No entities found in the database"); + } + + @Override + public SyntaxTree createInitialDriverImportFile() { + return BalSyntaxUtils.createDriverImportFile("mysql"); + } + +} diff --git a/persist-cli/src/main/java/io/ballerina/persist/nodegenerator/syntax/sources/GSheetSyntaxTree.java b/persist-cli/src/main/java/io/ballerina/persist/nodegenerator/syntax/sources/GSheetSyntaxTree.java index 20ab26d9f..ef18a8761 100644 --- a/persist-cli/src/main/java/io/ballerina/persist/nodegenerator/syntax/sources/GSheetSyntaxTree.java +++ b/persist-cli/src/main/java/io/ballerina/persist/nodegenerator/syntax/sources/GSheetSyntaxTree.java @@ -79,7 +79,7 @@ public io.ballerina.compiler.syntax.tree.SyntaxTree getClientSyntax(Module entit FunctionDefinitionNode[] functions = createQueryFunction(entity); resource.addFunction(functions[0], true); resource.addFunction(functions[1], true); - String entityResourceName = entity.getResourceName(); + String entityResourceName = entity.getClientResourceName(); resource.addFunction(NodeParser.parseStatement(String.format( BalSyntaxConstants.EXTERNAL_QUERY_STREAM_METHOD_TEMPLATE, entityResourceName.substring(0, 1). toUpperCase(Locale.ENGLISH) + entityResourceName.substring(1), @@ -163,7 +163,7 @@ private static io.ballerina.toml.syntax.tree.NodeList entityArray = entityModule.getEntityMap().values(); @@ -129,7 +129,7 @@ public io.ballerina.compiler.syntax.tree.SyntaxTree getConfigTomlSyntax(String m } private static FunctionDefinitionNode[] createQueryFunctions(Entity entity) { - String resourceName = entity.getResourceName(); + String resourceName = entity.getClientResourceName(); String nameInCamelCase = resourceName.substring(0, 1).toUpperCase(Locale.ENGLISH) + resourceName.substring(1); String clonedTables = getQueryClonedTables(entity); @@ -171,10 +171,10 @@ private static StringBuilder[] createQuery(Entity entity, StringBuilder queryBui Entity assocEntity = relation.getAssocEntity(); String fieldName = field.getFieldName(); queryBuilder.append(String.format(BalSyntaxConstants.QUERY_OUTER_JOIN, - fieldName.toLowerCase(Locale.ENGLISH), assocEntity.getResourceName())); + fieldName.toLowerCase(Locale.ENGLISH), assocEntity.getClientResourceName())); queryBuilder.append(BalSyntaxConstants.ON); queryOneBuilder.append(String.format(BalSyntaxConstants.QUERY_OUTER_JOIN, - fieldName.toLowerCase(Locale.ENGLISH), assocEntity.getResourceName())); + fieldName.toLowerCase(Locale.ENGLISH), assocEntity.getClientResourceName())); queryOneBuilder.append(BalSyntaxConstants.ON); relationalRecordFields.append(String.format(BalSyntaxConstants.VARIABLE, fieldName, fieldName.toLowerCase(Locale.ENGLISH))); @@ -259,9 +259,9 @@ public static String getClonedTable(Entity entity) { StringBuilder clonedTable = new StringBuilder(); clonedTable.append(String.format(BalSyntaxConstants.CLONED_TABLE_INIT_TEMPLATE, entity.getEntityName(), getPrimaryKeys(entity, false), - entity.getResourceName())); + entity.getClientResourceName())); String clonedTableDeclaration = String.format(BalSyntaxConstants.CLONED_TABLE_DECLARATION_TEMPLATE, - entity.getResourceName(), entity.getResourceName()); + entity.getClientResourceName(), entity.getClientResourceName()); clonedTable.append(String.format(BalSyntaxConstants.LOCK_TEMPLATE, clonedTableDeclaration)); return clonedTable.toString(); diff --git a/persist-cli/src/main/java/io/ballerina/persist/nodegenerator/syntax/sources/IntrospectSyntaxTree.java b/persist-cli/src/main/java/io/ballerina/persist/nodegenerator/syntax/sources/IntrospectSyntaxTree.java new file mode 100644 index 000000000..7ce28b463 --- /dev/null +++ b/persist-cli/src/main/java/io/ballerina/persist/nodegenerator/syntax/sources/IntrospectSyntaxTree.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you 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 + * + * http://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 io.ballerina.persist.nodegenerator.syntax.sources; + +import io.ballerina.persist.BalException; +import io.ballerina.persist.models.Module; + +public interface IntrospectSyntaxTree { + io.ballerina.compiler.syntax.tree.SyntaxTree getDataModels(Module entityModule) throws BalException; + io.ballerina.compiler.syntax.tree.SyntaxTree createInitialDriverImportFile(); +} diff --git a/persist-cli/src/main/java/io/ballerina/persist/nodegenerator/syntax/utils/BalSyntaxUtils.java b/persist-cli/src/main/java/io/ballerina/persist/nodegenerator/syntax/utils/BalSyntaxUtils.java index 437e483c1..6d6748bf4 100644 --- a/persist-cli/src/main/java/io/ballerina/persist/nodegenerator/syntax/utils/BalSyntaxUtils.java +++ b/persist-cli/src/main/java/io/ballerina/persist/nodegenerator/syntax/utils/BalSyntaxUtils.java @@ -40,6 +40,7 @@ import io.ballerina.compiler.syntax.tree.SyntaxKind; import io.ballerina.compiler.syntax.tree.SyntaxTree; import io.ballerina.compiler.syntax.tree.Token; +import io.ballerina.persist.PersistToolsConstants; import io.ballerina.persist.components.Client; import io.ballerina.persist.components.Function; import io.ballerina.persist.components.TypeDescriptor; @@ -49,15 +50,18 @@ import io.ballerina.persist.models.EnumMember; import io.ballerina.persist.models.Module; import io.ballerina.persist.models.Relation; +import io.ballerina.persist.models.SQLType; import io.ballerina.persist.nodegenerator.syntax.constants.BalSyntaxConstants; import io.ballerina.persist.nodegenerator.syntax.constants.SyntaxTokenConstants; import io.ballerina.tools.text.TextDocument; import io.ballerina.tools.text.TextDocuments; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Optional; +import java.util.stream.Stream; /** * This class is used to generate the common syntax tree for the client. @@ -95,7 +99,7 @@ public static NodeList generateConstantVariables(Mo for (Entity entity : entityModule.getEntityMap().values()) { moduleMembers = moduleMembers.add(NodeParser.parseModuleMemberDeclaration(String.format( "const %s = \"%s\";", stripEscapeCharacter(getStringWithUnderScore(entity.getEntityName())), - stripEscapeCharacter(entity.getResourceName())))); + stripEscapeCharacter(entity.getClientResourceName())))); } return moduleMembers; } @@ -140,7 +144,7 @@ public static Function generateCloseFunction() { public static FunctionDefinitionNode generateGetFunction(Entity entity, String className, String moduleName) { return (FunctionDefinitionNode) NodeParser.parseObjectMember( String.format(BalSyntaxConstants.EXTERNAL_GET_METHOD_TEMPLATE, - entity.getResourceName(), entity.getEntityName(), moduleName, className)); + entity.getClientResourceName(), entity.getEntityName(), moduleName, className)); } public static FunctionDefinitionNode generateGetByKeyFunction(Entity entity, String className, String moduleName) { @@ -158,13 +162,15 @@ public static FunctionDefinitionNode generateGetByKeyFunction(Entity entity, Str return (FunctionDefinitionNode) NodeParser.parseObjectMember( String.format(BalSyntaxConstants.EXTERNAL_GET_BY_KEY_METHOD_TEMPLATE, - entity.getResourceName(), keyBuilder, entity.getEntityName(), moduleName, className)); + entity.getClientResourceName(), + keyBuilder, entity.getEntityName(), moduleName, className)); } public static Function generatePostFunction(Entity entity, List primaryKeys, String parameterType) { Function create = new Function(BalSyntaxConstants.POST, SyntaxKind.RESOURCE_ACCESSOR_DEFINITION); NodeList resourcePaths = AbstractNodeFactory.createEmptyNodeList(); - resourcePaths = resourcePaths.add(AbstractNodeFactory.createIdentifierToken(entity.getResourceName())); + resourcePaths = resourcePaths.add(AbstractNodeFactory.createIdentifierToken( + entity.getClientResourceName())); create.addRelativeResourcePaths(resourcePaths); create.addRequiredParameter( TypeDescriptor.getArrayTypeDescriptorNode(parameterType), BalSyntaxConstants.KEYWORD_VALUE); @@ -183,7 +189,8 @@ public static Function generatePutFunction(Entity entity, StringBuilder filterKe update.addRequiredParameter(TypeDescriptor.getSimpleNameReferenceNode( String.format(BalSyntaxConstants.UPDATE_RECORD, entity.getEntityName())), BalSyntaxConstants.VALUE); NodeList resourcePaths = AbstractNodeFactory.createEmptyNodeList(); - resourcePaths = getResourcePath(resourcePaths, entity.getKeys(), filterKeys, path, entity.getResourceName()); + resourcePaths = getResourcePath(resourcePaths, entity.getKeys(), filterKeys, path, + entity.getClientResourceName()); update.addRelativeResourcePaths(resourcePaths); update.addReturns(TypeDescriptor.getUnionTypeDescriptorNode( TypeDescriptor.getSimpleNameReferenceNode(entity.getEntityName()), @@ -198,7 +205,8 @@ public static Function generateDeleteFunction(Entity entity, StringBuilder filte BalSyntaxConstants.KEYWORD_RESOURCE }); NodeList resourcePaths = AbstractNodeFactory.createEmptyNodeList(); - resourcePaths = getResourcePath(resourcePaths, entity.getKeys(), filterKeys, path, entity.getResourceName()); + resourcePaths = getResourcePath(resourcePaths, entity.getKeys(), filterKeys, path, + entity.getClientResourceName()); delete.addRelativeResourcePaths(resourcePaths); delete.addReturns(TypeDescriptor.getUnionTypeDescriptorNode( TypeDescriptor.getSimpleNameReferenceNode(entity.getEntityName()), @@ -285,7 +293,8 @@ private static NodeList getResourcePath(NodeList resourcePaths, List null, AbstractNodeFactory.createIdentifierToken(entry.getFieldName()), AbstractNodeFactory.createToken(SyntaxKind.CLOSE_BRACKET_TOKEN))); - filterKeys.append(BalSyntaxConstants.DOUBLE_QUOTE).append(stripEscapeCharacter(entry.getFieldName())) + filterKeys.append(BalSyntaxConstants.DOUBLE_QUOTE) + .append(stripEscapeCharacter(entry.getFieldName())) .append(BalSyntaxConstants.DOUBLE_QUOTE).append(BalSyntaxConstants.COLON). append(entry.getFieldName()).append(BalSyntaxConstants.COMMA_WITH_SPACE); path.append(BalSyntaxConstants.BACK_SLASH).append(BalSyntaxConstants.OPEN_BRACKET). @@ -294,6 +303,84 @@ private static NodeList getResourcePath(NodeList resourcePaths, List return resourcePaths; } + public static SyntaxTree createDriverImportFile(String datasource) { + NodeList imports = AbstractNodeFactory.createEmptyNodeList(); + NodeList moduleMembers = AbstractNodeFactory.createEmptyNodeList(); + imports = imports.add(NodeParser.parseImportDeclaration(("import ballerinax/mysql.driver as _;"))); + Token eofToken = AbstractNodeFactory.createIdentifierToken(BalSyntaxConstants.EMPTY_STRING); + ModulePartNode modulePartNode = NodeFactory.createModulePartNode(imports, moduleMembers, eofToken); + TextDocument textDocument = TextDocuments.from(BalSyntaxConstants.EMPTY_STRING); + SyntaxTree balTree = SyntaxTree.from(textDocument); + return balTree.modifyWith(modulePartNode); + } + + public static SyntaxTree generateModelSyntaxTree(Module entityModule) { + NodeList imports = AbstractNodeFactory.createEmptyNodeList(); + NodeList moduleMembers = AbstractNodeFactory.createEmptyNodeList(); + MinutiaeList commentMinutiaeList = createCommentMinutiaeList(String.format( + BalSyntaxConstants.AUTO_GENERATED_COMMENT_WITH_REASON, entityModule.getModuleName())); + imports = imports.add(NodeParser.parseImportDeclaration("import ballerina/persist as _;")); + boolean areAnnotationsAdded = false; + for (Entity entity : entityModule.getEntityMap().values()) { + if (entity.shouldTableMappingGenerated() + || (entity.getIndexes() != null && !entity.getIndexes().isEmpty()) + || (entity.getUniqueIndexes() != null && !entity.getUniqueIndexes().isEmpty())) { + areAnnotationsAdded = true; + break; + } + for (EntityField field : entity.getFields()) { + if (field.shouldColumnMappingGenerated() + || field.isDbGenerated() + || isDbTypeMappingRequired(field) + || (field.getRelationRefs() != null) && !field.getRelationRefs().isEmpty()) { + areAnnotationsAdded = true; + break; + } + } + } + if (areAnnotationsAdded) { + imports = imports.add(NodeParser.parseImportDeclaration(("import ballerinax/persist.sql;"))); + } + if (entityModule.getEntityMap().values().stream().anyMatch(entity -> + entity.getFields().stream().anyMatch(field -> field.getFieldType().startsWith("time")))) { + imports = imports.add(NodeParser.parseImportDeclaration("import ballerina/time;")); + } + for (String modulePrefix : entityModule.getImportModulePrefixes()) { + if (imports.isEmpty()) { + imports = imports.add(getImportDeclarationNodeWithAutogeneratedComment( + modulePrefix, + commentMinutiaeList)); + } else { + imports = imports.add(getImportDeclarationNode(modulePrefix)); + } + } + boolean includeAutoGeneratedComment = imports.isEmpty(); + + for (Enum enumValue: entityModule.getEnumMap().values()) { + moduleMembers = moduleMembers.add(createEnumDeclaration(enumValue, includeAutoGeneratedComment, + entityModule.getModuleName())); + + if (includeAutoGeneratedComment) { + includeAutoGeneratedComment = false; + } + } + + for (Entity entity : entityModule.getEntityMap().values()) { + + moduleMembers = moduleMembers.add(createEntityRecord(entity, includeAutoGeneratedComment, + entityModule.getModuleName(), true)); + + if (includeAutoGeneratedComment) { + includeAutoGeneratedComment = false; + } + } + Token eofToken = AbstractNodeFactory.createIdentifierToken(BalSyntaxConstants.EMPTY_STRING); + ModulePartNode modulePartNode = NodeFactory.createModulePartNode(imports, moduleMembers, eofToken); + TextDocument textDocument = TextDocuments.from(BalSyntaxConstants.EMPTY_STRING); + SyntaxTree balTree = SyntaxTree.from(textDocument); + return balTree.modifyWith(modulePartNode); + } + public static SyntaxTree generateTypeSyntaxTree(Module entityModule) { NodeList imports = AbstractNodeFactory.createEmptyNodeList(); NodeList moduleMembers = AbstractNodeFactory.createEmptyNodeList(); @@ -329,7 +416,7 @@ public static SyntaxTree generateTypeSyntaxTree(Module entityModule) { } moduleMembers = moduleMembers.add(createEntityRecord(entity, includeAutoGeneratedComment, - entityModule.getModuleName())); + entityModule.getModuleName(), false)); if (includeAutoGeneratedComment) { includeAutoGeneratedComment = false; @@ -340,9 +427,7 @@ public static SyntaxTree generateTypeSyntaxTree(Module entityModule) { moduleMembers = moduleMembers.add(createEntityRecordWithRelation(entity)); } moduleMembers = moduleMembers.add(createEntityTargetType(entity, hasRelations)); - moduleMembers = moduleMembers.add(NodeParser.parseModuleMemberDeclaration( - String.format("public type %sInsert %s;", entity.getEntityName(), - entity.getEntityName()))); + moduleMembers = moduleMembers.add(createInsertRecord(entity)); moduleMembers = moduleMembers.add(createUpdateRecord(entity)); } Token eofToken = AbstractNodeFactory.createIdentifierToken(BalSyntaxConstants.EMPTY_STRING); @@ -370,9 +455,16 @@ private static ImportDeclarationNode getImportDeclarationNode(String moduleName) } private static ModuleMemberDeclarationNode createEntityRecord(Entity entity, boolean includeAutogeneratedComment, - String moduleName) { + String moduleName, boolean withAnnotations) { StringBuilder recordFields = new StringBuilder(); for (EntityField field : entity.getFields()) { + if (withAnnotations) { + addDbMappingAnnotationToField(field, recordFields); + addDbTypeMappingAnnotationToField(field, recordFields); + addDbRelationMappingAnnotationToField(field, recordFields); + addDbIndexAnnotationToField(entity, field, recordFields); + addDbGeneratedAnnotationToField(field, recordFields); + } if (entity.getKeys().stream().anyMatch(key -> key == field)) { addConstrainAnnotationToField(field, recordFields); recordFields.append(BalSyntaxConstants.KEYWORD_READONLY); @@ -398,15 +490,10 @@ private static ModuleMemberDeclarationNode createEntityRecord(Entity entity, boo } } else { addConstrainAnnotationToField(field, recordFields); - recordFields.append(field.isOptionalType() ? field.getFieldType() + (field.isArrayType() ? - BalSyntaxConstants.ARRAY : "") + BalSyntaxConstants.QUESTION_MARK : field.getFieldType() + - (field.isArrayType() ? BalSyntaxConstants.ARRAY : "")); - recordFields.append(BalSyntaxConstants.SPACE); - recordFields.append(field.getFieldName()); - recordFields.append(BalSyntaxConstants.SEMICOLON); - recordFields.append(BalSyntaxConstants.SPACE); + addFieldString(recordFields, field); } + } if (includeAutogeneratedComment) { String commentBuilder = BalSyntaxConstants.AUTOGENERATED_FILE_COMMENT + System.lineSeparator() + @@ -416,10 +503,156 @@ private static ModuleMemberDeclarationNode createEntityRecord(Entity entity, boo return NodeParser.parseModuleMemberDeclaration(String.format(commentBuilder, entity.getEntityName().trim(), recordFields)); } - return NodeParser.parseModuleMemberDeclaration(String.format("public type %s record {| %s |};", + + StringBuilder recordString = new StringBuilder(); + if (withAnnotations) { + addDbMappingAnnotationToEntity(entity, recordString); + } + recordString.append(String.format("public type %s record {| %s |};", entity.getEntityName().trim(), recordFields)); + return NodeParser.parseModuleMemberDeclaration(recordString.toString()); + } + + private static void addDbGeneratedAnnotationToField(EntityField field, StringBuilder recordFields) { + if (field.isDbGenerated()) { + recordFields.append(BalSyntaxConstants.SQL_GENERATED_ANNOTATION); + recordFields.append(BalSyntaxConstants.NEWLINE); + } + } + + private static void addDbIndexAnnotationToField(Entity entity, EntityField field, StringBuilder recordFields) { + List indexNames = new ArrayList<>(); + List uniqueIndexNames = new ArrayList<>(); + entity.getUniqueIndexes().forEach(index -> { + if (index.getFields().contains(field)) { + uniqueIndexNames.add(index.getIndexName()); + } + }); + entity.getIndexes().forEach(index -> { + if (index.getFields().contains(field)) { + indexNames.add(index.getIndexName()); + } + }); + if (!indexNames.isEmpty()) { + recordFields.append(String.format(BalSyntaxConstants.SQL_INDEX_MAPPING_ANNOTATION, + formatToBalStringArray(indexNames))); + recordFields.append(BalSyntaxConstants.NEWLINE); + } + if (!uniqueIndexNames.isEmpty()) { + recordFields.append(String.format(BalSyntaxConstants.SQL_UNIQUE_INDEX_MAPPING_ANNOTATION, + formatToBalStringArray(uniqueIndexNames))); + recordFields.append(BalSyntaxConstants.NEWLINE); + } + } + + private static void addDbRelationMappingAnnotationToField(EntityField field, StringBuilder recordFields) { + if (!field.getRelationRefs().isEmpty()) { + recordFields.append(String.format(BalSyntaxConstants.SQL_RELATION_MAPPING_ANNOTATION, + formatToBalStringArray(field.getRelationRefs()))); + } + } + + private static String formatToBalStringArray(List list) { + StringBuilder stringArray = new StringBuilder(); + stringArray.append(SyntaxTokenConstants.SYNTAX_TREE_OPEN_BRACKET); + for (String item : list) { + stringArray.append(BalSyntaxConstants.DOUBLE_QUOTE); + stringArray.append(item); + stringArray.append(BalSyntaxConstants.DOUBLE_QUOTE); + stringArray.append(BalSyntaxConstants.COMMA_WITH_SPACE); + } + stringArray.delete(stringArray.length() - 2, stringArray.length()); + stringArray.append(SyntaxTokenConstants.SYNTAX_TREE_CLOSE_BRACKET); + return stringArray.toString(); + } + + private static void addDbTypeMappingAnnotationToField(EntityField field, StringBuilder recordFields) { + SQLType sqlType = field.getSqlType(); + if (sqlType != null) { + switch (sqlType.getTypeName()) { + case PersistToolsConstants.SqlTypes.CHAR: + recordFields.append(String.format + (BalSyntaxConstants.SQL_CHAR_MAPPING_ANNOTATION, sqlType.getMaxLength())); + break; + case PersistToolsConstants.SqlTypes.VARCHAR: + if (PersistToolsConstants.DefaultMaxLength.VARCHAR_LENGTH != sqlType.getMaxLength()) { + recordFields.append(String.format + (BalSyntaxConstants.SQL_VARCHAR_MAPPING_ANNOTATION, sqlType.getMaxLength())); + } + break; + case PersistToolsConstants.SqlTypes.DECIMAL: + // add later: check for default values for separate data sources + String dataSource = PersistToolsConstants.SupportedDataSources.MYSQL_DB; + int precision = PersistToolsConstants.DefaultMaxLength.DECIMAL_PRECISION_MYSQL; + int scale = PersistToolsConstants.DefaultMaxLength.DECIMAL_SCALE; + switch (dataSource) { + case PersistToolsConstants.SupportedDataSources.MYSQL_DB: + precision = PersistToolsConstants.DefaultMaxLength.DECIMAL_PRECISION_MYSQL; + break; + default: // do nothing + } + if (sqlType.getNumericPrecision() != precision || sqlType.getNumericScale() != scale) { + recordFields.append(String.format + (BalSyntaxConstants.SQL_DECIMAL_MAPPING_ANNOTATION, sqlType.getNumericPrecision(), + sqlType.getNumericScale())); + } + break; + default: + break; + } + } + } + + private static boolean isDbTypeMappingRequired(EntityField field) { + SQLType sqlType = field.getSqlType(); + if (sqlType != null) { + switch (sqlType.getTypeName()) { + case PersistToolsConstants.SqlTypes.CHAR: + return true; + case PersistToolsConstants.SqlTypes.VARCHAR: + if (PersistToolsConstants.DefaultMaxLength.VARCHAR_LENGTH != sqlType.getMaxLength()) { + return true; + } + return false; + case PersistToolsConstants.SqlTypes.DECIMAL: + // add later: check for default values for separate data sources + String dataSource = PersistToolsConstants.SupportedDataSources.MYSQL_DB; + int precision = PersistToolsConstants.DefaultMaxLength.DECIMAL_PRECISION_MYSQL; + int scale = PersistToolsConstants.DefaultMaxLength.DECIMAL_SCALE; + switch (dataSource) { + case PersistToolsConstants.SupportedDataSources.MYSQL_DB: + precision = PersistToolsConstants.DefaultMaxLength.DECIMAL_PRECISION_MYSQL; + break; + default: // do nothing + } + if (sqlType.getNumericPrecision() != precision || sqlType.getNumericScale() != scale) { + return true; + } + return false; + default: + return false; + } + } + return false; } + private static void addDbMappingAnnotationToField(EntityField field, StringBuilder recordFields) { + if (field.shouldColumnMappingGenerated()) { + recordFields.append(String.format(BalSyntaxConstants.SQL_DB_MAPPING_ANNOTATION, + field.getFieldColumnName())); + } + } + + private static void addDbMappingAnnotationToEntity(Entity entity, StringBuilder recordString) { + if (entity.shouldTableMappingGenerated()) { + recordString.append(String.format(BalSyntaxConstants.SQL_DB_MAPPING_ANNOTATION, + entity.getTableName())); + recordString.append(System.lineSeparator()); + } + } + + + private static ModuleMemberDeclarationNode createEnumDeclaration(Enum enumValue, boolean includeAutogeneratedComment, String moduleName) { @@ -461,14 +694,16 @@ private static ModuleMemberDeclarationNode createEntityRecordOptionalized(Entity if (field.getRelation() != null) { addConstraintsAnnotationForForeignKey(field, recordFields); if (field.getRelation().isOwner()) { - for (Relation.Key key : field.getRelation().getKeyColumns()) { - recordFields.append(key.getType()); - recordFields.append(BalSyntaxConstants.SPACE); - recordFields.append(key.getField()); - recordFields.append(BalSyntaxConstants.QUESTION_MARK); - recordFields.append(BalSyntaxConstants.SEMICOLON); - recordFields.append(BalSyntaxConstants.SPACE); - } + for (Relation.Key key : field.getRelation().getKeyColumns()) { + recordFields.append(key.getType()); + recordFields.append(BalSyntaxConstants.SPACE); + recordFields.append(key.getField()); + recordFields.append(BalSyntaxConstants.QUESTION_MARK); + recordFields.append(BalSyntaxConstants.SEMICOLON); + recordFields.append(BalSyntaxConstants.SPACE); + } + + } } else { addConstrainAnnotationToField(field, recordFields); @@ -493,13 +728,10 @@ private static void addConstraintsAnnotationForForeignKey(EntityField field, Str for (EntityField assocField : relation.getAssocEntity().getFields()) { for (String reference : references) { if (assocField.getFieldName().equals(reference)) { - NodeList annotation = assocField.getAnnotation(); - if (annotation != null) { - String params = getConstraintField(assocField); - if (params != null) { - recordFields.append(String.format(BalSyntaxConstants.CONSTRAINT_ANNOTATION, + String params = getConstraintField(assocField); + if (params != null) { + recordFields.append(String.format(BalSyntaxConstants.CONSTRAINT_ANNOTATION, params)); - } } break; } @@ -508,13 +740,72 @@ private static void addConstraintsAnnotationForForeignKey(EntityField field, Str } private static void addConstrainAnnotationToField(EntityField field, StringBuilder recordFields) { - NodeList annotation = field.getAnnotation(); - if (annotation != null) { - String params = getConstraintField(field); - if (params != null) { - recordFields.append(String.format(BalSyntaxConstants.CONSTRAINT_ANNOTATION, params)); + String params = getConstraintField(field); + if (params != null) { + recordFields.append(String.format(BalSyntaxConstants.CONSTRAINT_ANNOTATION, params)); + } + } + + public static String readStringValueFromAnnotation + (List annotationNodes, String annotation, + String field) { + for (AnnotationNode annotationNode : annotationNodes) { + String annotationName = annotationNode.annotReference().toSourceCode().trim(); + if (annotationName.equals(annotation)) { + Optional annotationFieldNode = annotationNode.annotValue(); + if (annotationFieldNode.isPresent()) { + for (MappingFieldNode mappingFieldNode : annotationFieldNode.get().fields()) { + SpecificFieldNode specificFieldNode = (SpecificFieldNode) mappingFieldNode; + String fieldName = specificFieldNode.fieldName().toSourceCode().trim(); + if (!fieldName.equals(field)) { + return ""; + } + Optional valueExpr = specificFieldNode.valueExpr(); + if (valueExpr.isPresent()) { + return valueExpr.get().toSourceCode().trim().replace("\"", "").trim(); + } + } + } } } + return ""; + } + + public static boolean isAnnotationPresent + (List annotationNodes, String annotation) { + for (AnnotationNode annotationNode : annotationNodes) { + String annotationName = annotationNode.annotReference().toSourceCode().trim(); + if (annotationName.equals(annotation)) { + return true; + } + } + return false; + } + public static List readStringArrayValueFromAnnotation + (List annotationNodes, String annotation, + String field) { + for (AnnotationNode annotationNode : annotationNodes) { + String annotationName = annotationNode.annotReference().toSourceCode().trim(); + if (annotationName.equals(annotation)) { + Optional annotationFieldNode = annotationNode.annotValue(); + if (annotationFieldNode.isPresent()) { + for (MappingFieldNode mappingFieldNode : annotationFieldNode.get().fields()) { + SpecificFieldNode specificFieldNode = (SpecificFieldNode) mappingFieldNode; + String fieldName = specificFieldNode.fieldName().toSourceCode().trim(); + if (!fieldName.equals(field)) { + return Collections.emptyList(); + } + Optional valueExpr = specificFieldNode.valueExpr(); + if (valueExpr.isPresent()) { + return Stream.of(valueExpr.get().toSourceCode().trim().replace("\"", "") + .replace("[", "") + .replace("]", "").split(",")).map(String::trim).toList(); + } + } + } + } + } + return Collections.emptyList(); } private static String getConstraintField(EntityField field) { @@ -579,15 +870,16 @@ private static ModuleMemberDeclarationNode createUpdateRecord(Entity entity) { if (entity.getKeys().stream().noneMatch(key -> key == field)) { if (field.getRelation() != null) { if (field.getRelation().isOwner()) { - for (Relation.Key key : field.getRelation().getKeyColumns()) { - addConstraintsAnnotationForForeignKey(field, recordFields); - recordFields.append(key.getType()); - recordFields.append(" "); - recordFields.append(key.getField()); - recordFields.append(BalSyntaxConstants.QUESTION_MARK); - recordFields.append(BalSyntaxConstants.SEMICOLON); - recordFields.append(BalSyntaxConstants.SPACE); - } + for (Relation.Key key : field.getRelation().getKeyColumns()) { + addConstraintsAnnotationForForeignKey(field, recordFields); + recordFields.append(key.getType()); + recordFields.append(" "); + recordFields.append(key.getField()); + recordFields.append(BalSyntaxConstants.QUESTION_MARK); + recordFields.append(BalSyntaxConstants.SEMICOLON); + recordFields.append(BalSyntaxConstants.SPACE); + } + } } else { addConstrainAnnotationToField(field, recordFields); @@ -608,6 +900,49 @@ private static ModuleMemberDeclarationNode createUpdateRecord(Entity entity) { entity.getEntityName().trim(), recordFields)); } + private static ModuleMemberDeclarationNode createInsertRecord(Entity entity) { + boolean isAutoGenerated = entity.getFields().stream().anyMatch(EntityField::isDbGenerated); + if (!isAutoGenerated) { + return NodeParser.parseModuleMemberDeclaration( + String.format("public type %sInsert %s;", entity.getEntityName(), + entity.getEntityName())); + } + StringBuilder recordFields = new StringBuilder(); + for (EntityField field : entity.getFields()) { + if (entity.getKeys().stream().anyMatch(key -> key == field)) { + continue; + } + if (field.getRelation() != null) { + if (field.getRelation().isOwner()) { + for (Relation.Key key : field.getRelation().getKeyColumns()) { + recordFields.append(key.getType()); + recordFields.append(BalSyntaxConstants.SPACE); + recordFields.append(key.getField()); + recordFields.append(BalSyntaxConstants.SEMICOLON); + recordFields.append(BalSyntaxConstants.SPACE); + } + + } + } else { + addFieldString(recordFields, field); + } + } + StringBuilder recordString = new StringBuilder(); + recordString.append(String.format("public type %sInsert record {| %s |};", + entity.getEntityName().trim(), recordFields)); + return NodeParser.parseModuleMemberDeclaration(recordString.toString()); + } + + private static void addFieldString(StringBuilder recordFields, EntityField field) { + recordFields.append(field.getFieldType()); + recordFields.append(field.isArrayType() ? BalSyntaxConstants.ARRAY : ""); + recordFields.append(field.isOptionalType() ? BalSyntaxConstants.QUESTION_MARK : ""); + recordFields.append(BalSyntaxConstants.SPACE); + recordFields.append(field.getFieldName()); + recordFields.append(BalSyntaxConstants.SEMICOLON); + recordFields.append(BalSyntaxConstants.SPACE); + } + private static ImportDeclarationNode getImportDeclarationNodeWithAutogeneratedComment( String moduleName, MinutiaeList commentMinutiaeList) { Token orgNameToken = AbstractNodeFactory.createIdentifierToken(BalSyntaxConstants.KEYWORD_BALLERINA); diff --git a/persist-cli/src/main/java/io/ballerina/persist/nodegenerator/syntax/utils/SqlScriptUtils.java b/persist-cli/src/main/java/io/ballerina/persist/nodegenerator/syntax/utils/SqlScriptUtils.java index 2042d8226..d41bb12d5 100644 --- a/persist-cli/src/main/java/io/ballerina/persist/nodegenerator/syntax/utils/SqlScriptUtils.java +++ b/persist-cli/src/main/java/io/ballerina/persist/nodegenerator/syntax/utils/SqlScriptUtils.java @@ -28,18 +28,20 @@ import io.ballerina.persist.models.EntityField; import io.ballerina.persist.models.Enum; import io.ballerina.persist.models.EnumMember; +import io.ballerina.persist.models.Index; import io.ballerina.persist.models.Relation; +import io.ballerina.persist.models.SQLType; import io.ballerina.persist.nodegenerator.syntax.constants.BalSyntaxConstants; import java.text.MessageFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; -import java.util.stream.Collectors; /** * Sql script generator. @@ -62,14 +64,33 @@ private SqlScriptUtils() {} public static String[] generateSqlScript(Collection entities, String datasource) throws BalException { HashMap> referenceTables = new HashMap<>(); HashMap> tableScripts = new HashMap<>(); + //generate create table for (Entity entity : entities) { List tableScript = new ArrayList<>(); - String tableName = removeSingleQuote(entity.getEntityName()); + String tableName = removeSingleQuote(entity.getTableName()); tableScript.add(generateDropTableQuery(escape(tableName, datasource))); tableScript.add(generateCreateTableQuery(entity, referenceTables, datasource)); tableScripts.put(tableName, tableScript); } - return rearrangeScriptsWithReference(tableScripts.keySet(), referenceTables, tableScripts); + //generate create index + List indexScripts = new ArrayList<>(); + for (Entity entity : entities) { + entity.getIndexes().forEach(index -> { + indexScripts.add( + generateCreateIndexQuery(index, entity, datasource, index.isUnique()) + ); + }); + entity.getUniqueIndexes().forEach(index -> { + indexScripts.add( + generateCreateIndexQuery(index, entity, datasource, index.isUnique()) + ); + }); + } + List scripts = new ArrayList<>(Arrays.asList( + rearrangeScriptsWithReference(tableScripts.keySet(), referenceTables, tableScripts))); + scripts.add(NEW_LINE); + scripts.addAll(indexScripts); + return scripts.toArray(new String[0]); } private static String generateDropTableQuery(String tableName) { return MessageFormat.format("DROP TABLE IF EXISTS {0};", tableName); @@ -81,7 +102,17 @@ private static String generateCreateTableQuery(Entity entity, HashMap escape(removeSingleQuote(field.getFieldColumnName()), datasource)) + .reduce((s1, s2) -> s1 + COMMA_WITH_SPACE + s2).orElse("")); } private static String generateFieldsDefinitionSegments(Entity entity, HashMap> referenceTables, @@ -90,9 +121,9 @@ private static String generateFieldsDefinitionSegments(Entity entity, HashMap relationFields = entity.getFields().stream() .filter(entityField -> entityField.getRelation() != null && entityField.getRelation().isOwner()) - .collect(Collectors.toList()); + .toList(); for (EntityField entityField : relationFields) { - sqlScript.append(getRelationScripts(removeSingleQuote(entity.getEntityName()), + sqlScript.append(getRelationScripts(removeSingleQuote(entity.getTableName()), entityField, referenceTables, datasource)); } sqlScript.append(addPrimaryKey(entity.getKeys(), datasource)); @@ -106,7 +137,7 @@ private static String getColumnsScript(Entity entity, String datasource) throws continue; } - String fieldName = escape(removeSingleQuote(entityField.getFieldName()), datasource); + String fieldName = escape(removeSingleQuote(entityField.getFieldColumnName()), datasource); String sqlType; Enum enumValue = entityField.getEnum(); if (enumValue == null) { @@ -120,7 +151,8 @@ private static String getColumnsScript(Entity entity, String datasource) throws NEW_LINE, TAB, fieldName, sqlType)); } else { columnScript.append(MessageFormat.format("{0}{1}{2} {3}{4},", - NEW_LINE, TAB, fieldName, sqlType, " NOT NULL")); + NEW_LINE, TAB, fieldName, sqlType, + entityField.isDbGenerated() ? " AUTO_INCREMENT" : " NOT NULL")); } } return columnScript.toString(); @@ -132,7 +164,8 @@ private static String getRelationScripts(String tableName, EntityField entityFie StringBuilder relationScripts = new StringBuilder(); Relation relation = entityField.getRelation(); List keyColumns = relation.getKeyColumns(); - List references = relation.getReferences(); + List references = relation.getKeyColumns().stream().map(Relation.Key::getReferenceColumnName) + .toList(); Entity assocEntity = relation.getAssocEntity(); StringBuilder foreignKey = new StringBuilder(); StringBuilder referenceFieldName = new StringBuilder(); @@ -144,7 +177,7 @@ private static String getRelationScripts(String tableName, EntityField entityFie if (assocField.getRelation() != null) { continue; } - if (assocField.getFieldName().equals(references.get(i))) { + if (assocField.getFieldColumnName().equals(references.get(i))) { referenceSqlType = getSqlType(assocField, datasource); break; } @@ -159,14 +192,14 @@ private static String getRelationScripts(String tableName, EntityField entityFie associatedEntityRelationType.equals(Relation.RelationType.ONE) && noOfReferencesKey == 1) { referenceSqlType += " UNIQUE"; } - foreignKey.append(escape(removeSingleQuote(keyColumns.get(i).getField()), datasource)); + foreignKey.append(escape(removeSingleQuote(keyColumns.get(i).getColumnName()), datasource)); referenceFieldName.append(escape(removeSingleQuote(references.get(i)), datasource)); if (i < noOfReferencesKey - 1) { foreignKey.append(COMMA_WITH_SPACE); referenceFieldName.append(COMMA_WITH_SPACE); } relationScripts.append(MessageFormat.format("{0}{1}{2} {3}{4},", NEW_LINE, TAB, - escape(removeSingleQuote(keyColumns.get(i).getField()), datasource), referenceSqlType, + escape(removeSingleQuote(keyColumns.get(i).getColumnName()), datasource), referenceSqlType, " NOT NULL")); } if (noOfReferencesKey > 1 && relation.getRelationType().equals(Relation.RelationType.ONE) && @@ -175,8 +208,8 @@ private static String getRelationScripts(String tableName, EntityField entityFie } relationScripts.append(MessageFormat.format("{0}{1}FOREIGN KEY({2}) REFERENCES {3}({4}),", NEW_LINE, TAB, foreignKey.toString(), - escape(removeSingleQuote(assocEntity.getEntityName()), datasource), referenceFieldName)); - updateReferenceTable(tableName, assocEntity.getEntityName(), referenceTables); + escape(removeSingleQuote(assocEntity.getTableName()), datasource), referenceFieldName)); + updateReferenceTable(tableName, assocEntity.getTableName(), referenceTables); return relationScripts.toString(); } @@ -209,7 +242,7 @@ private static String createKeysScript(List keys, String datasource keyScripts.append(MessageFormat.format("{0}", PRIMARY_KEY_START_SCRIPT)); for (EntityField key : keys) { keyScripts.append(MessageFormat.format("{0},", - escape(removeSingleQuote(key.getFieldName()), datasource))); + escape(removeSingleQuote(key.getFieldColumnName()), datasource))); } keyScripts.deleteCharAt(keyScripts.length() - 1).append("),"); } @@ -219,7 +252,7 @@ private static String createKeysScript(List keys, String datasource private static String getSqlType(EntityField entityField, String datasource) throws BalException { String sqlType; if (!entityField.isArrayType()) { - sqlType = getTypeNonArray(entityField.getFieldType(), datasource); + sqlType = getTypeNonArray(entityField, datasource); } else { sqlType = getTypeArray(entityField.getFieldType(), datasource); } @@ -227,7 +260,6 @@ private static String getSqlType(EntityField entityField, String datasource) thr return sqlType; } String length = BalSyntaxConstants.VARCHAR_LENGTH; - if (entityField.getAnnotation() != null) { for (AnnotationNode annotationNode : entityField.getAnnotation()) { String annotationName = annotationNode.annotReference().toSourceCode().trim(); if (annotationName.equals(BalSyntaxConstants.CONSTRAINT_STRING)) { @@ -251,7 +283,6 @@ private static String getSqlType(EntityField entityField, String datasource) thr } } } - } return sqlType + (String.format("(%s)", length)); } @@ -353,6 +384,24 @@ public static String getTypeNonArray(String field, String datasource) throws Bal } } + public static String getTypeNonArray(EntityField field, String datasource) throws BalException { + SQLType sqlType = field.getSqlType(); + if (sqlType != null) { + switch (sqlType.getTypeName()) { + case PersistToolsConstants.SqlTypes.DECIMAL: + return PersistToolsConstants.SqlTypes.DECIMAL + String.format("(%s,%s)", + sqlType.getNumericPrecision(), + sqlType.getNumericScale()); + case PersistToolsConstants.SqlTypes.VARCHAR: + return PersistToolsConstants.SqlTypes.VARCHAR + String.format("(%s)", sqlType.getMaxLength()); + case PersistToolsConstants.SqlTypes.CHAR: + return PersistToolsConstants.SqlTypes.CHAR + String.format("(%s)", sqlType.getMaxLength()); + default: { } + } + } + return getTypeNonArray(field.getFieldType(), datasource); + } + public static String getTypeArray(String field, String datasource) throws BalException { // Ballerina --> byte[] diff --git a/persist-cli/src/main/java/io/ballerina/persist/utils/BalProjectUtils.java b/persist-cli/src/main/java/io/ballerina/persist/utils/BalProjectUtils.java index 73251de2d..6f68b3fc1 100644 --- a/persist-cli/src/main/java/io/ballerina/persist/utils/BalProjectUtils.java +++ b/persist-cli/src/main/java/io/ballerina/persist/utils/BalProjectUtils.java @@ -18,6 +18,7 @@ package io.ballerina.persist.utils; +import io.ballerina.compiler.syntax.tree.AnnotationNode; import io.ballerina.compiler.syntax.tree.ArrayTypeDescriptorNode; import io.ballerina.compiler.syntax.tree.BuiltinSimpleNameReferenceNode; import io.ballerina.compiler.syntax.tree.EnumDeclarationNode; @@ -45,11 +46,14 @@ import io.ballerina.persist.models.EnumMember; import io.ballerina.persist.models.Module; import io.ballerina.persist.models.Relation; +import io.ballerina.persist.models.SQLType; import io.ballerina.persist.nodegenerator.syntax.constants.BalSyntaxConstants; +import io.ballerina.persist.nodegenerator.syntax.utils.BalSyntaxUtils; import io.ballerina.projects.BuildOptions; import io.ballerina.projects.DiagnosticResult; import io.ballerina.projects.Package; import io.ballerina.projects.PackageCompilation; +import io.ballerina.projects.Project; import io.ballerina.projects.directory.SingleFileProject; import io.ballerina.toml.syntax.tree.AbstractNodeFactory; import io.ballerina.toml.syntax.tree.DocumentMemberDeclarationNode; @@ -63,17 +67,22 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.regex.Pattern; import java.util.stream.Collectors; +import java.util.stream.IntStream; import java.util.stream.Stream; import static io.ballerina.compiler.syntax.tree.SyntaxKind.QUALIFIED_NAME_REFERENCE; import static io.ballerina.persist.PersistToolsConstants.GENERATE_CMD_FILE; import static io.ballerina.persist.PersistToolsConstants.TARGET_DIRECTORY; +import static io.ballerina.persist.PersistToolsConstants.SqlTypes.CHAR; +import static io.ballerina.persist.PersistToolsConstants.SqlTypes.VARCHAR; import static io.ballerina.projects.util.ProjectConstants.BALLERINA_TOML; /** @@ -139,6 +148,20 @@ public static void validateSchemaFile(Path schemaPath) throws BalException { } } + public static Project buildDriverFile(Path driverPath) throws BalException { + BuildOptions.BuildOptionsBuilder buildOptionsBuilder = BuildOptions.builder(); + buildOptionsBuilder.setOffline(true); + SingleFileProject buildProject = SingleFileProject.load(driverPath.toAbsolutePath(), + buildOptionsBuilder.build()); + Package currentPackage = buildProject.currentPackage(); + PackageCompilation compilation = currentPackage.getCompilation(); + DiagnosticResult diagnosticResult = compilation.diagnosticResult(); + if (diagnosticResult.hasErrors()) { + throw new BalException("ERROR: failed to build the driver file."); + } + return buildProject; + } + public static void validateBallerinaProject(Path projectPath) throws BalException { Optional ballerinaToml; try (Stream stream = Files.list(projectPath)) { @@ -190,6 +213,15 @@ public static void populateEntities(Module.Builder moduleBuilder, SyntaxTree bal List keyArray = new ArrayList<>(); RecordTypeDescriptorNode recordDesc = (RecordTypeDescriptorNode) ((TypeDefinitionNode) moduleNode) .typeDescriptor(); + Optional entityMetadataNode = typeDefinitionNode.metadata(); + entityBuilder.setTableName(typeDefinitionNode.typeName().text().trim()); + entityMetadataNode.ifPresent(value -> entityBuilder.setTableName( + BalSyntaxUtils.readStringValueFromAnnotation( + value.annotations().stream().toList(), + BalSyntaxConstants.SQL_DB_MAPPING_ANNOTATION_NAME, + "name" + ) + )); for (Node node : recordDesc.fields()) { EntityField.Builder fieldBuilder; RecordFieldNode fieldNode = (RecordFieldNode) node; @@ -210,8 +242,121 @@ public static void populateEntities(Module.Builder moduleBuilder, SyntaxTree bal String qualifiedNamePrefix = getQualifiedModulePrefix(type); fieldBuilder.setType(fType); fieldBuilder.setOptionalType(fieldNode.typeName().kind().equals(SyntaxKind.OPTIONAL_TYPE_DESC)); + fieldBuilder.setFieldColumnName(fieldNode.fieldName().text().trim()); Optional metadataNode = fieldNode.metadata(); - metadataNode.ifPresent(value -> fieldBuilder.setAnnotation(value.annotations())); + metadataNode.ifPresent(value -> { + //read the db generated annotation + List annotations = value.annotations().stream().toList(); + boolean dbGenerated = BalSyntaxUtils.isAnnotationPresent( + annotations, + BalSyntaxConstants.SQL_GENERATED_ANNOTATION_NAME + ); + fieldBuilder.setIsDbGenerated(dbGenerated); + + //read the db mapping annotation + String fieldResourceName = BalSyntaxUtils.readStringValueFromAnnotation( + annotations, + BalSyntaxConstants.SQL_DB_MAPPING_ANNOTATION_NAME, + "name" + ); + if (!fieldResourceName.isEmpty()) { + fieldBuilder.setFieldColumnName(fieldResourceName); + } + //read the unique index annotation + boolean isUniqueIndexPresent = BalSyntaxUtils.isAnnotationPresent( + annotations, + BalSyntaxConstants.SQL_UNIQUE_INDEX_MAPPING_ANNOTATION_NAME + ); + List uniqueIndexNames = BalSyntaxUtils.readStringArrayValueFromAnnotation( + annotations, + BalSyntaxConstants.SQL_UNIQUE_INDEX_MAPPING_ANNOTATION_NAME, + "names" + ); + if (uniqueIndexNames != null && !uniqueIndexNames.isEmpty()) { + uniqueIndexNames.forEach(uniqueIndexName -> + entityBuilder.upsertUniqueIndex(uniqueIndexName, fieldBuilder.build())); + } else if (isUniqueIndexPresent) { + entityBuilder.upsertUniqueIndex("unique_idx_" + + fieldBuilder.getFieldName().toLowerCase(Locale.ENGLISH), fieldBuilder.build()); + } + //read the relation annotation + List relationRefs = BalSyntaxUtils.readStringArrayValueFromAnnotation( + annotations, + BalSyntaxConstants.SQL_RELATION_MAPPING_ANNOTATION_NAME, + "refs" + ); + if (relationRefs != null) { + fieldBuilder.setRelationRefs(relationRefs); + } + + //read the index annotation + boolean isIndexPresent = BalSyntaxUtils.isAnnotationPresent( + annotations, + BalSyntaxConstants.SQL_INDEX_MAPPING_ANNOTATION_NAME + ); + List indexNames = BalSyntaxUtils.readStringArrayValueFromAnnotation( + annotations, + BalSyntaxConstants.SQL_INDEX_MAPPING_ANNOTATION_NAME, + "names" + ); + if (indexNames != null && !indexNames.isEmpty()) { + indexNames.forEach(indexName -> + entityBuilder.upsertIndex(indexName, fieldBuilder.build())); + } else if (isIndexPresent) { + entityBuilder.upsertIndex("idx_" + + fieldBuilder.getFieldName().toLowerCase(Locale.ENGLISH), fieldBuilder.build()); + } + // read the varchar annotation + String varcharLength = BalSyntaxUtils.readStringValueFromAnnotation( + annotations, + BalSyntaxConstants.SQL_VARCHAR_MAPPING_ANNOTATION_NAME, + "length" + ); + if (!varcharLength.isEmpty()) { + fieldBuilder.setSqlType( + new SQLType( + VARCHAR, + null, + 0, + 0, + null, + Integer.parseInt(varcharLength))); + } + //read the char annotation + String charLength = BalSyntaxUtils.readStringValueFromAnnotation( + annotations, + BalSyntaxConstants.SQL_CHAR_MAPPING_ANNOTATION_NAME, + "length" + ); + if (!charLength.isEmpty()) { + fieldBuilder.setSqlType( + new SQLType( + CHAR, + null, + 0, + 0, + null, + Integer.parseInt(charLength))); + } + //read the decimal annotation + List decimal = BalSyntaxUtils.readStringArrayValueFromAnnotation( + annotations, + BalSyntaxConstants.SQL_DECIMAL_MAPPING_ANNOTATION_NAME, + "precision" + ); + if (decimal != null && decimal.size() == 2) { + fieldBuilder.setSqlType( + new SQLType( + PersistToolsConstants.SqlTypes.DECIMAL, + null, + Integer.parseInt(decimal.get(0).trim()), + Integer.parseInt(decimal.get(1).trim()), + null, + 0) + ); + } + fieldBuilder.setAnnotations(annotations); + }); EntityField entityField = fieldBuilder.build(); entityBuilder.addField(entityField); if (fieldNode.readonlyKeyword().isPresent()) { @@ -305,65 +450,70 @@ public static void inferRelationDetails(Module entityModule) { Map entityMap = entityModule.getEntityMap(); for (Entity entity : entityMap.values()) { List fields = entity.getFields(); - fields.stream().filter(field -> entityMap.get(field.getFieldType()) != null) + HashMap> relationFields = new HashMap<>(); + fields.stream().filter(field -> entityMap.get(field.getFieldType()) != null && field.getRelation() == null) .forEach(field -> { - String fieldType = field.getFieldType(); - Entity assocEntity = entityMap.get(fieldType); - if (field.getRelation() == null) { - // this branch only handles one-to-one or one-to-many or many-to-many with no relation - // annotations - assocEntity.getFields().stream().filter(assocfield -> assocfield.getFieldType() - .equals(entity.getEntityName())) - .filter(assocfield -> assocfield.getRelation() == null).forEach(assocfield -> { - // skip if the relation is already set for the entity field. - if (field.getRelation() != null) { - return; - } - // one-to-many or many-to-many with no relation annotations - if (field.isArrayType() && assocfield.isArrayType()) { - throw new RuntimeException("unsupported many to many relation between " + - entity.getEntityName() + " and " + assocEntity.getEntityName()); - } - // one-to-one - if (!field.isArrayType() && !assocfield.isArrayType()) { - if (!field.isOptionalType() && assocfield.isOptionalType()) { - field.setRelation(computeRelation(field.getFieldName(), entity, - assocEntity, true, Relation.RelationType.ONE)); - assocfield.setRelation(computeRelation(field.getFieldName(), - assocEntity, entity, false, Relation.RelationType.ONE)); - } else if (field.isOptionalType() && !assocfield.isOptionalType()) { - field.setRelation(computeRelation(field.getFieldName(), entity, - assocEntity, false, Relation.RelationType.ONE)); - assocfield.setRelation(computeRelation(field.getFieldName(), - assocEntity, entity, true, Relation.RelationType.ONE)); - } else { - throw new RuntimeException("unsupported ownership annotation " + - "in the relation between " + entity.getEntityName() + - " and " + assocEntity.getEntityName()); - } - } else { - if (field.isArrayType() && field.isOptionalType()) { - // one-to-many relation. associated entity is the owner. - // first param should be always owner entities field name - field.setRelation(computeRelation(assocfield.getFieldName(), entity, - assocEntity, false, Relation.RelationType.MANY)); - assocfield.setRelation(computeRelation(assocfield.getFieldName(), - assocEntity, entity, true, Relation.RelationType.ONE)); - } else if (field.isArrayType() || field.getFieldType().equals("byte")) { - field.setRelation(null); - } else { - // one-to-many relation. entity is the owner. - // one-to-one relation. entity is the owner. - // first param should be always owner entities field name - field.setRelation(computeRelation(field.getFieldName(), entity, - assocEntity, true, Relation.RelationType.ONE)); - assocfield.setRelation(computeRelation(field.getFieldName(), - assocEntity, entity, false, Relation.RelationType.MANY)); - } - } - }); + if (relationFields.containsKey(field.getFieldType())) { + relationFields.get(field.getFieldType()).add(field); + } else { + List fieldList = new ArrayList<>(); + fieldList.add(field); + relationFields.put(field.getFieldType(), fieldList); } }); + for (List fieldList : relationFields.values()) { + Entity assocEntity = entityMap.get(fieldList.get(0).getFieldType()); + List assocFields = assocEntity.getFields().stream() + .filter(assocField -> assocField.getFieldType() + .equals(entity.getEntityName()) && assocField.getRelation() == null).toList(); + for (int i = 0; i < fieldList.size(); i++) { + EntityField field = fieldList.get(i); + EntityField assocField = assocFields.get(i); + if (field.isArrayType() && assocField.isArrayType()) { + //both are array types. many-to-many is not supported + throw new RuntimeException("unsupported many to many relation between " + + entity.getEntityName() + " and " + assocEntity.getEntityName()); + } + if (field.isArrayType() || assocField.isArrayType()) { + // one of them is array type -> one-to-many or many-to-many relation + if (field.isArrayType()) { + // many-to-one -> associated entity is the owner + field.setRelation(computeRelation(assocField.getFieldName(), entity, assocEntity, false, + Relation.RelationType.MANY, assocField.getRelationRefs())); + assocField.setRelation(computeRelation(assocField.getFieldName(), assocEntity, entity, + true, Relation.RelationType.ONE, assocField.getRelationRefs())); + + } else { + // one-to-many -> entity is the owner + field.setRelation(computeRelation(field.getFieldName(), entity, assocEntity, true, + Relation.RelationType.ONE, field.getRelationRefs())); + assocField.setRelation(computeRelation(field.getFieldName(), assocEntity, entity, + false, Relation.RelationType.MANY, field.getRelationRefs())); + } + } else { + // one-to-one relation + if (field.isOptionalType()) { + // associated entity is the owner + field.setRelation(computeRelation(assocField.getFieldName(), entity, assocEntity, false, + Relation.RelationType.ONE, assocField.getRelationRefs())); + assocField.setRelation(computeRelation(assocField.getFieldName(), assocEntity, entity, + true, Relation.RelationType.ONE, assocField.getRelationRefs())); + } else { + // entity is the owner + field.setRelation(computeRelation(field.getFieldName(), entity, assocEntity, true, + Relation.RelationType.ONE, field.getRelationRefs())); + assocField.setRelation(computeRelation(field.getFieldName(), assocEntity, entity, + false, Relation.RelationType.ONE, field.getRelationRefs())); + } + } + if (field.getRelationRefs() != null) { + field.getRelationRefs().forEach(entity::removeField); + } + if (assocField.getRelationRefs() != null) { + assocField.getRelationRefs().forEach(assocEntity::removeField); + } + } + } } } @@ -379,27 +529,54 @@ public static void inferEnumDetails(Module entityModule) { } } + private static Relation computeRelation(String fieldName, Entity entity, Entity assocEntity, boolean isOwner, - Relation.RelationType relationType) { + Relation.RelationType relationType, List relationRefs) { Relation.Builder relBuilder = new Relation.Builder(); relBuilder.setAssocEntity(assocEntity); if (isOwner) { - List keyColumns = assocEntity.getKeys().stream().map(key -> - new Relation.Key(stripEscapeCharacter(fieldName.toLowerCase(Locale.ENGLISH)) - + stripEscapeCharacter(key.getFieldName()).substring(0, 1).toUpperCase(Locale.ENGLISH) - + stripEscapeCharacter(key.getFieldName()).substring(1), key.getFieldName(), - key.getFieldType())).collect(Collectors.toList()); + List keyColumns = IntStream.range(0, assocEntity.getKeys().size()) + .mapToObj(i -> { + + EntityField key = assocEntity.getKeys().get(i); + if (!relationRefs.isEmpty()) { + String fkField = relationRefs.get(i); + EntityField fkEntityField = entity.getFieldByName(fkField); + return new Relation.Key(fkField, + fkEntityField.getFieldColumnName(), key.getFieldName(), key.getFieldColumnName(), + key.getFieldType()); + } + String fkField = stripEscapeCharacter(fieldName.toLowerCase(Locale.ENGLISH)) + + stripEscapeCharacter(key.getFieldName()).substring(0, 1).toUpperCase(Locale.ENGLISH) + + stripEscapeCharacter(key.getFieldName()).substring(1); + + return new Relation.Key(fkField, + fkField, key.getFieldName(), key.getFieldColumnName(), key.getFieldType()); + + }) + .collect(Collectors.toList()); relBuilder.setOwner(true); relBuilder.setRelationType(relationType); relBuilder.setKeys(keyColumns); relBuilder.setReferences(assocEntity.getKeys().stream().map(EntityField::getFieldName) .collect(Collectors.toList())); } else { - List keyColumns = entity.getKeys().stream().map(key -> new Relation.Key(key.getFieldName(), - fieldName.toLowerCase(Locale.ENGLISH) + - stripEscapeCharacter(key.getFieldName()).substring(0, 1).toUpperCase(Locale.ENGLISH) - + stripEscapeCharacter(key.getFieldName()).substring(1), - key.getFieldType())) + List keyColumns = IntStream.range(0, entity.getKeys().size()) + .mapToObj(i -> { + + EntityField key = entity.getKeys().get(i); + String fkField = stripEscapeCharacter(fieldName.toLowerCase(Locale.ENGLISH)) + + stripEscapeCharacter(key.getFieldName()).substring(0, 1).toUpperCase(Locale.ENGLISH) + + stripEscapeCharacter(key.getFieldName()).substring(1); + if (!relationRefs.isEmpty()) { + fkField = relationRefs.get(i); + EntityField assocField = assocEntity.getFieldByName(fkField); + return new Relation.Key(key.getFieldName(), key.getFieldColumnName(), fkField, + assocField.getFieldColumnName(), key.getFieldType()); + } + return new Relation.Key(key.getFieldName(), key.getFieldColumnName(), fkField, + fkField, key.getFieldType()); + }) .collect(Collectors.toList()); relBuilder.setOwner(false); relBuilder.setRelationType(relationType); @@ -440,4 +617,48 @@ public static Path getSchemaFilePath(String sourcePath) throws BalException { return schemaFilePaths.get(0); } + + public static void validatePullCommandOptions(String datastore, String host, String port, String user, + String database) throws BalException { + String nameRegex = "[A-Za-z]\\w*"; + List errors = new ArrayList<>(); + if (datastore == null) { + errors.add("The datastore type is not provided."); + } else if (datastore.isEmpty()) { + errors.add("The datastore type cannot be empty."); + } else if (!datastore.equals(PersistToolsConstants.SupportedDataSources.MYSQL_DB)) { + errors.add("Unsupported data store: '" + datastore + "'"); + } + if (host == null) { + errors.add("The host is not provided."); + } else if (host.isEmpty()) { + errors.add("The host cannot be empty."); + } + if (port == null) { + errors.add("The port is not provided."); + } else if (port.isEmpty()) { + errors.add("The port cannot be empty."); + } else if (!Pattern.matches("\\d+", port)) { + errors.add("The port is invalid. The port should be a number."); + } else if (Integer.parseInt(port) < 0 || Integer.parseInt(port) > 65535) { + errors.add("The port is invalid. The port should be in the range of 0 to 65535."); + } + if (user == null) { + errors.add("The user is not provided."); + } else if (user.isEmpty()) { + errors.add("The user cannot be empty."); + } + if (database == null) { + errors.add("The database is not provided."); + } else if (database.isEmpty()) { + errors.add("The database cannot be empty."); + } else if (!Pattern.matches(nameRegex, database)) { + errors.add("The database name is invalid. The database name should start with a letter or underscore (_)" + + " and must contain only alphanumeric characters."); + } + if (!errors.isEmpty()) { + throw new BalException(String.join(System.lineSeparator(), errors)); + } + } + } diff --git a/persist-cli/src/main/java/io/ballerina/persist/utils/DatabaseConnector.java b/persist-cli/src/main/java/io/ballerina/persist/utils/DatabaseConnector.java new file mode 100644 index 000000000..06a71ec61 --- /dev/null +++ b/persist-cli/src/main/java/io/ballerina/persist/utils/DatabaseConnector.java @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you 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 + * + * http://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 io.ballerina.persist.utils; + +import io.ballerina.persist.BalException; +import io.ballerina.persist.configuration.PersistConfiguration; +import io.ballerina.projects.DependencyGraph; +import io.ballerina.projects.JvmTarget; +import io.ballerina.projects.Package; +import io.ballerina.projects.PackageManifest; +import io.ballerina.projects.Project; +import io.ballerina.projects.ResolvedPackageDependency; + +import java.io.Console; +import java.io.IOException; +import java.io.PrintStream; +import java.lang.reflect.InvocationTargetException; +import java.net.URL; +import java.nio.file.Path; +import java.sql.Connection; +import java.sql.Driver; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Properties; +import java.util.Scanner; + +import static io.ballerina.persist.PersistToolsConstants.BALLERINA_MSSQL_DRIVER_NAME; +import static io.ballerina.persist.PersistToolsConstants.BALLERINA_MYSQL_DRIVER_NAME; +import static io.ballerina.persist.PersistToolsConstants.BALLERINA_POSTGRESQL_DRIVER_NAME; +import static io.ballerina.persist.PersistToolsConstants.MSSQL_CONNECTOR_NAME_PREFIX; +import static io.ballerina.persist.PersistToolsConstants.MYSQL_CONNECTOR_NAME_PREFIX; +import static io.ballerina.persist.PersistToolsConstants.PASSWORD; +import static io.ballerina.persist.PersistToolsConstants.POSTGRESQL_CONNECTOR_NAME_PREFIX; +import static io.ballerina.persist.PersistToolsConstants.PROPERTY_KEY_PATH; +import static io.ballerina.persist.PersistToolsConstants.USER; +import static io.ballerina.persist.nodegenerator.syntax.constants.BalSyntaxConstants.JDBC_URL_WITHOUT_DATABASE; + +public class DatabaseConnector { + + private final String jdbcUrlWithDatabaseFormat; + private final String driverClass; + + public DatabaseConnector (String jdbcUrlWithDatabaseFormat, String driverClass) { + this.driverClass = driverClass; + this.jdbcUrlWithDatabaseFormat = jdbcUrlWithDatabaseFormat; + } + + public Connection getConnection(Driver driver, PersistConfiguration persistConfigurations, + boolean withDB) throws SQLException { + String host = persistConfigurations.getDbConfig().getHost(); + int port = persistConfigurations.getDbConfig().getPort(); + String user = persistConfigurations.getDbConfig().getUsername(); + String password = persistConfigurations.getDbConfig().getPassword(); + String database = persistConfigurations.getDbConfig().getDatabase(); + String provider = persistConfigurations.getProvider(); + String url; + if (withDB) { + url = String.format(this.jdbcUrlWithDatabaseFormat, provider, host, port, database); + } else { + url = String.format(JDBC_URL_WITHOUT_DATABASE, provider, host, port); + } + Properties props = new Properties(); + if (user != null) { + props.put(USER, user); + } + if (password != null) { + props.put(PASSWORD, password); + } + return driver.connect(url, props); + } + + public Driver getJdbcDriver(JdbcDriverLoader driverLoader) throws BalException { + Driver driver; + try { + Class drvClass = driverLoader.loadClass(this.driverClass); + driver = (Driver) drvClass.getDeclaredConstructor().newInstance(); + } catch (ClassNotFoundException e) { + throw new BalException("required database driver class not found. " + e.getMessage()); + } catch (InstantiationException | InvocationTargetException e) { + throw new BalException("the database driver instantiation is failed. " + e.getMessage()); + } catch (IllegalAccessException e) { + throw new BalException("access denied while trying to instantiation the database driver. " + + e.getMessage()); + } catch (NoSuchMethodException e) { + throw new BalException("method not found while trying to instantiate jdbc driver. " + + e.getMessage()); + } + return driver; + } + + public JdbcDriverLoader getJdbcDriverLoader(Project balProject) throws BalException { + return this.getJdbcDriverLoaderPrivate(balProject); + } + private JdbcDriverLoader getJdbcDriverLoaderPrivate(Project balProject) throws BalException { + JdbcDriverLoader driverLoader = null; + Path driverDirectoryPath = getDriverPath(balProject).getParent(); + if (Objects.nonNull(driverDirectoryPath)) { + Path driverPath = driverDirectoryPath.toAbsolutePath(); + URL[] urls = {}; + try { + driverLoader = new JdbcDriverLoader(urls, driverPath); + } catch (IOException e) { + throw new BalException("could not load the driver from the driver path. " + e.getMessage()); + } + } + return driverLoader; + } + + private Path getDriverPath(Project balProject) throws BalException { + String relativeLibPath; + + DependencyGraph resolvedPackageDependencyDependencyGraph = + balProject.currentPackage().getResolution().dependencyGraph(); + + ResolvedPackageDependency root = resolvedPackageDependencyDependencyGraph.getRoot(); + + Optional mysqlDriverDependency = resolvedPackageDependencyDependencyGraph + .getDirectDependencies(root).stream(). + filter(resolvedPackageDependency -> resolvedPackageDependency.packageInstance(). + descriptor().toString().contains(BALLERINA_MYSQL_DRIVER_NAME)).findFirst(); + if (mysqlDriverDependency.isPresent()) { + Package mysqlDriverPackage = mysqlDriverDependency.get().packageInstance(); + List> dependencies = getDependencies(mysqlDriverPackage); + for (Map dependency : dependencies) { + if (dependency.get(PROPERTY_KEY_PATH).toString().contains(MYSQL_CONNECTOR_NAME_PREFIX)) { + relativeLibPath = dependency.get(PROPERTY_KEY_PATH).toString(); + return mysqlDriverPackage.project().sourceRoot().resolve(relativeLibPath); + } + } + } + + Optional mssqlDriverDependency = resolvedPackageDependencyDependencyGraph + .getDirectDependencies(root).stream(). + filter(resolvedPackageDependency -> resolvedPackageDependency.packageInstance(). + descriptor().toString().contains(BALLERINA_MSSQL_DRIVER_NAME)).findFirst(); + + if (mssqlDriverDependency.isPresent()) { + Package mssqlDriverPackage = mssqlDriverDependency.get().packageInstance(); + List> dependencies = getDependencies(mssqlDriverPackage); + for (Map dependency : dependencies) { + if (dependency.get(PROPERTY_KEY_PATH).toString().contains(MSSQL_CONNECTOR_NAME_PREFIX)) { + relativeLibPath = dependency.get(PROPERTY_KEY_PATH).toString(); + return mssqlDriverPackage.project().sourceRoot().resolve(relativeLibPath); + } + } + } + + Optional postgresqlDriverDependency = resolvedPackageDependencyDependencyGraph + .getDirectDependencies(root).stream(). + filter(resolvedPackageDependency -> resolvedPackageDependency.packageInstance(). + descriptor().toString().contains(BALLERINA_POSTGRESQL_DRIVER_NAME)).findFirst(); + + if (postgresqlDriverDependency.isPresent()) { + Package postgresqlDriverPackage = postgresqlDriverDependency.get().packageInstance(); + List> dependencies = getDependencies(postgresqlDriverPackage); + for (Map dependency : dependencies) { + if (dependency.get(PROPERTY_KEY_PATH).toString().contains(POSTGRESQL_CONNECTOR_NAME_PREFIX)) { + relativeLibPath = dependency.get(PROPERTY_KEY_PATH).toString(); + return postgresqlDriverPackage.project().sourceRoot().resolve(relativeLibPath); + } + } + } + + throw new BalException("failed to retrieve driver path in the local cache."); + } + private static List> getDependencies(Package driverPackage) { + List> dependencies = new ArrayList<>(); + for (JvmTarget jvmTarget : JvmTarget.values()) { + PackageManifest.Platform platform = driverPackage.manifest().platform(jvmTarget.code()); + if (platform != null) { + dependencies.addAll(platform.dependencies()); + } + } + return dependencies; + } + public static String readDatabasePassword(Scanner scanner, PrintStream errStream) { + String password; + Console console = System.console(); + if (console == null) { + errStream.println("[WARNING] console could not be detected. falling back to standard input."); + errStream.print("Database Password: "); + password = scanner.nextLine(); + } else { + password = new String(console.readPassword("Database Password: ")); + } + return password; + } +} diff --git a/persist-cli/src/main/java/io/ballerina/persist/utils/ScriptRunner.java b/persist-cli/src/main/java/io/ballerina/persist/utils/ScriptRunner.java index 6482ce53e..a0271307b 100644 --- a/persist-cli/src/main/java/io/ballerina/persist/utils/ScriptRunner.java +++ b/persist-cli/src/main/java/io/ballerina/persist/utils/ScriptRunner.java @@ -18,18 +18,28 @@ package io.ballerina.persist.utils; + +import io.ballerina.persist.introspectiondto.SqlColumn; +import io.ballerina.persist.introspectiondto.SqlEnum; +import io.ballerina.persist.introspectiondto.SqlForeignKey; +import io.ballerina.persist.introspectiondto.SqlIndex; +import io.ballerina.persist.introspectiondto.SqlTable; + import java.io.BufferedReader; import java.io.Reader; import java.sql.Connection; +import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; + /** * The script runner class executes SQL query or scripts against DB. * @since 0.1.0 */ public class ScriptRunner { - private static final String LINE_SEPARATOR = System.lineSeparator(); private static final String DEFAULT_DELIMITER = ";"; @@ -56,6 +66,9 @@ public void runQuery(String query) throws SQLException { } } + + + private void executeLineByLine(Reader reader) throws Exception { StringBuilder command = new StringBuilder(); BufferedReader lineReader = new BufferedReader(reader); @@ -126,4 +139,144 @@ private void executeStatement(String command) throws SQLException { statement.execute(sql); } } + + public List getSQLTables(String query) throws SQLException { + List tables = new ArrayList<>(); + try (Statement statement = connection.createStatement()) { + try (ResultSet results = statement.executeQuery(query)) { + while (results.next()) { + tables.add(SqlTable.newBuilder(results.getString("table_name")) + .setTableComment(results.getString("table_comment")) + .setCreateOptions(results.getString("create_options")).build()); + } + if (tables.isEmpty()) { + throw new SQLException("No tables found in the database."); + } + return tables; + } + } catch (SQLException e) { + throw new SQLException("Error while retrieving tables for database: " + e.getMessage()); + } finally { + rollbackConnection(); + } + } + + public List getSQLEnums(String query) throws SQLException { + List enums = new ArrayList<>(); + try (Statement statement = connection.createStatement()) { + try (ResultSet results = statement.executeQuery(query)) { + while (results.next()) { + enums.add(new SqlEnum( + results.getString("full_enum_type"), + results.getString("table_name"), + results.getString("column_name") + )); + } + return enums; + } + } catch (SQLException e) { + throw new SQLException("Error while retrieving enums for database: " + e.getMessage()); + } finally { + rollbackConnection(); + } + } + + public void readColumnsOfSQLTable(SqlTable table, String query) throws SQLException { + try (Statement statement = connection.createStatement()) { + try (ResultSet results = statement.executeQuery(query)) { + while (results.next()) { + SqlColumn column = SqlColumn.newBuilder(results.getString("column_name")) + .setTableName(results.getString("table_name")) + .setDataType(results.getString("data_type")) + .setFullDataType(results.getString("full_data_type")) + .setCharacterMaximumLength(results.getString("character_maximum_length")) + .setNumericPrecision(results.getString("numeric_precision")) + .setNumericScale(results.getString("numeric_scale")) + .setDatetimePrecision(results.getString("datetime_precision")) + .setColumnDefault(results.getString("column_default")) + .setIsNullable(results.getString("is_nullable")) + .setExtra(results.getString("extra")) + .setColumnComment(results.getString("column_comment")) + .setIsPrimaryKey(results.getString("column_key").equals("PRI")) + .setIsDbGenerated(results.getBoolean("dbgenerated")) + .build(); + table.addColumn(column); + } + } + } catch (SQLException e) { + throw new SQLException("Error while retrieving columns for table: " + e.getMessage()); + } finally { + rollbackConnection(); + } + } + + public List readForeignKeysOfSQLTable(SqlTable table, String query) throws SQLException { + List sqlForeignKeys = new ArrayList<>(); + try (Statement statement = connection.createStatement()) { + try (ResultSet results = statement.executeQuery(query)) { + while (results.next()) { + String constraintName = results.getString("constraint_name"); + SqlForeignKey existingForeignKey = table.getSqlForeignKeys().stream().filter( + fKey -> fKey.getConstraintName().equals(constraintName)) + .findFirst().orElse(null); + if (existingForeignKey == null) { + SqlForeignKey foreignKey = SqlForeignKey.Builder + .newBuilder(results.getString("constraint_name")) + .setTableName(results.getString("table_name")) + .addColumnName(results.getString("column_name")) + .setReferencedTableName(results.getString("referenced_table_name")) + .addReferencedColumnName(results.getString("referenced_column_name")) + .setUpdateRule(results.getString("update_rule")) + .setDeleteRule(results.getString("delete_rule")) + .build(); + table.addForeignKey(foreignKey); + sqlForeignKeys.add(foreignKey); + } else { + existingForeignKey.addColumnName(results.getString("column_name")); + existingForeignKey.addReferencedColumnName(results.getString("referenced_column_name")); + } + } + } + return sqlForeignKeys; + } catch (SQLException e) { + throw new SQLException("Error while retrieving foreign keys for table: " + e.getMessage()); + } finally { + rollbackConnection(); + + } + } + + public void readIndexesOfSQLTable(SqlTable table, String query) throws SQLException { + try (Statement statement = connection.createStatement()) { + try (ResultSet results = statement.executeQuery(query)) { + while (results.next()) { + String indexName = results.getString("index_name"); + SqlIndex existingIndex = table.getIndexes().stream().filter( + index -> index.getIndexName().equals(indexName)) + .findFirst().orElse(null); + if (existingIndex == null) { + table.addIndex(SqlIndex.Builder.newBuilder(results.getString("index_name")) + .setTableName(results.getString("table_name")) + .addColumnName(results.getString("column_name")) + .setPartial(results.getString("partial")) + .setColumnOrder(results.getString("column_order")) + .setNonUnique(results.getString("non_unique")) + .setIndexType(results.getString("index_type")) + .build() + ); + } else { + existingIndex.addColumnName(results.getString("column_name")); + } + } + } + } catch (SQLException e) { + throw new SQLException("Error while retrieving indexes for table: " + e.getMessage()); + } finally { + rollbackConnection(); + } + } + + + + } diff --git a/persist-cli/src/main/java/io/ballerina/persist/utils/StubUtils.java b/persist-cli/src/main/java/io/ballerina/persist/utils/StubUtils.java new file mode 100644 index 000000000..396022e4d --- /dev/null +++ b/persist-cli/src/main/java/io/ballerina/persist/utils/StubUtils.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2024 WSO2 LLC. (http://www.wso2.com). + * + * WSO2 Inc. licenses this file to you 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 + * + * http://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 io.ballerina.persist.utils; + +/** + * Utilities related to Stub files. + * + */ +public class StubUtils { + + private StubUtils() {} + + private static final String[] RESERVED_LITERAL_NAMES = { + "import", "as", "public", "private", "external", "final", "service", "resource", "function", "object", + "record", "annotation", "parameter", "transformer", "worker", "listener", "remote", "xmlns", "returns", + "version", "channel", "abstract", "client", "const", "typeof", "source", "from", "on", "group", "by", + "having", "order", "where", "followed", "for", "window", "every", "within", "snapshot", "inner", "outer", + "right", "left", "full", "unidirectional", "forever", "limit", "ascending", "descending", "int", "byte", + "float", "decimal", "boolean", "string", "error", "map", "json", "xml", "table", "stream", "any", + "typedesc", "type", "future", "anydata", "handle", "var", "new", "init", "if", "match", "else", + "foreach", "while", "continue", "break", "fork", "join", "some", "all", "try", "catch", "finally", "throw", + "panic", "trap", "return", "transaction", "abort", "retry", "onretry", "retries", "committed", "aborted", + "with", "in", "lock", "untaint", "start", "but", "check", "checkpanic", "primarykey", "is", "flush", + "wait", "default", "enum", "error"}; + + public static boolean isLiteralName(String name) { + for (String reservedLiteralName : RESERVED_LITERAL_NAMES) { + if (reservedLiteralName.equals(name)) { + return true; + } + } + return false; + } +} diff --git a/persist-cli/src/main/resources/cli-help/ballerina-persist-pull.help b/persist-cli/src/main/resources/cli-help/ballerina-persist-pull.help new file mode 100644 index 000000000..aabd226af --- /dev/null +++ b/persist-cli/src/main/resources/cli-help/ballerina-persist-pull.help @@ -0,0 +1,23 @@ +NAME + bal persist pull - Introspect the existing database schema and generate data model. + +SYNOPSIS + bal persist pull [--datastore ] + [--host ] + [--port ] + [--user ] + [<-h> | <--help>] + +DESCRIPTION + This command introspects an existing database, generate the entity model and write it to a `model.bal` + file in the `persist` directory. If the file already exists, it will prompt the user to confirm overwriting the + file. The database configurations must be passed in as command line arguments. The user must enter the + database password when prompted. + +EXAMPLES + Print the usage details of the `bal persist pull` command. + $ bal persist pull --help + + Generate data model by introspecting database. + $ bal persist pull --datastore mysql --host localhost --port 3306 --user root --database db diff --git a/persist-cli/src/main/resources/version.properties b/persist-cli/src/main/resources/version.properties deleted file mode 100644 index 22e655c24..000000000 --- a/persist-cli/src/main/resources/version.properties +++ /dev/null @@ -1,4 +0,0 @@ -version = ${project.version} -persistSqlVersion = ${project.persistSqlNativeVersion} -persistInMemoryVersion = ${project.persistInMemoryNativeVersion} -persistGoogleSheetsVersion = ${project.persistGoogleSheetsNativeVersion} diff --git a/persist-cli/src/test/java/io/ballerina/persist/CaseConversionTest.java b/persist-cli/src/test/java/io/ballerina/persist/CaseConversionTest.java new file mode 100644 index 000000000..64ef92a68 --- /dev/null +++ b/persist-cli/src/test/java/io/ballerina/persist/CaseConversionTest.java @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. + * + * WSO2 LLC. licenses this file to you 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 + * + * http://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 io.ballerina.persist; + +import io.ballerina.persist.inflector.CaseConverter; +import org.testng.annotations.Test; + +public class CaseConversionTest { + private static final String[] randomWords = { + "this is a test", + "snake_case", + "Title Case", + "dot.case", + "path/case", + "sentences case", + "random case", + "UPPERCASE", + "theQuickBrownFoxJumpsOverTheLazyDog", + "the_quick_brown_fox_jumps_over_the_lazy_dog", + "the-quick-brown-fox-jumps-over-the-lazy-dog", + "TheQuickBrownFoxJumpsOverTheLazyDog", + "THE_QUICK_BROWN_FOX_JUMPS_OVER_THE_LAZY_DOG", + "the_quick_brown_foxes_jumps_over_the_lazy_dog", + "snakesAndLadders", + "snakes_and_ladders", + "snakes-and-ladders", + "SnakesAndLadders", + "SNAKES_AND_LADDERS" + }; + + private static final String[] camelCase = { + "thisIsATest", + "snakeCase", + "titleCase", + "dotCase", + "pathCase", + "sentencesCase", + "randomCase", + "uppercase", + "theQuickBrownFoxJumpsOverTheLazyDog", + "theQuickBrownFoxJumpsOverTheLazyDog", + "theQuickBrownFoxJumpsOverTheLazyDog", + "theQuickBrownFoxJumpsOverTheLazyDog", + "theQuickBrownFoxJumpsOverTheLazyDog", + "theQuickBrownFoxesJumpsOverTheLazyDog", + "snakesAndLadders", + "snakesAndLadders", + "snakesAndLadders", + "snakesAndLadders", + "snakesAndLadders" + }; + + private static final String[] pascalCase = { + "ThisIsATest", + "SnakeCase", + "TitleCase", + "DotCase", + "PathCase", + "SentencesCase", + "RandomCase", + "Uppercase", + "TheQuickBrownFoxJumpsOverTheLazyDog", + "TheQuickBrownFoxJumpsOverTheLazyDog", + "TheQuickBrownFoxJumpsOverTheLazyDog", + "TheQuickBrownFoxJumpsOverTheLazyDog", + "TheQuickBrownFoxJumpsOverTheLazyDog", + "TheQuickBrownFoxesJumpsOverTheLazyDog", + "SnakesAndLadders", + "SnakesAndLadders", + "SnakesAndLadders", + "SnakesAndLadders", + "SnakesAndLadders" + }; + + private static final String[] singularPascalCase = { + "ThisIsATest", + "SnakeCase", + "TitleCase", + "DotCase", + "PathCase", + "SentenceCase", + "RandomCase", + "Uppercase", + "TheQuickBrownFoxJumpOverTheLazyDog", + "TheQuickBrownFoxJumpOverTheLazyDog", + "TheQuickBrownFoxJumpOverTheLazyDog", + "TheQuickBrownFoxJumpOverTheLazyDog", + "TheQuickBrownFoxJumpOverTheLazyDog", + "TheQuickBrownFoxJumpOverTheLazyDog", + "SnakeAndLadder", + "SnakeAndLadder", + "SnakeAndLadder", + "SnakeAndLadder", + "SnakeAndLadder" + }; + + @Test + public void testToPascalCase() { + for (int i = 0; i < randomWords.length; i++) { + assert CaseConverter.toPascalCase(randomWords[i]).equals(pascalCase[i]); + } + } + + @Test + public void testToCamelCase() { + for (int i = 0; i < randomWords.length; i++) { + assert CaseConverter.toCamelCase(randomWords[i]).equals(camelCase[i]); + } + } + + @Test + public void testToSingularPascalCase() { + for (int i = 0; i < randomWords.length; i++) { + assert CaseConverter.toSingularPascalCase(randomWords[i]).equals(singularPascalCase[i]); + } + } + +} diff --git a/persist-cli/src/test/java/io/ballerina/persist/SingularPluralTest.java b/persist-cli/src/test/java/io/ballerina/persist/SingularPluralTest.java new file mode 100644 index 000000000..fa63b261a --- /dev/null +++ b/persist-cli/src/test/java/io/ballerina/persist/SingularPluralTest.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. + * + * WSO2 LLC. licenses this file to you 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 + * + * http://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 io.ballerina.persist; + +import io.ballerina.persist.inflector.Pluralizer; +import io.ballerina.persist.inflector.Singularizer; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.io.PrintStream; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.stream.Stream; + +/** + * A unit test class for singular to plural functions. + */ +public class SingularPluralTest { + + List singularWords = Arrays.asList( + "boy", "girl", "bird", "cod", "commerce", "quiz", "lemma", "dingo", "echo", "yes", + "tornado", "dingo", "bus", "child", "mom", "dad", "bottle", "sticker", "moss", + "wolf", "wife", "life", "leaf", "woman", "mouse", "goose", "baby", "toy", "kidney", + "potato", "memo", "stereo", "sheep", "deer", "series", "species", "window", "sticker", "desk", + "pencil", "cup", "milk", "choice", "box", "thief", "army", "woman", "friend", "daisy", + "boss", "marsh", "class", "lunch", "belief", "chef", "city", "ray", "photo", "piano", + "cactus", "focus", "series", "species", "mouse", "foot", "nanny", "study", "fox", "pouch", + "brush", "quiz", "roof", "truck", "bug", "pen", "book", "vegetable", "chair", + "medium", "kangaroo", "cherry", "sky", "monkey", "berry", "video", "studio", "mango", + "tornado", "tuxedo", "volcano", "house", "sister", "item", "thing", "computer", "flower", "roof", + "bacterium", "have" + ); + + List pluralWords = Arrays.asList( + "boys", "girls", "birds", "cod", "commerce", "quizzes", "lemmata", "dingoes", "echoes", "yeses", + "tornadoes", "dingoes", "buses", "children", "moms", "dads", "bottles", "stickers", "mosses", + "wolves", "wives", "lives", "leaves", "women", "mouses", "geese", "babies", "toys", "kidneys", + "potatoes", "memos", "stereos", "sheep", "deer", "series", "species", "windows", "stickers", "desks", + "pencils", "cups", "milks", "choices", "boxes", "thieves", "armies", "women", "friends", "daisies", + "bosses", "marshes", "classes", "lunches", "beliefs", "chefs", "cities", "rays", "photos", "pianos", + "cactuses", "focuses", "series", "species", "mouses", "feet", "nannies", "studies", "foxes", "pouches", + "brushes", "quizzes", "roofs", "trucks", "bugs", "pens", "books", "vegetables", "chairs", + "mediums", "kangaroos", "cherries", "skies", "monkeys", "berries", "videos", "studios", + "mangoes", "tornadoes", "tuxedos", "volcanoes", "houses", "sisters", "items", "things", "computers", + "flowers", "roofs", "bacteria", "have" + ); + + List inputForPluralTest = + Stream.concat(singularWords.stream(), Stream.of("bacterium", "has")).toList(); + List outputForPluralTest = + Stream.concat(pluralWords.stream(), Stream.of("bacteria", "have")).toList(); + List inputForSingularTest = Stream.concat(pluralWords.stream(), Stream.of("bacterium")).toList(); + List outputForSingularTest = Stream.concat(singularWords.stream(), Stream.of("bacterium")).toList(); + + @Test + public void testSingularToPlural() { + long startTime = System.nanoTime(); + List outputs = inputForPluralTest.stream().map(Pluralizer::pluralize).toList(); + assertResults(startTime, outputs, outputForPluralTest); + } + @Test(enabled = true) + public void testPluralToSingular() { + long startTime = System.nanoTime(); + List outputs = inputForSingularTest.stream().map(Singularizer::singularize).toList(); + assertResults(startTime, outputs, outputForSingularTest); + } + private void assertResults(long startTime, List outputs, List expectedOutputs) { + PrintStream print = System.out; + long endTime = System.nanoTime(); + // todo: Total time in milliseconds with initial implementation : 62 - 66 + print.println("Total time in milliseconds which takes to convert 100 words to plural: " + + TimeUnit.MILLISECONDS.convert(endTime - startTime, TimeUnit.NANOSECONDS)); + for (int i = 0; i < outputs.size(); i++) { + Assert.assertEquals(outputs.get(i), expectedOutputs.get(i)); + } + } +} diff --git a/persist-cli/src/test/java/io/ballerina/persist/UnitTest.java b/persist-cli/src/test/java/io/ballerina/persist/UnitTest.java deleted file mode 100644 index 777b6401a..000000000 --- a/persist-cli/src/test/java/io/ballerina/persist/UnitTest.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. - * - * WSO2 LLC. licenses this file to you 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 - * - * http://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 io.ballerina.persist; - -import io.ballerina.persist.plural.Pluralizer; -import org.testng.Assert; -import org.testng.annotations.Test; - -import java.io.PrintStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.TimeUnit; - -/** - * A unit test class for singular to plural functions. - */ -public class UnitTest { - - @Test - public void testSingularToPlural() { - PrintStream print = System.out; - List words = Arrays.asList( - "boy", "girl", "bird", "cod", "commerce", "quiz", "lemma", "dingo", "echo", "yes", - "tornado", "have", "dingo", "bus", "child", "mom", "dad", "bottle", "sticker", "moss", - "wolf", "wife", "life", "leaf", "woman", "mouse", "goose", "baby", "toy", "kidney", - "potato", "memo", "stereo", "sheep", "deer", "series", "species", "window", "sticker", "desk", - "pencil", "cup", "milk", "choice", "box", "thief", "army", "woman", "friend", "daisy", - "boss", "marsh", "class", "lunch", "belief", "chef", "city", "ray", "photo", "piano", - "cactus", "focus", "series", "species", "mouse", "foot", "nanny", "study", "fox", "pouch", - "brush", "quiz", "roof", "truck", "bug", "pen", "book", "vegetable", "chair", "bacteria", - "medium", "bacterium", "kangaroo", "cherry", "sky", "monkey", "berry", "video", "studio", "mango", - "tornado", "tuxedo", "volcano", "house", "sister", "item", "thing", "computer", "flower", "roof" - ); - List pluralWords = Arrays.asList( - "boys", "girls", "birds", "cod", "commerce", "quizzes", "lemmata", "dingoes", "echoes", "yeses", - "tornadoes", "have", "dingoes", "buses", "children", "moms", "dads", "bottles", "stickers", "mosses", - "wolves", "wives", "lives", "leaves", "women", "mouses", "geese", "babies", "toys", "kidneys", - "potatoes", "memos", "stereos", "sheep", "deer", "series", "species", "windows", "stickers", "desks", - "pencils", "cups", "milks", "choices", "boxes", "thieves", "armies", "women", "friends", "daisies", - "bosses", "marshes", "classes", "lunches", "beliefs", "chefs", "cities", "rays", "photos", "pianos", - "cactuses", "focuses", "series", "species", "mouses", "feet", "nannies", "studies", "foxes", "pouches", - "brushes", "quizzes", "roofs", "trucks", "bugs", "pens", "books", "vegetables", "chairs", "bacteria", - "mediums", "bacteria", "kangaroos", "cherries", "skies", "monkeys", "berries", "videos", "studios", - "mangos", "tornadoes", "tuxedos", "volcanoes", "houses", "sisters", "items", "things", "computers", - "flowers", "roofs" - ); - List outputs = new ArrayList<>(); - long startTime = System.nanoTime(); - for (String word: words) { - outputs.add(Pluralizer.pluralize(word)); - } - long endTime = System.nanoTime(); - // todo: Total time in milliseconds with initial implementation : 62 - 66 - print.println("Total time in milliseconds which takes to convert 100 words to plural: " + - TimeUnit.MILLISECONDS.convert(endTime - startTime, TimeUnit.NANOSECONDS)); - for (int i = 0; i < outputs.size(); i++) { - Assert.assertEquals(outputs.get(i), pluralWords.get(i)); - } - } -} diff --git a/spotbugs-exclude.xml b/spotbugs-exclude.xml index 387c2b8d4..97030924d 100644 --- a/spotbugs-exclude.xml +++ b/spotbugs-exclude.xml @@ -41,4 +41,16 @@ + + + + + + + + + + + +