diff --git a/docker-compose.yml b/docker-compose.yml index 2e4422f02fe..4c81a828c7c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,3 +13,11 @@ services: - MYSQL_DATABASE=petclinic volumes: - "./conf.d:/etc/mysql/conf.d:ro" + postgres: + image: postgres:14.1 + ports: + - "5432:5432" + environment: + - POSTGRES_PASSWORD=petclinic + - POSTGRES_USER=petclinic + - POSTGRES_DB=petclinic diff --git a/pom.xml b/pom.xml index d78a188a0eb..ae02829f255 100644 --- a/pom.xml +++ b/pom.xml @@ -81,6 +81,11 @@ mysql-connector-java runtime + + org.postgresql + postgresql + runtime + diff --git a/readme.md b/readme.md index 0304a6f3f3c..79d4b16228a 100644 --- a/readme.md +++ b/readme.md @@ -36,15 +36,17 @@ In its default configuration, Petclinic uses an in-memory database (H2) which gets populated at startup with data. The h2 console is automatically exposed at `http://localhost:8080/h2-console` and it is possible to inspect the content of the database using the `jdbc:h2:mem:testdb` url. -A similar setup is provided for MySql in case a persistent database configuration is needed. Note that whenever the database type is changed, the app needs to be run with a different profile: `spring.profiles.active=mysql` for MySql. +A similar setup is provided for MySQL and PostgreSQL in case a persistent database configuration is needed. Note that whenever the database type is changed, the app needs to be run with a different profile: `spring.profiles.active=mysql` for MySQL or `spring.profiles.active=postgres` for PostgreSQL. -You could start MySql locally with whatever installer works for your OS, or with docker: +You could start MySQL or PostgreSQL locally with whatever installer works for your OS, or with docker: ``` docker run -e MYSQL_USER=petclinic -e MYSQL_PASSWORD=petclinic -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=petclinic -p 3306:3306 mysql:5.7.8 +docker run -e POSTGRES_USER=petclinic -e POSTGRES_PASSWORD=petclinic -e POSTGRES_DB=petclinic -p 5432:5432 postgres:14.1 ``` -Further documentation is provided [here](https://github.com/spring-projects/spring-petclinic/blob/main/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt). +Further documentation is provided for [MySQL](https://github.com/spring-projects/spring-petclinic/blob/main/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt) +and for [PostgreSQL](https://github.com/spring-projects/spring-petclinic/blob/main/src/main/resources/db/postgres/petclinic_db_setup_postgres.txt). ## Compiling the CSS diff --git a/src/main/resources/application-postgres.properties b/src/main/resources/application-postgres.properties new file mode 100644 index 00000000000..80bd3e10a80 --- /dev/null +++ b/src/main/resources/application-postgres.properties @@ -0,0 +1,6 @@ +database=postgres +spring.datasource.url=${POSTGRES_URL:jdbc:postgresql://localhost/petclinic} +spring.datasource.username=${POSTGRES_USER:petclinic} +spring.datasource.password=${POSTGRES_PASS:petclinic} +# SQL is written to be idempotent so this is safe +spring.datasource.initialization-mode=always diff --git a/src/main/resources/db/postgres/data.sql b/src/main/resources/db/postgres/data.sql new file mode 100644 index 00000000000..9ea00d91a3f --- /dev/null +++ b/src/main/resources/db/postgres/data.sql @@ -0,0 +1,59 @@ +INSERT INTO vets VALUES (1, 'James', 'Carter'); +INSERT INTO vets VALUES (2, 'Helen', 'Leary'); +INSERT INTO vets VALUES (3, 'Linda', 'Douglas'); +INSERT INTO vets VALUES (4, 'Rafael', 'Ortega'); +INSERT INTO vets VALUES (5, 'Henry', 'Stevens'); +INSERT INTO vets VALUES (6, 'Sharon', 'Jenkins'); +ALTER SEQUENCE vets_id_seq RESTART WITH 7; + +INSERT INTO specialties VALUES (1, 'radiology'); +INSERT INTO specialties VALUES (2, 'surgery'); +INSERT INTO specialties VALUES (3, 'dentistry'); +ALTER SEQUENCE specialties_id_seq RESTART WITH 4; + +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 (1, 'cat'); +INSERT INTO types VALUES (2, 'dog'); +INSERT INTO types VALUES (3, 'lizard'); +INSERT INTO types VALUES (4, 'snake'); +INSERT INTO types VALUES (5, 'bird'); +INSERT INTO types VALUES (6, 'hamster'); +ALTER SEQUENCE types_id_seq RESTART WITH 7; + +INSERT INTO owners VALUES (1, 'George', 'Franklin', '110 W. Liberty St.', 'Madison', '6085551023'); +INSERT INTO owners VALUES (2, 'Betty', 'Davis', '638 Cardinal Ave.', 'Sun Prairie', '6085551749'); +INSERT INTO owners VALUES (3, 'Eduardo', 'Rodriquez', '2693 Commerce St.', 'McFarland', '6085558763'); +INSERT INTO owners VALUES (4, 'Harold', 'Davis', '563 Friendly St.', 'Windsor', '6085553198'); +INSERT INTO owners VALUES (5, 'Peter', 'McTavish', '2387 S. Fair Way', 'Madison', '6085552765'); +INSERT INTO owners VALUES (6, 'Jean', 'Coleman', '105 N. Lake St.', 'Monona', '6085552654'); +INSERT INTO owners VALUES (7, 'Jeff', 'Black', '1450 Oak Blvd.', 'Monona', '6085555387'); +INSERT INTO owners VALUES (8, 'Maria', 'Escobito', '345 Maple St.', 'Madison', '6085557683'); +INSERT INTO owners VALUES (9, 'David', 'Schroeder', '2749 Blackhawk Trail', 'Madison', '6085559435'); +INSERT INTO owners VALUES (10, 'Carlos', 'Estaban', '2335 Independence La.', 'Waunakee', '6085555487'); +ALTER SEQUENCE owners_id_seq RESTART WITH 11; + +INSERT INTO pets VALUES (1, 'Leo', '2000-09-07', 1, 1); +INSERT INTO pets VALUES (2, 'Basil', '2002-08-06', 6, 2); +INSERT INTO pets VALUES (3, 'Rosy', '2001-04-17', 2, 3); +INSERT INTO pets VALUES (4, 'Jewel', '2000-03-07', 2, 3); +INSERT INTO pets VALUES (5, 'Iggy', '2000-11-30', 3, 4); +INSERT INTO pets VALUES (6, 'George', '2000-01-20', 4, 5); +INSERT INTO pets VALUES (7, 'Samantha', '1995-09-04', 1, 6); +INSERT INTO pets VALUES (8, 'Max', '1995-09-04', 1, 6); +INSERT INTO pets VALUES (9, 'Lucky', '1999-08-06', 5, 7); +INSERT INTO pets VALUES (10, 'Mulligan', '1997-02-24', 2, 8); +INSERT INTO pets VALUES (11, 'Freddy', '2000-03-09', 5, 9); +INSERT INTO pets VALUES (12, 'Lucky', '2000-06-24', 2, 10); +INSERT INTO pets VALUES (13, 'Sly', '2002-06-08', 1, 10); +ALTER SEQUENCE pets_id_seq RESTART WITH 14; + +INSERT INTO visits VALUES (1, 7, '2010-03-04', 'rabies shot'); +INSERT INTO visits VALUES (2, 8, '2011-03-04', 'rabies shot'); +INSERT INTO visits VALUES (3, 8, '2009-06-04', 'neutered'); +INSERT INTO visits VALUES (4, 7, '2008-09-04', 'spayed'); +ALTER SEQUENCE visits_id_seq RESTART WITH 5; diff --git a/src/main/resources/db/postgres/petclinic_db_setup_postgres.txt b/src/main/resources/db/postgres/petclinic_db_setup_postgres.txt new file mode 100644 index 00000000000..a998749f0cc --- /dev/null +++ b/src/main/resources/db/postgres/petclinic_db_setup_postgres.txt @@ -0,0 +1,19 @@ +=============================================================================== +=== Spring PetClinic sample application - PostgreSQL Configuration === +=============================================================================== + +-------------------------------------------------------------------------------- + +1) Run the "docker-compose.yml" from the root of the project: + + $ docker-compose up + ... + spring-petclinic-postgres-1 | The files belonging to this database system will be owned by user "postgres". + ... + +2) Run the app with `spring.profiles.active=postgres` (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=postgres + + To activate the profile on the command line. diff --git a/src/main/resources/db/postgres/schema.sql b/src/main/resources/db/postgres/schema.sql new file mode 100644 index 00000000000..a498b109477 --- /dev/null +++ b/src/main/resources/db/postgres/schema.sql @@ -0,0 +1,56 @@ +-- Wipe everything before creating the tables to make the script idempotent. +DROP SCHEMA public cascade; +CREATE SCHEMA public; + +CREATE TABLE vets ( + id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + first_name TEXT, + last_name TEXT +); +CREATE INDEX ON vets (last_name); + +CREATE TABLE specialties ( + id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + name TEXT +); +CREATE INDEX ON specialties (name); + +CREATE TABLE vet_specialties ( + vet_id INT NOT NULL REFERENCES vets (id), + specialty_id INT NOT NULL REFERENCES specialties (id), + UNIQUE (vet_id, specialty_id) +); + +CREATE TABLE types ( + id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + name TEXT +); +CREATE INDEX ON types (name); + +CREATE TABLE owners ( + id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + first_name TEXT, + last_name TEXT, + address TEXT, + city TEXT, + telephone TEXT +); +CREATE INDEX ON owners (last_name); + +CREATE TABLE pets ( + id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + name TEXT, + birth_date DATE, + type_id INT NOT NULL REFERENCES types (id), + owner_id INT NOT NULL REFERENCES owners (id) +); +CREATE INDEX ON pets (name); +CREATE INDEX ON pets (owner_id); + +CREATE TABLE visits ( + id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + pet_id INT NOT NULL REFERENCES pets (id), + visit_date DATE, + description TEXT +); +CREATE INDEX ON visits (pet_id);