Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issues in annotations with MSSQL and PostgreSQL databases #61

Merged
merged 3 commits into from
Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion ballerina/metadata_types.bal
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@ public type EntityFieldMetadata record {|
# Represents the metadata associated with a simple field in the entity record.
#
# + columnName - The name of the SQL table column to which the field is mapped
# + dbGenerated - Whether the field is generated by the database
public type SimpleFieldMetadata record {|
string columnName;
boolean dbGenerated = false;
|};

# Represents the metadata associated with a field of an entity.
Expand All @@ -52,11 +54,13 @@ public type FieldMetadata SimpleFieldMetadata|EntityFieldMetadata;
# Only used by the generated persist clients and `persist:SQLClient`.
#
# + entityName - The name of the entity represented in the relation
# + refField - The name of the referenced column in the SQL table
# + refField - The name of the field in the entity that is being referenced
# + refColumn - The name of the column in the SQL table that is being referenced. If this is not provided, the `refField` is used as the `refColumn`

public type RelationMetadata record {|
string entityName;
string refField;
string? refColumn = ();
|};

# Represents the metadata associated with performing an SQL `JOIN` operation.
Expand Down
8 changes: 5 additions & 3 deletions ballerina/sql_client.bal
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,8 @@ public isolated client class SQLClient {
columnNames.push(self.escape(self.entityName) + "." + self.escape(fieldMetadata.columnName) + " AS " + self.escape(key));
} else {
// column is in another entity's table
columnNames.push(self.escape(fieldName) + "." + self.escape(fieldMetadata.relation.refField) + " AS " + self.escape(fieldName + "." + fieldMetadata.relation.refField));
columnNames.push(self.escape(fieldName) + "." + self.escape(fieldMetadata.relation.refColumn ?: fieldMetadata.relation.refField) + " AS " + self.escape(fieldName + "." + fieldMetadata.relation.refField));

}

}
Expand All @@ -313,7 +314,7 @@ public isolated client class SQLClient {
continue;
}

string columnName = fieldMetadata.relation.refField;
string columnName = fieldMetadata.relation.refColumn ?: fieldMetadata.relation.refField;
columnNames.push(self.escape(columnName));
}
return arrayToParameterizedQuery(columnNames);
Expand Down Expand Up @@ -478,7 +479,8 @@ public isolated client class SQLClient {

private isolated function getInsertableFields() returns string[] {
return from string key in self.fieldMetadata.keys()
where self.fieldMetadata.get(key) is SimpleFieldMetadata
let FieldMetadata metadataField = self.fieldMetadata.get(key)
where metadataField is SimpleFieldMetadata && !metadataField.dbGenerated
select key;
}

Expand Down
143 changes: 143 additions & 0 deletions ballerina/tests/hospital_persist_types.bal
Original file line number Diff line number Diff line change
@@ -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.

// 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/time;

public enum AppointmentStatus {
SCHEDULED = "SCHEDULED",
STARTED = "STARTED",
ENDED = "ENDED"
}

public enum PatientGender {
MALE = "MALE",
FEMALE = "FEMALE"
}

public type Appointment record {|
readonly int id;
string reason;
time:Civil appointmentTime;
AppointmentStatus status;
int patientId;
int doctorId;
|};

public type AppointmentOptionalized record {|
int id?;
string reason?;
time:Civil appointmentTime?;
AppointmentStatus status?;
int patientId?;
int doctorId?;
|};

public type AppointmentWithRelations record {|
*AppointmentOptionalized;
PatientOptionalized patient?;
DoctorOptionalized doctor?;
|};

public type AppointmentTargetType typedesc<AppointmentWithRelations>;

public type AppointmentInsert Appointment;

public type AppointmentUpdate record {|
string reason?;
time:Civil appointmentTime?;
AppointmentStatus status?;
int patientId?;
int doctorId?;
|};

public type Patient record {|
readonly int id;
string name;
int age;
string address;
string phoneNumber;
PatientGender gender;

|};

public type PatientOptionalized record {|
int id?;
string name?;
int age?;
string address?;
string phoneNumber?;
PatientGender gender?;
|};

public type PatientWithRelations record {|
*PatientOptionalized;
AppointmentOptionalized[] appointments?;
|};

public type PatientTargetType typedesc<PatientWithRelations>;

public type PatientInsert record {|
string name;
int age;
string address;
string phoneNumber;
PatientGender gender;
|};

public type PatientUpdate record {|
string name?;
int age?;
string address?;
string phoneNumber?;
PatientGender gender?;
|};

public type Doctor record {|
readonly int id;
string name;
string specialty;
string phoneNumber;
decimal? salary;

|};

public type DoctorOptionalized record {|
int id?;
string name?;
string specialty?;
string phoneNumber?;
decimal? salary?;
|};

public type DoctorWithRelations record {|
*DoctorOptionalized;
AppointmentOptionalized[] appointments?;
|};

public type DoctorTargetType typedesc<DoctorWithRelations>;

public type DoctorInsert Doctor;

public type DoctorUpdate record {|
string name?;
string specialty?;
string phoneNumber?;
decimal? salary?;
|};

37 changes: 37 additions & 0 deletions ballerina/tests/init-tests.bal
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ function initMySqlTests() returns error? {
_ = check mysqlDbClient->execute(`TRUNCATE IntIdRecord`);
_ = check mysqlDbClient->execute(`TRUNCATE AllTypesIdRecord`);
_ = check mysqlDbClient->execute(`TRUNCATE CompositeAssociationRecord`);
_ = check mysqlDbClient->execute(`TRUNCATE Doctor`);
_ = check mysqlDbClient->execute(`TRUNCATE appointment`);
_ = check mysqlDbClient->execute(`TRUNCATE patients`);
_ = check mysqlDbClient->execute(`SET FOREIGN_KEY_CHECKS = 1`);
check mysqlDbClient.close();
}
Expand Down Expand Up @@ -232,6 +235,40 @@ function initMsSqlTests() returns error? {
PRIMARY KEY(id)
);
`);
_ = check mssqlDbClient->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 mssqlDbClient->execute(`
CREATE TABLE [patients] (
[IDP] INT IDENTITY(1,1),
[name] VARCHAR(191) NOT NULL,
[age] INT NOT NULL,
[ADD_RESS] VARCHAR(191) NOT NULL,
[phoneNumber] CHAR(10) NOT NULL,
[gender] VARCHAR(6) CHECK ([gender] IN ('MALE', 'FEMALE')) NOT NULL,
PRIMARY KEY([IDP])
);
`);
_ = check mssqlDbClient->execute(`
CREATE TABLE [appointment] (
[id] INT NOT NULL,
[reason] VARCHAR(191) NOT NULL,
[appointmentTime] DATETIME2 NOT NULL,
[status] VARCHAR(9) CHECK ([status] IN ('SCHEDULED', 'STARTED', 'ENDED')) NOT NULL,
[patient_id] INT NOT NULL,
FOREIGN KEY([patient_id]) REFERENCES [patients]([IDP]),
[doctorId] INT NOT NULL,
FOREIGN KEY([doctorId]) REFERENCES [Doctor]([id]),
PRIMARY KEY([id])
);
`);
}

function initPostgreSqlTests() returns error? {
Expand Down
Loading
Loading