composite_primary_keys 8.1.7 → 8.1.8
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 +4 -4
- data/History.rdoc +3 -0
- data/lib/composite_primary_keys/associations/preloader/association.rb +3 -4
- data/lib/composite_primary_keys/base.rb +1 -1
- data/lib/composite_primary_keys/composite_arrays.rb +50 -7
- data/lib/composite_primary_keys/connection_adapters/abstract_adapter.rb +1 -1
- data/lib/composite_primary_keys/relation/finder_methods.rb +2 -2
- data/lib/composite_primary_keys/version.rb +1 -1
- data/test/fixtures/db_definitions/mysql.sql +2 -2
- data/test/test_composite_arrays.rb +14 -0
- data/test/test_find.rb +8 -0
- data/test/test_ids.rb +3 -0
- metadata +11 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 98777241ea29aef880ba2b53631fb47686751a898df5b7200cd64a06fb84b838
|
4
|
+
data.tar.gz: 0f5d62c48beab81bcc7a31dd9a025af2867eeb8821482e2aabc0933ae10b95e5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 498c215b18b6056347095a00e81edf399cb0a684c8130413fbb0db87181451bf0801d9c5446b2d34d707137df0e984267d79a9f432accf0287003719a1e229b3
|
7
|
+
data.tar.gz: 1ed759331f302c751f4f93899d3d95945c8c768cd279f817b6431add9c7d97e5caa6b47f8500b8871fa6993a145b288fc6e56f7067ab2f5c479956a10e303d71
|
data/History.rdoc
CHANGED
@@ -64,7 +64,7 @@ module ActiveRecord
|
|
64
64
|
@preloaded_records.map { |record|
|
65
65
|
key = Array(association_key_name).map do |key_name|
|
66
66
|
record[key_name]
|
67
|
-
end.
|
67
|
+
end.to_composite_keys.to_s
|
68
68
|
|
69
69
|
[record, key]
|
70
70
|
}
|
@@ -77,7 +77,7 @@ module ActiveRecord
|
|
77
77
|
# owner[owner_key_name].to_s
|
78
78
|
Array(owner_key_name).map do |key_name|
|
79
79
|
owner[key_name]
|
80
|
-
end.
|
80
|
+
end.to_composite_keys.to_s
|
81
81
|
end
|
82
82
|
else
|
83
83
|
owners.group_by do |owner|
|
@@ -85,10 +85,9 @@ module ActiveRecord
|
|
85
85
|
# owner[owner_key_name]
|
86
86
|
Array(owner_key_name).map do |key_name|
|
87
87
|
owner[key_name]
|
88
|
-
end.
|
88
|
+
end.to_composite_keys.to_s
|
89
89
|
end
|
90
90
|
end
|
91
|
-
|
92
91
|
end
|
93
92
|
end
|
94
93
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module CompositePrimaryKeys
|
2
2
|
ID_SEP = ','
|
3
3
|
ID_SET_SEP = ';'
|
4
|
+
ESCAPE_CHAR = '^'
|
4
5
|
|
5
6
|
module ArrayExtension
|
6
7
|
def to_composite_keys
|
@@ -8,12 +9,27 @@ module CompositePrimaryKeys
|
|
8
9
|
end
|
9
10
|
end
|
10
11
|
|
11
|
-
|
12
|
+
# Convert mixed representation of CPKs (by strings or arrays) to normalized
|
13
|
+
# representation (just by arrays).
|
14
|
+
#
|
15
|
+
# `ids` is Array that may contain:
|
16
|
+
# 1. A CPK represented by an array or a string.
|
17
|
+
# 2. An array of CPKs represented by arrays or strings.
|
18
|
+
#
|
19
|
+
# There is an issue. Let `ids` contain an array with serveral strings. We can't distinguish case 1
|
20
|
+
# from case 2 there in general. E.g. the item can be an array containing appropriate number of strings,
|
21
|
+
# and each string can contain appropriate number of commas. We consider case 2 to win there.
|
22
|
+
def self.normalize(ids, cpk_size)
|
12
23
|
ids.map do |id|
|
13
|
-
if id.
|
14
|
-
|
15
|
-
|
16
|
-
|
24
|
+
if Utils.cpk_as_array?(id, cpk_size) && id.any? { |item| !Utils.cpk_as_string?(item, cpk_size) }
|
25
|
+
# CPK as an array - case 1
|
26
|
+
id
|
27
|
+
elsif id.is_a?(Array)
|
28
|
+
# An array of CPKs - case 2
|
29
|
+
normalize(id, cpk_size)
|
30
|
+
elsif id.is_a?(String)
|
31
|
+
# CPK as a string - case 1
|
32
|
+
CompositeKeys.parse(id)
|
17
33
|
else
|
18
34
|
id
|
19
35
|
end
|
@@ -27,7 +43,7 @@ module CompositePrimaryKeys
|
|
27
43
|
when Array
|
28
44
|
value.to_composite_keys
|
29
45
|
when String
|
30
|
-
|
46
|
+
value.split(ID_SEP).map { |key| Utils.unescape_string_key(key) }.to_composite_keys
|
31
47
|
else
|
32
48
|
raise(ArgumentError, "Unsupported type: #{value}")
|
33
49
|
end
|
@@ -35,9 +51,36 @@ module CompositePrimaryKeys
|
|
35
51
|
|
36
52
|
def to_s
|
37
53
|
# Doing this makes it easier to parse Base#[](attr_name)
|
38
|
-
join(ID_SEP)
|
54
|
+
map { |key| Utils.escape_string_key(key.to_s) }.join(ID_SEP)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
module Utils
|
59
|
+
class << self
|
60
|
+
def escape_string_key(key)
|
61
|
+
key.gsub(Regexp.union(ESCAPE_CHAR, ID_SEP)) do |unsafe|
|
62
|
+
"#{ESCAPE_CHAR}#{unsafe.ord.to_s(16).upcase}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def unescape_string_key(key)
|
67
|
+
key.gsub(/#{Regexp.escape(ESCAPE_CHAR)}[0-9a-fA-F]{2}/) do |escaped|
|
68
|
+
char = escaped.slice(1, 2).hex.chr
|
69
|
+
(char == ESCAPE_CHAR || char == ID_SEP) ? char : escaped
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def cpk_as_array?(value, pk_size)
|
74
|
+
# We don't permit Array to be an element of CPK.
|
75
|
+
value.is_a?(Array) && value.size == pk_size && value.none? { |item| item.is_a?(Array) }
|
76
|
+
end
|
77
|
+
|
78
|
+
def cpk_as_string?(value, pk_size)
|
79
|
+
value.is_a?(String) && value.count(ID_SEP) == pk_size - 1
|
80
|
+
end
|
39
81
|
end
|
40
82
|
end
|
83
|
+
private_constant :Utils
|
41
84
|
end
|
42
85
|
|
43
86
|
Array.send(:include, CompositePrimaryKeys::ArrayExtension)
|
@@ -84,7 +84,7 @@ module CompositePrimaryKeys
|
|
84
84
|
|
85
85
|
# CPK
|
86
86
|
# expects_array = ids.first.kind_of?(Array)
|
87
|
-
ids = CompositePrimaryKeys.normalize(ids)
|
87
|
+
ids = CompositePrimaryKeys.normalize(ids, @klass.primary_keys.length)
|
88
88
|
expects_array = ids.flatten != ids.flatten(1)
|
89
89
|
|
90
90
|
return ids.first if expects_array && ids.first.empty?
|
@@ -138,7 +138,7 @@ module CompositePrimaryKeys
|
|
138
138
|
|
139
139
|
result = ids.map do |cpk_ids|
|
140
140
|
cpk_ids = if cpk_ids.length == 1
|
141
|
-
cpk_ids.first
|
141
|
+
CompositePrimaryKeys::CompositeKeys.parse(cpk_ids.first)
|
142
142
|
else
|
143
143
|
cpk_ids.to_composite_keys
|
144
144
|
end
|
@@ -21,4 +21,18 @@ class CompositeArraysTest < ActiveSupport::TestCase
|
|
21
21
|
assert_equal CompositePrimaryKeys::CompositeKeys, keys.class
|
22
22
|
assert_equal '1,2,3', keys.to_s
|
23
23
|
end
|
24
|
+
|
25
|
+
def test_parse
|
26
|
+
assert_equal ['1', '2'], CompositePrimaryKeys::CompositeKeys.parse('1,2')
|
27
|
+
assert_equal ['The USA', '^Washington, D.C.'],
|
28
|
+
CompositePrimaryKeys::CompositeKeys.parse('The USA,^5EWashington^2C D.C.')
|
29
|
+
assert_equal ['The USA', '^Washington, D.C.'],
|
30
|
+
CompositePrimaryKeys::CompositeKeys.parse(['The USA', '^Washington, D.C.'])
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_to_s
|
34
|
+
assert_equal '1,2', CompositePrimaryKeys::CompositeKeys.new([1, 2]).to_s
|
35
|
+
assert_equal 'The USA,^5EWashington^2C D.C.',
|
36
|
+
CompositePrimaryKeys::CompositeKeys.new(['The USA', '^Washington, D.C.']).to_s
|
37
|
+
end
|
24
38
|
end
|
data/test/test_find.rb
CHANGED
@@ -41,6 +41,14 @@ class TestFind < ActiveSupport::TestCase
|
|
41
41
|
assert_equal(['The Netherlands', 'Amsterdam'], capitol.id)
|
42
42
|
end
|
43
43
|
|
44
|
+
def test_find_with_strings_with_comma_as_composite_keys
|
45
|
+
capitol = Capitol.create!(country: 'The USA', city: 'Washington, D.C.')
|
46
|
+
assert_equal ['The USA', 'Washington, D.C.'], capitol.id
|
47
|
+
|
48
|
+
assert_equal capitol, Capitol.find(['The USA', 'Washington, D.C.'])
|
49
|
+
assert_equal capitol, Capitol.find(capitol.to_param)
|
50
|
+
end
|
51
|
+
|
44
52
|
def test_find_each
|
45
53
|
room_assignments = []
|
46
54
|
RoomAssignment.find_each(:batch_size => 2) do |assignment|
|
data/test/test_ids.rb
CHANGED
@@ -40,6 +40,9 @@ class TestIds < ActiveSupport::TestCase
|
|
40
40
|
testing_with do
|
41
41
|
assert_equal '1,1', @first.to_param if composite?
|
42
42
|
end
|
43
|
+
|
44
|
+
capitol = Capitol.create!(country: 'The USA', city: 'Washington, D.C.')
|
45
|
+
assert_equal 'The USA,Washington^2C D.C.', capitol.to_param
|
43
46
|
end
|
44
47
|
|
45
48
|
def test_ids_to_s
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: composite_primary_keys
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 8.1.
|
4
|
+
version: 8.1.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Charlie Savage
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-01-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -28,30 +28,30 @@ dependencies:
|
|
28
28
|
name: sqlite3
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 1.3.6
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 1.3.6
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: pg
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
47
|
+
version: '0.15'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
54
|
+
version: '0.15'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: mysql2
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -285,7 +285,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
285
285
|
- !ruby/object:Gem::Version
|
286
286
|
version: '0'
|
287
287
|
requirements: []
|
288
|
-
rubygems_version: 3.0.
|
288
|
+
rubygems_version: 3.0.6
|
289
289
|
signing_key:
|
290
290
|
specification_version: 4
|
291
291
|
summary: Composite key support for ActiveRecord
|