class NoSE::Backend::Backend
Superclass of all database backends
Public Class Methods
# File lib/nose/backend.rb, line 11 def initialize(model, indexes, plans, update_plans, _config) @model = model @indexes = indexes @plans = plans @update_plans = update_plans end
Public Instance Methods
By default, do not use ID graphs @return [Boolean]
# File lib/nose/backend.rb, line 20 def by_id_graph false end
@abstract Subclasses implement to remove existing indexes @return [void]
# File lib/nose/backend.rb, line 38 def drop_index end
@abstract Subclasses implement to generate a new random ID :nocov: @return [Object]
# File lib/nose/backend.rb, line 53 def generate_id fail NotImplementedError end
@abstract Subclasses implement to check if an index is empty @return [Boolean]
# File lib/nose/backend.rb, line 26 def index_empty?(_index) true end
@abstract Subclasses implement to check if an index already exists @return [Boolean]
# File lib/nose/backend.rb, line 32 def index_exists?(_index) false end
@abstract Subclasses implement to allow inserting
data into the backend database
:nocov: @return [void]
# File lib/nose/backend.rb, line 45 def index_insert_chunk(_index, _chunk) fail NotImplementedError end
@abstract Subclasses should create indexes :nocov: @return [Enumerable]
# File lib/nose/backend.rb, line 61 def indexes_ddl(_execute = false, _skip_existing = false, _drop_existing = false) fail NotImplementedError end
@abstract Subclasses should return sample values from the index :nocov: @return [Array<Hash>]
# File lib/nose/backend.rb, line 70 def indexes_sample(_index, _count) fail NotImplementedError end
Prepare a statement to be executed with the given plans
# File lib/nose/backend.rb, line 87 def prepare(statement, plans = []) if statement.is_a? Query prepare_query statement, statement.all_fields, statement.conditions, plans elsif statement.is_a? Delete prepare_update statement, plans elsif statement.is_a? Disconnect prepare_update statement, plans elsif statement.is_a? Connection prepare_update statement, plans else prepare_update statement, plans end end
Prepare a query to be executed with the given plans @return [PreparedQuery]
# File lib/nose/backend.rb, line 77 def prepare_query(query, fields, conditions, plans = []) plan = plans.empty? ? find_query_plan(query) : plans.first state = Plans::QueryState.new(query, @model) unless query.nil? first_step = Plans::RootPlanStep.new state steps = [first_step] + plan.to_a + [nil] PreparedQuery.new query, prepare_query_steps(steps, fields, conditions) end
Prepare an update for execution @return [PreparedUpdate]
# File lib/nose/backend.rb, line 111 def prepare_update(update, plans) # Search for plans if they were not given plans = find_update_plans(update) if plans.empty? fail PlanNotFound if plans.empty? # Prepare each plan plans.map do |plan| delete = false insert = false plan.update_steps.each do |step| delete = true if step.is_a?(Plans::DeletePlanStep) insert = true if step.is_a?(Plans::InsertPlanStep) end steps = [] add_delete_step(plan, steps) if delete add_insert_step(plan, steps, plan.update_fields) if insert PreparedUpdate.new update, prepare_support_plans(plan), steps end end
Execute a query with the stored plans @return [Array<Hash>]
# File lib/nose/backend.rb, line 104 def query(query, plans = []) prepared = prepare query, plans prepared.execute query.conditions end
Execute an update with the stored plans @return [void]
# File lib/nose/backend.rb, line 135 def update(update, plans = []) prepared = prepare_update update, plans prepared.each { |p| p.execute update.settings, update.conditions } end
Private Instance Methods
Add a delete step to a prepared update plan @return [void]
# File lib/nose/backend.rb, line 331 def add_delete_step(plan, steps) step_class = DeleteStatementStep subclass_step_name = step_class.name.sub \ 'NoSE::Backend::Backend', self.class.name step_class = Object.const_get subclass_step_name steps << step_class.new(client, plan.index) end
Add an insert step to a prepared update plan @return [void]
# File lib/nose/backend.rb, line 341 def add_insert_step(plan, steps, fields) step_class = InsertStatementStep subclass_step_name = step_class.name.sub \ 'NoSE::Backend::Backend', self.class.name step_class = Object.const_get subclass_step_name steps << step_class.new(client, plan.index, fields) end
Find plans for a given query @return [Plans::QueryPlan]
# File lib/nose/backend.rb, line 297 def find_query_plan(query) plan = @plans.find do |possible_plan| possible_plan.query == query end unless query.nil? fail PlanNotFound if plan.nil? plan end
Find plans for a given update @return [Array<Plans::UpdatePlan>]
# File lib/nose/backend.rb, line 323 def find_update_plans(update) @update_plans.select do |possible_plan| possible_plan.statement == update end end
Prepare all the steps for executing a given query @return [Array<StatementStep>]
# File lib/nose/backend.rb, line 308 def prepare_query_steps(steps, fields, conditions) steps.each_cons(3).map do |prev_step, step, next_step| step_class = StatementStep.subtype_class step.subtype_name # Check if the subclass has overridden this step subclass_step_name = step_class.name.sub \ 'NoSE::Backend::Backend', self.class.name step_class = Object.const_get subclass_step_name step_class.new client, fields, conditions, step, next_step, prev_step end end
Prepare plans for each support query @return [Array<PreparedQuery>]
# File lib/nose/backend.rb, line 351 def prepare_support_plans(plan) plan.query_plans.map do |query_plan| query = query_plan.instance_variable_get(:@query) prepare_query query, query_plan.select_fields, query_plan.params, [query_plan.steps] end end