Class: RedisCounters::Dumpers::Destination

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
RedisCounters::Dumpers::Dsl::Destination
Defined in:
lib/redis_counters/dumpers/destination.rb

Overview

Класс представляет конечную точку сохранения данных счетчика.

Описывает в какую модель (таблицу), какие поля имеющиеся в распоряжении дампера, должны быть сохранены и каким образом.

По сути, мерджит указанные поля из temp - таблицы, дампера в указанную таблицу.

Может использоваться как напрямую так и с помощью DSL (см. модуль RedisCounters::Dumpers::Dsl::Destination).

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(engine) ⇒ Destination

Returns a new instance of Destination.



57
58
59
60
61
# File 'lib/redis_counters/dumpers/destination.rb', line 57

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

Instance Attribute Details

#conditionsObject

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



55
56
57
# File 'lib/redis_counters/dumpers/destination.rb', line 55

def conditions
  @conditions
end

#engineObject

Ссылка на родительский движек - дампер.



22
23
24
# File 'lib/redis_counters/dumpers/destination.rb', line 22

def engine
  @engine
end

#fieldsObject

Список полей, из доступных дамперу, которые необходимо сохранить, Array.



28
29
30
# File 'lib/redis_counters/dumpers/destination.rb', line 28

def fields
  @fields
end

#fields_mapObject

Карта полей - карта псевдонимов полей, Hash. Названия полей в целевой таблице, могут отличаться от названий полей дампера. Для сопоставления полей целевой таблицы и дампера, необходимо заполнить карту соответствия. Карта, заполняется только для тех полей, названия которых отличаются. Во всех свойствах, содержащий указания полей: fields, key_fields, increment_fields, conditions используются имена конечных полей целевой таблицы.

Example:

fields_map = {:pages => :value, :date => :start_month_date}

Означает, что целевое поле :pages, указывает на поле :value, дампера, а целевое поле :date, указывает на поле :start_month_date, дампера.



49
50
51
# File 'lib/redis_counters/dumpers/destination.rb', line 49

def fields_map
  @fields_map
end

#increment_fieldsObject

Список полей, которые будет инкрементированы при обновлении существующей записи, Array.



35
36
37
# File 'lib/redis_counters/dumpers/destination.rb', line 35

def increment_fields
  @increment_fields
end

#key_fieldsObject

Список полей, по комбинации которых, будет происходить определение существования записи, при мердже данных, Array.



32
33
34
# File 'lib/redis_counters/dumpers/destination.rb', line 32

def key_fields
  @key_fields
end

#modelObject

Модель, в таблицу, которой будет производится мердж данных, AR::Model.



25
26
27
# File 'lib/redis_counters/dumpers/destination.rb', line 25

def model
  @model
end

Instance Method Details

#mergeObject



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/redis_counters/dumpers/destination.rb', line 63

def merge
  target_fields = fields.join(', ')

  sql = <<-SQL
    WITH
      source AS
      (
        SELECT #{selected_fields_expression}
          FROM #{source_table}
      ),
      updated AS
      (
        UPDATE #{target_table} target
        SET
          #{updating_expression}
        FROM source
        WHERE #{matching_expression}
          #{extra_conditions}
        RETURNING target.*
      )
    INSERT INTO #{target_table} (#{target_fields})
      SELECT #{target_fields}
      FROM source
    WHERE NOT EXISTS (
      SELECT 1
        FROM updated target
      WHERE #{matching_expression}
        #{extra_conditions}
    )
  SQL

  sql = model.send(:sanitize_sql, [sql, engine.common_params])
  connection.execute sql
end