Class: AnyQuery::Adapters::Base Private

Inherits:
Object
  • Object
show all
Defined in:
lib/any_query/adapters/base.rb

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Direct Known Subclasses

Csv, FixedLength, Http, Sql

Defined Under Namespace

Classes: Config

Instance Method Summary collapse

Constructor Details

#initialize(config) ⇒ Base

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of Base.



7
8
9
# File 'lib/any_query/adapters/base.rb', line 7

def initialize(config)
  @config = config.to_h
end

Instance Method Details

#fallback_where(data, wheres) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



41
42
43
44
45
46
47
48
49
# File 'lib/any_query/adapters/base.rb', line 41

def fallback_where(data, wheres)
  data.filter do |row|
    wheres.all? do |where|
      where.all? do |key, value|
        resolve_path(row, key) == value
      end
    end
  end
end

#group_join_data(data, join) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



63
64
65
66
67
68
69
# File 'lib/any_query/adapters/base.rb', line 63

def group_join_data(data, join)
  if join[:as] == :list
    data.group_by { |e| resolve_path(e, join[:primary_key]) }
  else
    data.index_by { |e| resolve_path(e, join[:primary_key]) }
  end
end

#instantiate_model(model, record) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



19
20
21
22
23
24
25
26
# File 'lib/any_query/adapters/base.rb', line 19

def instantiate_model(model, record)
  instance = model.new
  attrs = instance.instance_variable_get(:@attributes)
  record.each do |key, value|
    attrs.send("#{key}=", value)
  end
  instance
end

#load(model, select:, joins:, where:, limit:) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Raises:

  • (NotImplementedError)


11
12
13
# File 'lib/any_query/adapters/base.rb', line 11

def load(model, select:, joins:, where:, limit:)
  raise NotImplementedError
end

#load_single(model, id, joins) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



15
16
17
# File 'lib/any_query/adapters/base.rb', line 15

def load_single(model, id, joins)
  load(model, select: [], joins:, where: [{ id: }], limit: 1).first
end

#map_multi_threaded(list, concurrency = 50) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



92
93
94
95
96
97
98
99
# File 'lib/any_query/adapters/base.rb', line 92

def map_multi_threaded(list, concurrency = 50)
  list.each_slice(concurrency).flat_map do |slice|
    slice
      .map { |data| Thread.new { yield(data) } }
      .each(&:join)
      .map(&:value)
  end
end

#parse_field_type(field, line) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/any_query/adapters/base.rb', line 101

def parse_field_type(field, line)
  method_name = "parse_field_type_#{field[:type]}"

  if respond_to?(method_name)
    send(method_name, field, line)
  else
    line.strip
  end
rescue StandardError => e
  AnyQuery::Config.logger.error "Failed to parse field \"#{line}\" with type #{field.inspect}: #{e.message}"
  nil
end

#parse_field_type_boolean(_, line) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



146
147
148
# File 'lib/any_query/adapters/base.rb', line 146

def parse_field_type_boolean(_, line)
  line.strip == 'true'
end

#parse_field_type_date(field, line) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



118
119
120
121
122
123
124
# File 'lib/any_query/adapters/base.rb', line 118

def parse_field_type_date(field, line)
  if field[:format]
    Date.strptime(line.strip, field[:format])
  else
    Date.parse(line)
  end
end

#parse_field_type_datetime(field, line) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



126
127
128
129
130
131
132
# File 'lib/any_query/adapters/base.rb', line 126

def parse_field_type_datetime(field, line)
  if field[:format]
    DateTime.strptime(line.strip, field[:format])
  else
    DateTime.parse(line)
  end
end

#parse_field_type_decimal(_, line) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



138
139
140
# File 'lib/any_query/adapters/base.rb', line 138

def parse_field_type_decimal(_, line)
  BigDecimal(line)
end

#parse_field_type_float(_, line) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



134
135
136
# File 'lib/any_query/adapters/base.rb', line 134

def parse_field_type_float(_, line)
  line.to_f
end

#parse_field_type_integer(_, line) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



114
115
116
# File 'lib/any_query/adapters/base.rb', line 114

def parse_field_type_integer(_, line)
  line.to_i
end

#parse_field_type_string(_, line) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



142
143
144
# File 'lib/any_query/adapters/base.rb', line 142

def parse_field_type_string(_, line)
  line.strip
end

#resolve_join(data, join) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



51
52
53
54
55
56
57
58
59
60
61
# File 'lib/any_query/adapters/base.rb', line 51

def resolve_join(data, join)
  AnyQuery::Config.logger.debug "Joining #{join[:model]} on #{join[:primary_key]} = #{join[:foreign_key]}"
  foreign_keys = data.map { |row| resolve_path(row, join[:foreign_key]) }.compact.uniq
  result = run_external_join(join, foreign_keys)

  result = group_join_data(result, join)

  data.each do |row|
    row[join[:into]] = result[resolve_path(row, join[:foreign_key])] || (join[:as] == :list ? [] : nil)
  end
end

#resolve_path(data, path) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/any_query/adapters/base.rb', line 28

def resolve_path(data, path)
  if path.is_a?(Proc)
    path.call(data)
  elsif path.is_a?(Array)
    data.dig(*path)
  else
    data[path]
  end
rescue StandardError => e
  AnyQuery::Config.logger.error "Failed to resolve path #{path} on #{data.inspect}"
  raise e
end

#resolve_select(chain, select) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



84
85
86
87
88
89
90
# File 'lib/any_query/adapters/base.rb', line 84

def resolve_select(chain, select)
  chain.map do |record|
    select.map do |field|
      resolve_path(record, field)
    end
  end
end

#run_external_join(join, foreign_keys) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/any_query/adapters/base.rb', line 71

def run_external_join(join, foreign_keys)
  case join[:strategy]
  when Proc
    join[:strategy].call(foreign_keys)
  when :single
    map_multi_threaded(foreign_keys.uniq) { |key| join[:model].find(key) }
  when :full_scan
    join[:model].to_a
  else
    join[:model].where(id: foreign_keys).to_a
  end
end