Class: Atomically::QueryService

Inherits:
Object
  • Object
show all
Defined in:
lib/atomically/query_service.rb

Instance Method Summary collapse

Constructor Details

#initialize(klass, relation: nil, model: nil) ⇒ QueryService

Returns a new instance of QueryService.



11
12
13
14
15
# File 'lib/atomically/query_service.rb', line 11

def initialize(klass, relation: nil, model: nil)
  @klass = klass
  @relation = relation || @klass
  @model = model
end

Instance Method Details

#create_or_plus(columns, data, update_columns) ⇒ Object



17
18
19
# File 'lib/atomically/query_service.rb', line 17

def create_or_plus(columns, data, update_columns)
  @klass.import(columns, data, on_duplicate_key_update: on_duplicate_key_plus_sql(update_columns))
end

#pay_all(hash, update_columns, primary_key: :id) ⇒ Object

{ id => pay_count }



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/atomically/query_service.rb', line 21

def pay_all(hash, update_columns, primary_key: :id) # { id => pay_count }
  return 0 if hash.blank?

  update_columns = update_columns.map(&method(:quote_column))

  query = hash.inject(@klass.none) do |relation, (id, pay_count)|
    condition = @relation.where(primary_key => id)
    update_columns.each{|s| condition = condition.where("#{s} >= ?", pay_count) }
    next relation.or(condition)
  end

  raw_when_sql = hash.map{|id, pay_count| "WHEN #{sanitize(id)} THEN #{sanitize(-pay_count)}" }.join("\n")
  update_sqls = update_columns.map.with_index do |column, idx|
    value = idx == 0 ? "(@change := \nCASE #{quote_column(primary_key)}\n#{raw_when_sql}\nEND)" : '@change'
    next "#{column} = #{column} + #{value}"
  end

  return where_all_can_be_updated(query, hash.size).update_all(update_sqls.join(', '))
end

#update(attrs, from: :not_set) ⇒ Object



45
46
47
48
49
# File 'lib/atomically/query_service.rb', line 45

def update(attrs, from: :not_set)
  success = update_and_return_number_of_updated_rows(attrs, from) == 1
  assign_without_changes(attrs) if success
  return success
end

#update_all(expected_size, *args) ⇒ Object



41
42
43
# File 'lib/atomically/query_service.rb', line 41

def update_all(expected_size, *args)
  where_all_can_be_updated(@relation, expected_size).update_all(*args)
end

#update_all_and_get_ids(*args) ⇒ Object



51
52
53
54
55
56
57
58
59
60
# File 'lib/atomically/query_service.rb', line 51

def update_all_and_get_ids(*args)
  ids = nil
  id_column = "#{@klass.quoted_table_name}.#{quote_column(:id)}"
  @klass.transaction do
    @relation.connection.execute('SET @ids := NULL')
    @relation.where("(SELECT @ids := CONCAT_WS(',', #{id_column}, @ids))").update_all(*args) # 撈出有真的被更新的 id,用逗號串在一起
    ids = @klass.from(nil).pluck('@ids').first
  end
  return ids.try{|s| s.split(',').map(&:to_i).uniq.sort } || [] # 將 id 從字串取出來 @id 的格式範例: '1,4,12'
end