lib/wcc/contentful/store/postgres_store.rb in wcc-contentful-0.1.0 vs lib/wcc/contentful/store/postgres_store.rb in wcc-contentful-0.2.0

- old
+ new

@@ -2,62 +2,61 @@ gem 'pg', '~> 1.0' require 'pg' module WCC::Contentful::Store - class PostgresStore + class PostgresStore < Base def initialize(connection_options = nil) + super() connection_options ||= { dbname: 'postgres' } @conn = PG.connect(connection_options) PostgresStore.ensure_schema(@conn) end - def index(key, value) - @conn.exec_prepared('index_entry', [key, value.to_json]) - true + def set(key, value) + result = @conn.exec_prepared('upsert_entry', [key, value.to_json]) + return if result.num_tuples == 0 + val = result.getvalue(0, 0) + JSON.parse(val) if val end def keys result = @conn.exec_prepared('select_ids') arr = [] result.each { |r| arr << r['id'].strip } arr end + def delete(key) + result = @conn.exec_prepared('delete_by_id', [key]) + return if result.num_tuples == 0 + JSON.parse(result.getvalue(0, 1)) + end + def find(key) result = @conn.exec_prepared('select_entry', [key]) return if result.num_tuples == 0 JSON.parse(result.getvalue(0, 1)) end - def find_all - Query.new(@conn) - end - - def find_by(content_type:) + def find_all(content_type:) statement = "WHERE data->'sys'->'contentType'->'sys'->>'id' = $1" Query.new( @conn, statement, [content_type] ) end - class Query + class Query < Base::Query def initialize(conn, statement = nil, params = nil) @conn = conn @statement = statement || "WHERE data->'sys'->>'id' IS NOT NULL" @params = params || [] end - def apply(filter, context = nil) - return eq(filter[:field], filter[:eq], context) if filter[:eq] - - raise ArgumentError, "Filter not implemented: #{filter}" - end - def eq(field, expected, context = nil) locale = context[:locale] if context.present? locale ||= 'en-US' params = @params.dup @@ -113,20 +112,34 @@ end def self.ensure_schema(conn) conn.exec(<<~HEREDOC CREATE TABLE IF NOT EXISTS contentful_raw ( - id char(22) PRIMARY KEY, + id varchar PRIMARY KEY, data jsonb ); CREATE INDEX IF NOT EXISTS contentful_raw_value_type ON contentful_raw ((data->'sys'->>'type')); CREATE INDEX IF NOT EXISTS contentful_raw_value_content_type ON contentful_raw ((data->'sys'->'contentType'->'sys'->>'id')); + + DROP FUNCTION IF EXISTS "upsert_entry"; + CREATE FUNCTION "upsert_entry"(_id varchar, _data jsonb) RETURNS jsonb AS $$ + DECLARE + prev jsonb; + BEGIN + SELECT data FROM contentful_raw WHERE id = _id INTO prev; + INSERT INTO contentful_raw (id, data) values (_id, _data) + ON CONFLICT (id) DO + UPDATE + SET data = _data; + RETURN prev; + END; + $$ LANGUAGE 'plpgsql'; HEREDOC ) - conn.prepare('index_entry', 'INSERT INTO contentful_raw (id, data) values ($1, $2) ' \ - 'ON CONFLICT (id) DO UPDATE SET data = $2') + conn.prepare('upsert_entry', 'SELECT * FROM upsert_entry($1,$2)') conn.prepare('select_entry', 'SELECT * FROM contentful_raw WHERE id = $1') conn.prepare('select_ids', 'SELECT id FROM contentful_raw') + conn.prepare('delete_by_id', 'DELETE FROM contentful_raw WHERE id = $1 RETURNING *') end end end