sunstone 6.0.0.4 → 6.1.0.1
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/.travis.yml +26 -7
- data/ext/active_record/associations.rb +2 -2
- data/ext/active_record/attribute_methods.rb +2 -2
- data/ext/active_record/callbacks.rb +1 -1
- data/ext/active_record/finder_methods.rb +40 -35
- data/ext/active_record/persistence.rb +2 -0
- data/ext/active_record/relation/calculations.rb +12 -4
- data/ext/active_record/statement_cache.rb +9 -5
- data/ext/active_record/transactions.rb +8 -15
- data/ext/arel/attributes/empty_relation.rb +31 -31
- data/ext/arel/nodes/select_statement.rb +1 -1
- data/lib/active_record/connection_adapters/sunstone/column.rb +2 -2
- data/lib/active_record/connection_adapters/sunstone/database_statements.rb +5 -5
- data/lib/active_record/connection_adapters/sunstone/schema_statements.rb +18 -8
- data/lib/active_record/connection_adapters/sunstone/type/binary.rb +34 -0
- data/lib/active_record/connection_adapters/sunstone_adapter.rb +39 -26
- data/lib/arel/visitors/sunstone.rb +12 -37
- data/lib/sunstone.rb +15 -2
- data/lib/sunstone/connection.rb +1 -1
- data/lib/sunstone/version.rb +1 -1
- data/sunstone.gemspec +3 -2
- data/test/active_record/persistance_test.rb +31 -6
- data/test/active_record/query_test.rb +1 -1
- data/test/schema_mock.rb +30 -26
- data/test/sunstone/connection/column_definition_test.rb +30 -0
- metadata +27 -11
- data/ext/arel/attributes/relation.rb +0 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 70fcfa3e9252509421cfb640f2f0ea0294c37018f6b8a9feeaf4fcb2f9d75161
|
4
|
+
data.tar.gz: 9dd9af70b45187707817193f5632302005e8e0ede8a8c146db6fae567c706e84
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ac6d53c45d04cf82a891aa9bf736f69492e76847a3748aeecdda6830da80ae04f43f4e9fd981467627d301726ac2459f4297200a57ce917f48b35dc2e8734101
|
7
|
+
data.tar.gz: d7db042c9710800367267f124d7abc33814ce638409200a080e7c1e27e99e78b41cd84a22dbc160ec2d7c7f739df77cca0bec77b17d92b672c1ae9f69db5dc1b
|
data/.travis.yml
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
dist:
|
1
|
+
dist: bionic
|
2
2
|
language: ruby
|
3
3
|
sudo: false
|
4
4
|
|
@@ -8,23 +8,42 @@ cache:
|
|
8
8
|
- /home/travis/.rvm/gems
|
9
9
|
|
10
10
|
rvm:
|
11
|
-
- 2.
|
11
|
+
- 2.7
|
12
|
+
- 3.0
|
12
13
|
|
13
14
|
env:
|
14
15
|
matrix:
|
15
|
-
- RAILS_VERSION=v6.
|
16
|
-
- RAILS_VERSION=v6.
|
17
|
-
- RAILS_VERSION=v6.
|
16
|
+
- RAILS_VERSION=v6.1.0 TASK='db:mysql:rebuild mysql2:test'
|
17
|
+
- RAILS_VERSION=v6.1.0 TASK='db:mysql:rebuild mysql2:isolated_test'
|
18
|
+
- RAILS_VERSION=v6.1.0 TASK='db:postgresql:rebuild postgresql:test'
|
19
|
+
- RAILS_VERSION=v6.1.0 TASK='db:postgresql:rebuild postgresql:isolated_test'
|
20
|
+
- RAILS_VERSION=v6.1.0 TASK='sqlite3:test'
|
21
|
+
- RAILS_VERSION=v6.1.0 TASK='sqlite3:isolated_test'
|
22
|
+
- RAILS_VERSION=v6.1.0 TASK='sqlite3_mem:test'
|
18
23
|
|
19
24
|
services:
|
20
25
|
- mysql
|
21
26
|
addons:
|
22
|
-
postgresql: "
|
27
|
+
postgresql: "13"
|
28
|
+
apt:
|
29
|
+
packages:
|
30
|
+
- postgresql-13
|
31
|
+
- postgresql-client-13
|
23
32
|
|
24
33
|
before_install:
|
34
|
+
- sudo sed -i 's/port = 5433/port = 5432/' /etc/postgresql/13/main/postgresql.conf
|
35
|
+
- sudo cp /etc/postgresql/{9.3,13}/main/pg_hba.conf
|
36
|
+
- sudo pg_ctlcluster 13 main restart
|
25
37
|
- unset BUNDLE_GEMFILE
|
26
38
|
- gem update --system
|
27
39
|
- gem update bundler
|
40
|
+
- gem install bundler --version 1.17.3
|
41
|
+
- mysql -e "create user rails@localhost;"
|
42
|
+
- mysql -e "grant all privileges on activerecord_unittest.* to rails@localhost;"
|
43
|
+
- mysql -e "grant all privileges on activerecord_unittest2.* to rails@localhost;"
|
44
|
+
- mysql -e "grant all privileges on inexistent_activerecord_unittest.* to rails@localhost;"
|
45
|
+
- mysql -e "create database activerecord_unittest default character set utf8mb4;"
|
46
|
+
- mysql -e "create database activerecord_unittest2 default character set utf8mb4;"
|
28
47
|
|
29
48
|
install:
|
30
49
|
- git clone --branch $RAILS_VERSION https://github.com/rails/rails.git ~/build/rails
|
@@ -46,4 +65,4 @@ before_script:
|
|
46
65
|
|
47
66
|
script:
|
48
67
|
- bundle exec rake test
|
49
|
-
- cd ~/build/rails &&
|
68
|
+
- cd ~/build/rails/activerecord && bundle exec rake $TASK
|
@@ -35,11 +35,11 @@ module ActiveRecord
|
|
35
35
|
hm_options[:through] = middle_reflection.name
|
36
36
|
hm_options[:source] = join_model.right_reflection.name
|
37
37
|
|
38
|
-
[:before_add, :after_add, :before_remove, :after_remove, :autosave, :validate, :join_table, :class_name, :extend].each do |k|
|
38
|
+
[:before_add, :after_add, :before_remove, :after_remove, :autosave, :validate, :join_table, :class_name, :extend, :strict_loading].each do |k|
|
39
39
|
hm_options[k] = options[k] if options.key? k
|
40
40
|
end
|
41
41
|
|
42
|
-
has_many name, scope, hm_options, &extension
|
42
|
+
has_many name, scope, **hm_options, &extension
|
43
43
|
_reflections[name.to_s].parent_reflection = habtm_reflection
|
44
44
|
end
|
45
45
|
end
|
@@ -6,8 +6,8 @@ module ActiveRecord
|
|
6
6
|
# Returns a Hash of the Arel::Attributes and attribute values that have been
|
7
7
|
# typecasted for use in an Arel insert/update method.
|
8
8
|
def attributes_with_values(attribute_names)
|
9
|
-
attrs = attribute_names.
|
10
|
-
|
9
|
+
attrs = attribute_names.index_with do |name|
|
10
|
+
_read_attribute(name)
|
11
11
|
end
|
12
12
|
|
13
13
|
if self.class.connection.is_a?(ActiveRecord::ConnectionAdapters::SunstoneAPIAdapter)
|
@@ -2,7 +2,7 @@ module ActiveRecord
|
|
2
2
|
module Callbacks
|
3
3
|
private
|
4
4
|
|
5
|
-
def create_or_update(
|
5
|
+
def create_or_update(**) #:nodoc:
|
6
6
|
if self.class.connection.is_a?(ActiveRecord::ConnectionAdapters::SunstoneAPIAdapter)
|
7
7
|
@_already_called ||= {}
|
8
8
|
self.class.reflect_on_all_associations.each do |r|
|
@@ -1,24 +1,12 @@
|
|
1
|
-
module Arel
|
2
|
-
module Visitors
|
3
|
-
class ToSql < Arel::Visitors::Visitor
|
4
|
-
|
5
|
-
def visit_Arel_Attributes_Relation o, collector
|
6
|
-
visit(o.relation, collector)
|
7
|
-
end
|
8
|
-
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
1
|
module ActiveRecord
|
14
2
|
class PredicateBuilder # :nodoc:
|
15
3
|
|
16
|
-
def expand_from_hash(attributes)
|
4
|
+
def expand_from_hash(attributes, &block)
|
17
5
|
return ["1=0"] if attributes.empty?
|
18
6
|
|
19
7
|
attributes.flat_map do |key, value|
|
20
8
|
if value.is_a?(Hash) && !table.has_column?(key)
|
21
|
-
ka =
|
9
|
+
ka = table.associated_table(key, &block).predicate_builder.expand_from_hash(value.stringify_keys)
|
22
10
|
if self.send(:table).instance_variable_get(:@klass).connection.is_a?(ActiveRecord::ConnectionAdapters::SunstoneAPIAdapter)
|
23
11
|
ka.each { |k|
|
24
12
|
if k.left.is_a?(Arel::Attributes::Attribute) || k.left.is_a?(Arel::Attributes::Relation)
|
@@ -40,13 +28,18 @@ module ActiveRecord
|
|
40
28
|
value = [value] unless value.is_a?(Array)
|
41
29
|
klass = PolymorphicArrayValue
|
42
30
|
end
|
31
|
+
elsif associated_table.through_association?
|
32
|
+
next associated_table.predicate_builder.expand_from_hash(
|
33
|
+
associated_table.primary_key => value
|
34
|
+
)
|
43
35
|
end
|
44
36
|
|
45
37
|
klass ||= AssociationQueryValue
|
46
|
-
queries = klass.new(associated_table, value).queries.map do |query|
|
47
|
-
expand_from_hash(query)
|
38
|
+
queries = klass.new(associated_table, value).queries.map! do |query|
|
39
|
+
expand_from_hash(query)
|
48
40
|
end
|
49
|
-
|
41
|
+
|
42
|
+
grouping_queries(queries)
|
50
43
|
elsif table.aggregated_with?(key)
|
51
44
|
mapping = table.reflect_on_aggregation(key).mapping
|
52
45
|
values = value.nil? ? [nil] : Array.wrap(value)
|
@@ -55,17 +48,18 @@ module ActiveRecord
|
|
55
48
|
values = values.map do |object|
|
56
49
|
object.respond_to?(aggr_attr) ? object.public_send(aggr_attr) : object
|
57
50
|
end
|
58
|
-
|
51
|
+
self[column_name, values]
|
59
52
|
else
|
60
53
|
queries = values.map do |object|
|
61
54
|
mapping.map do |field_attr, aggregate_attr|
|
62
|
-
|
63
|
-
end
|
55
|
+
self[field_attr, object.try!(aggregate_attr)]
|
56
|
+
end
|
64
57
|
end
|
65
|
-
|
58
|
+
|
59
|
+
grouping_queries(queries)
|
66
60
|
end
|
67
61
|
else
|
68
|
-
|
62
|
+
self[key, value]
|
69
63
|
end
|
70
64
|
end
|
71
65
|
end
|
@@ -89,7 +83,7 @@ module ActiveRecord
|
|
89
83
|
relation
|
90
84
|
end
|
91
85
|
|
92
|
-
def instantiate(result_set, &block)
|
86
|
+
def instantiate(result_set, strict_loading_value, &block)
|
93
87
|
seen = Hash.new { |i, object_id|
|
94
88
|
i[object_id] = Hash.new { |j, child_class|
|
95
89
|
j[child_class] = {}
|
@@ -110,14 +104,14 @@ module ActiveRecord
|
|
110
104
|
result_set.each { |row_hash|
|
111
105
|
parent_key = @klass.primary_key ? row_hash[@klass.primary_key] : row_hash
|
112
106
|
parent = parents[parent_key] ||= @klass.instantiate(row_hash.select{|k,v| @klass.column_names.include?(k.to_s) }, &block)
|
113
|
-
construct(parent, row_hash.select{|k,v| !@klass.column_names.include?(k.to_s) }, seen, model_cache)
|
107
|
+
construct(parent, row_hash.select{|k,v| !@klass.column_names.include?(k.to_s) }, seen, model_cache, strict_loading_value)
|
114
108
|
}
|
115
109
|
end
|
116
110
|
|
117
111
|
parents.values
|
118
112
|
end
|
119
113
|
|
120
|
-
def construct(parent, relations, seen, model_cache)
|
114
|
+
def construct(parent, relations, seen, model_cache, strict_loading_value)
|
121
115
|
relations.each do |key, attributes|
|
122
116
|
reflection = parent.class.reflect_on_association(key)
|
123
117
|
next unless reflection
|
@@ -128,22 +122,22 @@ module ActiveRecord
|
|
128
122
|
else
|
129
123
|
if parent.association_cached?(reflection.name)
|
130
124
|
model = parent.association(reflection.name).target
|
131
|
-
construct(model, attributes.select{|k,v| !model.class.column_names.include?(k.to_s) }, seen, model_cache)
|
125
|
+
construct(model, attributes.select{|k,v| !model.class.column_names.include?(k.to_s) }, seen, model_cache, strict_loading_value)
|
132
126
|
end
|
133
127
|
end
|
134
128
|
|
135
129
|
if !reflection.collection?
|
136
|
-
construct_association(parent, reflection, attributes, seen, model_cache)
|
130
|
+
construct_association(parent, reflection, attributes, seen, model_cache, strict_loading_value)
|
137
131
|
else
|
138
132
|
attributes.each do |row|
|
139
|
-
construct_association(parent, reflection, row, seen, model_cache)
|
133
|
+
construct_association(parent, reflection, row, seen, model_cache, strict_loading_value)
|
140
134
|
end
|
141
135
|
end
|
142
136
|
|
143
137
|
end
|
144
138
|
end
|
145
139
|
|
146
|
-
def construct_association(parent, reflection, attributes, seen, model_cache)
|
140
|
+
def construct_association(parent, reflection, attributes, seen, model_cache, strict_loading_value)
|
147
141
|
return if attributes.nil?
|
148
142
|
|
149
143
|
klass = if reflection.polymorphic?
|
@@ -155,7 +149,7 @@ module ActiveRecord
|
|
155
149
|
model = seen[parent.object_id][klass][id]
|
156
150
|
|
157
151
|
if model
|
158
|
-
construct(model, attributes.select{|k,v| !klass.column_names.include?(k.to_s) }, seen, model_cache)
|
152
|
+
construct(model, attributes.select{|k,v| !klass.column_names.include?(k.to_s) }, seen, model_cache, strict_loading_value)
|
159
153
|
|
160
154
|
other = parent.association(reflection.name)
|
161
155
|
|
@@ -167,14 +161,14 @@ module ActiveRecord
|
|
167
161
|
|
168
162
|
other.set_inverse_instance(model)
|
169
163
|
else
|
170
|
-
model = construct_model(parent, reflection, id, attributes.select{|k,v| klass.column_names.include?(k.to_s) }, seen, model_cache)
|
164
|
+
model = construct_model(parent, reflection, id, attributes.select{|k,v| klass.column_names.include?(k.to_s) }, seen, model_cache, strict_loading_value)
|
171
165
|
seen[parent.object_id][model.class.base_class][id] = model
|
172
|
-
construct(model, attributes.select{|k,v| !klass.column_names.include?(k.to_s) }, seen, model_cache)
|
166
|
+
construct(model, attributes.select{|k,v| !klass.column_names.include?(k.to_s) }, seen, model_cache, strict_loading_value)
|
173
167
|
end
|
174
168
|
end
|
175
169
|
|
176
170
|
|
177
|
-
def construct_model(record, reflection, id, attributes, seen, model_cache)
|
171
|
+
def construct_model(record, reflection, id, attributes, seen, model_cache, strict_loading_value)
|
178
172
|
klass = if reflection.polymorphic?
|
179
173
|
record.send(reflection.foreign_type).constantize
|
180
174
|
else
|
@@ -202,11 +196,22 @@ module ActiveRecord
|
|
202
196
|
relation = except(:includes, :eager_load, :preload)
|
203
197
|
relation.arel.eager_load = Arel::Nodes::EagerLoad.new(eager_load_values)
|
204
198
|
else
|
205
|
-
join_dependency = construct_join_dependency(
|
199
|
+
join_dependency = construct_join_dependency(
|
200
|
+
eager_load_values | includes_values, Arel::Nodes::OuterJoin
|
201
|
+
)
|
206
202
|
relation = except(:includes, :eager_load, :preload).joins!(join_dependency)
|
207
203
|
end
|
208
204
|
|
209
|
-
if eager_loading && !
|
205
|
+
if eager_loading && !(
|
206
|
+
using_limitable_reflections?(join_dependency.reflections) &&
|
207
|
+
using_limitable_reflections?(
|
208
|
+
construct_join_dependency(
|
209
|
+
select_association_list(joins_values).concat(
|
210
|
+
select_association_list(left_outer_joins_values)
|
211
|
+
), nil
|
212
|
+
).reflections
|
213
|
+
)
|
214
|
+
)
|
210
215
|
if has_limit_or_offset?
|
211
216
|
limited_ids = limited_ids_for(relation)
|
212
217
|
limited_ids.empty? ? relation.none! : relation.where!(primary_key => limited_ids)
|
@@ -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,18 @@ module ActiveRecord
|
|
14
14
|
return records.pluck(*column_names.map{|n| n.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
|
-
|
20
|
-
result
|
19
|
+
relation.select_values = columns
|
20
|
+
|
21
|
+
result = skip_query_cache_if_necessary do
|
22
|
+
if where_clause.contradiction?
|
23
|
+
ActiveRecord::Result.new([], [])
|
24
|
+
else
|
25
|
+
klass.connection.select_all(relation.arel, nil)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
type_cast_pluck_values(result, columns)
|
21
29
|
end
|
22
30
|
end
|
23
31
|
|
@@ -5,10 +5,9 @@ module ActiveRecord
|
|
5
5
|
def initialize(values, sunstone=false)
|
6
6
|
@values = values
|
7
7
|
@indexes = if sunstone
|
8
|
-
|
9
8
|
else
|
10
|
-
values.each_with_index.find_all { |thing,i|
|
11
|
-
|
9
|
+
values.each_with_index.find_all { |thing, i|
|
10
|
+
Substitute === thing
|
12
11
|
}.map(&:last)
|
13
12
|
end
|
14
13
|
end
|
@@ -19,8 +18,13 @@ module ActiveRecord
|
|
19
18
|
@values
|
20
19
|
else
|
21
20
|
val = @values.dup
|
22
|
-
|
23
|
-
|
21
|
+
@indexes.each do |i|
|
22
|
+
value = binds.shift
|
23
|
+
if ActiveModel::Attribute === value
|
24
|
+
value = value.value_for_database
|
25
|
+
end
|
26
|
+
val[i] = connection.quote(value)
|
27
|
+
end
|
24
28
|
val.join
|
25
29
|
end
|
26
30
|
end
|
@@ -20,7 +20,7 @@ module ActiveRecord
|
|
20
20
|
# end
|
21
21
|
# end
|
22
22
|
#
|
23
|
-
def save!(
|
23
|
+
def save!(**) #:nodoc:
|
24
24
|
if instance_variable_defined?(:@no_save_transaction) && @no_save_transaction
|
25
25
|
super
|
26
26
|
else
|
@@ -35,29 +35,22 @@ module ActiveRecord
|
|
35
35
|
|
36
36
|
def with_transaction_returning_status
|
37
37
|
status = nil
|
38
|
+
connection = self.class.connection
|
38
39
|
|
39
|
-
if
|
40
|
+
if connection.is_a?(ActiveRecord::ConnectionAdapters::SunstoneAPIAdapter) && instance_variable_defined?(:@updating) && @updating
|
40
41
|
status = yield
|
41
|
-
status
|
42
42
|
else
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
else
|
47
|
-
sync_with_transaction_state if @transaction_state&.finalized?
|
48
|
-
@transaction_state = self.class.connection.transaction_state
|
49
|
-
end
|
43
|
+
ensure_finalize = !connection.transaction_open?
|
44
|
+
connection.transaction do
|
45
|
+
add_to_transaction(ensure_finalize || has_transactional_callbacks?)
|
50
46
|
remember_transaction_record_state
|
51
47
|
|
52
48
|
status = yield
|
53
49
|
raise ActiveRecord::Rollback unless status
|
54
50
|
end
|
55
|
-
status
|
56
|
-
end
|
57
|
-
ensure
|
58
|
-
if @transaction_state && @transaction_state.committed?
|
59
|
-
clear_transaction_record_state
|
60
51
|
end
|
52
|
+
|
53
|
+
status
|
61
54
|
end
|
62
55
|
|
63
56
|
|
@@ -1,31 +1,31 @@
|
|
1
|
-
module Arel
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
end
|
1
|
+
# module Arel
|
2
|
+
# module Attributes
|
3
|
+
# class EmptyRelation < Attribute
|
4
|
+
#
|
5
|
+
# attr_accessor :collection, :for_write
|
6
|
+
#
|
7
|
+
# def initialize(relation, name, collection = false, for_write=false)
|
8
|
+
# self[:relation] = relation
|
9
|
+
# self[:name] = name
|
10
|
+
# @collection = collection
|
11
|
+
# @for_write = for_write
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# def able_to_type_cast?
|
15
|
+
# false
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# def table_name
|
19
|
+
# nil
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# def eql? other
|
23
|
+
# self.class == other.class &&
|
24
|
+
# self.relation == other.relation &&
|
25
|
+
# self.name == other.name &&
|
26
|
+
# self.collection == other.collection
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# end
|
30
|
+
# end
|
31
|
+
# end
|