diff --git a/plpgsql/README.md b/plpgsql/README.md index 63d144d1..4ba245c2 100644 --- a/plpgsql/README.md +++ b/plpgsql/README.md @@ -1,11 +1,41 @@ +# Requirements +You'll need: +- PostgreSQL database, version >= 11 because PROCEDURE keyword isn't supported before [version 11](https://www.postgresql.org/docs/11/release-11.html) +- OS user with local connection privilege to database on standard 5432 port + +To use remote / local dockerized database, add ``` --host --port --username``` parameters to plsql invocation. + # Setup -Create database structure: psql -f ./structure/create.sql -Load code into database psql -f ./code/update_quality.sql -d gilded_rose -Load test data into database: psql -f ./test/data/load.sql -d gilded_rose -Execute: CALL update_quality(); -Check results: SELECT * FROM items; +In shell: +- create database: ```createdb gilded_rose``` +- create item table (structure): ```psql -d gilded_rose -f ./structure/create.sql``` +- load code into database: ```psql -d gilded_rose -f ./src/update_quality.sql ``` + +If you get this message```LINE 1: CREATE OR REPLACE PROCEDURE public.update_quality()```, your PostgreSQL version may under 11, consider upgrading. + +# Run +In shell: +- load manual test data into database: ```psql -d gilded_rose -f ./test/manual/load.sql``` +- connect to CLI: ```psql -d gilded_rose``` +- check item state: ```SELECT * FROM item;``` +- execute item update: ```CALL update_quality();``` +- check item state: ```SELECT * FROM item;``` +- empty table : ```TRUNCATE TABLE item;``` + # Test -No test code provided, only a sample of test data -TODO: [https://pgtap.org/](introduce TAP - xUnit for PL/pg SQL) +## Using pgTAP + +### Requirements +Install pgTAP [instructions here](https://pgtap.org/documentation.html#installation) + +```item``` table is supposed to be empty. +If not, it would cause a (false positive)[https://en.wikipedia.org/wiki/False_positives_and_false_negatives] + +### Execute +In shell, execute ```pg_prove --dbname gilded_rose test/pgtap/*.sql```. +You should get ```test/pgtap/template.sql .. ok All tests successful.``` + +If you get this message ```ERROR: function plan(integer) does not exist LINE 1: SELECT PLAN(1);```, pgTAP is not working => check your pgTAP installation. +If you get this message ```Failed test: 2 Parse errors: Bad plan. You planned 1 tests but ran 2.```, the item table contains data, interfering with the test => empty it, then run test again. diff --git a/plpgsql/code/update_quality.sql b/plpgsql/code/update_quality.sql deleted file mode 100644 index 69c18516..00000000 --- a/plpgsql/code/update_quality.sql +++ /dev/null @@ -1,80 +0,0 @@ -CREATE OR REPLACE PROCEDURE public.update_quality() - LANGUAGE plpgsql -AS $$ - -DECLARE - - rec_item RECORD; - cur_items CURSOR FOR SELECT * FROM item; - -BEGIN - -OPEN cur_items; - - - LOOP - - FETCH cur_items INTO rec_item; - EXIT WHEN NOT FOUND; - - IF (rec_item.name <> 'Aged Brie' AND rec_item.name <> 'Backstage passes to a TAFKAL80ETC concert') THEN - IF (rec_item.quality > 0) THEN - IF (rec_item.name <> 'Sulfuras, Hand of Ragnaros') THEN - rec_item.quality = rec_item.quality - 1; - END IF; - END IF; - ELSE - IF (rec_item.quality < 50) THEN - rec_item.quality = rec_item.quality + 1; - IF (rec_item.name = 'Backstage passes to a TAFKAL80ETC concert') THEN - IF (rec_item.sellIn < 11) THEN - IF (rec_item.quality < 50) THEN - rec_item.quality = rec_item.quality + 1; - END IF; - END IF; - IF (rec_item.sellIn < 6) THEN - IF (rec_item.quality < 50) THEN - rec_item.quality = rec_item.quality + 1; - END IF; - END IF; - END IF; - END IF; - END IF; - - IF (rec_item.name <> 'Sulfuras, Hand of Ragnaros') THEN - rec_item.sellIn = rec_item.sellIn - 1; - END IF; - - IF (rec_item.sellIn < 0) THEN - IF (rec_item.name <> 'Aged Brie') THEN - IF (rec_item.name <> 'Backstage passes to a TAFKAL80ETC concert') THEN - IF (rec_item.quality > 0) THEN - IF (rec_item.name <> 'Sulfuras, Hand of Ragnaros') THEN - rec_item.quality = rec_item.quality - 1; - END IF; - END IF; - ELSE - rec_item.quality = rec_item.quality - rec_item.quality; - END IF; - ELSE - IF (rec_item.quality < 50) THEN - rec_item.quality = rec_item.quality + 1; - END IF; - END IF; - END IF; - - UPDATE item - SET - quality = rec_item.quality, - sellIn = rec_item.sellIn - WHERE - name = rec_item.name; - - END LOOP; - - CLOSE cur_items; - - COMMIT; - -END; -$$ diff --git a/plpgsql/structure/create.sql b/plpgsql/structure/create.sql index 5ce4d245..263b860d 100644 --- a/plpgsql/structure/create.sql +++ b/plpgsql/structure/create.sql @@ -1,7 +1,3 @@ -CREATE DATABASE gilded_rose; - -\connect gilded_rose; - CREATE TABLE item ( name CHARACTER VARYING(100) NOT NULL, sellIn INTEGER, diff --git a/plpgsql/test/data/load.sql b/plpgsql/test/data/load.sql deleted file mode 100644 index c03aa4ba..00000000 --- a/plpgsql/test/data/load.sql +++ /dev/null @@ -1,17 +0,0 @@ -\set AUTOCOMMIT off - -TRUNCATE TABLE item; - -INSERT INTO item (name, sellIn, quality) VALUES ('+5 Dexterity Vest', 10, 20); -INSERT INTO item (name, sellIn, quality) VALUES ('Aged Brie', 2, 0); -INSERT INTO item (name, sellIn, quality) VALUES ('Elixir of the Mongoose', 5, 7); -INSERT INTO item (name, sellIn, quality) VALUES ('Sulfuras, Hand of Ragnaros', 0, 80); -INSERT INTO item (name, sellIn, quality) VALUES ('Sulfuras, Hand of Ragnaros', -1, 80); -INSERT INTO item (name, sellIn, quality) VALUES ('Backstage passes to a TAFKAL80ETC concert', 15, 20); -INSERT INTO item (name, sellIn, quality) VALUES ('Backstage passes to a TAFKAL80ETC concert', 10, 49); -INSERT INTO item (name, sellIn, quality) VALUES ('Backstage passes to a TAFKAL80ETC concert', 5, 49); - --- this conjured item does not work properly yet -INSERT INTO item (name, sellIn, quality) VALUES ('Conjured Mana Cake', 3, 6); - -COMMIT;