class NoSE::Backend::Backend

Superclass of all database backends

Public Class Methods

new(model, indexes, plans, update_plans, _config) click to toggle source
# 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_id_graph() click to toggle source

By default, do not use ID graphs @return [Boolean]

# File lib/nose/backend.rb, line 20
def by_id_graph
  false
end
drop_index() click to toggle source

@abstract Subclasses implement to remove existing indexes @return [void]

# File lib/nose/backend.rb, line 38
def drop_index
end
generate_id() click to toggle source

@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
index_empty?(_index) click to toggle source

@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
index_exists?(_index) click to toggle source

@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
index_insert_chunk(_index, _chunk) click to toggle source

@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
indexes_ddl(_execute = false, _skip_existing = false, _drop_existing = false) click to toggle source

@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
indexes_sample(_index, _count) click to toggle source

@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(statement, plans = []) click to toggle source

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_query(query, fields, conditions, plans = []) click to toggle source

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_update(update, plans) click to toggle source

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
query(query, plans = []) click to toggle source

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
update(update, plans = []) click to toggle source

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_delete_step(plan, steps) click to toggle source

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_insert_step(plan, steps, fields) click to toggle source

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_query_plan(query) click to toggle source

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_update_plans(update) click to toggle source

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_query_steps(steps, fields, conditions) click to toggle source

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_support_plans(plan) click to toggle source

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