Class: ActiveFacts::Metamodel::DataType

Inherits:
Object
  • Object
show all
Defined in:
lib/activefacts/metamodel/datatypes.rb

Defined Under Namespace

Classes: Context, DefaultContext

Constant Summary collapse

TypeNames =
%w{
  Boolean
  Integer Real Decimal Money
  Char String Text
  Date Time DateTime Timestamp
  Binary
}.freeze
AlternateNames =

Alternate names are case-insensitive, and underscore can be literal, or correspond to a space or to nothing

{
  TYPE_Boolean =>
    %w{ bit },
  TYPE_Integer =>
    %w{ auto_counter int tiny_int small_int big_int unsigned unsigned_int unsigned_integer signed_int signed_integer},
  TYPE_Real =>
    %w{ float double },
  TYPE_Decimal =>
    %w{ },
  TYPE_Money =>
    %w{ currency },
  TYPE_Char =>
    %w{ character nchar national_character fixed_length_text },
  TYPE_String =>
    %w{ varchar nvarchar national_character_varying variable_length_text },
  TYPE_Text =>
    %w{ large_length_text },
  TYPE_Date =>
    %w{ },
  TYPE_Time =>
    %w{ },
  TYPE_DateTime =>
    %w{ date_time },
  TYPE_Timestamp =>
    %w{ time_stamp auto_time_stamp },
  TYPE_Binary =>
    %w{ guid picture_raw_data variable_length_raw_data },
}
TypeParameters =
{
  TYPE_Integer => [:length],            # Length is the number of bits
  TYPE_Real => [:length],               # Length is the number of bits in the mantissa
  TYPE_Decimal => [:precision, :scale], # Precision is the number of significant digits
  TYPE_Money => [:precision, :scale],   # Precision is the number of significant digits. Scale is the digits of fractional cents.
  TYPE_Char => [:length, :charset],     # Charset is e.g. ascii, latin1, iso8859-1, unicode
  TYPE_String => [:length, :charset],
  TYPE_Text => [:charset],
  TYPE_Binary => [:length, :charset],
}

Class Method Summary collapse

Class Method Details

.normalise(type_name) ⇒ Object



125
126
127
128
# File 'lib/activefacts/metamodel/datatypes.rb', line 125

def self.normalise type_name
  data_type, = type_mapping.detect{|t, names| names.detect{|n| n === type_name}}
  data_type
end

.normalise_int_length(type_name, length = nil, value_constraint = nil, context = DefaultContext.new) ⇒ Object



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
# File 'lib/activefacts/metamodel/datatypes.rb', line 130

def self.normalise_int_length type_name, length = nil, value_constraint = nil, context = DefaultContext.new
  int_length = length || context.default_length(TYPE_Integer, type_name)
  if int_length
    if value_constraint
      # Pick out the largest maximum and smallest minimum from the ValueConstraint:
      ranges = value_constraint.all_allowed_range_sorted.flat_map{|ar| ar.value_range}
      min = ranges.map(&:minimum_bound).compact.map{|minb| minb.is_inclusive ? minb.value : minb.value-1}.map{|v| v.literal.to_i}.sort[0]
      max = ranges.map(&:maximum_bound).compact.map{|maxb| maxb.is_inclusive ? maxb.value : maxb.value+1}.map{|v| v.literal.to_i}.sort[-1]
    end

    unsigned = type_name =~ /^unsigned/i
    int_min = unsigned ? 0 : -2**(int_length-1)+1
    min = int_min if !min || length && int_min < min
    # SQL does not have unsigned types.
    # Don't force the next largest type just because the app calls for unsigned:
    int_max = unsigned ? 2**(int_length-1) - 1 : 2**(int_length-1)-1
    max = int_max if !max || length && int_max < max
  end
  best = context.choose_integer_type(min, max)
  unless best || length
    # Use the largest available integer size
    best = context.integer_ranges.last
  end

  # Use a context-defined integer size if one suits, otherwise the requested size:
  best && [best[0], best[3]] || [ 'int', length ]
end