module ArJdbc::PostgreSQL::Column

@private (AR < 4.2 version) documented above

Attributes

array[RW]
array?[RW]

Public Class Methods

included(base) click to toggle source
# File lib/arjdbc/postgresql/column.rb, line 98
def self.included(base)
  # NOTE: assumes a standalone PostgreSQLColumn class
  base_meta = class << base; self end
  base_meta.send :attr_accessor, :money_precision

  # Loads pg_array_parser if available. String parsing can be
  # performed quicker by a native extension, which will not create
  # a large amount of Ruby objects that will need to be garbage
  # collected. pg_array_parser has a C and Java extension
  begin
    require 'pg_array_parser'
    base_meta.send :include, PgArrayParser
  rescue LoadError
    if AR42
      require 'active_record/connection_adapters/postgresql/array_parser'
    else
      require 'arjdbc/postgresql/base/array_parser'
    end
    base_meta.send :include, ActiveRecord::ConnectionAdapters::PostgreSQL::ArrayParser
  end if AR40

  base_meta.send :include, Cast

  base.send :include, ColumnHelpers
end
new(name, default, cast_type, sql_type = nil, null = true, default_function = nil, oid = nil, adapter = nil) click to toggle source
Calls superclass method
# File lib/arjdbc/postgresql/column.rb, line 57
def initialize(name, default, cast_type, sql_type = nil, null = true, default_function = nil,
  oid = nil, adapter = nil) # added arguments
  if sql_type.to_s[-2, 2] == '[]'
    @array = true
    super(name, default, cast_type, sql_type[0..-3], null)
  else
    @array = false
    super(name, default, cast_type, sql_type, null)
  end

  @oid = oid # used on Java side - expects @oid on Column instances
  #@adapter = adapter

  @default_function = default_function
end

Public Instance Methods

accessor() click to toggle source

@private

# File lib/arjdbc/postgresql/column.rb, line 135
def accessor; oid_type.accessor end
default_value(default) click to toggle source

Extracts the value from a PostgreSQL column default definition.

@override JdbcColumn#default_value NOTE: based on `self.extract_value_from_default(default)` code

