Add support for OracleSQL

This commit is contained in:
Radu Ghiorma 2023-12-01 13:37:59 +02:00
parent 8b8304fa25
commit c21793073c
8 changed files with 242 additions and 5 deletions

View file

@ -25,3 +25,14 @@ services:
- POSTGRES_DB=petclinic
profiles:
- postgres
oracle:
image: gvenzl/oracle-free:slim-faststart
ports:
- "1521:1521"
environment:
- APP_USER=petclinic
- APP_USER_PASSWORD=petclinic
- ORACLE_RANDOM_PASSWORD=yes
- ORACLE_DATABASE=petclinic
profiles:
- oracle

12
pom.xml
View file

@ -85,7 +85,11 @@
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc11</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Caching -->
<dependency>
<groupId>javax.cache</groupId>
@ -133,7 +137,11 @@
<artifactId>mysql</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>oracle-free</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>

View file

@ -0,0 +1,6 @@
database=oracle
spring.datasource.url=${ORACLE_URL:jdbc:oracle:thin:@//localhost:1521/petclinic}
spring.datasource.username=${APP_USER:petclinic}
spring.datasource.password=${APP_USER_PASSWORD:petclinic}
# SQL is written to be idempotent so this is safe
spring.sql.init.mode=always

View file

@ -0,0 +1,53 @@
INSERT INTO vets VALUES (default, 'James', 'Carter');
INSERT INTO vets VALUES (default, 'Helen', 'Leary');
INSERT INTO vets VALUES (default, 'Linda', 'Douglas');
INSERT INTO vets VALUES (default, 'Rafael', 'Ortega');
INSERT INTO vets VALUES (default, 'Henry', 'Stevens');
INSERT INTO vets VALUES (default, 'Sharon', 'Jenkins');
INSERT INTO specialties VALUES (default, 'radiology');
INSERT INTO specialties VALUES (default, 'surgery');
INSERT INTO specialties VALUES (default, 'dentistry');
INSERT INTO vet_specialties VALUES (2, 1);
INSERT INTO vet_specialties VALUES (3, 2);
INSERT INTO vet_specialties VALUES (3, 3);
INSERT INTO vet_specialties VALUES (4, 2);
INSERT INTO vet_specialties VALUES (5, 1);
INSERT INTO types VALUES (default, 'cat');
INSERT INTO types VALUES (default, 'dog');
INSERT INTO types VALUES (default, 'lizard');
INSERT INTO types VALUES (default, 'snake');
INSERT INTO types VALUES (default, 'bird');
INSERT INTO types VALUES (default, 'hamster');
INSERT INTO owners VALUES (default, 'George', 'Franklin', '110 W. Liberty St.', 'Madison', '6085551023');
INSERT INTO owners VALUES (default, 'Betty', 'Davis', '638 Cardinal Ave.', 'Sun Prairie', '6085551749');
INSERT INTO owners VALUES (default, 'Eduardo', 'Rodriquez', '2693 Commerce St.', 'McFarland', '6085558763');
INSERT INTO owners VALUES (default, 'Harold', 'Davis', '563 Friendly St.', 'Windsor', '6085553198');
INSERT INTO owners VALUES (default, 'Peter', 'McTavish', '2387 S. Fair Way', 'Madison', '6085552765');
INSERT INTO owners VALUES (default, 'Jean', 'Coleman', '105 N. Lake St.', 'Monona', '6085552654');
INSERT INTO owners VALUES (default, 'Jeff', 'Black', '1450 Oak Blvd.', 'Monona', '6085555387');
INSERT INTO owners VALUES (default, 'Maria', 'Escobito', '345 Maple St.', 'Madison', '6085557683');
INSERT INTO owners VALUES (default, 'David', 'Schroeder', '2749 Blackhawk Trail', 'Madison', '6085559435');
INSERT INTO owners VALUES (default, 'Carlos', 'Estaban', '2335 Independence La.', 'Waunakee', '6085555487');
INSERT INTO pets VALUES (default, 'Leo', TO_DATE('2010-09-07', 'YYYY-MM-DD'), 1, 1);
INSERT INTO pets VALUES (default, 'Basil', TO_DATE('2012-08-06', 'YYYY-MM-DD'), 6, 2);
INSERT INTO pets VALUES (default, 'Rosy', TO_DATE('2011-04-17', 'YYYY-MM-DD'), 2, 3);
INSERT INTO pets VALUES (default, 'Jewel', TO_DATE('2010-03-07', 'YYYY-MM-DD'), 2, 3);
INSERT INTO pets VALUES (default, 'Iggy', TO_DATE('2010-11-30', 'YYYY-MM-DD'), 3, 4);
INSERT INTO pets VALUES (default, 'George', TO_DATE('2010-01-20', 'YYYY-MM-DD'), 4, 5);
INSERT INTO pets VALUES (default, 'Samantha', TO_DATE('2012-09-04', 'YYYY-MM-DD'), 1, 6);
INSERT INTO pets VALUES (default, 'Max', TO_DATE('2012-09-04', 'YYYY-MM-DD'), 1, 6);
INSERT INTO pets VALUES (default, 'Lucky', TO_DATE('2011-08-06', 'YYYY-MM-DD'), 5, 7);
INSERT INTO pets VALUES (default, 'Mulligan', TO_DATE('2007-02-24', 'YYYY-MM-DD'), 2, 8);
INSERT INTO pets VALUES (default, 'Freddy', TO_DATE('2010-03-09', 'YYYY-MM-DD'), 5, 9);
INSERT INTO pets VALUES (default, 'Lucky', TO_DATE('2010-06-24', 'YYYY-MM-DD'), 2, 10);
INSERT INTO pets VALUES (default, 'Sly', TO_DATE('2012-06-08', 'YYYY-MM-DD'), 1, 10);
INSERT INTO visits VALUES (default, 7, TO_DATE('2013-01-01', 'YYYY-MM-DD'), 'rabies shot');
INSERT INTO visits VALUES (default, 8, TO_DATE('2013-01-02', 'YYYY-MM-DD'), 'rabies shot');
INSERT INTO visits VALUES (default, 8, TO_DATE('2013-01-03', 'YYYY-MM-DD'), 'neutered');
INSERT INTO visits VALUES (default, 7, TO_DATE('2013-01-04', 'YYYY-MM-DD'), 'spayed');

View file

@ -0,0 +1,19 @@
===============================================================================
=== Spring PetClinic sample application - OracleSQL Configuration ===
===============================================================================
1) Run the "docker-compose.yml" from the root of the project:
$ docker-compose up oracle
...
spring-petclinit-oracle-1 | #########################
spring-petclinit-oracle-1 | DATABASE IS READY TO USE!
spring-petclinit-oracle-1 | #########################
...
2) Run the app with `spring.profiles.active=oracle` (e.g. as a System property via the command
line, but any way that sets that property in a Spring Boot app should work). For example use
mvn spring-boot:run -Dspring-boot.run.profiles=oracle
To activate the profile on the command line.

