upsert 0.3.3 → 0.3.4
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 +10 -0
- data/README.md +4 -3
- data/lib/upsert.rb +1 -1
- data/lib/upsert/active_record_upsert.rb +1 -1
- data/lib/upsert/pg_connection/column_definition.rb +2 -27
- data/lib/upsert/version.rb +1 -1
- data/test/shared/database.rb +14 -1
- metadata +2 -2
data/CHANGELOG
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
0.3.4 / 2012-07-03
|
2
|
+
|
3
|
+
* Bug fixes
|
4
|
+
|
5
|
+
* Allow upserting by auto-increment primary key (thanks @atandrau https://github.com/seamusabshere/upsert/issues/3)
|
6
|
+
|
7
|
+
* Enhancements
|
8
|
+
|
9
|
+
* Make document an optional argument
|
10
|
+
|
1
11
|
0.3.3 / 2012-06-26
|
2
12
|
|
3
13
|
* Bug fixes
|
data/README.md
CHANGED
@@ -54,9 +54,10 @@ Pull requests for any of these would be greatly appreciated:
|
|
54
54
|
|
55
55
|
1. Fix SQLite tests.
|
56
56
|
2. For PG, be smarter about when you create functions - try to re-use them within a connection.
|
57
|
-
3. Provide
|
58
|
-
4.
|
59
|
-
5.
|
57
|
+
3. Provide optional SQL logging.
|
58
|
+
4. Provide `require 'upsert/debug'` that will make sure you are selecting on columns that have unique indexes
|
59
|
+
5. Make `Upsert` instances accept arbitrary columns, which is what people probably expect.
|
60
|
+
6. Naming suggestions: should "document" be called "setters" or "attributes"?
|
60
61
|
|
61
62
|
## Real-world usage
|
62
63
|
|
data/lib/upsert.rb
CHANGED
@@ -94,7 +94,7 @@ class Upsert
|
|
94
94
|
# upsert = Upsert.new Pet.connection, Pet.table_name
|
95
95
|
# upsert.row({:name => 'Jerry'}, :breed => 'beagle')
|
96
96
|
# upsert.row({:name => 'Pierre'}, :breed => 'tabby')
|
97
|
-
def row(selector, document)
|
97
|
+
def row(selector, document = {})
|
98
98
|
buffer.push Row.new(self, selector, document)
|
99
99
|
if sql = chunk
|
100
100
|
execute sql
|
@@ -4,41 +4,16 @@ class Upsert
|
|
4
4
|
# activerecord-3.2.5/lib/active_record/connection_adapters/postgresql_adapter.rb#column_definitions
|
5
5
|
class ColumnDefinition
|
6
6
|
class << self
|
7
|
-
def auto_increment_primary_key(connection, table_name)
|
8
|
-
res = connection.exec <<-EOS
|
9
|
-
SELECT attr.attname, seq.relname
|
10
|
-
FROM pg_class seq,
|
11
|
-
pg_attribute attr,
|
12
|
-
pg_depend dep,
|
13
|
-
pg_namespace name,
|
14
|
-
pg_constraint cons
|
15
|
-
WHERE seq.oid = dep.objid
|
16
|
-
AND seq.relkind = 'S'
|
17
|
-
AND attr.attrelid = dep.refobjid
|
18
|
-
AND attr.attnum = dep.refobjsubid
|
19
|
-
AND attr.attrelid = cons.conrelid
|
20
|
-
AND attr.attnum = cons.conkey[1]
|
21
|
-
AND cons.contype = 'p'
|
22
|
-
AND dep.refobjid = '#{connection.quote_ident(table_name.to_s)}'::regclass
|
23
|
-
EOS
|
24
|
-
if hit = res.first
|
25
|
-
hit['attname']
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
7
|
def all(connection, table_name)
|
30
|
-
auto_increment_primary_key = auto_increment_primary_key(connection, table_name)
|
31
8
|
res = connection.exec <<-EOS
|
32
9
|
SELECT a.attname AS name, format_type(a.atttypid, a.atttypmod) AS sql_type, d.adsrc AS default
|
33
10
|
FROM pg_attribute a LEFT JOIN pg_attrdef d
|
34
11
|
ON a.attrelid = d.adrelid AND a.attnum = d.adnum
|
35
12
|
WHERE a.attrelid = '#{connection.quote_ident(table_name.to_s)}'::regclass
|
36
|
-
|
13
|
+
AND a.attnum > 0 AND NOT a.attisdropped
|
37
14
|
ORDER BY a.attnum
|
38
15
|
EOS
|
39
|
-
res.
|
40
|
-
row['name'] == auto_increment_primary_key
|
41
|
-
end.map do |row|
|
16
|
+
res.map do |row|
|
42
17
|
new connection, row['name'], row['sql_type'], row['default']
|
43
18
|
end
|
44
19
|
end
|
data/lib/upsert/version.rb
CHANGED
data/test/shared/database.rb
CHANGED
@@ -36,7 +36,6 @@ shared_examples_for 'is a database with an upsert trick' do
|
|
36
36
|
end
|
37
37
|
Pet.where(:gender => 'male').count.must_equal 0
|
38
38
|
end
|
39
|
-
|
40
39
|
it "works for a single row with implicit nulls" do
|
41
40
|
upsert = Upsert.new connection, :pets
|
42
41
|
assert_creates(Pet, [{:name => 'Inky', :gender => nil}]) do
|
@@ -44,6 +43,13 @@ shared_examples_for 'is a database with an upsert trick' do
|
|
44
43
|
upsert.row({:name => 'Inky'}, {})
|
45
44
|
end
|
46
45
|
end
|
46
|
+
it "works for a single row with empty document" do
|
47
|
+
upsert = Upsert.new connection, :pets
|
48
|
+
assert_creates(Pet, [{:name => 'Inky', :gender => nil}]) do
|
49
|
+
upsert.row(:name => 'Inky')
|
50
|
+
upsert.row(:name => 'Inky')
|
51
|
+
end
|
52
|
+
end
|
47
53
|
it "works for a single row with explicit nulls" do
|
48
54
|
upsert = Upsert.new connection, :pets
|
49
55
|
assert_creates(Pet, [{:name => 'Inky', :gender => nil}]) do
|
@@ -51,6 +57,13 @@ shared_examples_for 'is a database with an upsert trick' do
|
|
51
57
|
upsert.row({:name => 'Inky'}, {:gender => nil})
|
52
58
|
end
|
53
59
|
end
|
60
|
+
it "works with ids" do
|
61
|
+
jerry = Pet.create :name => 'Jerry', :lovability => 1.0
|
62
|
+
upsert = Upsert.new connection, :pets
|
63
|
+
assert_creates(Pet, [{:name => 'Jerry', :lovability => 2.0}]) do
|
64
|
+
upsert.row({:id => jerry.id}, :lovability => 2.0)
|
65
|
+
end
|
66
|
+
end
|
54
67
|
end
|
55
68
|
describe :batch do
|
56
69
|
it "works for multiple rows (base case)" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: upsert
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-07-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: sqlite3
|