Module: ActiveHll::Utils
- Defined in:
- lib/active_hll/utils.rb
Class Method Summary collapse
- .hll_calculate(relation, operation, column, default_value:) ⇒ Object
- .hll_calculate_sql(relation, operation, column) ⇒ Object
- .hll_hash_sql(klass, value) ⇒ Object
Class Method Details
.hll_calculate(relation, operation, column, default_value:) ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/active_hll/utils.rb', line 20 def hll_calculate(relation, operation, column, default_value:) sql, relation, group_values = hll_calculate_sql(relation, operation, column) result = relation.connection.select_all(sql) # typecast rows = [] columns = result.columns result.rows.each do |untyped_row| rows << (result.column_types.empty? ? untyped_row : columns.each_with_index.map { |c, i| untyped_row[i] && result.column_types[c] ? result.column_types[c].deserialize(untyped_row[i]) : untyped_row[i] }) end result = if group_values.any? Hash[rows.map { |r| [r.size == 2 ? r[0] : r[0..-2], r[-1]] }] else rows[0] && rows[0][0] end result = Groupdate.process_result(relation, result, default_value: default_value) if defined?(Groupdate.process_result) result end |
.hll_calculate_sql(relation, operation, column) ⇒ Object
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 |
# File 'lib/active_hll/utils.rb', line 43 def hll_calculate_sql(relation, operation, column) # basic version of Active Record disallow_raw_sql! # symbol = column (safe), Arel node = SQL (safe), other = untrusted # matches table.column and column unless column.is_a?(Symbol) || column.is_a?(Arel::Nodes::SqlLiteral) column = column.to_s unless /\A\w+(\.\w+)?\z/i.match?(column) raise ActiveRecord::UnknownAttributeReference, "Query method called with non-attribute argument(s): #{column.inspect}. Use Arel.sql() for known-safe values." end end # column resolution node = relation.all.send(:arel_columns, [column]).first node = Arel::Nodes::SqlLiteral.new(node) if node.is_a?(String) column = relation.connection.visitor.accept(node, Arel::Collectors::SQLString.new).value group_values = relation.all.group_values relation = relation.unscope(:select).select(*group_values, operation % [column]) # same as average relation = relation.unscope(:order).distinct!(false) if group_values.empty? [relation.to_sql, relation, group_values] end |
.hll_hash_sql(klass, value) ⇒ Object
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# File 'lib/active_hll/utils.rb', line 4 def hll_hash_sql(klass, value) hash_function = case value when true, false "hll_hash_boolean" when Integer "hll_hash_bigint" when String "hll_hash_text" else raise ArgumentError, "Unexpected type: #{value.class.name}" end quoted_value = klass.connection.quote(value) "#{hash_function}(#{quoted_value})" end |