class NoSE::Backend::PreparedUpdate
An update prepared with a backend which is ready to execute
Attributes
statement[R]
steps[R]
Public Class Methods
new(statement, support_plans, steps)
click to toggle source
# File lib/nose/backend.rb, line 402 def initialize(statement, support_plans, steps) @statement = statement @support_plans = support_plans @delete_step = steps.find do |step| step.is_a? Backend::DeleteStatementStep end @insert_step = steps.find do |step| step.is_a? Backend::InsertStatementStep end end
Public Instance Methods
execute(update_settings, update_conditions)
click to toggle source
Execute the statement for the given set of conditions @return [void]
# File lib/nose/backend.rb, line 415 def execute(update_settings, update_conditions) # Execute all the support queries settings = initial_update_settings update_settings, update_conditions # Execute the support queries for this update support = support_results update_conditions # Perform the deletion @delete_step.process support unless support.empty? || @delete_step.nil? return if @insert_step.nil? # Get the fields which should be used from the original statement # If we didn't delete old entries, then we just need the primary key # attributes of the index, otherwise we need everything index = @insert_step.index include_fields = if @delete_step.nil? index.hash_fields + index.order_fields else index.all_fields end # Add fields from the original statement update_conditions.each_value do |condition| next unless include_fields.include? condition.field settings.merge! condition.field.id => condition.value end if support.empty? support = [settings] else support.each do |row| row.merge!(settings) { |_, value, _| value } end end # Stop if we have nothing to insert, otherwise insert return if support.empty? @insert_step.process support end
Private Instance Methods
initial_update_settings(update_settings, update_conditions)
click to toggle source
Get the initial values which will be used in the first plan step @return [Hash]
# File lib/nose/backend.rb, line 459 def initial_update_settings(update_settings, update_conditions) if !@insert_step.nil? && @delete_step.nil? # Populate the data to insert for Insert statements settings = Hash[update_settings.map do |setting| [setting.field.id, setting.value] end] else # Get values for updates and deletes settings = Hash[update_conditions.map do |field_id, condition| [field_id, condition.value] end] end settings end
support_results(settings)
click to toggle source
Execute all the support queries @return [Array<Hash>]
# File lib/nose/backend.rb, line 477 def support_results(settings) return [] if @support_plans.empty? # Get a hash of values used in settings, first # resolving any settings which specify foreign keys settings = Hash[settings.map do |k, v| new_condition = v.resolve_foreign_key [new_condition.field.id, new_condition] end] setting_values = Hash[settings.map { |k, v| [k, v.value] }] # If we have no query for IDs on the first entity, we must # have the fields we need to execute the other support queries if !@statement.nil? && @support_plans.first.query.entity != @statement.entity support = @support_plans.map do |plan| plan.execute settings end # Combine the results from multiple support queries unless support.empty? support = support.first.product(*support[1..-1]) support.map! do |results| results.reduce(&:merge!).merge!(setting_values) end end else # Execute the first support query to get a list of IDs first_query = @support_plans.first.query # We may not have a statement if this is manually defined if @statement.nil? select_key = false entity_fields = nil else id = @statement.entity.id_field select_key = first_query.select.include? id # Select any fields from the entity being modified if required entity_fields = @support_plans.first.execute settings \ if first_query.graph.size == 1 && \ first_query.graph.entities.first == @statement.entity end if select_key # Pull the IDs from the first support query conditions = entity_fields.map do |row| { id.id => Condition.new(id, :'=', row[id.id]) } end else # Use the ID specified in the statement conditions conditions = [settings] end # Execute the support queries for each ID support = conditions.each_with_index.flat_map do |condition, i| results = @support_plans[(select_key ? 1 : 0)..-1].map do |plan| plan.execute condition end # Combine the results of the different support queries results[0].product(*results[1..-1]).map do |result| row = result.reduce(&:merge!) row.merge!(entity_fields[i]) unless entity_fields.nil? row.merge!(setting_values) row end end end support end