View file

@ -0,0 +1,56 @@
CREATE TABLE IF NOT EXISTS vets (
id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
first_name VARCHAR(30),
last_name VARCHAR(30)
);
CREATE INDEX IF NOT EXISTS vets_last_name ON vets (last_name);
CREATE TABLE IF NOT EXISTS specialties (
id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
name VARCHAR(80)
);
CREATE INDEX IF NOT EXISTS specialties_name ON specialties (name);
CREATE TABLE IF NOT EXISTS vet_specialties (
vet_id INTEGER NOT NULL,
specialty_id INTEGER NOT NULL,
CONSTRAINT fk_vet_specialties_vets FOREIGN KEY (vet_id) REFERENCES vets (id),
CONSTRAINT fk_vet_specialties_specialties FOREIGN KEY (specialty_id) REFERENCES specialties (id)
);
CREATE TABLE IF NOT EXISTS types (
id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
name VARCHAR(80)
);
CREATE INDEX IF NOT EXISTS types_name ON types (name);
CREATE TABLE IF NOT EXISTS owners (
id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
first_name VARCHAR(30),
last_name VARCHAR(30),
address VARCHAR(255),
city VARCHAR(80),
telephone VARCHAR(20)
);
CREATE INDEX IF NOT EXISTS owners_last_name ON owners (last_name);
CREATE TABLE IF NOT EXISTS pets (
id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
name VARCHAR(30),
birth_date DATE,
type_id INTEGER NOT NULL,
owner_id INTEGER,
CONSTRAINT fk_pets_owners FOREIGN KEY (owner_id) REFERENCES owners (id),
CONSTRAINT fk_pets_types FOREIGN KEY (type_id) REFERENCES types (id)
);
CREATE INDEX IF NOT EXISTS pets_name ON pets (name);
CREATE TABLE IF NOT EXISTS visits (
id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
pet_id INTEGER,
visit_date DATE,
description VARCHAR(255),
CONSTRAINT fk_visits_pets FOREIGN KEY (pet_id) REFERENCES pets (id)
);
CREATE INDEX IF NOT EXISTS visits_pet_id ON visits (pet_id);

View file

@ -0,0 +1,54 @@
package org.springframework.samples.petclinic;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledInNativeImage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.HttpStatus;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.samples.petclinic.vet.VetRepository;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.web.client.RestTemplate;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.oracle.OracleContainer;
import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles("oracle")
@Testcontainers(disabledWithoutDocker = true)
@DisabledInNativeImage
class OracleIntegrationTests {
@ServiceConnection
@Container
static OracleContainer container = new OracleContainer("gvenzl/oracle-free:slim-faststart");
@LocalServerPort
int port;
@Autowired
private VetRepository vets;
@Autowired
private RestTemplateBuilder builder;
@Test
void testFindAll() {
vets.findAll();
vets.findAll(); // served from cache
}
@Test
void testOwnerDetails() {
RestTemplate template = builder.rootUri("http://localhost:" + port).build();
ResponseEntity<String> result = template.exchange(RequestEntity.get("/owners/1").build(), String.class);
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
}
}

View file

@ -0,0 +1,30 @@
package org.springframework.samples.petclinic;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.testcontainers.oracle.OracleContainer;
/**
* PetClinic Spring Boot Application
*
* @author Radu Ghiorma
*
*/
@Configuration
public class OracleTestApplication {
@ServiceConnection
@Profile("oracle")
@Bean
static OracleContainer container() {
return new OracleContainer("gvenzl/oracle-free:slim-faststart");
}
public static void main(String[] args) {
SpringApplication.run(PetClinicApplication.class, "--spring.profiles.active=oracle");
}
}