sunstone 6.1.0.2 → 7.0.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.
- checksums.yaml +4 -4
- data/ext/active_record/associations/collection_association.rb +1 -1
- data/ext/active_record/attribute_methods.rb +7 -1
- data/ext/active_record/finder_methods.rb +14 -13
- data/ext/active_record/persistence.rb +6 -3
- data/ext/active_record/relation/calculations.rb +11 -4
- data/ext/active_record/relation/query_methods.rb +1 -1
- data/ext/active_record/statement_cache.rb +0 -1
- data/ext/arel/nodes/select_statement.rb +3 -3
- data/lib/active_record/connection_adapters/sunstone/column.rb +1 -1
- data/lib/active_record/connection_adapters/sunstone/database_statements.rb +8 -9
- data/lib/active_record/connection_adapters/sunstone/schema_statements.rb +31 -14
- data/lib/active_record/connection_adapters/sunstone_adapter.rb +17 -7
- data/lib/arel/collectors/sunstone.rb +25 -4
- data/lib/arel/visitors/sunstone.rb +21 -26
- data/lib/sunstone/connection.rb +40 -13
- data/lib/sunstone/version.rb +1 -1
- metadata +21 -61
- data/.github/workflows/main.yml +0 -141
- data/.gitignore +0 -31
- data/.tm_properties +0 -1
- data/Gemfile +0 -4
- data/README.md +0 -46
- data/Rakefile +0 -37
- data/TODO.md +0 -89
- data/sunstone.gemspec +0 -40
- data/test/active_record/associations/belongs_to_test.rb +0 -162
- data/test/active_record/associations/has_and_belongs_to_many_test.rb +0 -125
- data/test/active_record/associations/has_many_test.rb +0 -244
- data/test/active_record/eager_loading_test.rb +0 -62
- data/test/active_record/persistance_test.rb +0 -184
- data/test/active_record/preload_test.rb +0 -51
- data/test/active_record/query/all_test.rb +0 -33
- data/test/active_record/query/count_test.rb +0 -51
- data/test/active_record/query/distinct_test.rb +0 -30
- data/test/active_record/query/find_test.rb +0 -37
- data/test/active_record/query/limit_test.rb +0 -19
- data/test/active_record/query/order_test.rb +0 -27
- data/test/active_record/query/where_test.rb +0 -79
- data/test/active_record/query_test.rb +0 -131
- data/test/active_record/rpc_test.rb +0 -30
- data/test/schema_mock.rb +0 -121
- data/test/sunstone/connection/column_definition_test.rb +0 -30
- data/test/sunstone/connection/configuration_test.rb +0 -44
- data/test/sunstone/connection/cookie_store_test.rb +0 -37
- data/test/sunstone/connection/request_helper_test.rb +0 -105
- data/test/sunstone/connection/send_request_test.rb +0 -164
- data/test/sunstone/connection_test.rb +0 -23
- data/test/test_helper.rb +0 -153
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 02df1d75e40c2ef207e6e1f329068c95098f5b99758d1bcea603e157ed2c1f40
|
4
|
+
data.tar.gz: 4807c8a530f9c7f09448a08bea1dbe015724f2afb53d81b86cf5cef6d6b49dcf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e884525eda7c249da0f4decbadff3d27ff97859eac4874e1c20b4b0e10c80d6d96ee49419d27bd2f6d429c55c93485bfe1961451ff8396d101e37752ec39ac6d
|
7
|
+
data.tar.gz: 4323252706192a940b6f730a6c46324d4c40729df5864a5d1aafc4283764ef159284ddefe9b1335a7d9174b6716d11a2d0da4aa59dbdfbc3ac7cdccc537b06f8
|
@@ -41,7 +41,7 @@ module ActiveRecord
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def insert_record(record, validate = true, raise = false, &block)
|
44
|
-
if record.class.connection.is_a?(ActiveRecord::ConnectionAdapters::SunstoneAPIAdapter) &&
|
44
|
+
if record.class.connection.is_a?(ActiveRecord::ConnectionAdapters::SunstoneAPIAdapter) && owner.instance_variable_defined?(:@updating) && owner.instance_variable_get(:@updating)
|
45
45
|
true
|
46
46
|
elsif raise
|
47
47
|
record.save!(validate: validate, &block)
|
@@ -97,7 +97,13 @@ module ActiveRecord
|
|
97
97
|
[]
|
98
98
|
else
|
99
99
|
association.target.select { |r| !r.destroyed? }.map do |record|
|
100
|
-
record.send(
|
100
|
+
record.send(
|
101
|
+
:attributes_with_values,
|
102
|
+
record.new_record? ?
|
103
|
+
record.send(:attribute_names_for_partial_inserts)
|
104
|
+
:
|
105
|
+
record.send(:attribute_names_for_partial_updates) + [record.class.primary_key]
|
106
|
+
)
|
101
107
|
end
|
102
108
|
end
|
103
109
|
|
@@ -6,7 +6,8 @@ module ActiveRecord
|
|
6
6
|
|
7
7
|
attributes.flat_map do |key, value|
|
8
8
|
if value.is_a?(Hash) && !table.has_column?(key)
|
9
|
-
ka = table.associated_table(key, &block)
|
9
|
+
ka = table.associated_table(key, &block)
|
10
|
+
.predicate_builder.expand_from_hash(value.stringify_keys)
|
10
11
|
if self.send(:table).instance_variable_get(:@klass).connection.is_a?(ActiveRecord::ConnectionAdapters::SunstoneAPIAdapter)
|
11
12
|
ka.each { |k|
|
12
13
|
if k.left.is_a?(Arel::Attributes::Attribute) || k.left.is_a?(Arel::Attributes::Relation)
|
@@ -23,11 +24,8 @@ module ActiveRecord
|
|
23
24
|
# PriceEstimate.where(estimate_of: treasure)
|
24
25
|
associated_table = table.associated_table(key)
|
25
26
|
if associated_table.polymorphic_association?
|
26
|
-
|
27
|
-
|
28
|
-
value = [value] unless value.is_a?(Array)
|
29
|
-
klass = PolymorphicArrayValue
|
30
|
-
end
|
27
|
+
value = [value] unless value.is_a?(Array)
|
28
|
+
klass = PolymorphicArrayValue
|
31
29
|
elsif associated_table.through_association?
|
32
30
|
next associated_table.predicate_builder.expand_from_hash(
|
33
31
|
associated_table.primary_key => value
|
@@ -36,7 +34,9 @@ module ActiveRecord
|
|
36
34
|
|
37
35
|
klass ||= AssociationQueryValue
|
38
36
|
queries = klass.new(associated_table, value).queries.map! do |query|
|
39
|
-
|
37
|
+
# If the query produced is identical to attributes don't go any deeper.
|
38
|
+
# Prevents stack level too deep errors when association and foreign_key are identical.
|
39
|
+
query == attributes ? self[key, value] : expand_from_hash(query)
|
40
40
|
end
|
41
41
|
|
42
42
|
grouping_queries(queries)
|
@@ -202,7 +202,7 @@ module ActiveRecord
|
|
202
202
|
relation = except(:includes, :eager_load, :preload).joins!(join_dependency)
|
203
203
|
end
|
204
204
|
|
205
|
-
if eager_loading && !(
|
205
|
+
if eager_loading && has_limit_or_offset? && !(
|
206
206
|
using_limitable_reflections?(join_dependency.reflections) &&
|
207
207
|
using_limitable_reflections?(
|
208
208
|
construct_join_dependency(
|
@@ -211,12 +211,12 @@ module ActiveRecord
|
|
211
211
|
), nil
|
212
212
|
).reflections
|
213
213
|
)
|
214
|
-
|
215
|
-
if
|
216
|
-
|
217
|
-
|
214
|
+
)
|
215
|
+
if !connection.is_a?(ActiveRecord::ConnectionAdapters::SunstoneAPIAdapter)
|
216
|
+
relation = skip_query_cache_if_necessary do
|
217
|
+
klass.connection.distinct_relation_for_primary_key(relation)
|
218
|
+
end
|
218
219
|
end
|
219
|
-
relation.limit_value = relation.offset_value = nil
|
220
220
|
end
|
221
221
|
|
222
222
|
if block_given?
|
@@ -225,6 +225,7 @@ module ActiveRecord
|
|
225
225
|
relation
|
226
226
|
end
|
227
227
|
end
|
228
|
+
|
228
229
|
end
|
229
230
|
|
230
231
|
end
|
@@ -79,17 +79,20 @@ module ActiveRecord
|
|
79
79
|
# Creates a record with values matching those of the instance attributes
|
80
80
|
# and returns its id.
|
81
81
|
def _create_record(attribute_names = self.attribute_names)
|
82
|
-
attribute_names
|
82
|
+
attribute_names = attributes_for_create(attribute_names)
|
83
83
|
attributes_values = attributes_with_values(attribute_names)
|
84
|
-
|
84
|
+
|
85
85
|
new_id = self.class._insert_record(attributes_values)
|
86
86
|
|
87
|
+
self.id ||= new_id if @primary_key
|
87
88
|
@new_record = false
|
89
|
+
@previously_new_record = true
|
90
|
+
|
91
|
+
yield(self) if block_given?
|
88
92
|
|
89
93
|
if self.class.connection.is_a?(ActiveRecord::ConnectionAdapters::SunstoneAPIAdapter)
|
90
94
|
new_id
|
91
95
|
else
|
92
|
-
self.id ||= new_id if self.class.primary_key
|
93
96
|
id
|
94
97
|
end
|
95
98
|
end
|
@@ -2,7 +2,7 @@ module ActiveRecord
|
|
2
2
|
module Calculations
|
3
3
|
|
4
4
|
def pluck(*column_names)
|
5
|
-
if loaded? && (column_names
|
5
|
+
if loaded? && all_attributes?(column_names)
|
6
6
|
return records.pluck(*column_names)
|
7
7
|
end
|
8
8
|
|
@@ -14,10 +14,17 @@ module ActiveRecord
|
|
14
14
|
return records.pluck(*column_names.map{|n| n.to_s.sub(/^#{klass.table_name}\./, "")})
|
15
15
|
else
|
16
16
|
klass.disallow_raw_sql!(column_names)
|
17
|
+
columns = arel_columns(column_names)
|
17
18
|
relation = spawn
|
18
|
-
relation.select_values =
|
19
|
-
result = skip_query_cache_if_necessary
|
20
|
-
|
19
|
+
relation.select_values = columns
|
20
|
+
result = skip_query_cache_if_necessary do
|
21
|
+
if where_clause.contradiction?
|
22
|
+
ActiveRecord::Result.empty
|
23
|
+
else
|
24
|
+
klass.connection.select_all(relation.arel, "#{klass.name} Pluck")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
type_cast_pluck_values(result, columns)
|
21
28
|
end
|
22
29
|
end
|
23
30
|
|
@@ -3,7 +3,7 @@ module ActiveRecord
|
|
3
3
|
private
|
4
4
|
def assert_mutability!
|
5
5
|
raise ImmutableRelation if @loaded
|
6
|
-
raise ImmutableRelation if defined?(@arel) && !klass.connection.is_a?(ActiveRecord::ConnectionAdapters::SunstoneAPIAdapter)
|
6
|
+
raise ImmutableRelation if defined?(@arel) && @arel && !klass.connection.is_a?(ActiveRecord::ConnectionAdapters::SunstoneAPIAdapter)
|
7
7
|
end
|
8
8
|
end
|
9
9
|
end
|
@@ -4,9 +4,9 @@ module Arel
|
|
4
4
|
|
5
5
|
attr_accessor :eager_load
|
6
6
|
|
7
|
-
def initialize(
|
7
|
+
def initialize(relation = nil)
|
8
8
|
super()
|
9
|
-
@cores =
|
9
|
+
@cores = [SelectCore.new(relation)]
|
10
10
|
@orders = []
|
11
11
|
@limit = nil
|
12
12
|
@lock = nil
|
@@ -36,7 +36,7 @@ module Arel
|
|
36
36
|
self.with == other.with &&
|
37
37
|
self.eager_load == other.eager_load
|
38
38
|
end
|
39
|
-
|
39
|
+
alias :== :eql?
|
40
40
|
end
|
41
41
|
end
|
42
42
|
end
|
@@ -8,7 +8,7 @@ module ActiveRecord
|
|
8
8
|
@name = name.freeze
|
9
9
|
@sql_type_metadata = sql_type_metadata
|
10
10
|
@null = options['null']
|
11
|
-
@default = options['default']
|
11
|
+
@default = options['default'] ? JSON.generate(options['default']) : options['default']
|
12
12
|
@default_function = nil
|
13
13
|
@collation = nil
|
14
14
|
@table_name = nil
|
@@ -28,18 +28,16 @@ module ActiveRecord
|
|
28
28
|
sar.compile(binds)
|
29
29
|
end
|
30
30
|
|
31
|
-
def to_sar_and_binds(arel_or_sar_string, binds = []) # :nodoc:
|
31
|
+
def to_sar_and_binds(arel_or_sar_string, binds = [], preparable = nil) # :nodoc:
|
32
32
|
if arel_or_sar_string.respond_to?(:ast)
|
33
33
|
unless binds.empty?
|
34
34
|
raise "Passing bind parameters with an arel AST is forbidden. " \
|
35
35
|
"The values must be stored on the AST directly"
|
36
36
|
end
|
37
37
|
sar = visitor.accept(arel_or_sar_string.ast, collector)
|
38
|
-
|
39
|
-
[sar.freeze, sar.binds]
|
38
|
+
[sar.freeze, sar.binds, false]
|
40
39
|
else
|
41
|
-
|
42
|
-
[arel_or_sar_string.dup.freeze, binds]
|
40
|
+
[arel_or_sar_string.dup.freeze, binds, false]
|
43
41
|
end
|
44
42
|
end
|
45
43
|
|
@@ -79,10 +77,11 @@ module ActiveRecord
|
|
79
77
|
end
|
80
78
|
|
81
79
|
# Returns an ActiveRecord::Result instance.
|
82
|
-
def select_all(arel, name = nil, binds = [], preparable: nil)
|
80
|
+
def select_all(arel, name = nil, binds = [], preparable: nil, async: false)
|
83
81
|
arel = arel_from_relation(arel)
|
84
|
-
sar, binds = to_sar_and_binds(arel, binds)
|
85
|
-
|
82
|
+
sar, binds, preparable = to_sar_and_binds(arel, binds, preparable)
|
83
|
+
|
84
|
+
select(sar, name, binds, prepare: prepared_statements && preparable, async: async && FutureResult::SelectAll)
|
86
85
|
end
|
87
86
|
|
88
87
|
def exec_query(arel, name = 'SAR', binds = [], prepare: false)
|
@@ -96,7 +95,7 @@ module ActiveRecord
|
|
96
95
|
requested_limit = if limit_bind_index
|
97
96
|
type_casted_binds[limit_bind_index]
|
98
97
|
else
|
99
|
-
arel.limit
|
98
|
+
arel.limit
|
100
99
|
end
|
101
100
|
|
102
101
|
if allowed_limit.nil?
|
@@ -29,17 +29,7 @@ module ActiveRecord
|
|
29
29
|
|
30
30
|
response = @connection.get("/#{table_name}/schema")
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
@definitions[table_name] = if (version >= Gem::Version.create('6.0.0.29'))
|
35
|
-
schema = JSON.parse(response.body)
|
36
|
-
schema['columns'] = schema.delete('attributes')
|
37
|
-
schema
|
38
|
-
elsif (version >= Gem::Version.create('5.0.0.5'))
|
39
|
-
JSON.parse(response.body)
|
40
|
-
else
|
41
|
-
{ 'columns' => JSON.parse(response.body), 'limit' => nil }
|
42
|
-
end
|
32
|
+
@definitions[table_name] = JSON.parse(response.body)
|
43
33
|
rescue ::Sunstone::Exception::NotFound
|
44
34
|
raise ActiveRecord::StatementInvalid, "Table \"#{table_name}\" does not exist"
|
45
35
|
end
|
@@ -50,9 +40,7 @@ module ActiveRecord
|
|
50
40
|
# - format_type includes the column size constraint, e.g. varchar(50)
|
51
41
|
# - ::regclass is a function that gives the id for a table name
|
52
42
|
def column_definitions(table_name) # :nodoc:
|
53
|
-
|
54
|
-
# TODO: Remove after 0.3
|
55
|
-
definition(table_name)['attributes'] || definition(table_name)['columns']
|
43
|
+
definition(table_name)['columns']
|
56
44
|
end
|
57
45
|
|
58
46
|
# Returns the limit definition of the table (the maximum limit that can
|
@@ -93,6 +81,35 @@ module ActiveRecord
|
|
93
81
|
def column_name_for_operation(operation, node) # :nodoc:
|
94
82
|
visitor.accept(node, collector).first[operation.to_sym]
|
95
83
|
end
|
84
|
+
|
85
|
+
# Given a set of columns and an ORDER BY clause, returns the columns for a SELECT DISTINCT.
|
86
|
+
# PostgreSQL, MySQL, and Oracle override this for custom DISTINCT syntax - they
|
87
|
+
# require the order columns appear in the SELECT.
|
88
|
+
#
|
89
|
+
# columns_for_distinct("posts.id", ["posts.created_at desc"])
|
90
|
+
#
|
91
|
+
def columns_for_distinct(columns, orders) # :nodoc:
|
92
|
+
columns
|
93
|
+
end
|
94
|
+
|
95
|
+
def distinct_relation_for_primary_key(relation) # :nodoc:
|
96
|
+
values = columns_for_distinct(
|
97
|
+
relation.table[relation.primary_key],
|
98
|
+
relation.order_values
|
99
|
+
)
|
100
|
+
|
101
|
+
limited = relation.reselect(values).distinct!
|
102
|
+
limited_ids = select_rows(limited.arel, "SQL").map(&:last)
|
103
|
+
|
104
|
+
if limited_ids.empty?
|
105
|
+
relation.none!
|
106
|
+
else
|
107
|
+
relation.where!(relation.primary_key => limited_ids)
|
108
|
+
end
|
109
|
+
|
110
|
+
relation.limit_value = relation.offset_value = nil
|
111
|
+
relation
|
112
|
+
end
|
96
113
|
|
97
114
|
# TODO: def encoding
|
98
115
|
|
@@ -85,8 +85,8 @@ module ActiveRecord
|
|
85
85
|
@prepared_statement_status = Concurrent::ThreadLocalVar.new(false)
|
86
86
|
@connection_parameters = connection_parameters
|
87
87
|
|
88
|
-
|
89
|
-
|
88
|
+
@type_map = Type::HashLookupTypeMap.new
|
89
|
+
initialize_type_map(@type_map)
|
90
90
|
end
|
91
91
|
|
92
92
|
def active?
|
@@ -180,14 +180,24 @@ module ActiveRecord
|
|
180
180
|
end
|
181
181
|
alias create insert
|
182
182
|
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
# end
|
183
|
+
def reload_type_map
|
184
|
+
type_map.clear
|
185
|
+
initialize_type_map
|
186
|
+
end
|
188
187
|
|
189
188
|
private
|
190
189
|
|
190
|
+
def type_map
|
191
|
+
@type_map ||= Type::HashLookupTypeMap.new.tap do |mapping|
|
192
|
+
initialize_type_map(mapping)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
def initialize_type_map(m = type_map)
|
197
|
+
self.class.initialize_type_map(m)
|
198
|
+
load_additional_types
|
199
|
+
end
|
200
|
+
|
191
201
|
def initialize_type_map(m) # :nodoc:
|
192
202
|
m.register_type 'boolean', Type::Boolean.new
|
193
203
|
m.register_type 'string' do |_, options|
|
@@ -24,7 +24,14 @@ module Arel
|
|
24
24
|
def substitute_binds hash, bvs
|
25
25
|
if hash.is_a?(Array)
|
26
26
|
hash.map do |v|
|
27
|
-
if v.is_a?(
|
27
|
+
if v.is_a?(ActiveRecord::Relation::QueryAttribute)
|
28
|
+
new_v = bvs.shift
|
29
|
+
if new_v.is_a?(ActiveRecord::Relation::QueryAttribute)
|
30
|
+
new_v.value_for_database
|
31
|
+
else
|
32
|
+
v.type.serialize(new_v)
|
33
|
+
end
|
34
|
+
elsif v.is_a?(Arel::Nodes::BindParam)
|
28
35
|
bvs.shift#.value_for_database
|
29
36
|
elsif v.is_a?(Hash) || v.is_a?(Array)
|
30
37
|
substitute_binds(v, bvs)
|
@@ -35,7 +42,14 @@ module Arel
|
|
35
42
|
elsif hash.is_a?(Hash)
|
36
43
|
newhash = {}
|
37
44
|
hash.each do |k, v|
|
38
|
-
if v.is_a?(
|
45
|
+
if v.is_a?(ActiveRecord::Relation::QueryAttribute)
|
46
|
+
new_v = bvs.shift
|
47
|
+
newhash[k] = if new_v.is_a?(ActiveRecord::Relation::QueryAttribute)
|
48
|
+
new_v.value_for_database
|
49
|
+
else
|
50
|
+
v.type.serialize(new_v)
|
51
|
+
end
|
52
|
+
elsif v.is_a?(Arel::Nodes::BindParam)
|
39
53
|
newhash[k] = bvs.shift || v.value.value_for_database
|
40
54
|
elsif v.is_a?(Hash)
|
41
55
|
newhash[k] = substitute_binds(v, bvs)
|
@@ -47,9 +61,16 @@ module Arel
|
|
47
61
|
end
|
48
62
|
newhash
|
49
63
|
elsif hash.is_a?(Arel::Nodes::BindParam)
|
50
|
-
bvs.shift
|
64
|
+
bvs.shift
|
65
|
+
elsif hash.is_a?(ActiveRecord::Relation::QueryAttribute)
|
66
|
+
new_v = bvs.shift
|
67
|
+
if new_v.is_a?(ActiveRecord::Relation::QueryAttribute)
|
68
|
+
new_v.value_for_database
|
69
|
+
else
|
70
|
+
v.type.serialize(new_v)
|
71
|
+
end
|
51
72
|
else
|
52
|
-
bvs.shift
|
73
|
+
bvs.shift
|
53
74
|
end
|
54
75
|
end
|
55
76
|
|
@@ -8,10 +8,6 @@ module Arel
|
|
8
8
|
accept(node, collector).value
|
9
9
|
end
|
10
10
|
|
11
|
-
def preparable
|
12
|
-
false
|
13
|
-
end
|
14
|
-
|
15
11
|
private
|
16
12
|
|
17
13
|
def visit_Arel_Nodes_SelectStatement o, collector
|
@@ -72,26 +68,12 @@ module Arel
|
|
72
68
|
else
|
73
69
|
collector.updates = {}
|
74
70
|
|
75
|
-
o.values.expr
|
76
|
-
k =
|
77
|
-
|
78
|
-
|
79
|
-
collector.updates.deep_merge!(k) { |key, v1, v2|
|
80
|
-
if (v1.is_a?(Array) && v2.is_a?(Array))
|
81
|
-
v2.each_with_index do |v, j|
|
82
|
-
if v1[j].nil?
|
83
|
-
v1[j] = v2[j]
|
84
|
-
else
|
85
|
-
v1[j].deep_merge!(v2[j]) unless v2[j].nil?
|
86
|
-
end
|
87
|
-
end
|
88
|
-
v1
|
89
|
-
else
|
90
|
-
v2
|
91
|
-
end
|
92
|
-
}
|
71
|
+
o.columns.map(&:name).zip(o.values.expr.first).to_h.each do |k, v|
|
72
|
+
collector.updates[k] = case v
|
73
|
+
when Nodes::SqlLiteral, Nodes::BindParam, ActiveModel::Attribute
|
74
|
+
visit(v, collector)
|
93
75
|
else
|
94
|
-
|
76
|
+
v
|
95
77
|
end
|
96
78
|
end
|
97
79
|
end
|
@@ -765,8 +747,13 @@ module Arel
|
|
765
747
|
def visit_Arel_Nodes_Assignment o, collector
|
766
748
|
case o.left
|
767
749
|
when Arel::Nodes::UnqualifiedColumn
|
768
|
-
|
769
|
-
|
750
|
+
case o.right
|
751
|
+
when Arel::Attributes::Attribute, Arel::Nodes::BindParam, ActiveModel::Attribute
|
752
|
+
{ visit(o.left.expr, collector) => visit(o.right, collector) }
|
753
|
+
else
|
754
|
+
{ visit(o.left.expr, collector) => o.right }
|
755
|
+
end
|
756
|
+
when Arel::Attributes::Attribute, Arel::Nodes::BindParam, ActiveModel::Attribute
|
770
757
|
{ visit(o.left, collector) => visit(o.right, collector) }
|
771
758
|
else
|
772
759
|
collector = visit o.left, collector
|
@@ -968,6 +955,15 @@ module Arel
|
|
968
955
|
alias :visit_Arel_Attributes_Time :visit_Arel_Attributes_Attribute
|
969
956
|
alias :visit_Arel_Attributes_Boolean :visit_Arel_Attributes_Attribute
|
970
957
|
|
958
|
+
def visit_ActiveModel_Attribute(o, collector)
|
959
|
+
if o.value.is_a?(ActiveRecord::StatementCache::Substitute)
|
960
|
+
a = collector.add_bind(o)
|
961
|
+
o
|
962
|
+
else
|
963
|
+
o.value_for_database
|
964
|
+
end
|
965
|
+
end
|
966
|
+
|
971
967
|
def visit_Arel_Nodes_BindParam o, collector
|
972
968
|
a = collector.add_bind(o.value)
|
973
969
|
o.is_a?(Arel::Nodes::BindParam) ? o : a
|
@@ -1067,7 +1063,6 @@ module Arel
|
|
1067
1063
|
|
1068
1064
|
def maybe_visit thing, collector
|
1069
1065
|
return collector unless thing
|
1070
|
-
collector << " "
|
1071
1066
|
visit thing, collector
|
1072
1067
|
end
|
1073
1068
|
end
|
data/lib/sunstone/connection.rb
CHANGED
@@ -132,25 +132,52 @@ module Sunstone
|
|
132
132
|
if Thread.current[:sunstone_transaction_count] == 1 && !Thread.current[:sunstone_request_sent]
|
133
133
|
Thread.current[:sunstone_request_sent] = request
|
134
134
|
elsif Thread.current[:sunstone_request_sent]
|
135
|
-
|
136
|
-
log_mess += Thread.current[:sunstone_request_sent].path.split('?', 2)
|
137
|
-
raise ActiveRecord::StatementInvalid, <<~MSG
|
135
|
+
message = <<~MSG
|
138
136
|
Cannot send multiple request in a transaction.
|
139
|
-
|
137
|
+
|
140
138
|
Trying to send:
|
141
|
-
#{request.method} #{log_mess[0]} #{(log_mess[1] && !log_mess[1].empty?) ? MessagePack.unpack(CGI.unescape(log_mess[1])) : '' }
|
142
|
-
|
143
|
-
Already sent:
|
144
|
-
#{Thread.current[:sunstone_request_sent].method} #{log_mess[2]} #{(log_mess[3] && !log_mess[3].empty?) ? MessagePack.unpack(CGI.unescape(log_mess[3])) : '' }
|
145
139
|
MSG
|
140
|
+
|
141
|
+
path_and_query = request.path.split('?', 2)
|
142
|
+
message << " #{request.method} #{path_and_query[0]}"
|
143
|
+
if path_and_query[1]
|
144
|
+
if request['Query-Encoding'] == 'application/msgpack'
|
145
|
+
message << " " << MessagePack.unpack(CGI.unescape(path_and_query[1]))
|
146
|
+
else
|
147
|
+
message << " " << CGI.unescape(path_and_query[1])
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
message << "\n\nAlready sent:\n"
|
152
|
+
path_and_query = Thread.current[:sunstone_request_sent].path.split('?', 2)
|
153
|
+
message << " #{Thread.current[:sunstone_request_sent].method} #{path_and_query[0]}"
|
154
|
+
if path_and_query[1]
|
155
|
+
if request['Query-Encoding'] == 'application/msgpack'
|
156
|
+
message << " " << MessagePack.unpack(CGI.unescape(path_and_query[1]))
|
157
|
+
else
|
158
|
+
message << " " << CGI.unescape(path_and_query[1])
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
raise ActiveRecord::StatementInvalid, message
|
146
163
|
else
|
147
164
|
log_mess = request.path.split('?', 2)
|
148
|
-
|
149
|
-
|
165
|
+
message = if request['Query-Encoding'] == 'application/msgpack'
|
166
|
+
<<~MSG
|
167
|
+
Cannot send multiple request in a transaction.
|
150
168
|
|
151
|
-
|
152
|
-
|
153
|
-
|
169
|
+
Trying to send:
|
170
|
+
#{request.method} #{log_mess[0]} #{(log_mess[1] && !log_mess[1].empty?) ? MessagePack.unpack(CGI.unescape(log_mess[1])) : '' }
|
171
|
+
MSG
|
172
|
+
else
|
173
|
+
<<~MSG
|
174
|
+
Cannot send multiple request in a transaction.
|
175
|
+
|
176
|
+
Trying to send:
|
177
|
+
#{request.method} #{log_mess[0]} #{(log_mess[1] && !log_mess[1].empty?) ? CGI.unescape(log_mess[1]) : '' }
|
178
|
+
MSG
|
179
|
+
end
|
180
|
+
raise ActiveRecord::StatementInvalid, message
|
154
181
|
end
|
155
182
|
end
|
156
183
|
|
data/lib/sunstone/version.rb
CHANGED