class MiniSql::Postgres::DeserializerCache

Constants

DEFAULT_MAX_SIZE

Public Class Methods

new(max_size = nil) click to toggle source
# File lib/mini_sql/postgres/deserializer_cache.rb, line 9
def initialize(max_size = nil)
  @cache = {}
  @max_size = max_size || DEFAULT_MAX_SIZE
end

Public Instance Methods

materialize(result, decorator_module = nil) click to toggle source
# File lib/mini_sql/postgres/deserializer_cache.rb, line 28
def materialize(result, decorator_module = nil)
  return [] if result.ntuples == 0

  key = result.fields.join(',')

  # trivial fast LRU implementation
  materializer = @cache.delete(key)
  if materializer
    @cache[key] = materializer
  else
    materializer = @cache[key] = new_row_materializer(result)
    @cache.shift if @cache.length > @max_size
  end

  if decorator_module
    materializer = materializer.decorated(decorator_module)
  end

  i = 0
  r = []
  # quicker loop
  while i < result.ntuples
    r << materializer.materialize(result, i)
    i += 1
  end
  r
end
materializer(result) click to toggle source
# File lib/mini_sql/postgres/deserializer_cache.rb, line 14
def materializer(result)
  key = result.fields.join(',')

  materializer = @cache.delete(key)
  if materializer
    @cache[key] = materializer
  else
    materializer = @cache[key] = new_row_materializer(result)
    @cache.shift if @cache.length > @max_size
  end

  materializer
end

Private Instance Methods

new_row_materializer(result) click to toggle source
# File lib/mini_sql/postgres/deserializer_cache.rb, line 58
      def new_row_materializer(result)
        fields = result.fields

        i = 0
        while i < fields.length
          # special handling for unamed column
          if fields[i] == "?column?"
            fields[i] = "column#{i}"
          end
          i += 1
        end

        Class.new do
          extend MiniSql::Decoratable
          include MiniSql::Result

          attr_accessor(*fields)

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