upsert 1.0.2 → 1.1.0
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.
- data/CHANGELOG +7 -0
- data/Gemfile +4 -0
- data/README.md +115 -66
- data/Rakefile +16 -5
- data/lib/upsert.rb +86 -25
- data/lib/upsert/binary.rb +2 -0
- data/lib/upsert/column_definition.rb +27 -3
- data/lib/upsert/column_definition/mysql.rb +20 -0
- data/lib/upsert/column_definition/{PG_Connection.rb → postgresql.rb} +1 -1
- data/lib/upsert/connection.rb +20 -22
- data/lib/upsert/connection/Java_ComMysqlJdbc_JDBC4Connection.rb +25 -0
- data/lib/upsert/connection/Java_OrgPostgresqlJdbc4_Jdbc4Connection.rb +14 -0
- data/lib/upsert/connection/Java_OrgSqliteConn.rb +17 -0
- data/lib/upsert/connection/Mysql2_Client.rb +40 -18
- data/lib/upsert/connection/PG_Connection.rb +7 -3
- data/lib/upsert/connection/SQLite3_Database.rb +10 -2
- data/lib/upsert/connection/jdbc.rb +81 -0
- data/lib/upsert/connection/sqlite3.rb +23 -0
- data/lib/upsert/merge_function/Java_ComMysqlJdbc_JDBC4Connection.rb +42 -0
- data/lib/upsert/merge_function/Java_OrgPostgresqlJdbc4_Jdbc4Connection.rb +35 -0
- data/lib/upsert/merge_function/Java_OrgSqliteConn.rb +10 -0
- data/lib/upsert/merge_function/Mysql2_Client.rb +5 -58
- data/lib/upsert/merge_function/PG_Connection.rb +6 -78
- data/lib/upsert/merge_function/SQLite3_Database.rb +3 -22
- data/lib/upsert/merge_function/mysql.rb +67 -0
- data/lib/upsert/merge_function/postgresql.rb +94 -0
- data/lib/upsert/merge_function/sqlite3.rb +30 -0
- data/lib/upsert/row.rb +3 -6
- data/lib/upsert/version.rb +1 -1
- data/spec/binary_spec.rb +0 -2
- data/spec/correctness_spec.rb +26 -25
- data/spec/database_functions_spec.rb +6 -14
- data/spec/logger_spec.rb +22 -10
- data/spec/precision_spec.rb +1 -1
- data/spec/spec_helper.rb +115 -31
- data/spec/speed_spec.rb +1 -1
- data/spec/timezones_spec.rb +35 -14
- data/spec/type_safety_spec.rb +2 -2
- data/upsert.gemspec +18 -6
- metadata +25 -38
- data/lib/upsert/cell.rb +0 -5
- data/lib/upsert/cell/Mysql2_Client.rb +0 -16
- data/lib/upsert/cell/PG_Connection.rb +0 -28
- data/lib/upsert/cell/SQLite3_Database.rb +0 -36
- data/lib/upsert/column_definition/Mysql2_Client.rb +0 -24
- data/lib/upsert/column_definition/SQLite3_Database.rb +0 -7
- data/lib/upsert/row/Mysql2_Client.rb +0 -21
- data/lib/upsert/row/PG_Connection.rb +0 -7
- data/lib/upsert/row/SQLite3_Database.rb +0 -7
@@ -0,0 +1,30 @@
|
|
1
|
+
class Upsert
|
2
|
+
class MergeFunction
|
3
|
+
# @private
|
4
|
+
module Sqlite3
|
5
|
+
attr_reader :quoted_setter_names
|
6
|
+
attr_reader :quoted_selector_names
|
7
|
+
|
8
|
+
def initialize(*)
|
9
|
+
super
|
10
|
+
@quoted_setter_names = setter_keys.map { |k| connection.quote_ident k }
|
11
|
+
@quoted_selector_names = selector_keys.map { |k| connection.quote_ident k }
|
12
|
+
end
|
13
|
+
|
14
|
+
def create!
|
15
|
+
# not necessary
|
16
|
+
end
|
17
|
+
|
18
|
+
def execute(row)
|
19
|
+
bind_setter_values = row.setter.values.map { |v| connection.bind_value v }
|
20
|
+
bind_selector_values = row.selector.values.map { |v| connection.bind_value v }
|
21
|
+
|
22
|
+
insert_or_ignore_sql = %{INSERT OR IGNORE INTO #{quoted_table_name} (#{quoted_setter_names.join(',')}) VALUES (#{Array.new(bind_setter_values.length, '?').join(',')})}
|
23
|
+
connection.execute insert_or_ignore_sql, bind_setter_values
|
24
|
+
|
25
|
+
update_sql = %{UPDATE #{quoted_table_name} SET #{quoted_setter_names.map { |qk| "#{qk}=?" }.join(',')} WHERE #{quoted_selector_names.map { |qk| "#{qk}=?" }.join(' AND ')}}
|
26
|
+
connection.execute update_sql, (bind_setter_values + bind_selector_values)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/upsert/row.rb
CHANGED
@@ -16,17 +16,14 @@ class Upsert
|
|
16
16
|
attr_reader :setter
|
17
17
|
|
18
18
|
|
19
|
-
def initialize(
|
20
|
-
connection = controller.connection
|
21
|
-
cell_class = controller.cell_class
|
22
|
-
|
19
|
+
def initialize(raw_selector, raw_setter)
|
23
20
|
@selector = raw_selector.inject({}) do |memo, (k, v)|
|
24
|
-
memo[k.to_s] =
|
21
|
+
memo[k.to_s] = v
|
25
22
|
memo
|
26
23
|
end
|
27
24
|
|
28
25
|
@setter = raw_setter.inject({}) do |memo, (k, v)|
|
29
|
-
memo[k.to_s] =
|
26
|
+
memo[k.to_s] = v
|
30
27
|
memo
|
31
28
|
end
|
32
29
|
|
data/lib/upsert/version.rb
CHANGED
data/spec/binary_spec.rb
CHANGED
@@ -13,9 +13,7 @@ describe Upsert do
|
|
13
13
|
upsert = Upsert.new $conn, :pets
|
14
14
|
assert_creates(Pet, [{:name => name, :zipped_biography => zipped_biography}]) do
|
15
15
|
upsert.row({:name => name}, {:zipped_biography => Upsert.binary(zipped_biography)})
|
16
|
-
# binding.pry
|
17
16
|
end
|
18
|
-
|
19
17
|
Zlib::Inflate.inflate(Pet.find_by_name(name).zipped_biography).should == biography
|
20
18
|
end
|
21
19
|
end
|
data/spec/correctness_spec.rb
CHANGED
@@ -47,6 +47,7 @@ describe Upsert do
|
|
47
47
|
Pet.find_by_name_and_gender('Jerry', 'blue').tag_number.should == 777
|
48
48
|
end
|
49
49
|
end
|
50
|
+
|
50
51
|
describe "is just as correct as other ways" do
|
51
52
|
describe 'compared to native ActiveRecord' do
|
52
53
|
it "is as correct as than new/set/save" do
|
@@ -67,33 +68,33 @@ describe Upsert do
|
|
67
68
|
end
|
68
69
|
end
|
69
70
|
end
|
70
|
-
it "is as correct as than find_or_create + update_attributes" do
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
end
|
80
|
-
it "is as correct as than create + rescue/find/update" do
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
end
|
71
|
+
# it "is as correct as than find_or_create + update_attributes" do
|
72
|
+
# assert_same_result lotsa_records do |records|
|
73
|
+
# dynamic_method = nil
|
74
|
+
# records.each do |selector, setter|
|
75
|
+
# dynamic_method ||= "find_or_create_by_#{selector.keys.join('_or_')}"
|
76
|
+
# pet = Pet.send(dynamic_method, *selector.values)
|
77
|
+
# pet.update_attributes setter, :without_protection => true
|
78
|
+
# end
|
79
|
+
# end
|
80
|
+
# end
|
81
|
+
# it "is as correct as than create + rescue/find/update" do
|
82
|
+
# assert_same_result lotsa_records do |records|
|
83
|
+
# dynamic_method = nil
|
84
|
+
# records.each do |selector, setter|
|
85
|
+
# dynamic_method ||= "find_or_create_by_#{selector.keys.join('_or_')}"
|
86
|
+
# begin
|
87
|
+
# Pet.create selector.merge(setter), :without_protection => true
|
88
|
+
# rescue
|
89
|
+
# pet = Pet.send(dynamic_method, *selector.values)
|
90
|
+
# pet.update_attributes setter, :without_protection => true
|
91
|
+
# end
|
92
|
+
# end
|
93
|
+
# end
|
94
|
+
# end
|
94
95
|
end
|
95
96
|
|
96
|
-
if ENV['
|
97
|
+
if ENV['DB'] == 'mysql'
|
97
98
|
describe 'compared to activerecord-import' do
|
98
99
|
it "is as correct as faking upserts with activerecord-import" do
|
99
100
|
assert_same_result lotsa_records do |records|
|
@@ -1,14 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'stringio'
|
3
3
|
describe Upsert do
|
4
|
-
def fresh_connection
|
5
|
-
case ENV['ADAPTER']
|
6
|
-
when 'postgresql'
|
7
|
-
PGconn.new $conn_config
|
8
|
-
when 'mysql2'
|
9
|
-
Mysql2::Client.new $conn_config
|
10
|
-
end
|
11
|
-
end
|
12
4
|
describe 'database functions' do
|
13
5
|
it "re-uses merge functions across connections" do
|
14
6
|
begin
|
@@ -17,19 +9,19 @@ describe Upsert do
|
|
17
9
|
Upsert.logger = Logger.new io, Logger::INFO
|
18
10
|
|
19
11
|
# clear
|
20
|
-
Upsert.clear_database_functions(
|
12
|
+
Upsert.clear_database_functions($conn_factory.new_connection)
|
21
13
|
|
22
14
|
# create
|
23
|
-
Upsert.new(
|
15
|
+
Upsert.new($conn_factory.new_connection, :pets).row :name => 'hello'
|
24
16
|
|
25
17
|
# clear
|
26
|
-
Upsert.clear_database_functions(
|
18
|
+
Upsert.clear_database_functions($conn_factory.new_connection)
|
27
19
|
|
28
20
|
# create (#2)
|
29
|
-
Upsert.new(
|
21
|
+
Upsert.new($conn_factory.new_connection, :pets).row :name => 'hello'
|
30
22
|
|
31
23
|
# no create!
|
32
|
-
Upsert.new(
|
24
|
+
Upsert.new($conn_factory.new_connection, :pets).row :name => 'hello'
|
33
25
|
|
34
26
|
io.rewind
|
35
27
|
hits = io.read.split("\n").grep(/Creating or replacing/)
|
@@ -39,4 +31,4 @@ describe Upsert do
|
|
39
31
|
end
|
40
32
|
end
|
41
33
|
end
|
42
|
-
end if %w{ postgresql
|
34
|
+
end if %w{ postgresql mysql }.include?(ENV['DB'])
|
data/spec/logger_spec.rb
CHANGED
@@ -7,7 +7,9 @@ describe Upsert do
|
|
7
7
|
io = StringIO.new
|
8
8
|
Thread.exclusive do
|
9
9
|
Upsert.logger = Logger.new(io)
|
10
|
+
|
10
11
|
Upsert.logger.warn "hello"
|
12
|
+
|
11
13
|
io.rewind
|
12
14
|
io.read.chomp.should == 'hello'
|
13
15
|
end
|
@@ -17,21 +19,31 @@ describe Upsert do
|
|
17
19
|
end
|
18
20
|
|
19
21
|
it "logs queries" do
|
20
|
-
require 'sqlite3'
|
21
|
-
db = SQLite3::Database.open(':memory:')
|
22
|
-
db.execute_batch "CREATE TABLE cats (name CHARACTER VARYING(255))"
|
23
22
|
begin
|
24
|
-
io = StringIO.new
|
25
23
|
old_logger = Upsert.logger
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
24
|
+
io = StringIO.new
|
25
|
+
Thread.exclusive do
|
26
|
+
Upsert.logger = Logger.new(io)
|
27
|
+
|
28
|
+
u = Upsert.new($conn, :pets)
|
29
|
+
u.row(name: 'Jerry')
|
30
|
+
|
31
|
+
io.rewind
|
32
|
+
log = io.read.chomp
|
33
|
+
case u.connection.class.name
|
34
|
+
when /sqlite/i
|
35
|
+
log.should =~ /insert or ignore/i
|
36
|
+
when /mysql/i
|
37
|
+
log.should =~ /call upsert_pets_SEL_name/i
|
38
|
+
when /p.*g/i
|
39
|
+
log.should =~ /select upsert_pets_SEL_name/i
|
40
|
+
else
|
41
|
+
raise "not sure"
|
42
|
+
end
|
43
|
+
end
|
31
44
|
ensure
|
32
45
|
Upsert.logger = old_logger
|
33
46
|
end
|
34
47
|
end
|
35
|
-
|
36
48
|
end
|
37
49
|
end
|
data/spec/precision_spec.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -4,33 +4,83 @@ require 'bundler/setup'
|
|
4
4
|
require 'pry'
|
5
5
|
|
6
6
|
require 'active_record'
|
7
|
+
ActiveRecord::Base.default_timezone = :utc
|
8
|
+
|
7
9
|
require 'active_record_inline_schema'
|
8
10
|
require 'activerecord-import'
|
9
11
|
|
10
|
-
ENV['
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
when '
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
12
|
+
ENV['DB'] ||= 'mysql'
|
13
|
+
|
14
|
+
class RawConnectionFactory
|
15
|
+
DATABASE = 'upsert_test'
|
16
|
+
CURRENT_USER = `whoami`.chomp
|
17
|
+
PASSWORD = 'password'
|
18
|
+
|
19
|
+
case ENV['DB']
|
20
|
+
|
21
|
+
when 'postgresql'
|
22
|
+
Kernel.system %{ dropdb upsert_test }
|
23
|
+
Kernel.system %{ createdb upsert_test }
|
24
|
+
if RUBY_PLATFORM == 'java'
|
25
|
+
CONFIG = "jdbc:postgresql://localhost/#{DATABASE}?user=#{CURRENT_USER}"
|
26
|
+
require 'jdbc/postgres'
|
27
|
+
# http://thesymanual.wordpress.com/2011/02/21/connecting-jruby-to-postgresql-with-jdbc-postgre-api/
|
28
|
+
java.sql.DriverManager.register_driver org.postgresql.Driver.new
|
29
|
+
def new_connection
|
30
|
+
java.sql.DriverManager.get_connection CONFIG
|
31
|
+
end
|
32
|
+
else
|
33
|
+
CONFIG = { :dbname => DATABASE }
|
34
|
+
require 'pg'
|
35
|
+
def new_connection
|
36
|
+
PG::Connection.new CONFIG
|
37
|
+
end
|
38
|
+
end
|
39
|
+
ActiveRecord::Base.establish_connection :adapter => 'postgresql', :database => DATABASE, :username => CURRENT_USER
|
40
|
+
|
41
|
+
when 'mysql'
|
42
|
+
Kernel.system %{ mysql -u root -ppassword -e "DROP DATABASE IF EXISTS #{DATABASE}" }
|
43
|
+
Kernel.system %{ mysql -u root -ppassword -e "CREATE DATABASE #{DATABASE} CHARSET utf8" }
|
44
|
+
if RUBY_PLATFORM == 'java'
|
45
|
+
CONFIG = "jdbc:mysql://127.0.0.1/#{DATABASE}?user=root&password=password"
|
46
|
+
require 'jdbc/mysql'
|
47
|
+
java.sql.DriverManager.register_driver com.mysql.jdbc.Driver.new
|
48
|
+
def new_connection
|
49
|
+
java.sql.DriverManager.get_connection CONFIG
|
50
|
+
end
|
51
|
+
else
|
52
|
+
CONFIG = { :username => 'root', :password => PASSWORD, :database => DATABASE}
|
53
|
+
require 'mysql2'
|
54
|
+
def new_connection
|
55
|
+
Mysql2::Client.new CONFIG
|
56
|
+
end
|
57
|
+
end
|
58
|
+
ActiveRecord::Base.establish_connection "#{RUBY_PLATFORM == 'java' ? 'mysql' : 'mysql2'}://root:password@127.0.0.1/#{DATABASE}"
|
59
|
+
|
60
|
+
when 'sqlite3'
|
61
|
+
if RUBY_PLATFORM == 'java'
|
62
|
+
def new_connection
|
63
|
+
ActiveRecord::Base.connection.raw_connection.connection
|
64
|
+
end
|
65
|
+
else
|
66
|
+
require 'sqlite3'
|
67
|
+
def new_connection
|
68
|
+
ActiveRecord::Base.connection.raw_connection
|
69
|
+
end
|
70
|
+
end
|
71
|
+
ActiveRecord::Base.establish_connection :adapter => 'sqlite3', :database => ':memory:'
|
72
|
+
|
73
|
+
else
|
74
|
+
raise "not supported"
|
75
|
+
end
|
31
76
|
end
|
32
77
|
|
78
|
+
$conn_factory = RawConnectionFactory.new
|
79
|
+
$conn = $conn_factory.new_connection
|
80
|
+
|
33
81
|
require 'logger'
|
82
|
+
require 'fileutils'
|
83
|
+
FileUtils.rm_f 'test.log'
|
34
84
|
ActiveRecord::Base.logger = Logger.new('test.log')
|
35
85
|
|
36
86
|
if ENV['VERBOSE'] == 'true'
|
@@ -59,6 +109,17 @@ require 'benchmark'
|
|
59
109
|
require 'faker'
|
60
110
|
|
61
111
|
module SpecHelper
|
112
|
+
def random_time_or_datetime
|
113
|
+
time = Time.at(rand * Time.now.to_i)
|
114
|
+
if ENV['DB'] == 'mysql'
|
115
|
+
time = time.change(:usec => 0)
|
116
|
+
end
|
117
|
+
if rand > 0.5
|
118
|
+
time = time.change(:usec => 0).to_datetime
|
119
|
+
end
|
120
|
+
time
|
121
|
+
end
|
122
|
+
|
62
123
|
def lotsa_records
|
63
124
|
@records ||= begin
|
64
125
|
memo = []
|
@@ -69,7 +130,7 @@ module SpecHelper
|
|
69
130
|
2000.times do
|
70
131
|
selector = ActiveSupport::OrderedHash.new
|
71
132
|
selector[:name] = if RUBY_VERSION >= '1.9'
|
72
|
-
names.sample
|
133
|
+
names.sample
|
73
134
|
else
|
74
135
|
names.choice
|
75
136
|
end
|
@@ -79,7 +140,7 @@ module SpecHelper
|
|
79
140
|
:spiel => Faker::Lorem.sentences.join,
|
80
141
|
:good => true,
|
81
142
|
:birthday => Time.at(rand * Time.now.to_i).to_date,
|
82
|
-
:morning_walk_time =>
|
143
|
+
:morning_walk_time => random_time_or_datetime,
|
83
144
|
:home_address => Faker::Lorem.sentences.join,
|
84
145
|
# hard to know how to have AR insert this properly unless Upsert::Binary subclasses String
|
85
146
|
# :zipped_biography => Upsert.binary(Zlib::Deflate.deflate(Faker::Lorem.paragraphs.join, Zlib::BEST_SPEED))
|
@@ -102,19 +163,42 @@ module SpecHelper
|
|
102
163
|
end
|
103
164
|
end
|
104
165
|
ref2 = Pet.order(:name).all.map { |pet| pet.attributes.except('id') }
|
105
|
-
|
106
|
-
ref2a.to_yaml.should == ref1[i].to_yaml
|
107
|
-
end
|
108
|
-
# ref2.should == ref1
|
166
|
+
compare_attribute_sets ref1, ref2
|
109
167
|
end
|
110
168
|
|
111
169
|
def assert_creates(model, expected_records)
|
112
|
-
expected_records.each do |
|
113
|
-
|
170
|
+
expected_records.each do |selector, setter|
|
171
|
+
# should i use setter in where?
|
172
|
+
model.where(selector).count.should == 0
|
114
173
|
end
|
115
174
|
yield
|
116
|
-
expected_records.each do |
|
117
|
-
|
175
|
+
expected_records.each do |selector, setter|
|
176
|
+
setter ||= {}
|
177
|
+
found = model.where(selector).map { |record| record.attributes.except('id') }
|
178
|
+
expected = [ selector.stringify_keys.merge(setter.stringify_keys) ]
|
179
|
+
compare_attribute_sets expected, found
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def compare_attribute_sets(expected, found)
|
184
|
+
e = expected.map { |attrs| simplify_attributes attrs }
|
185
|
+
f = found.map { |attrs| simplify_attributes attrs }
|
186
|
+
f.each_with_index do |fa, i|
|
187
|
+
fa.should == e[i]
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
def simplify_attributes(attrs)
|
192
|
+
attrs.select do |k, v|
|
193
|
+
v.present?
|
194
|
+
end.inject({}) do |memo, (k, v)|
|
195
|
+
memo[k] = case v
|
196
|
+
when Time, DateTime
|
197
|
+
v.to_time.to_f
|
198
|
+
else
|
199
|
+
v
|
200
|
+
end
|
201
|
+
memo
|
118
202
|
end
|
119
203
|
end
|
120
204
|
|
data/spec/speed_spec.rb
CHANGED
@@ -46,7 +46,7 @@ describe Upsert do
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
-
if ENV['
|
49
|
+
if ENV['DB'] == 'mysql'
|
50
50
|
describe 'compared to activerecord-import' do
|
51
51
|
it "is faster than faking upserts with activerecord-import" do
|
52
52
|
assert_faster_than 'faking upserts with activerecord-import', lotsa_records do |records|
|
data/spec/timezones_spec.rb
CHANGED
@@ -1,28 +1,49 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
describe Upsert do
|
3
|
-
describe "
|
4
|
-
|
5
|
-
|
3
|
+
describe "timezone support" do
|
4
|
+
it "takes times in UTC" do
|
5
|
+
time = Time.new.utc
|
6
|
+
if ENV['DB'] == 'mysql'
|
7
|
+
time = time.change(:usec => 0)
|
8
|
+
end
|
9
|
+
upsert = Upsert.new $conn, :pets
|
10
|
+
assert_creates(Pet, [[{:name => 'Jerry'}, {:morning_walk_time => time}]]) do
|
11
|
+
upsert.row({:name => 'Jerry'}, {:morning_walk_time => time})
|
12
|
+
end
|
6
13
|
end
|
7
|
-
|
8
|
-
|
14
|
+
|
15
|
+
it "takes times in local" do
|
16
|
+
time = Time.new
|
17
|
+
if ENV['DB'] == 'mysql'
|
18
|
+
time = time.change(:usec => 0)
|
19
|
+
end
|
20
|
+
upsert = Upsert.new $conn, :pets
|
21
|
+
assert_creates(Pet, [[{:name => 'Jerry'}, {:morning_walk_time => time}]]) do
|
22
|
+
upsert.row({:name => 'Jerry'}, {:morning_walk_time => time})
|
23
|
+
end
|
9
24
|
end
|
10
|
-
|
11
|
-
it "
|
12
|
-
|
13
|
-
|
25
|
+
|
26
|
+
it "takes datetimes in UTC" do
|
27
|
+
time = DateTime.now.new_offset(Rational(0, 24))
|
28
|
+
if ENV['DB'] == 'mysql'
|
29
|
+
time = time.change(:usec => 0)
|
30
|
+
end
|
14
31
|
upsert = Upsert.new $conn, :pets
|
15
|
-
assert_creates(Pet, [{:name => 'Jerry', :morning_walk_time => time}]) do
|
32
|
+
assert_creates(Pet, [[{:name => 'Jerry'}, {:morning_walk_time => time}]]) do
|
16
33
|
upsert.row({:name => 'Jerry'}, {:morning_walk_time => time})
|
17
34
|
end
|
18
35
|
end
|
19
|
-
|
20
|
-
|
21
|
-
time =
|
36
|
+
|
37
|
+
it "takes datetimes in local" do
|
38
|
+
time = DateTime.now
|
39
|
+
if ENV['DB'] == 'mysql'
|
40
|
+
time = time.change(:usec => 0)
|
41
|
+
end
|
22
42
|
upsert = Upsert.new $conn, :pets
|
23
|
-
assert_creates(Pet, [{:name => 'Jerry', :morning_walk_time => time}]) do
|
43
|
+
assert_creates(Pet, [[{:name => 'Jerry'}, {:morning_walk_time => time}]]) do
|
24
44
|
upsert.row({:name => 'Jerry'}, {:morning_walk_time => time})
|
25
45
|
end
|
26
46
|
end
|
47
|
+
|
27
48
|
end
|
28
49
|
end
|