Class: ClickHouse::Client::QueryBuilder
- Defined in:
- lib/click_house/client/query_builder.rb
Constant Summary collapse
- VALID_NODES =
[ Arel::Nodes::In, Arel::Nodes::Equality, Arel::Nodes::LessThan, Arel::Nodes::LessThanOrEqual, Arel::Nodes::GreaterThan, Arel::Nodes::GreaterThanOrEqual, Arel::Nodes::NamedFunction, Arel::Nodes::NotIn, Arel::Nodes::NotEqual, Arel::Nodes::Between, Arel::Nodes::And, Arel::Nodes::Or, Arel::Nodes::Grouping ].freeze
Instance Attribute Summary collapse
-
#conditions ⇒ Object
Returns the value of attribute conditions.
-
#manager ⇒ Object
Returns the value of attribute manager.
-
#table ⇒ Object
readonly
Returns the value of attribute table.
Instance Method Summary collapse
- #group(*columns) ⇒ Object
-
#initialize(table_name) ⇒ QueryBuilder
constructor
A new instance of QueryBuilder.
- #limit(count) ⇒ Object
- #offset(count) ⇒ Object
- #order(field, direction = :asc) ⇒ Object
- #select(*fields) ⇒ Object
- #to_redacted_sql(bind_index_manager = ClickHouse::Client::BindIndexManager.new) ⇒ Object
- #to_sql ⇒ Object
-
#where(conditions) ⇒ ClickHouse::QueryBuilder
The ‘where` method currently only supports IN and equal to queries along with above listed VALID_NODES.
Methods inherited from QueryLike
Constructor Details
#initialize(table_name) ⇒ QueryBuilder
Returns a new instance of QueryBuilder.
27 28 29 30 31 |
# File 'lib/click_house/client/query_builder.rb', line 27 def initialize(table_name) @table = Arel::Table.new(table_name) @manager = Arel::SelectManager.new(Arel::Table.engine).from(@table).project(Arel.star) @conditions = [] end |
Instance Attribute Details
#conditions ⇒ Object
Returns the value of attribute conditions.
9 10 11 |
# File 'lib/click_house/client/query_builder.rb', line 9 def conditions @conditions end |
#manager ⇒ Object
Returns the value of attribute manager.
9 10 11 |
# File 'lib/click_house/client/query_builder.rb', line 9 def manager @manager end |
#table ⇒ Object (readonly)
Returns the value of attribute table.
8 9 10 |
# File 'lib/click_house/client/query_builder.rb', line 8 def table @table end |
Instance Method Details
#group(*columns) ⇒ Object
98 99 100 101 102 |
# File 'lib/click_house/client/query_builder.rb', line 98 def group(*columns) deep_clone.tap do |new_instance| new_instance.manager.group(*columns) end end |
#limit(count) ⇒ Object
104 105 106 107 |
# File 'lib/click_house/client/query_builder.rb', line 104 def limit(count) manager.take(count) self end |
#offset(count) ⇒ Object
109 110 111 112 |
# File 'lib/click_house/client/query_builder.rb', line 109 def offset(count) manager.skip(count) self end |
#order(field, direction = :asc) ⇒ Object
88 89 90 91 92 93 94 95 96 |
# File 'lib/click_house/client/query_builder.rb', line 88 def order(field, direction = :asc) validate_order_direction!(direction) deep_clone.tap do |new_instance| table_field = new_instance.table[field] new_order = direction.to_s.casecmp('desc').zero? ? table_field.desc : table_field.asc new_instance.manager.order(new_order) end end |
#select(*fields) ⇒ Object
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 |
# File 'lib/click_house/client/query_builder.rb', line 60 def select(*fields) deep_clone.tap do |new_instance| existing_fields = new_instance.manager.projections.filter_map do |projection| if projection.is_a?(Arel::Attributes::Attribute) projection.name.to_s elsif projection.to_s == '*' nil end end new_projections = (existing_fields + fields).map do |field| if field.is_a?(Symbol) field.to_s else field end end new_instance.manager.projections = new_projections.uniq.map do |field| if field.is_a?(Arel::Expressions) field else new_instance.table[field.to_s] end end end end |
#to_redacted_sql(bind_index_manager = ClickHouse::Client::BindIndexManager.new) ⇒ Object
121 122 123 |
# File 'lib/click_house/client/query_builder.rb', line 121 def to_redacted_sql(bind_index_manager = ClickHouse::Client::BindIndexManager.new) ClickHouse::Client::Redactor.redact(self, bind_index_manager) end |
#to_sql ⇒ Object
114 115 116 117 118 119 |
# File 'lib/click_house/client/query_builder.rb', line 114 def to_sql apply_conditions! visitor = Arel::Visitors::ToSql.new(ClickHouse::Client::ArelEngine.new) visitor.accept(manager.ast, Arel::Collectors::SQLString.new).value end |
#where(conditions) ⇒ ClickHouse::QueryBuilder
The ‘where` method currently only supports IN and equal to queries along with above listed VALID_NODES. For example, using a range (start_date..end_date) will result in incorrect SQL. If you need to query a range, use greater than and less than conditions with Arel.
Correct usage:
query.where(query.table[:created_at].lteq(Date.today)).to_sql
"SELECT * FROM \"table\" WHERE \"table\".\"created_at\" <= '2023-08-01'"
This also supports array conditions which will result in an IN query.
query.where(entity_id: [1,2,3]).to_sql
"SELECT * FROM \"table\" WHERE \"table\".\"entity_id\" IN (1, 2, 3)"
Range support and more ‘Arel::Nodes` could be considered for future iterations.
48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/click_house/client/query_builder.rb', line 48 def where(conditions) validate_condition_type!(conditions) deep_clone.tap do |new_instance| if conditions.is_a?(Arel::Nodes::Node) new_instance.conditions << conditions else add_conditions_to(new_instance, conditions) end end end |