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
-
#manager ⇒ Object
Returns the value of attribute manager.
-
#table ⇒ Object
readonly
Returns the value of attribute table.
Instance Method Summary collapse
- #from(subquery, alias_name) ⇒ Object
- #group(*columns) ⇒ Object
-
#initialize(table_name) ⇒ QueryBuilder
constructor
A new instance of QueryBuilder.
- #initialize_copy(other) ⇒ Object
- #joins(table_name, constraint = nil) ⇒ Object
- #limit(count) ⇒ Object
- #offset(count) ⇒ Object
- #order(field, direction = :asc) ⇒ Object
- #select(*fields) ⇒ Object
- #to_arel ⇒ Object
- #to_redacted_sql(bind_index_manager = ClickHouse::Client::BindIndexManager.new) ⇒ Object
- #to_sql ⇒ Object
-
#where(constraints) ⇒ 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 |
# 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) end |
Instance Attribute Details
#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
#from(subquery, alias_name) ⇒ Object
123 124 125 126 127 128 129 130 131 |
# File 'lib/click_house/client/query_builder.rb', line 123 def from(subquery, alias_name) clone.tap do |new_instance| if subquery.is_a?(self.class) new_instance.manager.from(subquery.to_arel.as(alias_name)) else new_instance.manager.from(Arel::Nodes::TableAlias.new(subquery, alias_name)) end end end |
#group(*columns) ⇒ Object
107 108 109 110 111 |
# File 'lib/click_house/client/query_builder.rb', line 107 def group(*columns) clone.tap do |new_instance| new_instance.manager.group(*columns) end end |
#initialize_copy(other) ⇒ Object
32 33 34 35 36 |
# File 'lib/click_house/client/query_builder.rb', line 32 def initialize_copy(other) super @manager = other.manager.clone end |
#joins(table_name, constraint = nil) ⇒ Object
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/click_house/client/query_builder.rb', line 133 def joins(table_name, constraint = nil) clone.tap do |new_instance| join_table = table_name.is_a?(Arel::Table) ? table_name : Arel::Table.new(table_name) join_condition = case constraint when Hash # Handle hash based constraints like { table1.id: table2.ref_id } or {id: :ref_id} constraint_conditions = constraint.map do |left, right| left_field = left.is_a?(Arel::Attributes::Attribute) ? left : new_instance.table[left] right_field = right.is_a?(Arel::Attributes::Attribute) ? right : join_table[right] left_field.eq(right_field) end constraint_conditions.reduce(&:and) when Proc constraint.call(new_instance.table, join_table) when Arel::Nodes::Node constraint end if join_condition new_instance.manager.join(join_table).on(join_condition) else new_instance.manager.join(join_table) end end end |
#limit(count) ⇒ Object
113 114 115 116 |
# File 'lib/click_house/client/query_builder.rb', line 113 def limit(count) manager.take(count) self end |
#offset(count) ⇒ Object
118 119 120 121 |
# File 'lib/click_house/client/query_builder.rb', line 118 def offset(count) manager.skip(count) self end |
#order(field, direction = :asc) ⇒ Object
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/click_house/client/query_builder.rb', line 91 def order(field, direction = :asc) validate_order_direction!(direction) clone.tap do |new_instance| order_node = case field when Arel::Nodes::SqlLiteral, Arel::Nodes::Node, Arel::Attribute field else new_instance.table[field] end new_order = direction.to_s.casecmp('desc').zero? ? order_node.desc : order_node.asc new_instance.manager.order(new_order) end end |
#select(*fields) ⇒ Object
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 87 88 89 |
# File 'lib/click_house/client/query_builder.rb', line 61 def select(*fields) clone.tap do |new_instance| existing_fields = new_instance.manager.projections.filter_map do |projection| if projection.respond_to?(:to_s) && projection.to_s == '*' nil elsif projection.is_a?(Arel::Attributes::Attribute) projection.name.to_s elsif projection.is_a?(Arel::Expressions) projection 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_arel ⇒ Object
170 171 172 |
# File 'lib/click_house/client/query_builder.rb', line 170 def to_arel manager end |
#to_redacted_sql(bind_index_manager = ClickHouse::Client::BindIndexManager.new) ⇒ Object
166 167 168 |
# File 'lib/click_house/client/query_builder.rb', line 166 def to_redacted_sql(bind_index_manager = ClickHouse::Client::BindIndexManager.new) ClickHouse::Client::Redactor.redact(self, bind_index_manager) end |
#to_sql ⇒ Object
161 162 163 164 |
# File 'lib/click_house/client/query_builder.rb', line 161 def to_sql visitor = Arel::Visitors::ToSql.new(ClickHouse::Client::ArelEngine.new) visitor.accept(manager.ast, Arel::Collectors::SQLString.new).value end |
#where(constraints) ⇒ 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 constraints 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 constraints 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.
53 54 55 56 57 58 59 |
# File 'lib/click_house/client/query_builder.rb', line 53 def where(constraints) validate_constraint_type!(constraints) clone.tap do |new_instance| add_constraints_to(new_instance, constraints) end end |