Skip to content

Commit

Permalink
Merge pull request #799 from 9tigerio/feature/710_oracle_sp
Browse files Browse the repository at this point in the history
#710 - add first oracle stored procedure test
  • Loading branch information
kdhrubo authored Nov 14, 2024
2 parents 15c6021 + c41e5db commit 5d87dfd
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 11 deletions.
3 changes: 2 additions & 1 deletion api-rest/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ logging:
springframework:
web: INFO
beans: INFO
jdbc: INFO
jdbc: DEBUG


management:
endpoints:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.homihq.db2rest.rest.oracle;

import com.homihq.db2rest.MySQLBaseIntegrationTest;
import com.homihq.db2rest.OracleBaseIntegrationTest;
import org.junit.jupiter.api.*;
import org.springframework.http.MediaType;

import java.util.Map;

import static com.homihq.db2rest.jdbc.rest.RdbmsRestApi.VERSION;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.hamcrest.Matchers.*;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@TestClassOrder(ClassOrderer.OrderAnnotation.class)
@Order(250)
class OracleProcedureControllerTest extends OracleBaseIntegrationTest {

@Disabled
@Test
@DisplayName("Execute stored procedure on oracle db")
void execute() throws Exception {
var json = """
{
"movieTitle": "ACADEMY DINOSAUR"
}
""";

mockMvc.perform(post(VERSION + "/oradb/procedure/GetMovieRentalRateProc")
.characterEncoding(UTF_8)
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.content(json))
.andExpect(status().isOk())
.andExpect(jsonPath("$", instanceOf(Map.class)))
.andExpect(jsonPath("$.*", hasSize(2)))
.andExpect(jsonPath("$.rentalRate", equalTo(0.99)))
//.andDo(print())
.andDo(document("oracle-execute-procedure"));
}
}
38 changes: 37 additions & 1 deletion api-rest/src/test/resources/oracle/oracle-sakila.sql
Original file line number Diff line number Diff line change
Expand Up @@ -743,4 +743,40 @@ ALTER TABLE inventory ADD CONSTRAINT fk_inventory_store FOREIGN KEY (store_id) R

ALTER TABLE staff ADD CONSTRAINT fk_staff_store FOREIGN KEY (store_id) REFERENCES store (store_id);

ALTER TABLE payment ADD CONSTRAINT fk_payment_rental FOREIGN KEY (rental_id) REFERENCES rental (rental_id) ON DELETE SET NULL;
ALTER TABLE payment ADD CONSTRAINT fk_payment_rental FOREIGN KEY (rental_id) REFERENCES rental (rental_id) ON DELETE SET NULL;



CREATE OR REPLACE PROCEDURE GetMovieRentalRateProc (
movieTitle IN VARCHAR2,
p_rental_rate OUT NUMBER
) IS
/*
* Purpose: Retrieves the rental rate for a given movie title
* Parameters:
* p_movie_title - Input parameter for the movie title
* p_rental_rate - Output parameter for the rental rate
* Returns: Rental rate via OUT parameter, -1 if movie not found
*/
BEGIN
-- Input parameter validation
IF movieTitle IS NULL THEN
RAISE_APPLICATION_ERROR(-20001, 'Movie title cannot be null');
END IF;

-- Get rental rate for the movie
SELECT rental_rate
INTO p_rental_rate
FROM film
WHERE UPPER(title) = UPPER(movieTitle);

EXCEPTION
WHEN NO_DATA_FOUND THEN
p_rental_rate := -1;
WHEN OTHERS THEN
-- Log error and re-raise
p_rental_rate := NULL;
RAISE_APPLICATION_ERROR(-20002,
'Error getting rental rate: ' || SQLERRM);
END GetMovieRentalRateProc;
/
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
package com.homihq.db2rest.jdbc.core.service;


import com.homihq.db2rest.core.exception.RpcException;
import com.homihq.db2rest.jdbc.JdbcManager;
import com.homihq.db2rest.jdbc.config.dialect.Dialect;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcCall;

import java.util.Map;
Expand All @@ -17,14 +22,25 @@ public class JdbcProcedureService implements ProcedureService {
private final JdbcManager jdbcManager;

@Override
public SimpleJdbcCall getSimpleJdbcCall(String dbId,String subRoutineName) {
public Map<String, Object> execute(String dbId, String subRoutineName, Map<String, Object> inParams) {
JdbcTemplate jdbcTemplate = jdbcManager.getNamedParameterJdbcTemplate(dbId).getJdbcTemplate();
return new SimpleJdbcCall(jdbcTemplate).withProcedureName(subRoutineName);
Dialect dialect = jdbcManager.getDialect(dbId);

log.info("Dialect selected: {}", dialect);
log.info("inParams: {}", inParams);

return doExecuteInternal(jdbcTemplate, subRoutineName, inParams);
}

@Override
public Map<String, Object> execute(String dbId, String subRoutineName, Map<String, Object> inParams) {
JdbcTemplate jdbcTemplate = jdbcManager.getNamedParameterJdbcTemplate(dbId).getJdbcTemplate();
return doExecute(jdbcTemplate, dbId, subRoutineName, inParams);
private Map<String, Object> doExecuteInternal(JdbcTemplate jdbcTemplate,
String subRoutineName, Map<String, Object> inParams) {
jdbcTemplate.setResultsMapCaseInsensitive(true);
SqlParameterSource in = new MapSqlParameterSource().addValues(inParams);

try {
return new SimpleJdbcCall(jdbcTemplate).withProcedureName(subRoutineName).execute(inParams);
} catch (InvalidDataAccessApiUsageException ex) {
throw new RpcException(subRoutineName, inParams);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package com.homihq.db2rest.jdbc.core.service;

import org.springframework.jdbc.core.simple.SimpleJdbcCall;

import java.util.Map;

public interface ProcedureService extends SubRoutine {
SimpleJdbcCall getSimpleJdbcCall(String dbId, String subRoutineName);
public interface ProcedureService {

Map<String, Object> execute(String dbId, String subRoutineName, Map<String, Object> inParams);
}

0 comments on commit 5d87dfd

Please sign in to comment.