sunstone 5.0.1.3 → 5.0.1.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 29f80fc835aafa5e3d90b698dfe9da88e770621a
4
- data.tar.gz: 6ecfcee3f4071b1723f1b0c914242da6ca2f800e
3
+ metadata.gz: 5ff6dca76dfaa5922dd16a451f32f8ab27d8a4ce
4
+ data.tar.gz: 82dcd2022fb893e8f764e0ef032eedac6d1b8762
5
5
  SHA512:
6
- metadata.gz: 7ce0c2a867d8e465303ce613b63f1000c391ad0f5abdda883dbf396a1521d36ca853de469f776e2cad03bed913d5f83f691ef6da23e5c9c1c3c8edff3e37bfb2
7
- data.tar.gz: 7a6c00884660361a6b344f1929dca4899d6934b07e7458739896a8fe61ea448ff83a123b75762977a8ee3c39cdecbcc2753e5200766de9b2013591eaddee558e
6
+ metadata.gz: 56c8135fad00fc2739483afdaa76eab3cf1b2fc494ffe9ee6ec83654021d8e1dd83fc51aaca35df5a505c8204c7c6bfc5aad259741034f25f66b2290616ff8d7
7
+ data.tar.gz: 6d9549f7854ef738858b49ee53650920a1dc2c49b86ca9a69967b53edc5505e3c240babcb41f0dbc06574e55b8acfc63d4a6875a671e490dd9c204d0bfdd863e
data/Rakefile.rb CHANGED
@@ -12,7 +12,7 @@ task :c => :console
12
12
  Rake::TestTask.new do |t|
13
13
  t.libs << 'test'
14
14
  t.test_files = FileList['test/**/*_test.rb']
15
- t.warning = false
15
+ t.warning = true
16
16
  #t.verbose = true
17
17
  end
18
18
 
@@ -34,4 +34,4 @@ task :default => :test
34
34
 
35
35
  namespace :pages do
36
36
  #TODO: https://github.com/defunkt/sdoc-helpers/blob/master/lib/sdoc_helpers/pages.rb
