perpetuity-postgres 0.0.7 → 0.0.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/CHANGELOG.md +4 -0
- data/lib/perpetuity/postgres/connection.rb +12 -0
- data/lib/perpetuity/postgres/version.rb +1 -1
- data/perpetuity-postgres.gemspec +1 -1
- data/spec/perpetuity/postgres/boolean_value_spec.rb +2 -2
- data/spec/perpetuity/postgres/connection_pool_spec.rb +3 -4
- data/spec/perpetuity/postgres/connection_spec.rb +6 -6
- data/spec/perpetuity/postgres/date_value_spec.rb +3 -3
- data/spec/perpetuity/postgres/expression_spec.rb +1 -1
- data/spec/perpetuity/postgres/index_collection_spec.rb +4 -4
- data/spec/perpetuity/postgres/index_spec.rb +13 -13
- data/spec/perpetuity/postgres/json_array_spec.rb +7 -7
- data/spec/perpetuity/postgres/json_hash_spec.rb +10 -10
- data/spec/perpetuity/postgres/json_string_value_spec.rb +3 -3
- data/spec/perpetuity/postgres/negated_query_spec.rb +8 -8
- data/spec/perpetuity/postgres/null_value_spec.rb +1 -1
- data/spec/perpetuity/postgres/numeric_value_spec.rb +1 -1
- data/spec/perpetuity/postgres/query_attribute_spec.rb +15 -15
- data/spec/perpetuity/postgres/query_expression_spec.rb +19 -19
- data/spec/perpetuity/postgres/query_intersection_spec.rb +3 -3
- data/spec/perpetuity/postgres/query_spec.rb +3 -3
- data/spec/perpetuity/postgres/query_union_spec.rb +3 -3
- data/spec/perpetuity/postgres/serialized_data_spec.rb +14 -14
- data/spec/perpetuity/postgres/serializer_spec.rb +23 -23
- data/spec/perpetuity/postgres/sql_function_spec.rb +2 -2
- data/spec/perpetuity/postgres/sql_select_spec.rb +11 -11
- data/spec/perpetuity/postgres/sql_update_spec.rb +2 -2
- data/spec/perpetuity/postgres/sql_value_spec.rb +14 -14
- data/spec/perpetuity/postgres/table/attribute_spec.rb +17 -17
- data/spec/perpetuity/postgres/table_name_spec.rb +2 -2
- data/spec/perpetuity/postgres/table_spec.rb +6 -6
- data/spec/perpetuity/postgres/text_value_spec.rb +2 -2
- data/spec/perpetuity/postgres/timestamp_value_spec.rb +4 -4
- data/spec/perpetuity/postgres/value_with_attribute_spec.rb +6 -6
- data/spec/perpetuity/postgres_spec.rb +38 -38
- metadata +6 -6
@@ -8,82 +8,82 @@ module Perpetuity
|
|
8
8
|
|
9
9
|
describe 'translation to SQL expressions' do
|
10
10
|
it 'translates equality to symbol by comparing with a string' do
|
11
|
-
expression.to_db.
|
11
|
+
expect(expression.to_db).to be == "attribute = 'value'"
|
12
12
|
end
|
13
13
|
|
14
14
|
it 'translates equality to strings' do
|
15
15
|
expression.value = expression.value.to_s
|
16
|
-
expression.to_db.
|
16
|
+
expect(expression.to_db).to be == "attribute = 'value'"
|
17
17
|
end
|
18
18
|
|
19
19
|
it 'removes SQL injection from strings' do
|
20
20
|
expression.value = "' OR 1; --"
|
21
|
-
expression.to_db.
|
21
|
+
expect(expression.to_db).to be == "attribute = ''' OR 1; --'"
|
22
22
|
end
|
23
23
|
|
24
24
|
it 'translates equality to numbers' do
|
25
25
|
expression.value = 1
|
26
|
-
expression.to_db.
|
26
|
+
expect(expression.to_db).to be == 'attribute = 1'
|
27
27
|
end
|
28
28
|
|
29
29
|
it 'less-than expression' do
|
30
30
|
expression.comparator = :<
|
31
|
-
expression.to_db.
|
31
|
+
expect(expression.to_db).to be == "attribute < 'value'"
|
32
32
|
end
|
33
33
|
|
34
34
|
it 'less-than-or-equal-to expression' do
|
35
35
|
expression.comparator = :<=
|
36
|
-
expression.to_db.
|
36
|
+
expect(expression.to_db).to be == "attribute <= 'value'"
|
37
37
|
end
|
38
38
|
|
39
39
|
it 'greater-than expression' do
|
40
40
|
expression.comparator = :>
|
41
|
-
expression.to_db.
|
41
|
+
expect(expression.to_db).to be == "attribute > 'value'"
|
42
42
|
end
|
43
43
|
|
44
44
|
it 'greater-than-or-equal-to expression' do
|
45
45
|
expression.comparator = :>=
|
46
|
-
expression.to_db.
|
46
|
+
expect(expression.to_db).to be == "attribute >= 'value'"
|
47
47
|
end
|
48
48
|
|
49
49
|
it 'not-equal' do
|
50
50
|
expression.comparator = :!=
|
51
|
-
expression.to_db.
|
51
|
+
expect(expression.to_db).to be == "attribute != 'value'"
|
52
52
|
end
|
53
53
|
|
54
54
|
it 'checks for inclusion' do
|
55
55
|
expression.comparator = :in
|
56
56
|
expression.value = [1, 2, 3]
|
57
|
-
expression.to_db.
|
57
|
+
expect(expression.to_db).to be == "attribute IN (1,2,3)"
|
58
58
|
end
|
59
59
|
|
60
60
|
it 'checks for inclusion in a range' do
|
61
61
|
expression.comparator = :in
|
62
62
|
expression.value = (1..3)
|
63
|
-
expression.to_db.
|
63
|
+
expect(expression.to_db).to be == "attribute BETWEEN 1 AND 3"
|
64
64
|
end
|
65
65
|
|
66
66
|
it 'checks for inclusion of strings' do
|
67
67
|
expression.comparator = :in
|
68
68
|
expression.value = ['abc', '123']
|
69
|
-
expression.to_db.
|
69
|
+
expect(expression.to_db).to be == "attribute IN ('abc','123')"
|
70
70
|
end
|
71
71
|
|
72
72
|
it 'checks for regexp matching' do
|
73
73
|
expression.comparator = :=~
|
74
74
|
expression.value = /value/
|
75
|
-
expression.to_db.
|
75
|
+
expect(expression.to_db).to be == "attribute ~ 'value'"
|
76
76
|
|
77
77
|
expression.value = /value/i
|
78
|
-
expression.to_db.
|
78
|
+
expect(expression.to_db).to be == "attribute ~* 'value'"
|
79
79
|
end
|
80
80
|
|
81
81
|
it 'checks for nil' do
|
82
82
|
expression.value = nil
|
83
|
-
expression.to_db.
|
83
|
+
expect(expression.to_db).to be == "attribute IS NULL"
|
84
84
|
|
85
85
|
expression.comparator = :!=
|
86
|
-
expression.to_db.
|
86
|
+
expect(expression.to_db).to be == "attribute IS NOT NULL"
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
@@ -92,7 +92,7 @@ module Perpetuity
|
|
92
92
|
let(:rhs) { QueryExpression.new :second, :==, :two }
|
93
93
|
|
94
94
|
it 'converts | to an $or query' do
|
95
|
-
(lhs | rhs).to_db.
|
95
|
+
expect((lhs | rhs).to_db).to be == "(first = 'one' OR second = 'two')"
|
96
96
|
end
|
97
97
|
end
|
98
98
|
|
@@ -101,14 +101,14 @@ module Perpetuity
|
|
101
101
|
let(:rhs) { QueryExpression.new :second, :==, :two }
|
102
102
|
|
103
103
|
it 'converts & to an $and query' do
|
104
|
-
(lhs & rhs).to_db.
|
104
|
+
expect((lhs & rhs).to_db).to be == "(first = 'one' AND second = 'two')"
|
105
105
|
end
|
106
106
|
end
|
107
107
|
|
108
108
|
describe 'values' do
|
109
109
|
it 'compares against times' do
|
110
110
|
expression.value = Time.new(2013, 1, 2, 3, 4, 5.1234567, '-05:00')
|
111
|
-
expression.to_db.
|
111
|
+
expect(expression.to_db).to be == "attribute = '2013-01-02 03:04:05.123456-0500'::timestamptz"
|
112
112
|
end
|
113
113
|
end
|
114
114
|
end
|
@@ -8,15 +8,15 @@ module Perpetuity
|
|
8
8
|
let(:intersection) { QueryIntersection.new(lhs, rhs) }
|
9
9
|
|
10
10
|
it 'converts to a SQL "AND" expression' do
|
11
|
-
intersection.to_db.
|
11
|
+
expect(intersection.to_db).to be == '(left = 1 AND right = 2)'
|
12
12
|
end
|
13
13
|
|
14
14
|
it 'allows intersections to have other intersections' do
|
15
|
-
(intersection&intersection).to_db.
|
15
|
+
expect((intersection&intersection).to_db).to be == '((left = 1 AND right = 2) AND (left = 1 AND right = 2))'
|
16
16
|
end
|
17
17
|
|
18
18
|
it 'allows intersections to have unions' do
|
19
|
-
(intersection|intersection).to_db.
|
19
|
+
expect((intersection|intersection).to_db).to be == '((left = 1 AND right = 2) OR (left = 1 AND right = 2))'
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
@@ -6,17 +6,17 @@ module Perpetuity
|
|
6
6
|
let(:query) { Query.new { |o| o.name == 'foo' } }
|
7
7
|
|
8
8
|
it 'generates an equality statement' do
|
9
|
-
query.to_db.
|
9
|
+
expect(query.to_db).to be == "name = 'foo'"
|
10
10
|
end
|
11
11
|
|
12
12
|
it 'automatically converts to a string' do
|
13
13
|
q = ''
|
14
14
|
q << query
|
15
|
-
q.
|
15
|
+
expect(q).to be == "name = 'foo'"
|
16
16
|
end
|
17
17
|
|
18
18
|
it 'returns TRUE with no block passed' do
|
19
|
-
Query.new.to_db.
|
19
|
+
expect(Query.new.to_db).to be == 'TRUE'
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
@@ -8,15 +8,15 @@ module Perpetuity
|
|
8
8
|
let(:union) { QueryUnion.new(lhs, rhs) }
|
9
9
|
|
10
10
|
it 'converts to a SQL "OR" expression' do
|
11
|
-
union.to_db.
|
11
|
+
expect(union.to_db).to be == '(left = 1 OR right = 2)'
|
12
12
|
end
|
13
13
|
|
14
14
|
it 'allows unions to have other unions' do
|
15
|
-
(union|union).to_db.
|
15
|
+
expect((union|union).to_db).to be == '((left = 1 OR right = 2) OR (left = 1 OR right = 2))'
|
16
16
|
end
|
17
17
|
|
18
18
|
it 'allows unions to have intersections' do
|
19
|
-
(union&union).to_db.
|
19
|
+
expect((union&union).to_db).to be == '((left = 1 OR right = 2) AND (left = 1 OR right = 2))'
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
@@ -8,19 +8,19 @@ module Perpetuity
|
|
8
8
|
let(:serialized) { SerializedData.new(columns, data) }
|
9
9
|
|
10
10
|
it 'matches a SQL string' do
|
11
|
-
serialized.to_s.
|
11
|
+
expect(serialized.to_s).to be == "(name,age) VALUES ('Jamie',31)"
|
12
12
|
end
|
13
13
|
|
14
14
|
describe 'adding values' do
|
15
15
|
it 'adds a value' do
|
16
16
|
serialized['id'] = 'abc'
|
17
|
-
serialized.to_s.
|
17
|
+
expect(serialized.to_s).to be == "(name,age,id) VALUES ('Jamie',31,'abc')"
|
18
18
|
end
|
19
19
|
|
20
20
|
it 'replaces an existing value' do
|
21
21
|
serialized['id'] = 'abc'
|
22
22
|
serialized['id'] = 'xyz'
|
23
|
-
serialized.to_s.
|
23
|
+
expect(serialized.to_s).to be == "(name,age,id) VALUES ('Jamie',31,'xyz')"
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
@@ -33,39 +33,39 @@ module Perpetuity
|
|
33
33
|
end
|
34
34
|
|
35
35
|
it 'matches a SQL string' do
|
36
|
-
serialized_multiple.reduce(:+).to_s.
|
36
|
+
expect(serialized_multiple.reduce(:+).to_s).to be ==
|
37
37
|
"(name,age) VALUES ('Jamie',31),('Jessica',23),('Kevin',22)"
|
38
38
|
end
|
39
39
|
|
40
40
|
it 'does not modify the first value' do
|
41
41
|
jamie_values = serialized_multiple.first.values.dup
|
42
42
|
serialized_multiple.reduce(:+)
|
43
|
-
serialized_multiple.first.values.
|
43
|
+
expect(serialized_multiple.first.values).to be == jamie_values
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
47
|
it 'checks whether there are any objects' do
|
48
|
-
serialized.any
|
48
|
+
expect(serialized.any?).to be_truthy
|
49
49
|
serialized.values.clear << []
|
50
|
-
serialized.any
|
50
|
+
expect(serialized.any?).to be_falsey
|
51
51
|
end
|
52
52
|
|
53
53
|
it 'iterates like a hash' do
|
54
|
-
serialized.map { |attr, value| [attr, value] }.
|
54
|
+
expect(serialized.map { |attr, value| [attr, value] }).to be ==
|
55
55
|
[['name', "'Jamie'"], ['age', 31]]
|
56
56
|
end
|
57
57
|
|
58
58
|
it 'accesses values like a hash' do
|
59
|
-
serialized['age'].
|
60
|
-
serialized[:age].
|
59
|
+
expect(serialized['age']).to be == 31
|
60
|
+
expect(serialized[:age]).to be == 31
|
61
61
|
end
|
62
62
|
|
63
63
|
it 'equals another with the same data' do
|
64
64
|
original = SerializedData.new([:a, :b], [1, 2])
|
65
65
|
duplicate = SerializedData.new([:a, :b], [1, 2])
|
66
66
|
modified = SerializedData.new([:a, :b], [0, 2])
|
67
|
-
original.
|
68
|
-
original.
|
67
|
+
expect(original).to be == duplicate
|
68
|
+
expect(original).not_to be == modified
|
69
69
|
end
|
70
70
|
|
71
71
|
it 'returns a new SerializedData with the complement of values' do
|
@@ -73,8 +73,8 @@ module Perpetuity
|
|
73
73
|
original = SerializedData.new(columns, ["'Jamie'", 31, nil, nil])
|
74
74
|
new_name = SerializedData.new(columns, ["'Foo'", 31, nil, nil])
|
75
75
|
new_age = SerializedData.new(columns, ["'Jamie'", 32, nil, nil])
|
76
|
-
(new_name - original).
|
77
|
-
(new_age - original).
|
76
|
+
expect((new_name - original)).to be == SerializedData.new([:name], ["'Foo'"])
|
77
|
+
expect((new_age - original)).to be == SerializedData.new([:age], [32])
|
78
78
|
end
|
79
79
|
end
|
80
80
|
end
|
@@ -27,7 +27,7 @@ module Perpetuity
|
|
27
27
|
let(:serializer) { Serializer.new(book_mapper) }
|
28
28
|
|
29
29
|
it 'serializes simple objects' do
|
30
|
-
serializer.serialize(Book.new('Foo')).to_s.
|
30
|
+
expect(serializer.serialize(Book.new('Foo')).to_s).to be ==
|
31
31
|
%q{(title,authors,main_character) VALUES ('Foo','[]',NULL)}
|
32
32
|
end
|
33
33
|
|
@@ -42,7 +42,7 @@ module Perpetuity
|
|
42
42
|
context 'with nested objects' do
|
43
43
|
let(:book) { Book.new('Foo', jamie, character) }
|
44
44
|
it 'converts objects into JSON' do
|
45
|
-
serializer.serialize(book).to_s.
|
45
|
+
expect(serializer.serialize(book).to_s).to be ==
|
46
46
|
%Q{(title,authors,main_character) VALUES ('Foo','#{jamie_json}','#{character_json}')}
|
47
47
|
end
|
48
48
|
end
|
@@ -51,7 +51,7 @@ module Perpetuity
|
|
51
51
|
let(:book) { Book.new('Foo', [jamie], [character]) }
|
52
52
|
|
53
53
|
it 'adds the JSON array' do
|
54
|
-
serializer.serialize(book).to_s.
|
54
|
+
expect(serializer.serialize(book).to_s).to be ==
|
55
55
|
%Q{(title,authors,main_character) VALUES ('Foo','[#{jamie_json}]','[#{character_json}]')}
|
56
56
|
end
|
57
57
|
end
|
@@ -59,39 +59,39 @@ module Perpetuity
|
|
59
59
|
|
60
60
|
context 'with natively serializable values' do
|
61
61
|
it 'serializes strings' do
|
62
|
-
serializer.serialize_attribute('string').
|
62
|
+
expect(serializer.serialize_attribute('string')).to be == "'string'"
|
63
63
|
end
|
64
64
|
|
65
65
|
it 'serializes numbers' do
|
66
|
-
serializer.serialize_attribute(1).
|
67
|
-
serializer.serialize_attribute(1.5).
|
66
|
+
expect(serializer.serialize_attribute(1)).to be == '1'
|
67
|
+
expect(serializer.serialize_attribute(1.5)).to be == '1.5'
|
68
68
|
end
|
69
69
|
|
70
70
|
it 'serializes nil' do
|
71
|
-
serializer.serialize_attribute(nil).
|
71
|
+
expect(serializer.serialize_attribute(nil)).to be == 'NULL'
|
72
72
|
end
|
73
73
|
|
74
74
|
it 'serializes booleans' do
|
75
|
-
serializer.serialize_attribute(true).
|
76
|
-
serializer.serialize_attribute(false).
|
75
|
+
expect(serializer.serialize_attribute(true)).to be == 'TRUE'
|
76
|
+
expect(serializer.serialize_attribute(false)).to be == 'FALSE'
|
77
77
|
end
|
78
78
|
|
79
79
|
it 'serializes Time objects' do
|
80
80
|
time = Time.new(2000, 1, 2, 3, 4, 5.123456, '-04:00')
|
81
|
-
serializer.serialize_attribute(time).
|
81
|
+
expect(serializer.serialize_attribute(time)).to be == "'2000-01-02 03:04:05.123456-0400'::timestamptz"
|
82
82
|
end
|
83
83
|
|
84
84
|
it 'serializes Date objects' do
|
85
85
|
date = Date.new(2014, 8, 25)
|
86
|
-
serializer.serialize_attribute(date).
|
86
|
+
expect(serializer.serialize_attribute(date)).to be == "'2014-08-25'::date"
|
87
87
|
end
|
88
88
|
|
89
89
|
it 'serializes an array as JSON' do
|
90
|
-
serializer.serialize_attribute([1, 'foo']).
|
90
|
+
expect(serializer.serialize_attribute([1, 'foo'])).to be == %q{'[1,"foo"]'}
|
91
91
|
end
|
92
92
|
|
93
93
|
it 'serializes a hash as JSON' do
|
94
|
-
serializer.serialize_attribute(a: 1, foo: ['bar']).
|
94
|
+
expect(serializer.serialize_attribute(a: 1, foo: ['bar'])).to be == %q{'{"a":1,"foo":["bar"]}'}
|
95
95
|
end
|
96
96
|
end
|
97
97
|
|
@@ -114,7 +114,7 @@ module Perpetuity
|
|
114
114
|
}].to_json
|
115
115
|
serialized_book['authors'] = serialized_authors
|
116
116
|
book = Book.new('My Book', [author])
|
117
|
-
serializer.unserialize(serialized_book).
|
117
|
+
expect(serializer.unserialize(serialized_book)).to be == book
|
118
118
|
end
|
119
119
|
|
120
120
|
it 'deserializes an object which references another object' do
|
@@ -125,7 +125,7 @@ module Perpetuity
|
|
125
125
|
}
|
126
126
|
}.to_json
|
127
127
|
deserialized_book = Book.new('My Book', [], Reference.new(Person, 'id-id-id'))
|
128
|
-
serializer.unserialize(serialized_book).
|
128
|
+
expect(serializer.unserialize(serialized_book)).to be == deserialized_book
|
129
129
|
end
|
130
130
|
|
131
131
|
let(:article_class) do
|
@@ -180,31 +180,31 @@ module Perpetuity
|
|
180
180
|
published_at: Time.new(2013, 1, 2, 3, 4, 5.123456, '-05:00'),
|
181
181
|
published: true
|
182
182
|
)
|
183
|
-
serializer.unserialize(serialized_article).
|
183
|
+
expect(serializer.unserialize(serialized_article)).to be == article
|
184
184
|
end
|
185
185
|
end
|
186
186
|
|
187
187
|
describe 'identifying embedded/referenced objects as foreign' do
|
188
188
|
it 'sees hashes with metadata keys as foreign objects' do
|
189
|
-
serializer.foreign_object?({'__metadata__' => 'lol'}).
|
189
|
+
expect(serializer.foreign_object?({'__metadata__' => 'lol'})).to be_truthy
|
190
190
|
end
|
191
191
|
|
192
192
|
it 'sees hashes without metadata keys as simple hashes' do
|
193
|
-
serializer.foreign_object?({ 'name' => 'foo' }).
|
193
|
+
expect(serializer.foreign_object?({ 'name' => 'foo' })).to be_falsey
|
194
194
|
end
|
195
195
|
end
|
196
196
|
|
197
197
|
describe 'identifying possible JSON strings' do
|
198
198
|
it 'identifies JSON objects' do
|
199
|
-
serializer.possible_json_value?('{"name":"foo"}').
|
199
|
+
expect(serializer.possible_json_value?('{"name":"foo"}')).to be_truthy
|
200
200
|
end
|
201
201
|
|
202
202
|
it 'identifies JSON arrays' do
|
203
|
-
serializer.possible_json_value?('[{"name":"foo"}]').
|
203
|
+
expect(serializer.possible_json_value?('[{"name":"foo"}]')).to be_truthy
|
204
204
|
end
|
205
205
|
|
206
206
|
it 'rejects things it does not detect as either of the above' do
|
207
|
-
serializer.possible_json_value?('foo is my name').
|
207
|
+
expect(serializer.possible_json_value?('foo is my name')).to be_falsey
|
208
208
|
end
|
209
209
|
end
|
210
210
|
|
@@ -212,13 +212,13 @@ module Perpetuity
|
|
212
212
|
original = Book.new('Old title')
|
213
213
|
modified = original.dup
|
214
214
|
modified.title = 'New title'
|
215
|
-
serializer.serialize_changes(modified, original).
|
215
|
+
expect(serializer.serialize_changes(modified, original)).to be ==
|
216
216
|
SerializedData.new([:title], ["'New title'"])
|
217
217
|
end
|
218
218
|
|
219
219
|
it 'serializes a reference as its referenced class' do
|
220
220
|
reference = Reference.new(Object, 123)
|
221
|
-
serializer.serialize_reference(reference).
|
221
|
+
expect(serializer.serialize_reference(reference)).to be == JSONHash.new(
|
222
222
|
__metadata__: {
|
223
223
|
class: Object,
|
224
224
|
id: 123
|
@@ -5,12 +5,12 @@ module Perpetuity
|
|
5
5
|
describe SQLFunction do
|
6
6
|
it 'converts to a SQL function call' do
|
7
7
|
function = SQLFunction.new('json_array_length', :comments)
|
8
|
-
function.to_s.
|
8
|
+
expect(function.to_s).to be == 'json_array_length(comments)'
|
9
9
|
end
|
10
10
|
|
11
11
|
it 'takes multiple arguments' do
|
12
12
|
function = SQLFunction.new('compare', :a, :b)
|
13
|
-
function.to_s.
|
13
|
+
expect(function.to_s).to be == 'compare(a,b)'
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
@@ -9,50 +9,50 @@ module Perpetuity
|
|
9
9
|
subject { query }
|
10
10
|
|
11
11
|
it 'returns its table name' do
|
12
|
-
query.table.
|
12
|
+
expect(query.table).to be == 'foo'
|
13
13
|
end
|
14
14
|
|
15
15
|
it 'returns its WHERE clause' do
|
16
|
-
query.where.
|
16
|
+
expect(query.where).to be == "name = 'foo'"
|
17
17
|
end
|
18
18
|
|
19
19
|
it 'returns its limit' do
|
20
|
-
query.limit.
|
20
|
+
expect(query.limit).to be == 4
|
21
21
|
end
|
22
22
|
|
23
23
|
it 'generates a SQL query' do
|
24
|
-
query.to_s.
|
24
|
+
expect(query.to_s).to be == %Q{SELECT * FROM "foo" WHERE name = 'foo' LIMIT 4}
|
25
25
|
end
|
26
26
|
|
27
27
|
it 'generates a query with no clauses' do
|
28
28
|
sql = SQLSelect.new(from: 'foo').to_s
|
29
|
-
sql.
|
29
|
+
expect(sql).to be == %Q{SELECT * FROM "foo"}
|
30
30
|
end
|
31
31
|
|
32
32
|
it 'generates a count query' do
|
33
33
|
sql = SQLSelect.new('COUNT(*)', from: 'foo').to_s
|
34
|
-
sql.
|
34
|
+
expect(sql).to be == %Q{SELECT COUNT(*) FROM "foo"}
|
35
35
|
end
|
36
36
|
|
37
37
|
it 'generates a query with an ORDER BY clause' do
|
38
38
|
sql = SQLSelect.new(from: 'foo', order: 'name').to_s
|
39
|
-
sql.
|
39
|
+
expect(sql).to be == %Q{SELECT * FROM "foo" ORDER BY name}
|
40
40
|
|
41
41
|
sql = SQLSelect.new(from: 'foo', order: { name: :asc }).to_s
|
42
|
-
sql.
|
42
|
+
expect(sql).to be == %Q{SELECT * FROM "foo" ORDER BY name ASC}
|
43
43
|
|
44
44
|
sql = SQLSelect.new(from: 'foo', order: { name: :asc, age: :desc }).to_s
|
45
|
-
sql.
|
45
|
+
expect(sql).to be == %Q{SELECT * FROM "foo" ORDER BY name ASC,age DESC}
|
46
46
|
end
|
47
47
|
|
48
48
|
it 'generates a query with an OFFSET clause' do
|
49
49
|
sql = SQLSelect.new(from: 'foo', offset: 12).to_s
|
50
|
-
sql.
|
50
|
+
expect(sql).to be == %Q{SELECT * FROM "foo" OFFSET 12}
|
51
51
|
end
|
52
52
|
|
53
53
|
it 'generates a query with a GROUP BY clause' do
|
54
54
|
sql = SQLSelect.new(from: 'foo', group: :id).to_s
|
55
|
-
sql.
|
55
|
+
expect(sql).to be == %Q{SELECT * FROM "foo" GROUP BY id}
|
56
56
|
end
|
57
57
|
end
|
58
58
|
end
|
@@ -7,14 +7,14 @@ module Perpetuity
|
|
7
7
|
context 'when given a SerializedData' do
|
8
8
|
it 'generates the SQL to update an object' do
|
9
9
|
update = SQLUpdate.new('User', 'abc123', SerializedData.new([:foo, :baz], ["'bar'", "'quux'"]))
|
10
|
-
update.to_s.
|
10
|
+
expect(update.to_s).to be == %Q{UPDATE "User" SET foo = 'bar',baz = 'quux' WHERE id = 'abc123'}
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
14
|
context 'when given a hash' do
|
15
15
|
it 'sanitizes the data into SQLValues' do
|
16
16
|
update = SQLUpdate.new('User', 'abc123', foo: 'bar', baz: 'quux')
|
17
|
-
update.to_s.
|
17
|
+
expect(update.to_s).to be == %Q{UPDATE "User" SET foo = 'bar',baz = 'quux' WHERE id = 'abc123'}
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
@@ -4,56 +4,56 @@ module Perpetuity
|
|
4
4
|
class Postgres
|
5
5
|
describe SQLValue do
|
6
6
|
it 'converts strings' do
|
7
|
-
SQLValue.new('Foo').
|
8
|
-
SQLValue.new("Jamie's House").
|
7
|
+
expect(SQLValue.new('Foo')).to be == "'Foo'"
|
8
|
+
expect(SQLValue.new("Jamie's House")).to be == "'Jamie''s House'"
|
9
9
|
end
|
10
10
|
|
11
11
|
it 'converts symbols' do
|
12
|
-
SQLValue.new(:foo).
|
12
|
+
expect(SQLValue.new(:foo)).to be == "'foo'"
|
13
13
|
end
|
14
14
|
|
15
15
|
it 'converts integers' do
|
16
|
-
SQLValue.new(1).
|
16
|
+
expect(SQLValue.new(1)).to be == "1"
|
17
17
|
end
|
18
18
|
|
19
19
|
it 'converts floats' do
|
20
|
-
SQLValue.new(1.5).
|
20
|
+
expect(SQLValue.new(1.5)).to be == "1.5"
|
21
21
|
end
|
22
22
|
|
23
23
|
it 'converts nil' do
|
24
|
-
SQLValue.new(nil).
|
24
|
+
expect(SQLValue.new(nil)).to be == "NULL"
|
25
25
|
end
|
26
26
|
|
27
27
|
it 'converts booleans' do
|
28
|
-
SQLValue.new(true).
|
29
|
-
SQLValue.new(false).
|
28
|
+
expect(SQLValue.new(true)).to be == "TRUE"
|
29
|
+
expect(SQLValue.new(false)).to be == "FALSE"
|
30
30
|
end
|
31
31
|
|
32
32
|
it 'converts hashes' do
|
33
|
-
SQLValue.new({ a: 1, b: 'foo'}).
|
33
|
+
expect(SQLValue.new({ a: 1, b: 'foo'})).to be == %q({"a":1,"b":"foo"})
|
34
34
|
end
|
35
35
|
|
36
36
|
it 'converts arrays' do
|
37
|
-
SQLValue.new([1, 'foo', { a: 1 }]).
|
37
|
+
expect(SQLValue.new([1, 'foo', { a: 1 }])).to be == %q([1,"foo",{"a":1}])
|
38
38
|
end
|
39
39
|
|
40
40
|
it 'converts JSONHashes' do
|
41
|
-
SQLValue.new(JSONHash.new(a: 1)).
|
41
|
+
expect(SQLValue.new(JSONHash.new(a: 1))).to be == %q({"a":1})
|
42
42
|
end
|
43
43
|
|
44
44
|
it 'converts JSONArrays' do
|
45
|
-
SQLValue.new(JSONArray.new([1, 'foo', [1, 'foo']])).
|
45
|
+
expect(SQLValue.new(JSONArray.new([1, 'foo', [1, 'foo']]))).to be ==
|
46
46
|
%q([1,"foo",[1,"foo"]])
|
47
47
|
end
|
48
48
|
|
49
49
|
it 'converts Time objects' do
|
50
50
|
time = Time.new(2013, 1, 2, 3, 4, 5.1234567, '+05:30')
|
51
|
-
SQLValue.new(time).
|
51
|
+
expect(SQLValue.new(time)).to be == "'2013-01-02 03:04:05.123456+0530'::timestamptz"
|
52
52
|
end
|
53
53
|
|
54
54
|
it 'converts Date objects' do
|
55
55
|
date = Date.new(2014, 8, 25)
|
56
|
-
SQLValue.new(date).
|
56
|
+
expect(SQLValue.new(date)).to be == "'2014-08-25'::date"
|
57
57
|
end
|
58
58
|
end
|
59
59
|
end
|