Class: Upsert
- Inherits:
-
Object
- Object
- Upsert
- Defined in:
- lib/upsert.rb,
lib/upsert/row.rb,
lib/upsert/binary.rb,
lib/upsert/version.rb,
lib/upsert/connection.rb,
lib/upsert/merge_function.rb,
lib/upsert/connection/jdbc.rb,
lib/upsert/column_definition.rb,
lib/upsert/connection/sqlite3.rb,
lib/upsert/active_record_upsert.rb,
lib/upsert/merge_function/mysql.rb,
lib/upsert/connection/postgresql.rb,
lib/upsert/merge_function/sqlite3.rb,
lib/upsert/column_definition/mysql.rb,
lib/upsert/connection/Mysql2_Client.rb,
lib/upsert/connection/PG_Connection.rb,
lib/upsert/column_definition/sqlite3.rb,
lib/upsert/merge_function/postgresql.rb,
lib/upsert/connection/SQLite3_Database.rb,
lib/upsert/column_definition/postgresql.rb,
lib/upsert/merge_function/Mysql2_Client.rb,
lib/upsert/merge_function/PG_Connection.rb,
lib/upsert/connection/Java_OrgSqlite_Conn.rb,
lib/upsert/merge_function/SQLite3_Database.rb,
lib/upsert/merge_function/Java_OrgSqlite_Conn.rb,
lib/upsert/connection/Java_ComMysqlJdbc_JDBC4Connection.rb,
lib/upsert/connection/Java_OrgPostgresqlJdbc_PgConnection.rb,
lib/upsert/merge_function/Java_ComMysqlJdbc_JDBC4Connection.rb,
lib/upsert/merge_function/Java_OrgPostgresqlJdbc_PgConnection.rb
Defined Under Namespace
Modules: ActiveRecordUpsert
Constant Summary collapse
- MUTEX_FOR_PERFORM =
Mutex.new
- SINGLE_QUOTE =
%{'}
- DOUBLE_QUOTE =
%{"}
- BACKTICK =
%{`}
- X_AND_SINGLE_QUOTE =
%{x'}
- USEC_SPRINTF =
'%06d'
- SEC_FRACTION =
8.64e10
- NANO_FRACTION =
8.64e13
- ISO8601_DATETIME =
'%Y-%m-%d %H:%M:%S'
- ISO8601_DATE =
'%F'
- UTC_TZ =
'+00:00'
- NULL_WORD =
'NULL'
- METAL_CLASS_ALIAS =
{ 'PGConn' => 'PG::Connection', 'org.sqlite.Conn' => 'Java::OrgSqlite::Conn', # for some reason, org.sqlite.Conn doesn't have a ruby class name 'Sequel::Postgres::Adapter' => 'PG::Connection', # Only the Postgres adapter needs an alias }
- CREATED_COL_REGEX =
Only the Postgres adapter needs an alias
/\Acreated_(at|on)\z/
- VERSION =
"2.9.9"
Class Attribute Summary collapse
-
.logger ⇒ #info, ...
The current logger.
Instance Attribute Summary collapse
- #connection ⇒ Upsert::Connection readonly
- #table_name ⇒ String readonly
Class Method Summary collapse
-
.batch(connection, table_name, options = {}) {|Upsert| ... } ⇒ nil
(also: stream)
More efficient way of upserting multiple rows at once.
- .binary(v) ⇒ Upsert::Binary
-
.clear_database_functions(connection) ⇒ Object
Clear any database functions that may have been created.
- .mutex_for_function(upsert, row) ⇒ Object
- .mutex_for_row(upsert, row) ⇒ Object
-
.retrieve_mutex(*args) ⇒ Object
TODO: Rewrite this to use the thread_safe gem, perhaps?.
Instance Method Summary collapse
-
#initialize(connection, table_name, options = {}) ⇒ Upsert
constructor
A new instance of Upsert.
- #merge_function(row) ⇒ Object
-
#row(selector, setter = {}, options = nil) ⇒ nil
Upsert a row given a selector and a setter.
Constructor Details
#initialize(connection, table_name, options = {}) ⇒ Upsert
Returns a new instance of Upsert.
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 |
# File 'lib/upsert.rb', line 212 def initialize(connection, table_name, = {}) @table_name = self.class.normalize_table_name(table_name) = Upsert. connection @flavor = Upsert.flavor @adapter = Upsert.adapter # todo memoize Dir[File.("../upsert/**/{#{flavor.downcase},#{adapter}}.rb", __FILE__)].each do |path| require path end @connection = Connection.const_get(adapter).new self, @merge_function_class = MergeFunction.const_get adapter @merge_function_cache = {} @assume_function_exists = .fetch :assume_function_exists, @flavor != "Postgresql" @merge_function_mutex = Mutex.new @row_mutex = Mutex.new end |
Class Attribute Details
.logger ⇒ #info, ...
The current logger
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/upsert.rb', line 21 def logger @logger || MUTEX_FOR_PERFORM.synchronize do @logger ||= if defined?(::Rails) and (rails_logger = ::Rails.logger) rails_logger elsif defined?(::ActiveRecord) and ::ActiveRecord.const_defined?(:Base) and (ar_logger = ::ActiveRecord::Base.logger) ar_logger else my_logger = Logger.new $stderr case ENV['UPSERT_DEBUG'] when 'true' my_logger.level = Logger::DEBUG when 'false' my_logger.level = Logger::INFO end my_logger end end end |
Instance Attribute Details
#connection ⇒ Upsert::Connection (readonly)
189 190 191 |
# File 'lib/upsert.rb', line 189 def connection @connection end |
#table_name ⇒ String (readonly)
192 193 194 |
# File 'lib/upsert.rb', line 192 def table_name @table_name end |
Class Method Details
.batch(connection, table_name, options = {}) {|Upsert| ... } ⇒ nil Also known as: stream
More efficient way of upserting multiple rows at once.
96 97 98 99 |
# File 'lib/upsert.rb', line 96 def batch(connection, table_name, = {}) upsert = new connection, table_name, yield upsert end |
.clear_database_functions(connection) ⇒ Object
Clear any database functions that may have been created.
Currently only applies to PostgreSQL.
70 71 72 73 |
# File 'lib/upsert.rb', line 70 def clear_database_functions(connection) dummy = new(connection, :dummy) dummy.clear_database_functions end |
.mutex_for_function(upsert, row) ⇒ Object
44 45 46 |
# File 'lib/upsert.rb', line 44 def mutex_for_function(upsert, row) retrieve_mutex(upsert.table_name, row.selector.keys, row.setter.keys) end |
.mutex_for_row(upsert, row) ⇒ Object
40 41 42 |
# File 'lib/upsert.rb', line 40 def mutex_for_row(upsert, row) retrieve_mutex(upsert.table_name, row.selector.keys) end |
.retrieve_mutex(*args) ⇒ Object
TODO: Rewrite this to use the thread_safe gem, perhaps?
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/upsert.rb', line 49 def retrieve_mutex(*args) # ||= isn't an atomic operation MUTEX_FOR_PERFORM.synchronize do @mutex_cache ||= {} end @mutex_cache.fetch(args.flatten.join('::')) do |k| MUTEX_FOR_PERFORM.synchronize do # We still need the ||= because this block could have # theoretically been entered simultaneously by two threads # but the actual assignment is protected by the mutex @mutex_cache[k] ||= Mutex.new end end end |
Instance Method Details
#merge_function(row) ⇒ Object
258 259 260 261 262 263 264 |
# File 'lib/upsert.rb', line 258 def merge_function(row) cache_key = [row.selector.keys, row.setter.keys] self.class.mutex_for_function(self, row).synchronize do @merge_function_cache[cache_key] ||= merge_function_class.new(self, row.selector.keys, row.setter.keys, assume_function_exists?) end end |
#row(selector, setter = {}, options = nil) ⇒ nil
Upsert a row given a selector and a setter.
The selector values are used as setters if it’s a new row. So if your selector is ‘name=Jerry` and your setter is `age=4`, and there is no Jerry yet, then a new row will be created with name Jerry and age 4.
245 246 247 248 249 250 251 |
# File 'lib/upsert.rb', line 245 def row(selector, setter = {}, = nil) row_object = Row.new(selector, setter, ) self.class.mutex_for_row(self, row_object).synchronize do merge_function(row_object).execute(row_object) nil end end |