require 'pg' require 'sequel' require_relative 'connect' def migrate db = DB db.create_table? :threads do primary_key :id String :title String :creator, index: true Integer :remote_id, index: true, unique: true String :last_post_creator DateTime :last_post_created_at DateTime :created_at, index: true end db.create_table? :posts do primary_key :id String :body String :creator, index: true Integer :remote_id, index: true, unique: true foreign_key :thread_id, :threads DateTime :created_at, index: true column :tsv, 'tsvector' end db.run('CREATE INDEX IF NOT EXISTS tsv_idx ON posts USING gin(tsv);') begin db.create_function(:update_last_post, <<-SQL, language: :plpgsql, returns: :trigger) BEGIN UPDATE threads SET last_post_created_at = NEW.created_at, last_post_creator = NEW.creator WHERE threads.id = NEW.thread_id; RETURN NEW; END SQL rescue Sequel::DatabaseError => e raise e unless e.wrapped_exception.is_a?(PG::DuplicateFunction) end begin db.create_function(:set_posts_tsv, <<-SQL, language: :plpgsql, returns: :trigger) BEGIN NEW.tsv = to_tsvector(new.body); RETURN NEW; END SQL rescue Sequel::DatabaseError => e raise e unless e.wrapped_exception.is_a?(PG::DuplicateFunction) end begin db.run(<<-SQL) CREATE TRIGGER update_last_post AFTER INSERT ON posts FOR EACH ROW EXECUTE PROCEDURE update_last_post(); SQL rescue Sequel::DatabaseError => e raise e unless e.wrapped_exception.is_a?(PG::DuplicateObject) end begin db.run(<<-SQL) CREATE TRIGGER set_posts_tsv BEFORE INSERT OR UPDATE ON posts FOR EACH ROW EXECUTE PROCEDURE set_posts_tsv(); SQL rescue Sequel::DatabaseError => e raise e unless e.wrapped_exception.is_a?(PG::DuplicateObject) end end