sunstone 5.0.1.3 → 5.0.1.4

Sign up to get free protection for your applications and to get access to all the features.
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