class Flounder::Connection

Constants

Column

———————————————— official Connection iface

Attributes

pg[R]
visitor[R]

Public Class Methods

new(pg_conn_opts) click to toggle source
# File lib/flounder/connection.rb, line 7
def initialize pg_conn_opts
  search_path = pg_conn_opts.delete(:search_path)

  @pg = PG.connect(pg_conn_opts)
  @visitor = Arel::Visitors::PostgreSQL.new(self)

  if search_path
    exec('set search_path=' + search_path)
  end
end

Public Instance Methods

columns(name, message = nil) click to toggle source
# File lib/flounder/connection.rb, line 59
def columns name, message = nil
  fail NotImplementedError
end
columns_hash(table_name) click to toggle source
# File lib/flounder/connection.rb, line 27
def columns_hash table_name
  hash = {}
  pg.exec(%Q(select * from #{quote_table_name(table_name)} limit 0)) do |result|

    # TBD This is a duplicate from the code in Query.
    result.nfields.times do |idx|
      name = result.fname(idx)
      type_oid = result.ftype(idx)
      mod  = result.fmod(idx)
      typesym = type_oid_to_sym(self, type_oid)

      unless typesym
        type_string = type_name(type_oid, mod)
        fail "No map for oid #{type_oid} found, type(#{type_string})."
      end

      hash[name] = Column.new(name, typesym)
    end
  end

  hash
end
exec(*args, &block) click to toggle source
# File lib/flounder/connection.rb, line 21
def exec *args, &block
  pg.exec *args, &block
end
objectify_result_row(ent, result, row_idx) { |name| ... } click to toggle source

Turns a PG result row into a hash-like object. There are some transformation rules that govern this conversion:

  • All data types are converted to their closest Ruby equivalent (type conversion)

  • Fields from the main entity (the entity that started the select) are returned on the top level of the hash.

  • Fields from joined entities are returned in a subhash stored under the singular name of the joined entity.

Example:

row = users.join(posts).on(:id => :user_id).first 
row[:id]            # refers to users.id, also as row.id
row[:post][:id]     # refers to posts.id, also as row.post.id

row.keys            # hash keys of the row, not equal to row[:keys]!

@param ent [Entity] entity that the query originated from @param result [PG::Result] @param row_idx [Fixnum] row we’re interested in @return [Hashie::Mash] result row as hash-like object

# File lib/flounder/connection.rb, line 106
def objectify_result_row ent, result, row_idx
  obj = Hashie::Mash.new
  
  each_field(ent, result, row_idx) do 
    |entity, name, value, type_oid, binary, idx|

    # NOTE entity resolution is done both through aliasing and through
    # postgres column reporting. The above entity variable carries what
    # postgres reports to us; the block below resolves aliased entity
    # names:
    processed_entity, processed_name = yield name if block_given?
    entity = processed_entity if processed_entity
    name   = processed_name if processed_name

    typecast_value = typecast(type_oid, value)

    # JOIN tables are available from the result using their singular
    # names.
    if entity
      obj[entity.singular] ||= {}

      sub_obj = obj[entity.singular]
      sub_obj[name] = typecast_value
    end

    # The main entity and custom fields (AS something) are available on the
    # top-level of the result.
    if !entity || entity == ent
      raise DuplicateField, "#{name.inspect} already defined in result set, aliasing occurs." \
        if obj.has_key? name

      obj[name] = typecast_value
    end
  end

  return obj
end
primary_key(name) click to toggle source
# File lib/flounder/connection.rb, line 50
def primary_key name
  fail NotImplementedError
end
quote(thing, column = nil) click to toggle source
# File lib/flounder/connection.rb, line 75
def quote thing, column = nil
  # require 'pp '
  # p [:quote, thing, column]
  # pp caller.first(10)
  pg.escape_literal(thing.to_s)
end
quote_column_name(name) click to toggle source
# File lib/flounder/connection.rb, line 67
def quote_column_name name
  pg.quote_ident name.to_s
end
quote_table_name(name) click to toggle source
# File lib/flounder/connection.rb, line 63
def quote_table_name name
  pg.quote_ident name.to_s
end
schema_cache() click to toggle source
# File lib/flounder/connection.rb, line 71
 def schema_cache
  self
end
table_exists?(table_name) click to toggle source
# File lib/flounder/connection.rb, line 54
def table_exists? table_name
  # TBD Centralize these direct SQL statements in some class
  ! pg.exec(%Q(select count(*) from pg_class where relname = #{quote(table_name)})).getvalue(0,0).nil?
end
transaction(&block) click to toggle source
# File lib/flounder/connection.rb, line 18
def transaction &block
  pg.transaction(&block)
end