-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add abillity to work with mysql2 adapter
- Loading branch information
1 parent
7fd17b0
commit 2b8b0e8
Showing
4 changed files
with
104 additions
and
14 deletions.
There are no files selected for viewing
82 changes: 82 additions & 0 deletions
82
lib/activerecord_slotted_counters/adapters/mysql_upsert.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
# frozen_string_literal: true | ||
|
||
module ActiveRecordSlottedCounters | ||
module Adapters | ||
class MysqlUpsert | ||
attr_reader :klass, :current_adapter_name | ||
|
||
def initialize(klass, current_adapter_name) | ||
@klass = klass | ||
@current_adapter_name = current_adapter_name | ||
end | ||
|
||
def apply? | ||
return false unless defined?(ActiveRecord::ConnectionAdapters::Mysql2Adapter) | ||
|
||
current_adapter_name == ActiveRecord::ConnectionAdapters::Mysql2Adapter::ADAPTER_NAME | ||
end | ||
|
||
def bulk_insert(attributes, on_duplicate: nil, unique_by: nil) | ||
raise ArgumentError, "Values must not be empty" if attributes.empty? | ||
|
||
keys = attributes.first.keys + klass.all_timestamp_attributes_in_model | ||
|
||
current_time = klass.current_time_from_proper_timezone | ||
data = attributes.map { |attr| attr.values + [current_time, current_time] } | ||
|
||
columns = columns_for_attributes(keys) | ||
|
||
fields_str = quote_column_names(columns) | ||
values_str = quote_many_records(columns, data) | ||
|
||
sql = <<~SQL | ||
INSERT INTO #{klass.quoted_table_name} | ||
(#{fields_str}) | ||
VALUES #{values_str} | ||
SQL | ||
|
||
if on_duplicate.present? | ||
sql += " ON DUPLICATE KEY UPDATE #{on_duplicate};" | ||
end | ||
|
||
# insert/update and return amount of updated rows | ||
klass.connection.update(sql) | ||
end | ||
|
||
def wrap_column_name(value) | ||
"VALUES(#{value})" | ||
end | ||
|
||
private | ||
|
||
def columns_for_attributes(attributes) | ||
attributes.map do |attribute| | ||
klass.column_for_attribute(attribute) | ||
end | ||
end | ||
|
||
def quote_column_names(columns, table_name: false) | ||
columns.map do |column| | ||
column_name = klass.connection.quote_column_name(column.name) | ||
if table_name | ||
"#{klass.quoted_table_name}.#{column_name}" | ||
else | ||
column_name | ||
end | ||
end.join(",") | ||
end | ||
|
||
def quote_record(columns, record_values) | ||
values_str = record_values.each_with_index.map do |value, i| | ||
type = klass.connection.lookup_cast_type_from_column(columns[i]) | ||
klass.connection.quote(type.serialize(value)) | ||
end.join(",") | ||
"(#{values_str})" | ||
end | ||
|
||
def quote_many_records(columns, data) | ||
data.map { |values| quote_record(columns, values) }.join(",") | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters