Module: MiniSql::Serializer

Defined in:
lib/mini_sql/serializer.rb

Constant Summary collapse

MAX_CACHE_SIZE =
500

Class Method Summary collapse

Class Method Details

.cached_materializer(fields, decorator_module = nil) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/mini_sql/serializer.rb', line 34

def self.cached_materializer(fields, decorator_module = nil)
  @cache ||= {}
  key = fields
  m = @cache.delete(key)
  if m
    @cache[key] = m
  else
    m = @cache[key] = materializer(fields)
    @cache.shift if @cache.length > MAX_CACHE_SIZE
  end

  if decorator_module && decorator_module.length > 0
    decorator = Kernel.const_get(decorator_module)
    m = m.decorated(decorator)
  end

  m
end

.from_json(json) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
# File 'lib/mini_sql/serializer.rb', line 22

def self.from_json(json)
  wrapper = JSON.parse(json)
  if !wrapper["data"]
    []
  else
    materializer = cached_materializer(wrapper['fields'], wrapper['decorator'])
    wrapper["data"].map do |row|
      materializer.materialize(row)
    end
  end
end

.materializer(fields) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/mini_sql/serializer.rb', line 53

def self.materializer(fields)
  Class.new do
    extend MiniSql::Decoratable
    include MiniSql::Result

    attr_accessor(*fields)

    instance_eval <<~RUBY
      def materialize(values)
        r = self.new
        #{col = -1; fields.map { |f| "r.#{f} = values[#{col += 1}]" }.join("; ")}
        r
      end
    RUBY
  end
end

.to_json(result) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/mini_sql/serializer.rb', line 7

def self.to_json(result)
  wrapper =
    if result.length == 0
      {}
    else
      {
        "decorator" => result[0].class.decorator.to_s,
        "fields" => result[0].to_h.keys,
        "data" => result.map(&:values),
      }
    end

  JSON.generate(wrapper)
end