# File lib/arjdbc/postgresql/column.rb, line 148
def default_value(default)
  # This is a performance optimization for Ruby 1.9.2 in development.
  # If the value is nil, we return nil straight away without checking
  # the regular expressions. If we check each regular expression,
  # Regexp#=== will call NilClass#to_str, which will trigger
  # method_missing (defined by whiny nil in ActiveSupport) which
  # makes this method very very slow.
  return default unless default

  case default
    when /\A'(.*)'::(num|date|tstz|ts|int4|int8)range\z/m
      $1
    # Numeric types
    when /\A\(?(-?\d+(\.\d*)?\)?(::bigint)?)\z/
      $1
    # Character types
    when /\A\(?'(.*)'::.*\b(?:character varying|bpchar|text)\z/m
      $1
    # Binary data types
    when /\A'(.*)'::bytea\z/m
      $1
    # Date/time types
    when /\A'(.+)'::(?:time(?:stamp)? with(?:out)? time zone|date)\z/
      $1
    when /\A'(.*)'::interval\z/
      $1
    # Boolean type
    when 'true'
      true
    when 'false'
      false
    # Geometric types
    when /\A'(.*)'::(?:point|line|lseg|box|"?path"?|polygon|circle)\z/
      $1
    # Network address types
    when /\A'(.*)'::(?:cidr|inet|macaddr)\z/
      $1
    # Bit string types
    when /\AB'(.*)'::"?bit(?: varying)?"?\z/
      $1
    # XML type
    when /\A'(.*)'::xml\z/m
      $1
    # Arrays
    when /\A'(.*)'::"?\D+"?\[\]\z/
      $1
    when /\AARRAY\[(.*)\](::\D+)?\z/
      "{#{$1.gsub(/'(.*?)'::[a-z]+(,)?\s?/, '\1\2')}}"
    # Hstore
    when /\A'(.*)'::hstore\z/
      $1
    # JSON
    when /\A'(.*)'::json\z/
      $1
    # JSONB
    when /\A'(.*)'::jsonb\z/
      $1
    # Object identifier types
    when /\A-?\d+\z/
      $1
    else
      # Anything else is blank, some user type, or some function
      # and we can't know the value of that, so return nil.
      nil
  end
end
number?() click to toggle source
Calls superclass method
# File lib/arjdbc/postgresql/column.rb, line 141
def number?; !array && super end
oid_type() click to toggle source

@private

# File lib/arjdbc/postgresql/column.rb, line 127
def oid_type
  @oid_type ||= begin
    raise "oid not defined" unless oid = (@oid ||= nil)
    @adapter.get_oid_type(oid.to_i, @fmod.to_i, name)
  end
end
text?() click to toggle source
Calls superclass method
# File lib/arjdbc/postgresql/column.rb, line 142
def text?; !array && super end
type_cast(value) click to toggle source

Casts value (which is a String) to an appropriate instance. @private

Calls superclass method
# File lib/arjdbc/postgresql/column.rb, line 217
def type_cast(value) # AR < 4.0 version
  return if value.nil?
  return super if respond_to?(:encoded?) && encoded? # since AR-3.2

  case sql_type
  when 'money'
    self.class.string_to_money(value)
  else super
  end
end

Private Instance Methods

extract_bounds(value) click to toggle source

OID Type::Range helpers :

# File lib/arjdbc/postgresql/column.rb, line 406
def extract_bounds(value)
  f, t = value[1..-2].split(',')
  {
    :from => (value[1] == ',' || f == '-infinity') ? infinity(:negative => true) : f,
    :to   => (value[-2] == ',' || t == 'infinity') ? infinity : t,
    :exclude_start => (value[0] == '('), :exclude_end => (value[-1] == ')')
  }
end
extract_precision(sql_type) click to toggle source

Extracts the precision from PostgreSQL-specific data types.

Calls superclass method
# File lib/arjdbc/postgresql/column.rb, line 301
def extract_precision(sql_type)
  if sql_type == 'money'
    self.class.money_precision
  elsif sql_type =~ /timestamp/i
    $1.to_i if sql_type =~ /\((\d+)\)/
  else
    super
  end
end
extract_scale(sql_type) click to toggle source

Extracts the scale from PostgreSQL-specific data types.

Calls superclass method
# File lib/arjdbc/postgresql/column.rb, line 295
def extract_scale(sql_type)
  # Money type has a fixed scale of 2.
  sql_type =~ /^money/ ? 2 : super
end
infinity(options = {}) click to toggle source
# File lib/arjdbc/postgresql/column.rb, line 415
def infinity(options = {})
  ::Float::INFINITY * (options[:negative] ? -1 : 1)
end
marshal_dump() click to toggle source

TODO marshaling worked in 1.3.7 ,,, got broken in 1.3.8 (due @adapter) but the fix introduced in 1.3.10 causes backwards (1.3) incompatibility … for now should be fine - there's likely more refactoring to happen!

# File lib/arjdbc/postgresql/column.rb, line 425
def marshal_dump
  # NOTE: disabled oid_type ... due range warnings (maybe they're fine) :
  # unknown OID 3904: failed to recognize type of 'int4_range'. It will be treated as String.
  #oid_type if respond_to?(:oid_type)
  @adapter = nil
  instance_variables.map { |var| [ var, instance_variable_get(var) ] }
end
marshal_load(data) click to toggle source
# File lib/arjdbc/postgresql/column.rb, line 433
def marshal_load(data)
  data.each { |pair| instance_variable_set( pair[0], pair[1] ) }
end
simplified_type(field_type) click to toggle source

Maps PostgreSQL-specific data types to logical Rails types.

Calls superclass method
# File lib/arjdbc/postgresql/column.rb, line 312
def simplified_type(field_type)
  case field_type
    # Numeric and monetary types
  when /^(?:real|double precision)$/ then :float
    # Monetary types
  when 'money' then :decimal
    # Character types
  when /^(?:character varying|bpchar)(?:\(\d+\))?$/ then :string
    # Binary data types
  when 'bytea' then :binary
    # Date/time types
  when /^timestamp with(?:out)? time zone$/ then :datetime
  when 'interval' then :string
    # Geometric types
  when /^(?:point|line|lseg|box|"?path"?|polygon|circle)$/ then :string
    # Network address types
  when /^(?:cidr|inet|macaddr)$/ then :string
    # Bit strings
  when /^bit(?: varying)?(?:\(\d+\))?$/ then :string
    # XML type
  when 'xml' then :xml
    # tsvector type
  when 'tsvector' then :tsvector
    # Arrays
  when /^\D+\[\]$/ then :string
    # Object identifier types
  when 'oid' then :integer
    # UUID type
  when 'uuid' then :string
    # Small and big integer types
  when /^(?:small|big)int$/ then :integer
  # AR-JDBC added :
  when 'bool' then :boolean
  when 'char' then :string
  when 'serial' then :integer
    # Pass through all types that are not specific to PostgreSQL.
  else
    super
  end
end