sunstone 6.0.0.5 → 6.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/ext/active_record/associations.rb +2 -2
  3. data/ext/active_record/attribute_methods.rb +2 -2
  4. data/ext/active_record/callbacks.rb +1 -1
  5. data/ext/active_record/finder_methods.rb +42 -36
  6. data/ext/active_record/persistence.rb +2 -0
  7. data/ext/active_record/relation/calculations.rb +2 -2
  8. data/ext/active_record/statement_cache.rb +9 -5
  9. data/ext/active_record/transactions.rb +8 -15
  10. data/ext/arel/attributes/empty_relation.rb +31 -31
  11. data/ext/arel/nodes/select_statement.rb +1 -1
  12. data/lib/active_record/connection_adapters/sunstone/column.rb +3 -3
  13. data/lib/active_record/connection_adapters/sunstone/database_statements.rb +5 -5
  14. data/lib/active_record/connection_adapters/sunstone/schema_statements.rb +18 -8
  15. data/lib/active_record/connection_adapters/sunstone/type/binary.rb +34 -0
  16. data/lib/active_record/connection_adapters/sunstone_adapter.rb +39 -26
  17. data/lib/arel/visitors/sunstone.rb +13 -15
  18. data/lib/sunstone.rb +16 -2
  19. data/lib/sunstone/connection.rb +1 -1
  20. data/lib/sunstone/version.rb +1 -1
  21. metadata +40 -64
  22. data/.gitignore +0 -31
  23. data/.tm_properties +0 -1
  24. data/.travis.yml +0 -49
  25. data/Gemfile +0 -4
  26. data/README.md +0 -10
  27. data/Rakefile +0 -37
  28. data/TODO.md +0 -89
  29. data/ext/arel/attributes/relation.rb +0 -31
  30. data/sunstone.gemspec +0 -39
  31. data/test/active_record/associations/belongs_to_test.rb +0 -162
  32. data/test/active_record/associations/has_and_belongs_to_many_test.rb +0 -125
  33. data/test/active_record/associations/has_many_test.rb +0 -244
  34. data/test/active_record/eager_loading_test.rb +0 -62
  35. data/test/active_record/persistance_test.rb +0 -159
  36. data/test/active_record/preload_test.rb +0 -51
  37. data/test/active_record/query/all_test.rb +0 -33
  38. data/test/active_record/query/count_test.rb +0 -51
  39. data/test/active_record/query/distinct_test.rb +0 -30
  40. data/test/active_record/query/find_test.rb +0 -37
  41. data/test/active_record/query/limit_test.rb +0 -19
  42. data/test/active_record/query/order_test.rb +0 -27
  43. data/test/active_record/query/where_test.rb +0 -79
  44. data/test/active_record/query_test.rb +0 -123
  45. data/test/active_record/rpc_test.rb +0 -30
  46. data/test/schema_mock.rb +0 -117
  47. data/test/sunstone/connection/configuration_test.rb +0 -44
  48. data/test/sunstone/connection/cookie_store_test.rb +0 -37
  49. data/test/sunstone/connection/request_helper_test.rb +0 -105
  50. data/test/sunstone/connection/send_request_test.rb +0 -164
  51. data/test/sunstone/connection_test.rb +0 -23
  52. data/test/test_helper.rb +0 -152
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 87a052085f5f1445d0e6cdea630054ba3a17aa742b679c539a87f03af8f018ee
4
- data.tar.gz: 50007447eb6c02ce55c90aebd7973190913f43183151a783eb9e3914c95e7ffc
3
+ metadata.gz: 67c26e8a4275aa67d9e09b43cfce417732142a043b6ca49d2c1e85bbfb74950d
4
+ data.tar.gz: a46c586fe763e9d90029a007074919fca9e997efa8ddddf57588136d6cb2b883
5
5
  SHA512:
6
- metadata.gz: aef51f99ea18ba631bdfe4dcfd95ac2133ad3e721ef97251ba53151fe7f9c3076fb942580cdf147f796fa9c6d75f59efabd1bfb0964f550c8fd484de5f267a4b
7
- data.tar.gz: 41786cdf195c547c7ec704c7dcd5e92c65e1441732e32da3adf3f8f13398baece163f583a7f953b3ea5ab7d411519643acb0b8acc27ec2d6aabad197f844dd3a
6
+ metadata.gz: 1fd7cb872485fa5507d1bcb21e28e81d92b807279fbdbf12440a74de32cd39c4584c42e6f0ea1fd371261a3c614358967d94c1abc30bb304b2364bb8ae7e9dab
7
+ data.tar.gz: 3d3105125dfaad25f7884648406444ca3a4dab3e2782b482659179ca8a484ce52bded0222af6b48210ad7f0f00c901ca92a3e780380b22d4b62cb3e3c57019f8
@@ -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.each_with_object({}) do |name, attrs|
10
- attrs[name] = _read_attribute(name)
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(*) #:nodoc:
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 = associated_predicate_builder(key).expand_from_hash(value)
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).reduce(&:and)
38
+ queries = klass.new(associated_table, value).queries.map! do |query|
39
+ expand_from_hash(query)
48
40
  end
49
- queries.reduce(&:or)
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
- build(table.arel_attribute(column_name), values)
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
- build(table.arel_attribute(field_attr), object.try!(aggregate_attr))
63
- end.reduce(&:and)
55
+ self[field_attr, object.try!(aggregate_attr)]
56
+ end
64
57
  end
65
- queries.reduce(&:or)
58
+
59
+ grouping_queries(queries)
66
60
  end
