upsert 2.9.9-universal-java-11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/.ruby-version +1 -0
- data/.standard.yml +1 -0
- data/.travis.yml +63 -0
- data/.yardopts +2 -0
- data/CHANGELOG +265 -0
- data/Gemfile +16 -0
- data/LICENSE +24 -0
- data/README.md +411 -0
- data/Rakefile +54 -0
- data/lib/upsert.rb +284 -0
- data/lib/upsert/active_record_upsert.rb +12 -0
- data/lib/upsert/binary.rb +8 -0
- data/lib/upsert/column_definition.rb +79 -0
- data/lib/upsert/column_definition/mysql.rb +24 -0
- data/lib/upsert/column_definition/postgresql.rb +66 -0
- data/lib/upsert/column_definition/sqlite3.rb +34 -0
- data/lib/upsert/connection.rb +37 -0
- data/lib/upsert/connection/Java_ComMysqlJdbc_JDBC4Connection.rb +31 -0
- data/lib/upsert/connection/Java_OrgPostgresqlJdbc_PgConnection.rb +33 -0
- data/lib/upsert/connection/Java_OrgSqlite_Conn.rb +17 -0
- data/lib/upsert/connection/Mysql2_Client.rb +76 -0
- data/lib/upsert/connection/PG_Connection.rb +35 -0
- data/lib/upsert/connection/SQLite3_Database.rb +28 -0
- data/lib/upsert/connection/jdbc.rb +105 -0
- data/lib/upsert/connection/postgresql.rb +24 -0
- data/lib/upsert/connection/sqlite3.rb +19 -0
- data/lib/upsert/merge_function.rb +73 -0
- data/lib/upsert/merge_function/Java_ComMysqlJdbc_JDBC4Connection.rb +42 -0
- data/lib/upsert/merge_function/Java_OrgPostgresqlJdbc_PgConnection.rb +27 -0
- data/lib/upsert/merge_function/Java_OrgSqlite_Conn.rb +10 -0
- data/lib/upsert/merge_function/Mysql2_Client.rb +36 -0
- data/lib/upsert/merge_function/PG_Connection.rb +26 -0
- data/lib/upsert/merge_function/SQLite3_Database.rb +10 -0
- data/lib/upsert/merge_function/mysql.rb +66 -0
- data/lib/upsert/merge_function/postgresql.rb +365 -0
- data/lib/upsert/merge_function/sqlite3.rb +43 -0
- data/lib/upsert/row.rb +59 -0
- data/lib/upsert/version.rb +3 -0
- data/spec/active_record_upsert_spec.rb +26 -0
- data/spec/binary_spec.rb +21 -0
- data/spec/correctness_spec.rb +190 -0
- data/spec/database_functions_spec.rb +106 -0
- data/spec/database_spec.rb +121 -0
- data/spec/hstore_spec.rb +249 -0
- data/spec/jruby_spec.rb +9 -0
- data/spec/logger_spec.rb +52 -0
- data/spec/misc/get_postgres_reserved_words.rb +12 -0
- data/spec/misc/mysql_reserved.txt +226 -0
- data/spec/misc/pg_reserved.txt +742 -0
- data/spec/multibyte_spec.rb +27 -0
- data/spec/postgresql_spec.rb +94 -0
- data/spec/precision_spec.rb +11 -0
- data/spec/reserved_words_spec.rb +50 -0
- data/spec/sequel_spec.rb +57 -0
- data/spec/spec_helper.rb +417 -0
- data/spec/speed_spec.rb +44 -0
- data/spec/threaded_spec.rb +57 -0
- data/spec/timezones_spec.rb +58 -0
- data/spec/type_safety_spec.rb +12 -0
- data/travis/install_postgres.sh +18 -0
- data/travis/run_docker_db.sh +20 -0
- data/travis/tune_mysql.sh +7 -0
- data/upsert-java.gemspec +13 -0
- data/upsert.gemspec +11 -0
- data/upsert.gemspec.common +107 -0
- metadata +373 -0
@@ -0,0 +1,43 @@
|
|
1
|
+
class Upsert
|
2
|
+
class MergeFunction
|
3
|
+
# @private
|
4
|
+
module Sqlite3
|
5
|
+
def self.included(klass)
|
6
|
+
klass.extend ClassMethods
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
def clear(*)
|
11
|
+
# not necessary
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :quoted_setter_names
|
16
|
+
attr_reader :quoted_update_names
|
17
|
+
attr_reader :quoted_selector_names
|
18
|
+
|
19
|
+
def initialize(*)
|
20
|
+
super
|
21
|
+
@quoted_setter_names = setter_keys.map { |k| connection.quote_ident k }
|
22
|
+
@quoted_update_names = setter_keys.select { |k| k !~ CREATED_COL_REGEX }.map { |k| connection.quote_ident k }
|
23
|
+
@quoted_selector_names = selector_keys.map { |k| connection.quote_ident k }
|
24
|
+
end
|
25
|
+
|
26
|
+
def create!
|
27
|
+
# not necessary
|
28
|
+
end
|
29
|
+
|
30
|
+
def execute(row)
|
31
|
+
bind_setter_values = row.setter.values.map { |v| connection.bind_value v }
|
32
|
+
bind_selector_values = row.selector.values.map { |v| connection.bind_value v }
|
33
|
+
bind_update_values = row.setter.select{ |k,v| k !~ CREATED_COL_REGEX }.map { |k,v| connection.bind_value v }
|
34
|
+
|
35
|
+
insert_or_ignore_sql = %{INSERT OR IGNORE INTO #{quoted_table_name} (#{quoted_setter_names.join(',')}) VALUES (#{Array.new(bind_setter_values.length, '?').join(',')})}
|
36
|
+
connection.execute insert_or_ignore_sql, bind_setter_values
|
37
|
+
|
38
|
+
update_sql = %{UPDATE #{quoted_table_name} SET #{quoted_update_names.map { |qk| "#{qk}=?" }.join(',')} WHERE #{quoted_selector_names.map { |qk| "#{qk}=?" }.join(' AND ')}}
|
39
|
+
connection.execute update_sql, (bind_update_values + bind_selector_values)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/upsert/row.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
class Upsert
|
2
|
+
# @private
|
3
|
+
class Row
|
4
|
+
if RUBY_VERSION >= '1.9'
|
5
|
+
OrderedHash = ::Hash
|
6
|
+
else
|
7
|
+
begin
|
8
|
+
require 'orderedhash'
|
9
|
+
rescue LoadError
|
10
|
+
raise LoadError, "[upsert] If you're using upsert on Ruby 1.8, you need to add 'orderedhash' to your Gemfile."
|
11
|
+
end
|
12
|
+
OrderedHash = ::OrderedHash
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :selector
|
16
|
+
attr_reader :setter
|
17
|
+
attr_reader :hstore_delete_keys
|
18
|
+
|
19
|
+
def initialize(raw_selector, raw_setter, options)
|
20
|
+
eager_nullify = (options.nil? || options.fetch(:eager_nullify, true))
|
21
|
+
|
22
|
+
@selector = raw_selector.inject({}) do |memo, (k, v)|
|
23
|
+
memo[k.to_s] = v
|
24
|
+
memo
|
25
|
+
end
|
26
|
+
|
27
|
+
@hstore_delete_keys = {}
|
28
|
+
@setter = raw_setter.inject({}) do |memo, (k, v)|
|
29
|
+
k = k.to_s
|
30
|
+
if v.is_a?(::Hash) and eager_nullify
|
31
|
+
v.each do |kk, vv|
|
32
|
+
if vv.nil?
|
33
|
+
(@hstore_delete_keys[k] ||= []) << kk
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
memo[k] = v
|
38
|
+
memo
|
39
|
+
end
|
40
|
+
|
41
|
+
(selector.keys - setter.keys).each do |missing|
|
42
|
+
setter[missing] = selector[missing]
|
43
|
+
end
|
44
|
+
|
45
|
+
# there is probably a more clever way to incrementally sort these hashes
|
46
|
+
@selector = sort_hash selector
|
47
|
+
@setter = sort_hash setter
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def sort_hash(original)
|
53
|
+
original.keys.sort.inject(OrderedHash.new) do |memo, k|
|
54
|
+
memo[k] = original[k]
|
55
|
+
memo
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'upsert/active_record_upsert'
|
4
|
+
|
5
|
+
describe Upsert do
|
6
|
+
describe 'the optional active_record extension' do
|
7
|
+
describe :upsert do
|
8
|
+
it "is easy to use" do
|
9
|
+
assert_creates(Pet,[{:name => 'Jerry', :good => true}]) do
|
10
|
+
Pet.upsert({:name => 'Jerry'}, :good => false)
|
11
|
+
Pet.upsert({:name => 'Jerry'}, :good => true)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
it "doesn't fail inside a transaction" do
|
16
|
+
Upsert.clear_database_functions(Pet.connection)
|
17
|
+
expect {
|
18
|
+
Pet.transaction do
|
19
|
+
Pet.upsert({name: 'Simba'}, good: true)
|
20
|
+
end
|
21
|
+
}.to_not raise_error
|
22
|
+
expect(Pet.first.name).to eq('Simba')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/spec/binary_spec.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
describe Upsert do
|
3
|
+
describe "supports binary upserts" do
|
4
|
+
before do
|
5
|
+
@fakes = []
|
6
|
+
10.times do
|
7
|
+
@fakes << [Faker::Name.name, Faker::Lorem.paragraphs(10).join("\n\n")]
|
8
|
+
end
|
9
|
+
end
|
10
|
+
it "saves binary one by one" do
|
11
|
+
@fakes.each do |name, biography|
|
12
|
+
zipped_biography = Zlib::Deflate.deflate biography
|
13
|
+
upsert = Upsert.new $conn, :pets
|
14
|
+
assert_creates(Pet, [{:name => name, :zipped_biography => zipped_biography}]) do
|
15
|
+
upsert.row({:name => name}, {:zipped_biography => Upsert.binary(zipped_biography)})
|
16
|
+
end
|
17
|
+
Zlib::Inflate.inflate(Pet.find_by_name(name).zipped_biography).should == biography
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,190 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
describe Upsert do
|
5
|
+
describe 'clever correctness' do
|
6
|
+
it "doesn't confuse selector and setter" do
|
7
|
+
p = Pet.new
|
8
|
+
p.name = 'Jerry'
|
9
|
+
p.tag_number = 5
|
10
|
+
p.save!
|
11
|
+
|
12
|
+
# won't change anything because selector is wrong
|
13
|
+
u = Upsert.new($conn, :pets)
|
14
|
+
selector = {:name => 'Jerry', :tag_number => 6}
|
15
|
+
u.row(selector)
|
16
|
+
p.reload.tag_number.should == 5
|
17
|
+
next
|
18
|
+
|
19
|
+
# won't change anything because selector is wrong
|
20
|
+
u = Upsert.new($conn, :pets)
|
21
|
+
selector = {:name => 'Jerry', :tag_number => 10}
|
22
|
+
setter = { :tag_number => 5 }
|
23
|
+
u.row(selector, setter)
|
24
|
+
Pet.find_by_name('Jerry').tag_number.should == 5
|
25
|
+
|
26
|
+
u = Upsert.new($conn, :pets)
|
27
|
+
selector = { :name => 'Jerry' }
|
28
|
+
setter = { :tag_number => 10 }
|
29
|
+
u.row(selector, setter)
|
30
|
+
Pet.find_by_name('Jerry').tag_number.should == 10
|
31
|
+
|
32
|
+
u = Upsert.new($conn, :pets)
|
33
|
+
selector = { :name => 'Jerry', :tag_number => 10 }
|
34
|
+
setter = { :tag_number => 20 }
|
35
|
+
u.row(selector, setter)
|
36
|
+
Pet.find_by_name('Jerry').tag_number.should == 20
|
37
|
+
end
|
38
|
+
|
39
|
+
it "really limits its effects to the selector" do
|
40
|
+
p = Pet.new
|
41
|
+
p.name = 'Jerry'
|
42
|
+
p.gender = 'blue'
|
43
|
+
p.tag_number = 777
|
44
|
+
p.save!
|
45
|
+
Pet.find_by_name_and_gender('Jerry', 'blue').tag_number.should == 777
|
46
|
+
u = Upsert.new($conn, :pets)
|
47
|
+
selector = {:name => 'Jerry', :gender => 'red'} # this shouldn't select anything
|
48
|
+
setter = {:tag_number => 888}
|
49
|
+
u.row(selector, setter)
|
50
|
+
Pet.find_by_name_and_gender('Jerry', 'blue').tag_number.should == 777
|
51
|
+
end
|
52
|
+
|
53
|
+
# https://github.com/seamusabshere/upsert/issues/18
|
54
|
+
it "uses nil selectors" do
|
55
|
+
Pet.count.should == 0
|
56
|
+
now = Date.today
|
57
|
+
u = Upsert.new($conn, :pets)
|
58
|
+
5.times do
|
59
|
+
u.row(:gender => nil, :birthday => now)
|
60
|
+
end
|
61
|
+
|
62
|
+
Pet.count.should == 1
|
63
|
+
end
|
64
|
+
|
65
|
+
it "uses nil selectors on columns with date type" do
|
66
|
+
Pet.count.should == 0
|
67
|
+
u = Upsert.new($conn, :pets)
|
68
|
+
5.times do
|
69
|
+
u.row(:birthday => nil)
|
70
|
+
end
|
71
|
+
|
72
|
+
Pet.count.should == 1
|
73
|
+
end
|
74
|
+
|
75
|
+
it "uses nil selectors (another way of checking)" do
|
76
|
+
u = Upsert.new($conn, :pets)
|
77
|
+
now = Date.today
|
78
|
+
assert_creates(Pet, [{:name => 'Jerry', :gender => nil, :spiel => 'beagle', :birthday => now}]) do
|
79
|
+
u.row(:name => "Jerry", :gender => nil, :spiel => "samoyed")
|
80
|
+
u.row({:name => 'Jerry', :gender => nil}, :spiel => 'beagle', :birthday => now)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
it "works with utf-8 data" do
|
85
|
+
u = Upsert.new($conn, :pets)
|
86
|
+
records = [
|
87
|
+
{:name => '你好', :home_address => '人'},
|
88
|
+
{:name => 'Здравствуйте', :home_address => 'человек'},
|
89
|
+
{:name => '😀', :home_address => '😂'},
|
90
|
+
]
|
91
|
+
assert_creates(Pet, records) do
|
92
|
+
records.each { |rec| u.row(rec) }
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
it "tells you if you request a column that doesn't exist" do
|
97
|
+
u = Upsert.new($conn, :pets)
|
98
|
+
lambda { u.row(:gibberish => 'ba') }.should raise_error(/invalid col/i)
|
99
|
+
lambda { u.row(:name => 'Jerry', :gibberish => 'ba') }.should raise_error(/invalid col/i)
|
100
|
+
lambda { u.row(:name => 'Jerry', :gibberish => 'ba') }.should raise_error(/invalid col/i)
|
101
|
+
lambda { u.row(:name => 'Jerry', :gibberish => 'ba', :gender => 'male') }.should raise_error(/invalid col/i)
|
102
|
+
end
|
103
|
+
|
104
|
+
it "works with a long setter hash" do
|
105
|
+
Upsert.batch($conn, :alphabets) do |batch|
|
106
|
+
10_000.times do |time|
|
107
|
+
setter = Hash[("a".."z").map { |letter| ["the_letter_#{letter}".to_sym, rand(100)] }]
|
108
|
+
selector = Hash[("a".."z").map { |letter| ["the_letter_#{letter}".to_sym, rand(100)] }]
|
109
|
+
batch.row(setter, selector)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe "is just as correct as other ways" do
|
116
|
+
describe 'compared to native ActiveRecord' do
|
117
|
+
it "is as correct as than new/set/save" do
|
118
|
+
assert_same_result lotsa_records do |records|
|
119
|
+
records.each do |selector, setter|
|
120
|
+
if (pet = Pet.where(selector).first)
|
121
|
+
pet.update_attributes(setter)
|
122
|
+
else
|
123
|
+
pet = Pet.new
|
124
|
+
selector.each do |k, v|
|
125
|
+
pet.send "#{k}=", v
|
126
|
+
end
|
127
|
+
setter.each do |k, v|
|
128
|
+
pet.send "#{k}=", v
|
129
|
+
end
|
130
|
+
pet.save!
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
# it "is as correct as than find_or_create + update_attributes" do
|
136
|
+
# assert_same_result lotsa_records do |records|
|
137
|
+
# dynamic_method = nil
|
138
|
+
# records.each do |selector, setter|
|
139
|
+
# dynamic_method ||= "find_or_create_by_#{selector.keys.join('_or_')}"
|
140
|
+
# pet = Pet.send(dynamic_method, *selector.values)
|
141
|
+
# pet.update_attributes setter, :without_protection => true
|
142
|
+
# end
|
143
|
+
# end
|
144
|
+
# end
|
145
|
+
# it "is as correct as than create + rescue/find/update" do
|
146
|
+
# assert_same_result lotsa_records do |records|
|
147
|
+
# dynamic_method = nil
|
148
|
+
# records.each do |selector, setter|
|
149
|
+
# dynamic_method ||= "find_or_create_by_#{selector.keys.join('_or_')}"
|
150
|
+
# begin
|
151
|
+
# Pet.create selector.merge(setter), :without_protection => true
|
152
|
+
# rescue
|
153
|
+
# pet = Pet.send(dynamic_method, *selector.values)
|
154
|
+
# pet.update_attributes setter, :without_protection => true
|
155
|
+
# end
|
156
|
+
# end
|
157
|
+
# end
|
158
|
+
# end
|
159
|
+
end
|
160
|
+
|
161
|
+
if ENV['DB'] == 'mysql' || (UNIQUE_CONSTRAINT && ENV["DB"] == "postgresql")
|
162
|
+
describe 'compared to activerecord-import' do
|
163
|
+
it "is as correct as faking upserts with activerecord-import" do
|
164
|
+
assert_same_result lotsa_records do |records|
|
165
|
+
columns = nil
|
166
|
+
all_values = []
|
167
|
+
# Reverse because we want to mimic an 'overwrite' of previous values
|
168
|
+
records = records.reverse.uniq { |s, _| s } if ENV['DB'] == "postgresql"
|
169
|
+
|
170
|
+
records.each do |selector, setter|
|
171
|
+
columns ||= (selector.keys + setter.keys).uniq
|
172
|
+
all_values << columns.map do |k|
|
173
|
+
if setter.has_key?(k)
|
174
|
+
# prefer the setter so that you can change rows
|
175
|
+
setter[k]
|
176
|
+
else
|
177
|
+
selector[k]
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
conflict_update = ENV['DB'] == "postgresql" ? {conflict_target: records.first.first.keys, columns: columns} : columns
|
183
|
+
Pet.import columns, all_values, :timestamps => false, :on_duplicate_key_update => conflict_update
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
end
|
190
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'stringio'
|
3
|
+
require 'upsert/merge_function/postgresql'
|
4
|
+
|
5
|
+
describe Upsert do
|
6
|
+
describe 'database functions' do
|
7
|
+
version = 'postgresql' == ENV['DB'] ? Upsert::MergeFunction::Postgresql.extract_version(
|
8
|
+
Pet.connection.select_value("SHOW server_version")
|
9
|
+
) : 0
|
10
|
+
before(:each) {
|
11
|
+
skip "Not using DB functions" if 'postgresql' == ENV['DB'] && UNIQUE_CONSTRAINT && version >= 90500
|
12
|
+
}
|
13
|
+
it "does not re-use merge functions across connections" do
|
14
|
+
begin
|
15
|
+
io = StringIO.new
|
16
|
+
old_logger = Upsert.logger
|
17
|
+
Upsert.logger = Logger.new io, Logger::INFO
|
18
|
+
|
19
|
+
# clear, create (#1)
|
20
|
+
Upsert.clear_database_functions($conn_factory.new_connection)
|
21
|
+
Upsert.new($conn_factory.new_connection, :pets).row :name => 'hello'
|
22
|
+
|
23
|
+
# clear, create (#2)
|
24
|
+
Upsert.clear_database_functions($conn_factory.new_connection)
|
25
|
+
Upsert.new($conn_factory.new_connection, :pets).row :name => 'hello'
|
26
|
+
|
27
|
+
io.rewind
|
28
|
+
hits = io.read.split("\n").grep(/Creating or replacing/)
|
29
|
+
hits.length.should == 2
|
30
|
+
ensure
|
31
|
+
Upsert.logger = old_logger
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it "does not re-use merge functions even when on the same connection" do
|
36
|
+
begin
|
37
|
+
io = StringIO.new
|
38
|
+
old_logger = Upsert.logger
|
39
|
+
Upsert.logger = Logger.new io, Logger::INFO
|
40
|
+
|
41
|
+
connection = $conn_factory.new_connection
|
42
|
+
|
43
|
+
# clear, create (#1)
|
44
|
+
Upsert.clear_database_functions(connection)
|
45
|
+
Upsert.new(connection, :pets).row :name => 'hello'
|
46
|
+
|
47
|
+
# clear, create (#2)
|
48
|
+
Upsert.clear_database_functions(connection)
|
49
|
+
Upsert.new(connection, :pets).row :name => 'hello'
|
50
|
+
|
51
|
+
io.rewind
|
52
|
+
hits = io.read.split("\n").grep(/Creating or replacing/)
|
53
|
+
hits.length.should == 2
|
54
|
+
ensure
|
55
|
+
Upsert.logger = old_logger
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
it "re-uses merge functions within batch" do
|
60
|
+
begin
|
61
|
+
io = StringIO.new
|
62
|
+
old_logger = Upsert.logger
|
63
|
+
Upsert.logger = Logger.new io, Logger::INFO
|
64
|
+
|
65
|
+
# clear
|
66
|
+
Upsert.clear_database_functions($conn_factory.new_connection)
|
67
|
+
|
68
|
+
# create
|
69
|
+
Upsert.batch($conn_factory.new_connection, :pets) do |upsert|
|
70
|
+
upsert.row :name => 'hello'
|
71
|
+
upsert.row :name => 'world'
|
72
|
+
end
|
73
|
+
|
74
|
+
io.rewind
|
75
|
+
hits = io.read.split("\n").grep(/Creating or replacing/)
|
76
|
+
hits.length.should == 1
|
77
|
+
ensure
|
78
|
+
Upsert.logger = old_logger
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
it "assumes function exists if told to" do
|
83
|
+
begin
|
84
|
+
io = StringIO.new
|
85
|
+
old_logger = Upsert.logger
|
86
|
+
Upsert.logger = Logger.new io, Logger::INFO
|
87
|
+
|
88
|
+
# clear
|
89
|
+
Upsert.clear_database_functions($conn_factory.new_connection)
|
90
|
+
|
91
|
+
# tries, "went missing", creates
|
92
|
+
Upsert.new($conn_factory.new_connection, :pets, :assume_function_exists => true).row :name => 'hello'
|
93
|
+
|
94
|
+
# just works
|
95
|
+
Upsert.new($conn_factory.new_connection, :pets, :assume_function_exists => true).row :name => 'hello'
|
96
|
+
|
97
|
+
io.rewind
|
98
|
+
lines = io.read.split("\n")
|
99
|
+
lines.grep(/went missing/).length.should == 1
|
100
|
+
lines.grep(/Creating or replacing/).length.should == 1
|
101
|
+
ensure
|
102
|
+
Upsert.logger = old_logger
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end if %w{ postgresql mysql }.include?(ENV['DB'])
|