git.fiddlerwoaroof.com
sql/def.sql
d55c8a52
 -- Data model
 DROP TABLE reviews;
 DROP TABLE reviewers;
 DROP TABLE restaurants;
 CREATE TABLE restaurants (
   id SERIAL UNIQUE NOT NULL,
   restaurant_name TEXT NOT NULL,
   short_name TEXT NOT NULL UNIQUE,
   PRIMARY KEY (id)
 );
 
 CREATE TABLE reviewers (
   id SERIAL UNIQUE NOT NULL,
   reviewer_name TEXT UNIQUE NOT NULL,
   created_date TIMESTAMP,
   last_seen TIMESTAMP,
   PRIMARY KEY (id)
 );
 
 CREATE TABLE reviews (
   id SERIAL UNIQUE NOT NULL,
   reviewer_id INTEGER REFERENCES reviewers (id) NOT NULL,
   restaurant_id INTEGER REFERENCES restaurants (id) NOT NULL,
   review_posted TIMESTAMP DEFAULT current_timestamp,
   review TEXT NOT NULL,
   UNIQUE (reviewer_id, restaurant_id),
   PRIMARY KEY (id)
 );
 
 -- Stored Procedures
 
 CREATE OR REPLACE FUNCTION get_reviews(sn text)
   RETURNS TABLE(review text, reviewer text)  AS $$
 BEGIN
   RETURN QUERY SELECT reviews.review, reviewers.reviewer_name
                 FROM reviews
                   INNER JOIN reviewers ON reviews.reviewer_id=reviewers.id
                   INNER JOIN restaurants ON reviews.restaurant_id=restaurants.id
                   WHERE restaurants.short_name=sn
                   ORDER BY review_posted DESC,
                            reviewer_name ASC;
 END;
 $$ LANGUAGE plpgsql;
 
 CREATE OR REPLACE FUNCTION put_review(sn text, rn text, review text)
   RETURNS VOID AS $$
 DECLARE
   restaurant_id int;
   reviewer_id int;
   nowstamp timestamp;
 BEGIN
   SELECT restaurants.id INTO restaurant_id FROM restaurants WHERE restaurants.short_name=sn;
   SELECT reviewers.id INTO reviewer_id FROM reviewers WHERE reviewers.reviewer_name=rn;
 
   WITH new_values (rest_id, rev_id, review, tm) as (values (restaurant_id, reviewer_id, review, current_timestamp)),
   upsert as
   ( 
       UPDATE reviews m 
           SET restaurant_id = nv.rest_id,
               reviewer_id = nv.rev_id,
               review = nv.review,
               review_posted = tm
       FROM new_values nv
       WHERE m.restaurant_id = nv.rest_id AND m.reviewer_id = nv.rev_id
       RETURNING m.*
   )
   INSERT INTO reviews (restaurant_id, reviewer_id, review)
   SELECT rest_id, rev_id, new_values.review
   FROM new_values
   WHERE NOT EXISTS (SELECT 1 
                     FROM upsert up 
                     WHERE up.restaurant_id = new_values.rest_id AND up.reviewer_id = new_values.rev_id);
 END;
 $$ LANGUAGE plpgsql;
 
 -- Test Data
 INSERT INTO restaurants  (restaurant_name, short_name) VALUES
   ('Vigilante Coffee', 'vigilante-coffee'),
   ('The Coffee Bar', 'the-coffee-bar'),
   ('Peregrine Espresso', 'peregrine-espresso'),
   ('Graffiato', 'graffiato');
 
 INSERT INTO reviewers (reviewer_name) VALUES
   ('the_tooth_fairy'),
   ('fiddlerwoaroof'),
   ('grandma_johnson');
 
 INSERT INTO reviews (reviewer_id, restaurant_id, review) VALUES
   ((SELECT id FROM reviewers where reviewer_name='the_tooth_fairy'), (SELECT id FROM restaurants where short_name='vigilante-coffee'), 'Great Coffee!'),
   ((SELECT id FROM reviewers where reviewer_name='fiddlerwoaroof'),  (SELECT id FROM restaurants where short_name='vigilante-coffee'), 'My coffee was cold :/'),
   ((SELECT id FROM reviewers where reviewer_name='grandma_johnson'), (SELECT id FROM restaurants where short_name='vigilante-coffee'), 'Bad Customer service, will actively avoid!'),
   ((SELECT id FROM reviewers where reviewer_name='the_tooth_fairy'), (SELECT id FROM restaurants where short_name='peregrine-espresso'), 'The owner looked at me funny,  do not return!'),
   ((SELECT id FROM reviewers where reviewer_name='fiddlerwoaroof'),  (SELECT id FROM restaurants where short_name='peregrine-espresso'), 'Great Coffee!'),
   ((SELECT id FROM reviewers where reviewer_name='grandma_johnson'), (SELECT id FROM restaurants where short_name='peregrine-espresso'), 'Cockroach in bottom of french press, disgusting!'),
   ((SELECT id FROM reviewers where reviewer_name='the_tooth_fairy'), (SELECT id FROM restaurants where short_name='graffiato'), 'Too Italian'),
   ((SELECT id FROM reviewers where reviewer_name='fiddlerwoaroof'),  (SELECT id FROM restaurants where short_name='graffiato'), 'They dont have a peanut butter pizza!'),
   ((SELECT id FROM reviewers where reviewer_name='grandma_johnson'), (SELECT id FROM restaurants where short_name='graffiato'), 'Whatever . . . '),
   ((SELECT id FROM reviewers where reviewer_name='the_tooth_fairy'), (SELECT id FROM restaurants where short_name='the-coffee-bar'), 'Great Location! Good Coffee!'),
   ((SELECT id FROM reviewers where reviewer_name='fiddlerwoaroof'),  (SELECT id FROM restaurants where short_name='the-coffee-bar'), 'Great Coffee! Good Location!'),
   ((SELECT id FROM reviewers where reviewer_name='grandma_johnson'), (SELECT id FROM restaurants where short_name='the-coffee-bar'), 'This is too far from my knitting needles . . . ');
 
 SELECT * FROM reviews
   RIGHT JOIN reviewers ON reviews.reviewer_id=reviewers.id
   RIGHT JOIN restaurants ON reviews.restaurant_id=restaurants.id
   WHERE short_name='vigilante-coffee';
 
 INSERT INTO reviewers (reviewer_name) VALUES ('the_great_one');