This file is indexed.

/usr/lib/ruby/vendor_ruby/sequel/plugins/json_serializer.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
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
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
module Sequel
  tsk_require 'json'

  module Plugins
    # The json_serializer plugin handles serializing entire Sequel::Model
    # objects to JSON, as well as support for deserializing JSON directly
    # into Sequel::Model objects.  It requires the json library, and can
    # work with either the pure ruby version or the C extension.
    #
    # Basic Example:
    #
    #   album = Album[1]
    #   album.to_json
    #   # => '{"json_class"=>"Album","id"=>1,"name"=>"RF","artist_id"=>2}'
    #
    # In addition, you can provide options to control the JSON output:
    #
    #   album.to_json(:only=>:name)
    #   album.to_json(:except=>[:id, :artist_id])
    #   # => '{"json_class"="Album","name"=>"RF"}'
    #
    #   album.to_json(:include=>:artist)
    #   # => '{"json_class":"Album","id":1,"name":"RF","artist_id":2,
    #          "artist":{"json_class":"Artist","id":2,"name":"YJM"}}'
    # 
    # You can use a hash value with <tt>:include</tt> to pass options
    # to associations:
    #
    #   album.to_json(:include=>{:artist=>{:only=>:name}})
    #   # => '{"json_class":"Album","id":1,"name":"RF","artist_id":2,
    #          "artist":{"json_class":"Artist","name":"YJM"}}'
    #
    # You can specify the <tt>:root</tt> option to nest the JSON under the
    # name of the model:
    #
    #   album.to_json(:root => true)
    #   # => '{"album":{"id":1,"name":"RF","artist_id":2}}'
    #
    # In addition to creating JSON, this plugin also enables Sequel::Model
    # objects to be automatically created when JSON is parsed:
    #
    #   json = album.to_json
    #   album = JSON.parse(json)
    #
    # In addition, you can update existing model objects directly from JSON
    # using +from_json+:
    #
    #   album.from_json(json)
    #
    # This works by parsing the JSON (which should return a hash), and then
    # calling +set+ with the returned hash.
    #
    # Additionally, +to_json+ also exists as a class and dataset method, both
    # of which return all objects in the dataset:
    #
    #   Album.to_json
    #   Album.filter(:artist_id=>1).to_json(:include=>:tags)
    #
    # Usage:
    #
    #   # Add JSON output capability to all model subclass instances (called before loading subclasses)
    #   Sequel::Model.plugin :json_serializer
    #
    #   # Add JSON output capability to Album class instances
    #   Album.plugin :json_serializer
    module JsonSerializer
      # Set up the column readers to do deserialization and the column writers
      # to save the value in deserialized_values.
      def self.configure(model, opts={})
        model.instance_eval do
          @json_serializer_opts = (@json_serializer_opts || {}).merge(opts)
        end
      end
      
      # Helper class used for making sure that cascading options
      # for model associations works correctly.  Cascaded options
      # work by creating instances of this class, which take a
      # literal JSON string and have +to_json+ return it.
      class Literal
        # Store the literal JSON to use
        def initialize(json)
          @json = json
        end
        
        # Return the literal JSON to use
        def to_json(*a)
          @json
        end
      end

      module ClassMethods
        # The default opts to use when serializing model objects to JSON.
        attr_reader :json_serializer_opts

        # Create a new model object from the hash provided by parsing
        # JSON.  Handles column values (stored in +values+), associations
        # (stored in +associations+), and other values (by calling a
        # setter method).  If an entry in the hash is not a column or
        # an association, and no setter method exists, raises an Error.
        def json_create(hash)
          obj = new
          cols = columns.map{|x| x.to_s}
          assocs = associations.map{|x| x.to_s}
          meths = obj.send(:setter_methods, nil, nil)
          hash.delete(JSON.create_id)
          hash.each do |k, v|
            if assocs.include?(k)
              obj.associations[k.to_sym] = v
            elsif meths.include?("#{k}=")
              obj.send("#{k}=", v)
            elsif cols.include?(k)
              obj.values[k.to_sym] = v
            else
              raise Error, "Entry in JSON hash not an association or column and no setter method exists: #{k}"
            end
          end
          obj
        end

        # Call the dataset +to_json+ method.
        def to_json(*a)
          dataset.to_json(*a)
        end
        
        # Copy the current model object's default json options into the subclass.
        def inherited(subclass)
          super
          opts = {}
          json_serializer_opts.each{|k, v| opts[k] = (v.is_a?(Array) || v.is_a?(Hash)) ? v.dup : v}
          subclass.instance_variable_set(:@json_serializer_opts, opts)
        end
      end

      module InstanceMethods
        # Parse the provided JSON, which should return a hash,
        # and call +set+ with that hash.
        def from_json(json)
          set(JSON.parse(json))
        end

        # Return a string in JSON format.  Accepts the following
        # options:
        #
        # :except :: Symbol or Array of Symbols of columns not
        #            to include in the JSON output.
        # :include :: Symbol, Array of Symbols, or a Hash with
        #             Symbol keys and Hash values specifying
        #             associations or other non-column attributes
        #             to include in the JSON output.  Using a nested
        #             hash, you can pass options to associations
        #             to affect the JSON used for associated objects.
        # :naked :: Not to add the JSON.create_id (json_class) key to the JSON
        #           output hash, so when the JSON is parsed, it
        #           will yield a hash instead of a model object.
        # :only :: Symbol or Array of Symbols of columns to only
        #          include in the JSON output, ignoring all other
        #          columns.
        # :root :: Qualify the JSON with the name of the object.
        #          Implies :naked since the object name is explicit.
        def to_json(*a)
          if opts = a.first.is_a?(Hash)
            opts = model.json_serializer_opts.merge(a.first)
            a = []
          else
            opts = model.json_serializer_opts
          end
          vals = values
          cols = if only = opts[:only]
            Array(only)
          else
            vals.keys - Array(opts[:except])
          end
          h = (JSON.create_id && !opts[:naked] && !opts[:root]) ? {JSON.create_id=>model.name} : {}
          cols.each{|c| h[c.to_s] = send(c)}
          if inc = opts[:include]
            if inc.is_a?(Hash)
              inc.each do |k, v|
                v = v.empty? ? [] : [v]
                h[k.to_s] = case objs = send(k)
                when Array
                  objs.map{|obj| Literal.new(obj.to_json(*v))}
                else
                  Literal.new(objs.to_json(*v))
                end
              end
            else
              Array(inc).each{|c| h[c.to_s] = send(c)}
            end
          end
          h = {model.send(:underscore, model.to_s) => h} if opts[:root]
          h.to_json(*a)
        end
      end

      module DatasetMethods
        # Return a JSON string representing an array of all objects in
        # this dataset.  Takes the same options as the the instance
        # method, and passes them to every instance.
        def to_json(*a)
          if opts = a.first.is_a?(Hash)
            opts = model.json_serializer_opts.merge(a.first)
            a = []
          else
            opts = model.json_serializer_opts
          end
          res = row_proc ? all.map{|obj| Literal.new(obj.to_json(opts))} : all
          opts[:root] ? {model.send(:pluralize, model.send(:underscore, model.to_s)) => res}.to_json(*a) : res.to_json(*a)
        end
      end
    end
  end
end