module Sequel::Postgres::StaticCacheUpdater

def create_static_cache_update_function(opts=OPTS)

:function_name :: Override the function name to use.
:channel_name :: Override the channel name to use.
Options:

added.
This must be added before any triggers using this function are
Add the static cache update function to the PostgreSQL database.
def create_static_cache_update_function(opts=OPTS)
  create_function(opts[:function_name]||default_static_cache_update_name, <<SQL, :returns=>:trigger, :language=>:plpgsql)
ORM pg_notify(#{literal((opts[:channel_name]||default_static_cache_update_name).to_s)}, TG_RELID::text);
RN NULL;
end

def create_static_cache_update_trigger(table, opts=OPTS)

:trigger_name :: Override the trigger name to use.
:function_name :: Override the function name to use.
Options:

which will notify about table changes.
Add a trigger to the given table that calls the function
def create_static_cache_update_trigger(table, opts=OPTS)
  create_trigger(table, opts[:trigger_name]||default_static_cache_update_name, opts[:function_name]||default_static_cache_update_name, :after=>true)
end

def default_static_cache_update_name

for this extension.
The default name for the function, trigger, and notification channel
def default_static_cache_update_name
  :sequel_static_cache_update
end

def listen_for_static_cache_updates(models, opts=OPTS)

the created thread exits.
:before_thread_exit :: An object that responds to +call+ that is called before the
:channel_name :: Override the channel name to use.
Options:

models that use the same underlying table.
Note that this implementation does not currently support multiple

passed to Database#listen.
reload the cache for the related model. Options given are also
the models given in a new thread. If notified about a change to one of the tables,
Listen on the notification channel for changes to any of tables for
def listen_for_static_cache_updates(models, opts=OPTS)
  raise Error, "this database object does not respond to listen, use the postgres adapter with the pg driver" unless respond_to?(:listen)
  models = [models] unless models.is_a?(Array)
  raise Error, "array of models to listen for changes cannot be empty" if models.empty?
  oid_map = {}
  models.each do |model|
    raise Error, "#{model.inspect} does not use the static_cache plugin" unless model.respond_to?(:load_cache)
    oid_map[get(regclass_oid(model.dataset.first_source_table))] = model
  end
  Thread.new do
    begin
      listen(opts[:channel_name]||default_static_cache_update_name, {:loop=>true}.merge!(opts)) do |_, _, oid|
        if model = oid_map[oid.to_i]
          model.load_cache
        end
      end
    ensure
      opts[:before_thread_exit].call if opts[:before_thread_exit]
    end
  end
end