37
- end
37
+ end
@@ -0,0 +1,52 @@
1
+ require 'active_record'
2
+ require 'active_record/associations'
3
+ module ActiveRecord
4
+ module Associations
5
+ module ClassMethods
6
+ def has_and_belongs_to_many(name, scope = nil, options = {}, &extension)
7
+ if scope.is_a?(Hash)
8
+ options = scope
9
+ scope = nil
10
+ end
11
+
12
+ habtm_reflection = ActiveRecord::Reflection::HasAndBelongsToManyReflection.new(name, scope, options, self)
13
+
14
+ builder = Builder::HasAndBelongsToMany.new name, self, options
15
+
16
+ join_model = builder.through_model
17
+
18
+ const_set join_model.name, join_model
19
+ private_constant join_model.name
20
+
21
+ middle_reflection = builder.middle_reflection join_model
22
+
23
+ Builder::HasMany.define_callbacks self, middle_reflection
24
+ Reflection.add_reflection self, middle_reflection.name, middle_reflection
25
+ middle_reflection.parent_reflection = habtm_reflection
26
+
27
+ include Module.new {
28
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
29
+ def destroy_associations
30
+ if !self.class.connection.is_a?(ActiveRecord::ConnectionAdapters::SunstoneAPIAdapter)
31
+ association(:#{middle_reflection.name}).delete_all(:delete_all)
32
+ association(:#{name}).reset
33
+ end
34
+ super
35
+ end
36
+ RUBY
37
+ }
38
+
39
+ hm_options = {}
40
+ hm_options[:through] = middle_reflection.name
41
+ hm_options[:source] = join_model.right_reflection.name
42
+
43
+ [:before_add, :after_add, :before_remove, :after_remove, :autosave, :validate, :join_table, :class_name, :extend].each do |k|
44
+ hm_options[k] = options[k] if options.key? k
45
+ end
46
+
47
+ has_many name, scope, hm_options, &extension
48
+ self._reflections[name.to_s].parent_reflection = habtm_reflection
49
+ end
50
+ end
51
+ end
52
+ end
@@ -1,6 +1,17 @@
1
1
  module ActiveRecord
2
2
  # = Active Record \Persistence
3
3
  module Persistence
4
+
5
+ def update!(attributes)
6
+ @no_save_transaction = true
7
+ with_transaction_returning_status do
8
+ assign_attributes(attributes)
9
+ save!
10
+ end
11
+ ensure
12
+ @no_save_transaction = false
13
+ end
14
+
4
15
  private
5
16
 
6
17
  def create_or_update(*args)
@@ -45,5 +45,28 @@ module ActiveRecord
45
45
  end
46
46
  end
47
47
 
48
+ def _update_record(values, id, id_was) # :nodoc:
49
+ substitutes, binds = substitute_values values
50
+ scope = @klass.unscoped
51
+
52
+ if @klass.finder_needs_type_condition?
53
+ scope.unscope!(where: @klass.inheritance_column)
54
+ end
55
+
56
+ relation = scope.where(@klass.primary_key => (id_was || id))
57
+ bvs = binds + relation.bound_attributes
58
+ um = relation
59
+ .arel
60
+ .compile_update(substitutes, @klass.primary_key)
61
+ um.table @klass.arel_table
62
+
63
+ @klass.connection.update(
64
+ um,
65
+ 'SQL',
66
+ bvs,
67
+ )
68
+ end
69
+
70
+
48
71
  end
49
72
  end
@@ -1,3 +1,6 @@
1
+ require 'active_record'
2
+ require 'active_record/transactions'
3
+
1
4
  module ActiveRecord
2
5
  # See ActiveRecord::Transactions::ClassMethods for documentation.
3
6
  module Transactions
@@ -17,16 +20,21 @@ module ActiveRecord
17
20
  # end
18
21
  # end
19
22
  #
20
- # def save!(*) #:nodoc:
21
- # with_transaction_returning_status { super }
22
- # end
23
+ def save!(*) #:nodoc:
24
+ if instance_variable_defined?(:@no_save_transaction) && @no_save_transaction
25
+ super
26
+ else
27
+ with_transaction_returning_status { super }
28
+ end
29
+ end
30
+
23
31
  #
24
32
  # def touch(*) #:nodoc:
25
33
  # with_transaction_returning_status { super }
26
34
  # end
27
35
 
28
36
  def with_transaction_returning_status
29
- if self.class.connection.is_a?(ActiveRecord::ConnectionAdapters::SunstoneAPIAdapter) && @updating
37
+ if self.class.connection.is_a?(ActiveRecord::ConnectionAdapters::SunstoneAPIAdapter) && instance_variable_defined?(:@updating) && @updating
30
38
  begin
31
39
  status = yield
32
40
  rescue ActiveRecord::Rollback
@@ -21,7 +21,6 @@ module ActiveRecord
21
21
  end
22
22
 
23
23
  def exec_query(arel, name = 'SAR', binds = [], prepare: false)
24
-
25
24
  sars = []
26
25
  multiple_requests = arel.is_a?(Arel::SelectManager)
27
26
 
@@ -71,7 +70,7 @@ module ActiveRecord
71
70
  send_request.call(arel)
72
71
  end
73
72
 
74
- if sars[0].instance_variable_get(:@sunstone_calculation)
73
+ if sars[0].instance_variable_defined?(:@sunstone_calculation) && sars[0].instance_variable_get(:@sunstone_calculation)
75
74
  # this is a count, min, max.... yea i know..
76
75
  ActiveRecord::Result.new(['all'], [result], {:all => type_map.lookup('integer')})
77
76
  elsif result.is_a?(Array)
@@ -8,6 +8,11 @@ module Arel
8
8
 
9
9
  # This is used to removed an bind values. It is not used in the request
10
10
  attr_accessor :join_source
11
+
12
+ def initialize
13
+ @join_source = []
14
+ super
15
+ end
11
16
 
12
17
  def cast_attribute(v)
13
18
  if (v.is_a?(ActiveRecord::Attribute))
@@ -42,6 +47,8 @@ module Arel
42
47
  end
43
48
  end
44
49
  newhash
50
+ elsif hash.is_a?(Arel::Nodes::BindParam)
51
+ cast_attribute(bvs.last.is_a?(Array) ? bvs.shift.last : bvs.shift)
45
52
  else
46
53
  cast_attribute(bvs.last.is_a?(Array) ? bvs.shift.last : bvs.shift)
47
54
  end
@@ -73,17 +80,12 @@ module Arel
73
80
  }
74
81
  end
75
82
 
76
- if join_source
83
+ if !join_source.empty?
77
84
  substitute_binds(join_source.clone, bvs)
78
85
  end
79
86
 
80
87
  params = {}
81
- if where
82
- params[:where] = substitute_binds(where.clone, bvs)
83
- if params[:where].size == 1
84
- params[:where] = params[:where].pop
85
- end
86
- end
88
+ params[:where] = substitute_binds(where.clone, bvs) if where
87
89
 
88
90
  if eager_loads
89
91
  params[:include] = eager_loads.clone
@@ -25,18 +25,19 @@ module Arel
25
25
  private
26
26
 
27
27
  def visit_Arel_Nodes_SelectStatement o, collector
28
+ collector.table = o.cores.first.source.left.name
29
+
28
30
  collector = o.cores.inject(collector) { |c,x|
29
31
  visit_Arel_Nodes_SelectCore(x, c)
30
32
  }
31
-
33
+
32
34
  if !o.orders.empty?
33
35
  collector.order = o.orders.map { |x| visit(x, collector) }
34
36
  end
35
-
37
+
36
38
  collector = maybe_visit o.limit, collector
37
39
  collector = maybe_visit o.offset, collector
38
40
  collector = maybe_visit o.eager_load, collector
39
- # collector = maybe_visit o.lock, collector
40
41
 
41
42
  collector
42
43
  end
@@ -61,10 +62,10 @@ module Arel
61
62
  collector = visit o.source, collector
62
63
  end
63
64
 
64
- if !o.wheres.empty?
65
- collector.where = o.wheres.map { |x| visit(x, collector) }.inject([]) { |c, w|
66
- w.is_a?(Array) ? c += w : c << w
67
- }
65
+ if o.wheres.size == 1
66
+ collector.where = visit(o.wheres.first, collector)
67
+ elsif o.wheres.size > 1
68
+ collector.where = visit(Arel::Nodes::And.new(o.wheres), collector)
68
69
  end
69
70
 
70
71
  collector
@@ -135,6 +136,7 @@ module Arel
135
136
 
136
137
  def add_to_bottom_of_hash_or_array(hash, value)
137
138
  hash = find_bottom(hash)
139
+
138
140
  if hash.is_a?(Hash)
139
141
  nkey = hash.keys.first
140
142
  nvalue = hash.values.first
@@ -160,7 +162,7 @@ module Arel
160
162
  if wheres.size != 1 && wheres.first.size != 1 && !wheres['id']
161
163
  raise 'Upsupported'
162
164
  else
163
- collector.where = wheres
165
+ collector.where = wheres.first
164
166
  end
165
167
 
166
168
  collector
@@ -180,7 +182,8 @@ module Arel
180
182
  #
181
183
  def visit_Arel_Nodes_UpdateStatement o, collector
182
184
  collector.request_type = Net::HTTP::Patch
183
- collector.table = o.relation.name
185
+
186
+ collector.table = o.relation.name
184
187
  collector.operation = :update
185
188
 
186
189
  # collector.id = o.wheres.first.children.first.right
@@ -193,10 +196,8 @@ module Arel
193
196
  if collector.where.size != 1 && collector.where.first.size != 1 && !collector.where.first['id']
194
197
  raise 'Upsupported'
195
198
  end
196
- if !collector.where.first['id']
197
- collector.table = collector.where.first.keys.first if collector.is_a?(Arel::Collectors::Sunstone)
198
- collector.where[0] = {'id' => collector.where.first.values.first.values.first}
199
- end
199
+
200
+ collector.where = collector.where.first
200
201
 
201
202
  if o.values
202
203
  collector.updates = {}
@@ -465,7 +466,13 @@ module Arel
465
466
  # visit o.expr, collector
466
467
  # end
467
468
  #
468
- # def visit_Arel_Nodes_NamedFunction o, collector
469
+ def visit_Arel_Nodes_NamedFunction o, collector
470
+ case o.name
471
+ when 'ST_Within'
472
+ { visit(o.expressions.first, collector) => { within: o.expressions.last.expressions.map(&:expr)[0...4].reverse } }
473
+ else
474
+ raise 'xxx'
475
+ end
469
476
  # collector << o.name
470
477
  # collector << "("
471
478
  # collector << "DISTINCT " if o.distinct
@@ -476,7 +483,7 @@ module Arel
476
483
  # else
477
484
  # collector
478
485
  # end
479
- # end
486
+ end
480
487
  #
481
488
  # def visit_Arel_Nodes_Extract o, collector
482
489
  # collector << "EXTRACT(#{o.field.to_s.upcase} FROM "
@@ -513,7 +520,7 @@ module Arel
513
520
  if o.expressions.first.is_a?(Arel::Attributes::Attribute)
514
521
  relation = o.expressions.first.relation
515
522
  join_name = relation.table_alias || relation.name
516
- collector.columns << {:maximum => join_name ? o.expressions.first.name : "#{join_name}.#{o.expressions.first.name}"}
523
+ collector.columns << {:maximum => join_name ? o.expressions.first.name : {join_name => o.expressions.first.name}}
517
524
  else
518
525
  collector.columns << {:maximum => o.expressions.first}
519
526
  end
@@ -526,7 +533,7 @@ module Arel
526
533
  if o.expressions.first.is_a?(Arel::Attributes::Attribute)
527
534
  relation = o.expressions.first.relation
528
535
  join_name = relation.table_alias || relation.name
529
- collector.columns << {:minimum => join_name ? o.expressions.first.name : "#{join_name}.#{o.expressions.first.name}"}
536
+ collector.columns << {:minimum => join_name ? o.expressions.first.name : {join_name => o.expressions.first.name}}
530
537
  else
531
538
  collector.columns << {:minimum => o.expressions.first}
532
539
  end
@@ -539,18 +546,28 @@ module Arel
539
546
  if o.expressions.first.is_a?(Arel::Attributes::Attribute)
540
547
  relation = o.expressions.first.relation
541
548
  join_name = relation.table_alias || relation.name
542
- collector.columns << {:average => join_name ? o.expressions.first.name : "#{join_name}.#{o.expressions.first.name}"}
549
+ collector.columns << {:average => join_name ? o.expressions.first.name : {join_name => o.expressions.first.name}}
543
550
  else
544
551
 
545
552
  collector.columns << {:average => o.expressions.first}
546
553
  end
547
554
  end
548
- #
549
- # def visit_Arel_Nodes_TableAlias o, collector
550
- # collector = visit o.relation, collector
551
- # collector << " "
552
- # collector << quote_table_name(o.name)
553
- # end
555
+
556
+ def visit_Arel_Table o, collector
557
+ if o.table_alias
558
+ o.table_alias if collector.is_a?(Arel::Collectors::Sunstone)
559
+ else
560
+ o.name if collector.is_a?(Arel::Collectors::Sunstone)
561
+ end
562
+ collector
563
+ end
564
+
565
+ def visit_Arel_Nodes_TableAlias o, collector
566
+ # collector = visit o.relation, collector
567
+ # collector << " "
568
+ # collector << quote_table_name(o.name)
569
+ collector
570
+ end
554
571
  #
555
572
  # def visit_Arel_Nodes_Between o, collector
556
573
  # collector = visit o.left, collector
@@ -627,16 +644,10 @@ module Arel
627
644
  # end
628
645
  #
629
646
  def visit_Arel_Nodes_JoinSource o, collector
630
- if o.left
631
- collector.table = o.left.name if collector.is_a?(Arel::Collectors::Sunstone)
632
- end
633
647
  if o.right.any?
634
648
  # We need to visit the right to get remove bind values, but we don't
635
649
  # add it to the collector
636
- # collector << " " if o.left
637
- # collector = inject_join o.right, collector, ' '
638
- collector.join_source = inject_join(o.right, Arel::Collectors::Sunstone.new, ' ')
639
- # collector.join_source = Arel::Visitors::PostgreSQL.new(Arel::Collectors::SQLString.new).send(:inject_join, o.right, Arel::Collectors::SQLString.new, ' ')
650
+ collector.join_source << inject_join(o.right, collector, ' ')
640
651
  end
641
652
  collector
642
653
  end
@@ -658,8 +669,9 @@ module Arel
658
669
  # end
659
670
 
660
671
  def visit_Arel_Nodes_OuterJoin o, collector
661
- collector = visit o.left, collector
662
- visit o.right, collector
672
+ # collector = visit o.left, collector
673
+ # visit o.right, collector
674
+ collector
663
675
  end
664
676
 
665
677
  # def visit_Arel_Nodes_RightOuterJoin o
@@ -667,7 +679,7 @@ module Arel
667
679
  # end
668
680
 
669
681
  def visit_Arel_Nodes_InnerJoin o, collector
670
- collector = visit o.left, collector
682
+ collector = visit(o.left, collector)
671
683
  if o.right
672
684
  visit(o.right, collector)
673
685
  else
@@ -684,48 +696,72 @@ module Arel
684
696
  # visit(o.expr, collector) << ")"
685
697
  # end
686
698
  #
687
- def visit_Arel_Table o, collector
688
- if o.table_alias
689
- collector.table = o.table_alias if collector.is_a?(Arel::Collectors::Sunstone)
690
- else
691
- collector.table = o.name if collector.is_a?(Arel::Collectors::Sunstone)
692
- end
693
- collector
694
- end
695
699
 
696
700
  def visit_Arel_Nodes_In o, collector
697
- {
698
- visit(o.left, collector) => {in: visit(o.right, collector)}
699
- }
701
+ key = visit(o.left, collector)
702
+ value = {in: visit(o.right, collector)}
703
+ if key.is_a?(Hash)
704
+ add_to_bottom_of_hash_or_array(key, value)
705
+ key
706
+ else
707
+ {key => value}
708
+ end
700
709
  end
701
710
 
702
711
  def visit_Arel_Nodes_NotIn o, collector
703
- {
704
- visit(o.left, collector) => {not_in: visit(o.right, collector)}
705
- }
712
+ key = visit(o.left, collector)
713
+ value = {not_in: visit(o.right, collector)}
714
+
715
+ if hash.is_a?(Hash)
716
+ add_to_bottom_of_hash_or_array(key, value)
717
+ key
718
+ else
719
+ {key => value}
720
+ end
721
+ end
722
+
723
+ # You merge a into b if a keys do not colid with b keys
724
+ def mergeable?(hash_a, hash_b)
725
+
726
+ hash_a.each do |key, value_a|
727
+ if hash_b.has_key?(key)
728
+ value_b = hash_b[key]
729
+ if value_a.is_a?(Hash) && value_b.is_a?(Hash)
730
+ return false if !mergeable?(value_a, value_b)
731
+ else
732
+ return false
733
+ end
734
+ end
735
+ end
736
+ true
706
737
  end
707
738
 
708
739
  def visit_Arel_Nodes_And o, collector
709
740
  ors = []
710
- ors << o.children.inject({}) do |c, x|
711
- value = visit(x, collector)
712
- if value.is_a?(Hash)
713
- c.deep_merge!(value)
714
- elsif value.is_a?(Array)
715
- value.size == 1 ? ors << value : ors += value
741
+
742
+ o.children.each do |child, i|
743
+ while child.is_a?(Arel::Nodes::Grouping)
744
+ child = child.expr
745
+ end
746
+ value = visit(child, collector)
747
+ if value.is_a?(Hash) && ors.last.is_a?(Hash) && mergeable?(value, ors.last)
748
+ ors.last.deep_merge!(value)
749
+ else
750
+ ors << value
716
751
  end
717
- c
718
752
  end
719
- ors
753
+
754
+ result = []
755
+ ors.each_with_index do |c, i|
756
+ result << c
757
+ result << 'AND' if ors.size != i + 1
758
+ end
759
+
760
+ result.size == 1 ? result.first : result
720
761
  end
721
762
 
722
763
  def visit_Arel_Nodes_Or o, collector
723
- ors = []
724
- [o.left, o.right].each do |x|
725
- value = visit(x, collector)
726
- value.is_a?(Array) ? ors += value : ors << value
727
- end
728
- ors
764
+ [visit(o.left, collector), 'OR', visit(o.right, collector)]
729
765
  end
730
766
 
731
767
  def visit_Arel_Nodes_Assignment o, collector
@@ -768,16 +804,13 @@ module Arel
768
804
  def visit_Arel_Nodes_Equality o, collector
769
805
  key = visit(o.left, collector)
770
806
  value = (o.right.nil? ? nil : visit(o.right, collector))
771
-
807
+
772
808
  if key.is_a?(Hash)
773
809
  add_to_bottom_of_hash(key, {eq: value})
810
+ elsif o.left.class.name == 'Arel::Attributes::Key'
811
+ { key => {eq: value} }
774
812
  else
775
- key = key.to_s.split('.')
776
- hash = { key.pop => value }
777
- while key.size > 0
778
- hash = { key.pop => hash }
779
- end
780
- hash
813
+ { key => value }
781
814
  end
782
815
  end
783
816
 
@@ -848,46 +881,34 @@ module Arel
848
881
  end
849
882
 
850
883
  def visit_Arel_Attributes_Key o, collector
851
- key = visit(o.relation, collector)
852
- if key.is_a?(Hash)
853
- okey = key
854
- while okey.values.first.is_a?(Hash)
855
- okey = okey.values.first
856
- end
857
- nkey = okey.keys.first
858
- value = okey.values.first
859
- okey[nkey] = {value => o.name}
860
- key
861
- else
862
- { key => o.name }
863
- end
884
+ "#{visit(o.relation, collector)}.#{o.name}"
864
885
  end
865
886
 
866
887
  def visit_Arel_Attributes_Relation o, collector, top=true
867
888
  value = if o.relation.is_a?(Arel::Attributes::Relation)
868
- visit_Arel_Attributes_Relation(o.relation, collector, false)
889
+ { o.name => visit_Arel_Attributes_Relation(o.relation, collector, false) }
869
890
  else
870
891
  visit(o.relation, collector)
871
892
  end
872
- value = value.to_s.split('.').last if !value.is_a?(Hash)
893
+ # value = value.to_s.split('.').last if !value.is_a?(Hash)
873
894
 
874
895
  if o.collection
875
896
  ary = []
876
- ary[o.collection] = value
897
+ ary[o.collection] = value.values.first
877
898
  if top && o.name == collector.table
878
899
  ary
879
900
  elsif o.for_write
880
- {"#{o.name}_attributes" => ary}
901
+ { "#{o.name}_attributes" => ary }
881
902
  else
882
- {o.name => ary}
903
+ ary
883
904
  end
884
905
  else
885
906
  if top && o.name == collector.table
886
907
  value
887
908
  elsif o.for_write
888
- {"#{o.name}_attributes" => value}
909
+ { "#{o.name}_attributes" => value.values.first }
889
910
  else
890
- {o.name => value}
911
+ value
891
912
  end
892
913
  end
893
914
  end
@@ -898,7 +919,12 @@ module Arel
898
919
 
899
920
  def visit_Arel_Attributes_Attribute o, collector
900
921
  join_name = o.relation.table_alias || o.relation.name
901
- collector.table == join_name ? o.name : "#{join_name}.#{o.name}" if collector.is_a?(Arel::Collectors::Sunstone)
922
+
923
+ if join_name && join_name != collector.table
924
+ {join_name => o.name}
925
+ else
926
+ o.name
927
+ end
902
928
  end
903
929
  alias :visit_Arel_Attributes_Integer :visit_Arel_Attributes_Attribute
904
930
  alias :visit_Arel_Attributes_Float :visit_Arel_Attributes_Attribute
@@ -978,9 +1004,8 @@ module Arel
978
1004
  # end
979
1005
 
980
1006
  def inject_join list, collector, join_str
981
- len = list.length - 1
982
- list.each_with_index.inject(collector) { |c, (x,i)|
983
- visit x, c
1007
+ list.each_with_index.inject([]) { |c, (x,i)|
1008
+ c + [visit(x, collector)]
984
1009
  }
985
1010
  end
986
1011