Last active
August 29, 2015 14:05
-
-
Save fritzy/7f7716d11bb51a059d88 to your computer and use it in GitHub Desktop.
Using Posgres as an Indexed Document Store
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CREATE TABLE document_store (key CHAR(100) PRIMARY KEY, bucket CHAR(100), value JSON); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CREATE INDEX documentstore_value_lastname_index on document_store ((value->>'lastname')); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CREATE UNIQUE INDEX documentstore_value_username_index on document_store ((value->>'username')); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CREATE FUNCTION documentstore_get_by_field(field TEXT, bucket CHAR(100), value TEXT, limit INTEGER) | |
RETURNS TABLE(key TEXT, value TEXT) AS $$BODY$$ | |
BEGIN | |
RETURN query | |
EXECUTE 'SELECT key::text, value::text FROM document_store ' | |
|| 'WHERE bucket = ' || quote_literal(bucket) | |
|| ' AND value->>(' || quote_literal(field) || ') = ' || quote_literal(value) | |
|| ' LIMIT ' || quote_literal(limit); | |
END; | |
$$ | |
LANGUAGE plpgsql; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CREATE FUNCTION documentstore_get_by_key(key CHAR(100), bucket CHAR(100)) | |
RETURNS TABLE(key TEXT, value TEXT) AS $$BODY$$ | |
BEGIN | |
RETURN query | |
EXECUTE 'SELECT key::text, value::text FROM document_store ' | |
|| 'WHERE key = ' || quote_literal(key); | |
|| ' AND bucket = ' || quote_literal(bucket); | |
END; | |
$$ | |
LANGUAGE plpgsql; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CREATE FUNCTION documentstore_key_range(bucket CHAR(100), low CHAR(100), high CHAR(100), limit INTEGER) | |
RETURNS TABLE(key TEXT, value TEXT) AS $$BODY$$ | |
BEGIN | |
RETURN query | |
EXECUTE 'SELECT key::text, value::text FROM document_store ' | |
|| 'WHERE bucket = ' || quote_literal(bucket) | |
|| ' AND key >= ' || quote_literal(low) | |
|| ' AND key <= ' || quote_literal(high) | |
|| ' LIMIT ' || quote_literal(limit); | |
END; | |
$$ | |
LANGUAGE plpgsql; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CREATE OR REPLACE FUNCTION documentstore_put(tname TEXT, bucket TEXT, key TEXT, value TEXT) | |
RETURNS VOID AS $$ | |
BEGIN | |
LOOP | |
-- first try to update the key | |
EXECUTE 'UPDATE document_store' | |
|| ' SET value = ' | |
|| quote_nullable(value) | |
|| ' WHERE key = ' | |
|| quote_literal(key) | |
|| ' AND bucket = ' | |
|| quote_literal(bucket); | |
IF found THEN | |
RETURN; | |
END IF; | |
-- not there, so try to insert the key | |
-- if someone else inserts the same key concurrently, | |
-- we could get a unique-key failure | |
BEGIN | |
EXECUTE 'INSERT INTO document_store (value, key, bucket) values ( ' | |
|| quote_nullable(value) || ', ' | |
|| quote_literal(key) || ', ' | |
|| quote_literal(bucket) || ')'; | |
RETURN; | |
EXCEPTION WHEN unique_violation THEN | |
-- Do nothing, and loop to try the UPDATE again. | |
RETURN; | |
END; | |
END LOOP; | |
END; | |
$$ | |
LANGUAGE plpgsql; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CREATE FUNCTION documentstore_range_by_field(field TEXT, bucket CHAR(100), low TEXT, high TEXT, limit INTEGER) | |
RETURNS TABLE(key TEXT, value TEXT) AS $$BODY$$ | |
BEGIN | |
RETURN query | |
EXECUTE 'SELECT key::text, value::text FROM document_store ' | |
|| 'WHERE bucket = ' || quote_literal(bucket) | |
|| ' AND value->>(' || quote_literal(field) || ') >= ' || quote_literal(low) | |
|| ' AND value->>(' || quote_literal(field) || ') <= ' || quote_literal(high) | |
|| ' LIMIT ' || quote_literal(limit); | |
END; | |
$$ | |
LANGUAGE plpgsql; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment