Class: NativesonContainer

Inherits:
Object
  • Object
show all
Defined in:
lib/nativeson/nativeson_container.rb

Constant Summary collapse

ALLOWED_ATTRIBUTES =
[:where, :order, :limit, :columns, :associations, :klass, :name]
CONTAINER_TYPES =
[:base, :asscoation]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(container_type:, query:, parent: nil, name: nil) ⇒ NativesonContainer

Returns a new instance of NativesonContainer.



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/nativeson/nativeson_container.rb', line 10

def initialize(container_type: , query: , parent: nil, name: nil)
  @parent = parent
  @container_type = container_type
  @associations = {}
  @query = query
  query[:klass].is_a?(String) ? @klass = self.class.const_get(query[:klass]) : @klass = query[:klass]
  @columns = query[:columns]
  @name = name.to_s
  get_all_columns
  select_columns
  get_all_reflections
  get_parent_table
  get_foreign_key
  ALLOWED_ATTRIBUTES.each do |i|
    if i == :associations
      next unless query[i]
      query[i].each_pair { |k,v| create_association(k, v) }
    elsif [:klass, :columns].include?(i)
      next
    else
      instance_variable_set("@#{i}", query[i])
    end
  end
end

Instance Attribute Details

#all_columnsObject

Returns the value of attribute all_columns.



4
5
6
# File 'lib/nativeson/nativeson_container.rb', line 4

def all_columns
  @all_columns
end

#all_reflections_by_nameObject

Returns the value of attribute all_reflections_by_name.



4
5
6
# File 'lib/nativeson/nativeson_container.rb', line 4

def all_reflections_by_name
  @all_reflections_by_name
end

#columns_stringObject

Returns the value of attribute columns_string.



4
5
6
# File 'lib/nativeson/nativeson_container.rb', line 4

def columns_string
  @columns_string
end

#container_typeObject

Returns the value of attribute container_type.



3
4
5
# File 'lib/nativeson/nativeson_container.rb', line 3

def container_type
  @container_type
end

#parentObject

Returns the value of attribute parent.



4
5
6
# File 'lib/nativeson/nativeson_container.rb', line 4

def parent
  @parent
end

#queryObject

Returns the value of attribute query.



4
5
6
# File 'lib/nativeson/nativeson_container.rb', line 4

def query
  @query
end

#reflectionObject

Returns the value of attribute reflection.



3
4
5
# File 'lib/nativeson/nativeson_container.rb', line 3

def reflection
  @reflection
end

#sqlObject

Returns the value of attribute sql.



4
5
6
# File 'lib/nativeson/nativeson_container.rb', line 4

def sql
  @sql
end

Instance Method Details

#create_association(association_name, association_query) ⇒ Object



35
36
37
# File 'lib/nativeson/nativeson_container.rb', line 35

def create_association(association_name, association_query)
  @associations[association_name] = NativesonContainer.new(container_type: :association, query: association_query, parent: self, name: association_name)
end

#generate_association_sql(name, prefix, tmp_sql) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/nativeson/nativeson_container.rb', line 69

def generate_association_sql(name, prefix, tmp_sql)
  "
  ( SELECT JSON_AGG(tmp_#{@klass.table_name} )
      FROM (
        SELECT #{@columns_string}
        #{" , " + tmp_sql unless tmp_sql.blank?}
        FROM   #{@klass.table_name}
        WHERE  #{@foreign_key} = #{@parent_table}
        #{'AND '      + @where.to_s unless @where.blank?}
        #{'ORDER BY ' + @order.to_s unless @order.blank?}
        #{'LIMIT '    + @limit.to_s unless @limit.blank?}
       ) tmp_#{@klass.table_name}
   ) AS #{name}
  ".split("\n").map { |i| "#{prefix}#{i}" }.join("\n")
end

#generate_base_sqlObject



85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/nativeson/nativeson_container.rb', line 85

def generate_base_sql
  "
  SELECT JSON_AGG(t)
     FROM (
      SELECT #{@columns_string}
      #{" , " + @sql unless @sql.blank?}
      FROM #{@klass.table_name}
      AS base_table
      #{'WHERE '      + @where.to_s unless @where.blank?}
      #{'ORDER BY ' + @order.to_s unless @order.blank?}
      #{'LIMIT '    + @limit.to_s unless @limit.blank?}
    ) t;
  "
end

#generate_sql(prefix = '') ⇒ Object



100
101
102
103
104
105
106
107
108
109
# File 'lib/nativeson/nativeson_container.rb', line 100

def generate_sql(prefix = '')
  prefix << "  "
  @sql = ''
  @associations.each_pair do |association_name,association_data|
    tmp_sql = association_data.generate_association_sql(association_name, prefix, association_data.generate_sql(prefix))
    @sql.blank? ? @sql << tmp_sql : @sql << " , #{tmp_sql}"
  end
  @sql = generate_base_sql if @parent.nil?
  @sql
end

#get_all_columnsObject



111
112
113
114
# File 'lib/nativeson/nativeson_container.rb', line 111

def get_all_columns
  @all_columns = {}
  @klass.columns.each { |i| @all_columns[i.name] = i }
end

#get_all_reflectionsObject



116
117
118
# File 'lib/nativeson/nativeson_container.rb', line 116

def get_all_reflections
  @all_reflections_by_name = @klass.reflections
end

#get_foreign_keyObject

Raises:

  • (ArgumentError)


52
53
54
55
56
57
# File 'lib/nativeson/nativeson_container.rb', line 52

def get_foreign_key
  @foreign_key = nil
  return @foreign_key if @parent.nil?
  raise ArgumentError.new("#{__method__} :: #{@name} can't be found in #{@parent.name} reflections") unless @parent.all_reflections_by_name.key?(@name)
  @foreign_key = @parent.all_reflections_by_name[@name].foreign_key
end

#get_parent_tableObject



59
60
61
62
63
64
65
66
67
# File 'lib/nativeson/nativeson_container.rb', line 59

def get_parent_table
  if @parent.nil?
    @parent_table = @klass.table_name
  elsif @parent.container_type == :base
    @parent_table = "base_table.#{@klass.primary_key}"
  else
    @parent_table = "#{@parent.klass.table_name}.#{@parent.klass.primary_key}"
  end
end

#select_columnsObject



39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/nativeson/nativeson_container.rb', line 39

def select_columns
  @columns_string = ''
  if @columns.blank?
    @columns_string << '*'
  else
    @columns.each_with_index do |column,idx|
      raise ArgumentError.new("#{__method__} :: column '#{column}' wasn't found in the ActiveRecord #{@klass.name} columns") unless all_columns.key?(column)
      @columns_string << ' , ' if idx > 0
      @columns_string << column
    end
  end
end