This file is indexed.

/usr/lib/ruby/vendor_ruby/sequel/extensions/pg_static_cache_updater.rb is in ruby-sequel 4.15.0-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# The pg_static_cache_updater extension is designed to
# automatically update the caches in the models using the
# static_cache plugin when changes to the underlying tables
# are detected.
#
# Before using the extension in production, you have to add
# triggers to the tables for the classes where you want the
# caches updated automatically.  You would generally do this
# during a migration:
#
#   Sequel.migration do
#     up do
#       extension :pg_static_cache_updater
#       create_static_cache_update_function
#       create_static_cache_update_trigger(:table_1)
#       create_static_cache_update_trigger(:table_2)
#     end
#     down do
#       extension :pg_static_cache_updater
#       drop_trigger(:table_2, default_static_cache_update_name)
#       drop_trigger(:table_1, default_static_cache_update_name)
#       drop_function(default_static_cache_update_name)
#     end
#   end
#
# After the triggers have been added, in your application process,
# after setting up your models, you need to listen for changes to
# the underlying tables:
#
#   class Model1 < Sequel::Model(:table_1)
#     plugin :static_cache
#   end
#   class Model2 < Sequel::Model(:table_2)
#     plugin :static_cache
#   end
#
#   DB.extension :pg_static_cache_updater
#   DB.listen_for_static_cache_updates([Model1, Model2])
#
# When an INSERT/UPDATE/DELETE happens on the underlying table,
# the trigger will send a notification with the table's OID.
# The application(s) listening on that channel will receive
# the notification, check the oid to see if it matches one
# for the model tables it is interested in, and tell that model
# to reload the cache if there is a match.
#
# Note that listen_for_static_cache_updates spawns a new thread
# which will reserve its own database connection.  This thread
# runs until the application process is shutdown.
#
# Also note that PostgreSQL does not send notifications to
# channels until after the transaction including the changes
# is committed.  Also, because a separate thread is used to
# listen for notifications, there may be a slight delay between
# when the transaction is committed and when the cache is
# reloaded.
#
# Requirements:
# * PostgreSQL 9.0+
# * Listening Database object must be using the postgres adapter
#   with the pg driver (the model classes do not have to
#   use the same Database).
# * Must be using a thread-safe connection pool (the default).

#
module Sequel
  module Postgres
    module StaticCacheUpdater
      # Add the static cache update function to the PostgreSQL database.
      # This must be added before any triggers using this function are
      # added.
      #
      # Options:
      # :channel_name :: Override the channel name to use.
      # :function_name :: Override the function name to use.
      def create_static_cache_update_function(opts=OPTS)
        create_function(opts[:function_name]||default_static_cache_update_name, <<SQL, :returns=>:trigger, :language=>:plpgsql)
BEGIN
  PERFORM pg_notify(#{literal((opts[:channel_name]||default_static_cache_update_name).to_s)}, TG_RELID::text);
  RETURN NULL;
END
SQL
      end

      # Add a trigger to the given table that calls the function
      # which will notify about table changes.
      #
      # Options:
      # :function_name :: Override the function name to use.
      # :trigger_name :: Override the trigger name to use.
      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

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

      # Listen on the notification channel for changes to any of tables for
      # the models given in a new thread. If notified about a change to one of the tables,
      # reload the cache for the related model.  Options given are also
      # passed to Database#listen.
      #
      # Note that this implementation does not currently support multiple
      # models that use the same underlying table.
      #
      # Options:
      # :channel_name :: Override the channel name to use.
      # :before_thread_exit :: An object that responds to +call+ that is called before the 
      #                        the created thread exits.
      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, true)
          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.send(:load_cache)
              end
            end
          ensure
            opts[:before_thread_exit].call if opts[:before_thread_exit]
          end
        end
      end
    end
  end

  Database.register_extension(:pg_static_cache_updater, Postgres::StaticCacheUpdater)
end