67
61
  else
68
- build(table.arel_attribute(key), value)
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,12 +196,23 @@ 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(eager_load_values + includes_values)
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 && !using_limitable_reflections?(join_dependency.reflections)
210
- if has_limit_or_offset?
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
+ )
215
+ if has_limit_or_offset? && !connection.is_a?(ActiveRecord::ConnectionAdapters::SunstoneAPIAdapter)
211
216
  limited_ids = limited_ids_for(relation)
212
217
  limited_ids.empty? ? relation.none! : relation.where!(primary_key => limited_ids)
213
218
  end
@@ -220,6 +225,7 @@ module ActiveRecord
220
225
  relation
221
226
  end
222
227
  end
228
+
223
229
  end
224
230
 
225
231
  end
@@ -105,6 +105,8 @@ module ActiveRecord
105
105
  @_trigger_update_callback = affected_rows == 1
106
106
  end
107
107
 
108
+ @previously_new_record = false
109
+
108
110
  yield(self) if block_given?
109
111
 
110
112
  affected_rows
@@ -5,13 +5,13 @@ module ActiveRecord
5
5
  if loaded? && (column_names.map(&:to_s) - @klass.attribute_names - @klass.attribute_aliases.keys).empty?
6
6
  return records.pluck(*column_names)
7
7
  end
8
-
8
+
9
9
  if has_include?(column_names.first)
10
10
  relation = apply_join_dependency
11
11
  relation.pluck(*column_names)
12
12
  elsif klass.connection.is_a?(ActiveRecord::ConnectionAdapters::SunstoneAPIAdapter)
13
13
  load
14
- return records.pluck(*column_names.map{|n| n.sub(/^#{klass.table_name}\./, "")})
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
17
  relation = spawn
@@ -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
- Arel::Nodes::BindParam === thing
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
- casted_binds = binds.map(&:value_for_database)
23
- @indexes.each { |i| val[i] = connection.quote(casted_binds.shift) }
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!(*) #:nodoc:
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 self.class.connection.is_a?(ActiveRecord::ConnectionAdapters::SunstoneAPIAdapter) && instance_variable_defined?(:@updating) && @updating
40
+ if connection.is_a?(ActiveRecord::ConnectionAdapters::SunstoneAPIAdapter) && instance_variable_defined?(:@updating) && @updating
40
41
  status = yield
41
- status
42
42
  else
43
- self.class.transaction do
44
- if has_transactional_callbacks?
45
- add_to_transaction
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
- 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
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
@@ -4,7 +4,7 @@ module Arel
4
4
 
5
5
  attr_accessor :eager_load
6
6
 
7
- def initialize cores = [SelectCore.new]
7
+ def initialize(cores = [SelectCore.new])
8
8
  super()
9
9
  @cores = cores
10
10
  @orders = []
@@ -2,18 +2,18 @@ module ActiveRecord
2
2
  module ConnectionAdapters
3
3
  # Sunstone-specific extensions to column definitions in a table.
4
4
  class SunstoneColumn < Column #:nodoc:
5
- delegate :array, to: :sql_type_metadata
6
- alias :array? :array
5
+ attr_reader :array
7
6
 
8
7
  def initialize(name, sql_type_metadata, options={})
9
8
  @name = name.freeze
10
9
  @sql_type_metadata = sql_type_metadata
11
10
  @null = options['null']
12
- @default = options['default']
11
+ @default = (sql_type_metadata.type == :json ? JSON.generate(options['default']) : options['default'])
13
12
  @default_function = nil
14
13
  @collation = nil
15
14
  @table_name = nil
16
15
  @primary_key = (options['primary_key'] == true)
16
+ @array = options['array']
17
17
  end
18
18
 
19
19
  def primary_key?
@@ -47,15 +47,15 @@ module ActiveRecord
47
47
  # can be used to query the database repeatedly.
48
48
  def cacheable_query(klass, arel) # :nodoc:
49
49
  if prepared_statements
50
- sql, binds = visitor.accept(arel.ast, collector).value
50
+ sql, binds = visitor.compile(arel.ast, collector)
51
51
  query = klass.query(sql)
52
52
  elsif self.is_a?(ActiveRecord::ConnectionAdapters::SunstoneAPIAdapter)
53
53
  collector = SunstonePartialQueryCollector.new(self.collector)
54
- parts, binds = visitor.accept(arel.ast, collector).value
54
+ parts, binds = visitor.compile(arel.ast, collector)
55
55
  query = StatementCache::PartialQuery.new(parts, true)
56
56
  else
57
- collector = PartialQueryCollector.new
58
- parts, binds = visitor.accept(arel.ast, collector).value
57
+ collector = klass.partial_query_collector
58
+ parts, binds = visitor.compile(arel.ast, collector)
59
59
  query = klass.partial_query(parts)
60
60
  end
61
61
  [query, binds]
@@ -142,7 +142,7 @@ module ActiveRecord
142
142
 
143
143
  if sars[0].instance_variable_defined?(:@sunstone_calculation) && sars[0].instance_variable_get(:@sunstone_calculation)
144
144
  # this is a count, min, max.... yea i know..
145
- ActiveRecord::Result.new(['all'], [result], {:all => type_map.lookup('integer')})
145
+ ActiveRecord::Result.new(['all'], [result], {:all => type_map.lookup('integer', {})})
146
146
  elsif result.is_a?(Array)
147
147
  ActiveRecord::Result.new(result[0] ? result[0].keys : [], result.map{|r| r.values})
148
148
  else