This file is indexed.

/usr/lib/ruby/vendor_ruby/sequel/plugins/list.rb is in ruby-sequel 3.36.1-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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
module Sequel
  module Plugins
    # The list plugin allows for model instances to be part of an ordered list,
    # based on a position field in the database.  It can either consider all
    # rows in the table as being from the same list, or you can specify scopes
    # so that multiple lists can be kept in the same table.
    # 
    # Basic Example:
    #
    #   class Item < Sequel::Model(:items)
    #     plugin :list # will use :position field for position
    #     plugin :list, :field=>:pos # will use :pos field for position
    #   end
    #   
    #   item = Item[1]
    # 
    #   # Get the next or previous item in the list
    # 
    #   item.next
    #   item.prev
    # 
    #   # Modify the item's position, which may require modifying other items in
    #   # the same list
    # 
    #   item.move_to(3)
    #   item.move_to_top
    #   item.move_to_bottom
    #   item.move_up
    #   item.move_down
    # 
    # You can provide a <tt>:scope</tt> option to scope the list.  This option
    # can be a symbol or array of symbols specifying column name(s), or a proc
    # that accepts a model instance and returns a dataset representing the list
    # the object is in.
    # 
    # For example, if each item has a +user_id+ field, and you want every user
    # to have their own list:
    #
    #   Item.plugin :list, :scope=>:user_id
    # 
    # Note that using this plugin modifies the order of the model's dataset to
    # sort by the position and scope fields.  Also note that this plugin is subject to
    # race conditions, and is not safe when concurrent modifications are made
    # to the same list.
    #
    # Additionally, note that unlike ruby arrays, the list plugin assumes that the
    # first entry in the list has position 1, not position 0.
    #
    # Copyright (c) 2007-2010 Sharon Rosner, Wayne E. Seguin, Aman Gupta, Adrian Madrid, Jeremy Evans
    module List
      # Set the +position_field+ and +scope_proc+ attributes for the model,
      # using the <tt>:field</tt> and <tt>:scope</tt> options, respectively.
      # The <tt>:scope</tt> option can be a symbol, array of symbols, or a proc that
      # accepts a model instance and returns a dataset representing the list.
      # Also, modify the model dataset's order to order by the position and scope fields.
      def self.configure(model, opts = {})
        model.position_field = opts[:field] || :position
        model.dataset = model.dataset.order_prepend(model.position_field)
        
        model.scope_proc = case scope = opts[:scope]
        when Symbol
          model.dataset = model.dataset.order_prepend(scope)
          proc{|obj| obj.model.filter(scope=>obj.send(scope))}
        when Array
          model.dataset = model.dataset.order_prepend(*scope)
          proc{|obj| obj.model.filter(scope.map{|s| [s, obj.send(s)]})}
        else
          scope
        end
      end

      module ClassMethods
        # The column name holding the position in the list, as a symbol.
        attr_accessor :position_field

        # A proc that scopes the dataset, so that there can be multiple positions 
        # in the list, but the positions are unique with the scoped dataset. This
        # proc should accept an instance and return a dataset representing the list.
        attr_accessor :scope_proc

        # Copy the +position_field+ and +scope_proc+ to the subclass.
        def inherited(subclass)
          super
          subclass.position_field = position_field
          subclass.scope_proc = scope_proc
        end
      end

      module InstanceMethods
        # The model object at the given position in the list containing this instance.
        def at_position(p)
          list_dataset.first(position_field => p)
        end

        # Set the value of the position_field to the maximum value plus 1 unless the
        # position field already has a value.
        def before_create
          unless send(position_field)
            send("#{position_field}=", list_dataset.max(position_field).to_i+1)
          end
        end

        # Find the last position in the list containing this instance.
        def last_position
          list_dataset.max(position_field).to_i
        end

        # A dataset that represents the list containing this instance.
        def list_dataset
          model.scope_proc ? model.scope_proc.call(self) : model.dataset
        end

        # Move this instance down the given number of places in the list,
        # or 1 place if no argument is specified.
        def move_down(n = 1)
          move_to(position_value + n)
        end

        # Move this instance to the given place in the list.  Raises an
        # exception if target is less than 1 or greater than the last position in the list.
        def move_to(target, lp = nil)
          current = position_value
          if target != current
            checked_transaction do
              ds = list_dataset
              op, ds = if target < current
                raise(Sequel::Error, "Moving too far up (target = #{target})") if target < 1
                [:+, ds.filter(position_field=>target...current)]
              else
                lp ||= last_position
                raise(Sequel::Error, "Moving too far down (target = #{target}, last_position = #{lp})") if target > lp
                [:-, ds.filter(position_field=>(current + 1)..target)]
              end
              ds.update(position_field => Sequel::SQL::NumericExpression.new(op, position_field, 1))
              update(position_field => target)
            end
          end
          self
        end

        # Move this instance to the bottom (last position) of the list.
        def move_to_bottom
          lp = last_position 
          move_to(lp, lp)
        end

        # Move this instance to the top (first position, position 1) of the list.
        def move_to_top
          move_to(1)
        end

        # Move this instance the given number of places up in the list, or 1 place
        # if no argument is specified.
        def move_up(n = 1)
          move_to(position_value - n) 
        end

        # The model instance the given number of places below this model instance
        # in the list, or 1 place below if no argument is given.
        def next(n = 1)
          n == 0 ? self : at_position(position_value + n)
        end

        # The value of the model's position field for this instance.
        def position_value
          send(position_field)
        end

        # The model instance the given number of places below this model instance
        # in the list, or 1 place below if no argument is given.
        def prev(n = 1)
          self.next(n * -1)
        end

        private

        # The model's position field, an instance method for ease of use.
        def position_field
          model.position_field
        end
      end
    end
  end
end