class NoSE::Backend::CassandraBackend::IndexLookupStatementStep
A query step to look up data from a particular column family
Public Class Methods
new(client, select, conditions, step, next_step, prev_step)
click to toggle source
rubocop:disable Metrics/ParameterLists
Calls superclass method
NoSE::Backend::Backend::IndexLookupStatementStep::new
# File lib/nose/backend/cassandra.rb, line 273 def initialize(client, select, conditions, step, next_step, prev_step) super @logger = Logging.logger['nose::backend::cassandra::indexlookupstep'] # TODO: Check if we can apply the next filter via ALLOW FILTERING @prepared = client.prepare select_cql(select, conditions) end
Public Instance Methods
process(conditions, results)
click to toggle source
Perform a column family lookup in Cassandra
# File lib/nose/backend/cassandra.rb, line 284 def process(conditions, results) results = initial_results(conditions) if results.nil? condition_list = result_conditions conditions, results new_result = fetch_all_queries condition_list, results # Limit the size of the results in case we fetched multiple keys new_result[0..(@step.limit.nil? ? -1 : @step.limit)] end
Private Instance Methods
cql_order_by()
click to toggle source
Produce the CQL ORDER BY clause for this step @return [String]
# File lib/nose/backend/cassandra.rb, line 325 def cql_order_by # TODO: CQL3 requires all clustered columns before the one actually # ordered on also be specified # # Example: # # SELECT * FROM cf WHERE id=? AND col1=? ORDER by col1, col2 return '' if @step.order_by.empty? ' ORDER BY ' + @step.order_by.map { |f| "\"#{f.id}\"" }.join(', ') end
cql_where_clause(conditions)
click to toggle source
Produce a CQL where clause using the given conditions @return [String]
# File lib/nose/backend/cassandra.rb, line 311 def cql_where_clause(conditions) where = @eq_fields.map do |field| "\"#{field.id}\" = ?" end.join ' AND ' unless @range_field.nil? condition = conditions.each_value.find(&:range?) where << " AND \"#{condition.field.id}\" #{condition.operator} ?" end where end
fetch_all_queries(condition_list, results)
click to toggle source
Lookup values from an index selecting the given fields and filtering on the given conditions
# File lib/nose/backend/cassandra.rb, line 338 def fetch_all_queries(condition_list, results) new_result = [] @logger.debug { " #{@prepared.cql} * #{condition_list.size}" } # TODO: Chain enumerables of results instead # Limit the total number of queries as well as the query limit condition_list.zip(results).each do |condition_set, result| # Loop over all pages to fetch results values = lookup_values condition_set fetch_query_pages values, new_result, result # Don't continue with further queries break if !@step.limit.nil? && new_result.length >= @step.limit end @logger.debug "Total result size = #{new_result.size}" new_result end
fetch_query_pages(values, new_result, result)
click to toggle source
Get the necessary pages of results for a given list of values
# File lib/nose/backend/cassandra.rb, line 358 def fetch_query_pages(values, new_result, result) new_results = @client.execute(@prepared, arguments: values) loop do # Add the previous results to each row rows = new_results.map { |row| result.merge row } # XXX Ignore null values in results for now # fail if rows.any? { |row| row.values.any?(&:nil?) } new_result.concat rows break if new_results.last_page? || (!@step.limit.nil? && result.length >= @step.limit) new_results = new_results.next_page @logger.debug "Fetched #{result.length} results" end end
lookup_values(condition_set)
click to toggle source
Produce the values used for lookup on a given set of conditions
# File lib/nose/backend/cassandra.rb, line 376 def lookup_values(condition_set) condition_set.map do |condition| value = condition.value || conditions[condition.field.id].value fail if value.nil? if condition.field.is_a?(Fields::IDField) Cassandra::Uuid.new(value.to_i) else value end end end
select_cql(select, conditions)
click to toggle source
Produce the select CQL statement for a provided set of fields @return [String]
# File lib/nose/backend/cassandra.rb, line 297 def select_cql(select, conditions) select = expand_selected_fields select cql = "SELECT #{select.map { |f| "\"#{f.id}\"" }.join ', '} FROM " \ "\"#{@step.index.key}\" WHERE #{cql_where_clause conditions}" cql += cql_order_by # Add an optional limit cql << " LIMIT #{@step.limit}" unless @step.limit.nil? cql end