Class: LcpRuby::Metadata::VirtualColumnDefinition

Inherits:
Object
  • Object
show all
Defined in:
lib/lcp_ruby/metadata/virtual_column_definition.rb

Constant Summary collapse

VALID_FUNCTIONS =
%w[count sum min max avg].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(attrs = {}) ⇒ VirtualColumnDefinition

Returns a new instance of VirtualColumnDefinition.



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/lcp_ruby/metadata/virtual_column_definition.rb', line 10

def initialize(attrs = {})
  @name = attrs[:name].to_s
  @function = attrs[:function]&.to_s
  @association = attrs[:association]&.to_s
  @source_field = attrs[:source_field]&.to_s.presence
  @where = attrs[:where] || {}
  @distinct = attrs[:distinct] || false
  @default = attrs[:default]
  @include_discarded = attrs[:include_discarded] || false
  # Accept both :expression and legacy :sql kwarg
  @expression = attrs[:expression]&.to_s.presence || attrs[:sql]&.to_s.presence
  @service = attrs[:service]&.to_s.presence
  @type = attrs[:type]&.to_s.presence
  @options = attrs[:options] || {}
  @join = attrs[:join]&.to_s.presence
  @group = attrs[:group] || false
  @auto_include = attrs[:auto_include] || false

  validate!
end

Instance Attribute Details

#associationObject (readonly)

Returns the value of attribute association.



6
7
8
# File 'lib/lcp_ruby/metadata/virtual_column_definition.rb', line 6

def association
  @association
end

#auto_includeObject (readonly)

Returns the value of attribute auto_include.



6
7
8
# File 'lib/lcp_ruby/metadata/virtual_column_definition.rb', line 6

def auto_include
  @auto_include
end

#defaultObject (readonly)

Returns the value of attribute default.



6
7
8
# File 'lib/lcp_ruby/metadata/virtual_column_definition.rb', line 6

def default
  @default
end

#distinctObject (readonly)

Returns the value of attribute distinct.



6
7
8
# File 'lib/lcp_ruby/metadata/virtual_column_definition.rb', line 6

def distinct
  @distinct
end

#expressionObject (readonly)

Returns the value of attribute expression.



6
7
8
# File 'lib/lcp_ruby/metadata/virtual_column_definition.rb', line 6

def expression
  @expression
end

#functionObject (readonly)

Returns the value of attribute function.



6
7
8
# File 'lib/lcp_ruby/metadata/virtual_column_definition.rb', line 6

def function
  @function
end

#groupObject (readonly)

Returns the value of attribute group.



6
7
8
# File 'lib/lcp_ruby/metadata/virtual_column_definition.rb', line 6

def group
  @group
end

#include_discardedObject (readonly)

Returns the value of attribute include_discarded.



6
7
8
# File 'lib/lcp_ruby/metadata/virtual_column_definition.rb', line 6

def include_discarded
  @include_discarded
end

#joinObject (readonly)

Returns the value of attribute join.



6
7
8
# File 'lib/lcp_ruby/metadata/virtual_column_definition.rb', line 6

def join
  @join
end

#nameObject (readonly)

Returns the value of attribute name.



6
7
8
# File 'lib/lcp_ruby/metadata/virtual_column_definition.rb', line 6

def name
  @name
end

#optionsObject (readonly)

Returns the value of attribute options.



6
7
8
# File 'lib/lcp_ruby/metadata/virtual_column_definition.rb', line 6

def options
  @options
end

#serviceObject (readonly)

Returns the value of attribute service.



6
7
8
# File 'lib/lcp_ruby/metadata/virtual_column_definition.rb', line 6

def service
  @service
end

#source_fieldObject (readonly)

Returns the value of attribute source_field.



6
7
8
# File 'lib/lcp_ruby/metadata/virtual_column_definition.rb', line 6

def source_field
  @source_field
end

#typeObject (readonly)

Returns the value of attribute type.



6
7
8
# File 'lib/lcp_ruby/metadata/virtual_column_definition.rb', line 6

def type
  @type
end

#whereObject (readonly)

Returns the value of attribute where.



6
7
8
# File 'lib/lcp_ruby/metadata/virtual_column_definition.rb', line 6

def where
  @where
end

Class Method Details

.from_hash(name, hash) ⇒ Object



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/lcp_ruby/metadata/virtual_column_definition.rb', line 31

def self.from_hash(name, hash)
  # Reject both keys present (including explicit nil values)
  if hash.key?("sql") && hash.key?("expression")
    raise MetadataError, "Virtual column '#{name}': cannot specify both 'sql' and 'expression'"
  end

  # Map legacy "sql" key to expression
  expression_value = hash["expression"] || hash["sql"]

  new(
    name: name,
    function: hash["function"],
    association: hash["association"],
    source_field: hash["source_field"],
    where: hash["where"] || {},
    distinct: hash["distinct"],
    default: hash["default"],
    include_discarded: hash["include_discarded"],
    expression: expression_value,
    service: hash["service"],
    type: hash["type"],
    options: hash["options"],
    join: hash["join"],
    group: hash["group"],
    auto_include: hash["auto_include"]
  )
end

Instance Method Details

#declarative?Boolean

Returns:

  • (Boolean)


59
60
61
# File 'lib/lcp_ruby/metadata/virtual_column_definition.rb', line 59

def declarative?
  function.present? && expression.nil? && service.nil?
end

#expression_type?Boolean Also known as: sql_type?

Returns:

  • (Boolean)


63
64
65
# File 'lib/lcp_ruby/metadata/virtual_column_definition.rb', line 63

def expression_type?
  expression.present?
end

#inferred_type(model_definition = nil) ⇒ Object

Infer the result type based on function and source field type. For expression and service types, the explicit ‘type` attribute is used.



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
# File 'lib/lcp_ruby/metadata/virtual_column_definition.rb', line 81

def inferred_type(model_definition = nil)
  return type if type.present?
  return "integer" if function == "count"

  if model_definition && source_field.present? && association.present?
    assoc_def = model_definition.associations.find { |a| a.name == association }
    if assoc_def&.target_model
      target_def = LcpRuby.loader.model_definition(assoc_def.target_model)
      if target_def
        field_def = target_def.field(source_field)
        if field_def
          return "float" if function == "avg" && field_def.resolved_base_type != "decimal"
          return "decimal" if function == "avg" && field_def.resolved_base_type == "decimal"
          return field_def.resolved_base_type
        end
      end
    end
  end

  # Fallback when source field type cannot be resolved
  case function
  when "avg" then "float"
  when "sum", "min", "max" then "decimal"
  else "string"
  end
end

#service_type?Boolean

Returns:

  • (Boolean)


75
76
77
# File 'lib/lcp_ruby/metadata/virtual_column_definition.rb', line 75

def service_type?
  service.present?
end

#sqlObject

Legacy accessor for backward compatibility



71
72
73
# File 'lib/lcp_ruby/metadata/virtual_column_definition.rb', line 71

def sql
  expression
end