Skip to content

Commit

Permalink
feat: add source_conditions method
Browse files Browse the repository at this point in the history
Adds ability to specify WHERE-clause for select query from source tmp-table
  • Loading branch information
ZhidkovDenis committed Sep 14, 2015
1 parent a1d6595 commit 1f96c39
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 0 deletions.
15 changes: 15 additions & 0 deletions lib/redis_counters/dumpers/destination.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,18 @@ class Destination
# Условия соеденяются через AND.
attr_accessor :conditions

# Список дополнительных условий, которые применяются для выборки из source-таблицы для обновления
# target, Array of String.
# Каждое условие представляет собой строку - часть SQL выражения, которое может включать именованные
# параметры из числа доступных в хеше общих параметров дампера: engine.common_params.
# Условия соединяются через AND.
attr_accessor :source_conditions

def initialize(engine)
@engine = engine
@fields_map = HashWithIndifferentAccess.new
@conditions = []
@source_conditions = []
end

def merge
Expand All @@ -73,6 +81,7 @@ def merge
(
SELECT #{selected_fields_expression}
FROM #{source_table}
#{source_conditions_expression}
#{group_by_expression}
),
updated AS
Expand Down Expand Up @@ -133,6 +142,12 @@ def extra_conditions
result = conditions.map { |condition| "(#{condition})" }.join(' AND ')
result.present? ? "AND #{result}" : result
end

def source_conditions_expression
return if source_conditions.blank?

"WHERE #{source_conditions.map { |source_condition| "(#{source_condition})" }.join(' AND ')}"
end
end
end
end
4 changes: 4 additions & 0 deletions lib/redis_counters/dumpers/dsl/destination.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ def map(field, target_field)
def condition(value)
destination.conditions << value
end

def source_condition(value)
destination.source_conditions << value
end
end

module ClassMethods
Expand Down
59 changes: 59 additions & 0 deletions spec/lib/redis_counters/dumpers/engine_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -93,5 +93,64 @@
And { expect(StatsAggTotal.count).to eq 2 }
And { expect(StatsAggTotal.where(record_id: 1).first.hits).to eq 6 }
And { expect(StatsAggTotal.where(record_id: 2).first.hits).to eq 2 }

context 'with source conditions' do
let(:dumper) do
RedisCounters::Dumpers::Engine.build do
name :stats_totals
fields record_id: :integer,
column_id: :integer,
value: :integer,
date: :date

destination do
model StatsByDay
take :record_id, :column_id, :hits, :date
key_fields :record_id, :column_id, :date
increment_fields :hits
map :hits, to: :value
condition 'target.date = :date'
source_condition 'column_id = 100'
end

destination do
model StatsTotal
take :record_id, :column_id, :hits
key_fields :record_id, :column_id
increment_fields :hits
map :hits, to: :value
source_condition 'column_id = 100'
end

destination do
model StatsAggTotal
take :record_id, :hits
key_fields :record_id
increment_fields :hits
map :hits, to: 'sum(value)'
group_by :record_id
source_condition 'column_id = 100'
end

on_before_merge do |dumper, _connection|
dumper.common_params = {date: dumper.date.strftime('%Y-%m-%d')}
end
end
end

Then { expect(StatsByDay.count).to eq 4 }
And { expect(StatsByDay.where(record_id: 1, column_id: 100, date: prev_date).first.hits).to eq 1 }
And { expect(StatsByDay.where(record_id: 2, column_id: 100, date: prev_date).first.hits).to eq 1 }
And { expect(StatsByDay.where(record_id: 1, column_id: 100, date: date).first.hits).to eq 1 }
And { expect(StatsByDay.where(record_id: 2, column_id: 100, date: date).first.hits).to eq 1 }

And { expect(StatsTotal.count).to eq 2 }
And { expect(StatsTotal.where(record_id: 1, column_id: 100).first.hits).to eq 2 }
And { expect(StatsTotal.where(record_id: 2, column_id: 100).first.hits).to eq 2 }

And { expect(StatsAggTotal.count).to eq 2 }
And { expect(StatsAggTotal.where(record_id: 1).first.hits).to eq 2 }
And { expect(StatsAggTotal.where(record_id: 2).first.hits).to eq 2 }
end
end
end

0 comments on commit 1f96c39

Please sign in to comment.