Class: Upsert

Inherits:
Object
  • Object
show all
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/merge_function/Java_ComMysqlJdbc_JDBC4Connection.rb,
lib/upsert/connection/Java_OrgPostgresqlJdbc4_Jdbc4Connection.rb,
lib/upsert/merge_function/Java_OrgPostgresqlJdbc4_Jdbc4Connection.rb

Defined Under Namespace

Modules: ActiveRecordUpsert

Constant Summary

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.2.1'

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(connection, table_name, options = {}) ⇒ Upsert

Returns a new instance of Upsert

Options Hash (options):

  • :assume_function_exists (TrueClass, FalseClass) — default: true

    Assume the function has already been defined correctly by another process.



187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/upsert.rb', line 187

def initialize(connection, table_name, options = {})
  @table_name = table_name.to_s
  metal = Upsert.metal connection
  @flavor = Upsert.flavor metal
  @adapter = Upsert.adapter metal
  # todo memoize
  Dir[File.expand_path("../upsert/**/{#{flavor.downcase},#{adapter}}.rb", __FILE__)].each do |path|
    require path
  end
  @connection = Connection.const_get(adapter).new self, metal
  @merge_function_class = MergeFunction.const_get adapter
  @merge_function_cache = {}
  @assume_function_exists = options.fetch :assume_function_exists, true

  @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

#connectionUpsert::Connection (readonly)



164
165
166
# File 'lib/upsert.rb', line 164

def connection
  @connection
end

#table_nameString (readonly)



167
168
169
# File 'lib/upsert.rb', line 167

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.

Examples:

Many at once

Upsert.batch(Pet.connection, Pet.table_name) do |upsert|
  upsert.row({:name => 'Jerry'}, :breed => 'beagle')
  upsert.row({:name => 'Pierre'}, :breed => 'tabby')
end

Yields:

  • (Upsert)

    An Upsert object in batch mode. You can call #row on it multiple times and it will try to optimize on speed.



71
72
73
74
# File 'lib/upsert.rb', line 71

def batch(connection, table_name, options = {})
  upsert = new connection, table_name, options
  yield upsert
end

.binary(v) ⇒ Upsert::Binary



53
54
55
# File 'lib/upsert.rb', line 53

def binary(v)
  Binary.new v
end

.clear_database_functions(connection) ⇒ Object

Clear any database functions that may have been created.

Currently only applies to PostgreSQL.



45
46
47
48
# File 'lib/upsert.rb', line 45

def clear_database_functions(connection)
  dummy = new(connection, :dummy)
  dummy.clear_database_functions
end

Instance Method Details

#merge_function(row) ⇒ Object



233
234
235
236
237
238
239
# File 'lib/upsert.rb', line 233

def merge_function(row)
  cache_key = [row.selector.keys, row.setter.keys]
  @merge_function_mutex.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.

Examples:

One at a time

upsert = Upsert.new Pet.connection, Pet.table_name
upsert.row({:name => 'Jerry'}, :breed => 'beagle')
upsert.row({:name => 'Pierre'}, :breed => 'tabby')

See Also:



220
221
222
223
224
225
226
# File 'lib/upsert.rb', line 220

def row(selector, setter = {}, options = nil)
  @row_mutex.synchronize do
    row_object = Row.new(selector, setter, options)
    merge_function(row_object).execute(row_object)
    nil
  end
end