This file is indexed.

/usr/lib/ruby/vendor_ruby/sequel/plugins/touch.rb is in ruby-sequel 3.33.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
module Sequel
  module Plugins
    # The touch plugin adds a touch method to model instances, which saves
    # the object with a modified timestamp.  By default, it uses the
    # :updated_at column, but you can set which column to use.
    # It also supports touching of associations, so that when the current
    # model object is updated or destroyed, the associated rows in the
    # database can have their modified timestamp updated to the current
    # timestamp.
    #
    # Since the instance touch method works on model instances,
    # it uses Time.now for the timestamp.  The association touching works
    # on datasets, so it updates all related rows in a single query, using
    # the SQL standard CURRENT_TIMESTAMP.  Both of these can be overridden
    # easily if necessary.
    # 
    # Usage:
    #
    #   # Allow touching of all model instances (called before loading subclasses)
    #   Sequel::Model.plugin :touch
    #
    #   # Allow touching of Album instances, with a custom column
    #   Album.plugin :touch, :column=>:updated_on
    #
    #   # Allow touching of Artist instances, updating the albums and tags
    #   # associations when touching, touching the +updated_on+ column for
    #   # albums and the +updated_at+ column for tags
    #   Artist.plugin :touch, :associations=>[{:albums=>:updated_on}, :tags]
    module Touch
      # The default column to update when touching
      TOUCH_COLUMN_DEFAULT = :updated_at

      # Set the touch_column and touched_associations variables for the model.
      # Options:
      # * :associations - The associations to touch when a model instance is
      #   updated or destroyed.  Can be a symbol for a single association,
      #   a hash with association keys and column values, or an array of
      #   symbols and/or hashes.  If a symbol is used, the column used
      #   when updating the associated objects is the model's touch_column.
      #   If a hash is used, the value is used as the column to update.
      # * :column - The column to modify when touching a model instance.
      def self.configure(model, opts={})
        model.touch_column = opts[:column] || TOUCH_COLUMN_DEFAULT if opts[:column] || !model.touch_column
        model.instance_variable_set(:@touched_associations, {})
        model.touch_associations(opts[:associations]) if opts[:associations]
      end

      module ClassMethods
        # The column to modify when touching a model instance, as a symbol.  Also used
        # as the default column when touching associations, if
        # the associations don't specify a column.
        attr_accessor :touch_column

        # A hash specifying the associations to touch when instances are
        # updated or destroyed. Keys are association dataset method name symbols and values
        # are column name symbols.
        attr_reader :touched_associations

        # Set the touch_column for the subclass to be the same as the current class.
        # Also, create a copy of the touched_associations in the subclass.
        def inherited(subclass)
          super
          subclass.touch_column = touch_column
          subclass.instance_variable_set(:@touched_associations, touched_associations.dup)
        end

        # Add additional associations to be touched.  See the :association option
        # of the Sequel::Plugin::Touch.configure method for the format of the associations
        # arguments.
        def touch_associations(*associations)
          associations.flatten.each do |a|
            a = {a=>touch_column} if a.is_a?(Symbol)
            a.each do |k,v|
              raise(Error, "invalid association: #{k}") unless r = association_reflection(k)
              touched_associations[r.dataset_method] = v
            end
          end
        end
      end

      module InstanceMethods
        # Touch all of the model's touched_associations when destroying the object.
        def after_destroy
          super
          touch_associations
        end

        # Touch all of the model's touched_associations when updating the object.
        def after_update
          super
          touch_associations
        end

        # Touch the model object.  If a column is not given, use the model's touch_column
        # as the column.  If the column to use is not one of the model's columns, just
        # save the changes to the object instead of attempting to a value that doesn't
        # exist.
        def touch(column=nil)
          if column
            set(column=>touch_instance_value)
          else
            column = model.touch_column
            set(column=>touch_instance_value) if columns.include?(column)
          end
          save_changes
        end

        private

        # The value to use when modifying the touch column for the association datasets.  Uses
        # the SQL standard CURRENT_TIMESTAMP.
        def touch_association_value
          Sequel::CURRENT_TIMESTAMP
        end

        # Directly update the database using the association dataset for each association.
        def touch_associations
          model.touched_associations.each do |meth, column|
            send(meth).update(column=>touch_association_value)
          end
        end

        # The value to use when modifying the touch column for the model instance.
        # Uses Time.now to work well with typecasting.
        def touch_instance_value
          Time.now
        end
      end
    end
  end
end