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');
|