Class: Linkage::Data Abstract

Inherits:
Object
  • Object
show all
Defined in:
lib/linkage/data.rb

Overview

This class is abstract.

Superclass to Field and Function.

Direct Known Subclasses

Field, Function

Constant Summary collapse

TYPE_CONVERSION_TREE =

A “tree” used to find compatible types.

{
  TrueClass => [Integer],
  Integer => [Bignum, Float],
  Bignum => [BigDecimal],
  Float => [BigDecimal],
  BigDecimal => [String],
  String => nil,
  DateTime => nil,
  Date => nil,
  Time => nil,
  File => nil
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name) ⇒ Data

Returns a new instance of Data.



23
24
25
# File 'lib/linkage/data.rb', line 23

def initialize(name)
  @name = name
end

Instance Attribute Details

#nameSymbol (readonly)

Returns This object’s name.

Returns:

  • (Symbol)

    This object’s name



21
22
23
# File 'lib/linkage/data.rb', line 21

def name
  @name
end

Instance Method Details

#merge(other, new_name = nil) ⇒ Linkage::Field

Create a data object that can hold data from two other fields. If the fields have different types, the resulting type is determined via a type-conversion tree.

Parameters:

Returns:



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/linkage/data.rb', line 41

def merge(other, new_name = nil)
  schema_1 = self.ruby_type
  schema_2 = other.ruby_type
  if schema_1 == schema_2
    result = schema_1
  else
    type_1 = schema_1[:type]
    opts_1 = schema_1[:opts] || {}
    type_2 = schema_2[:type]
    opts_2 = schema_2[:opts] || {}
    result_type = type_1
    result_opts = schema_1[:opts] ? schema_1[:opts].dup : {}

    # type
    if type_1 != type_2
      result_type = first_common_type(type_1, type_2)
    end

    # text
    if opts_1[:text] != opts_2[:text]
      # This can only be of type String.
      result_opts[:text] = true
      result_opts.delete(:size)
    end

    # size
    if !result_opts[:text] && opts_1[:size] != opts_2[:size]
      types = [type_1, type_2].uniq
      if types.length == 1 && types[0] == BigDecimal
        # Two decimals
        if opts_1.has_key?(:size) && opts_2.has_key?(:size)
          s_1 = opts_1[:size]
          s_2 = opts_2[:size]
          result_opts[:size] = [ s_1[0] > s_2[0] ? s_1[0] : s_2[0] ]

          if s_1[1] && s_2[1]
            result_opts[:size][1] = s_1[1] > s_2[1] ? s_1[1] : s_2[1]
          else
            result_opts[:size][1] = s_1[1] ? s_1[1] : s_2[1]
          end
        else
          result_opts[:size] = opts_1.has_key?(:size) ? opts_1[:size] : opts_2[:size]
        end
      elsif types.include?(String) && types.include?(BigDecimal)
        # Add one to the precision of the BigDecimal (for the dot)
        if opts_1.has_key?(:size) && opts_2.has_key?(:size)
          s_1 = opts_1[:size].is_a?(Array) ? opts_1[:size][0] + 1 : opts_1[:size]
          s_2 = opts_2[:size].is_a?(Array) ? opts_2[:size][0] + 1 : opts_2[:size]
          result_opts[:size] = s_1 > s_2 ? s_1 : s_2
        elsif opts_1.has_key?(:size)
          result_opts[:size] = opts_1[:size].is_a?(Array) ? opts_1[:size][0] + 1 : opts_1[:size]
        elsif opts_2.has_key?(:size)
          result_opts[:size] = opts_2[:size].is_a?(Array) ? opts_2[:size][0] + 1 : opts_2[:size]
        end
      else
        # Treat as two strings
        if opts_1.has_key?(:size) && opts_2.has_key?(:size)
          result_opts[:size] = opts_1[:size] > opts_2[:size] ? opts_1[:size] : opts_2[:size]
        elsif opts_1.has_key?(:size)
          result_opts[:size] = opts_1[:size]
        else
          result_opts[:size] = opts_2[:size]
        end
      end
    end

    # fixed
    if opts_1[:fixed] != opts_2[:fixed]
      # This can only be of type String.
      result_opts[:fixed] = true
    end

    result = {:type => result_type}
    result[:opts] = result_opts  unless result_opts.empty?
  end

  if new_name
    name = new_name.to_sym
  else
    name = self.name == other.name ? self.name : :"#{self.name}_#{other.name}"
  end
  Field.new(name, nil, result)
end

#ruby_typeObject

Raises:

  • (NotImplementedError)


27
28
29
# File 'lib/linkage/data.rb', line 27

def ruby_type
  raise NotImplementedError
end

#to_exprObject

Raises:

  • (NotImplementedError)


31
32
33
# File 'lib/linkage/data.rb', line 31

def to_expr
  raise NotImplementedError
end