switchman 2.0.9 → 2.0.10
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/lib/switchman.rb +2 -0
 - data/lib/switchman/active_record/association.rb +1 -1
 - data/lib/switchman/active_record/calculations.rb +1 -1
 - data/lib/switchman/active_record/query_methods.rb +3 -3
 - data/lib/switchman/active_record/relation.rb +55 -3
 - data/lib/switchman/version.rb +1 -1
 - metadata +2 -2
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: bce5f0819ee2570b0bf51ba3872af1f34c23273712cc33c35559225723fb13a0
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 11e7c3d612263f94ea17bc5213580ae42e2c12743a13ff36e9f988feddda0a7e
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 0fad57a01e86f34533c5cf539cf92360605b129bdfdf77878fec72663c3783bad56e7a7a324f3b388e37a89296d05f309dc2c84084e30c1c44d20917e15d35e3
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 002bcec40325a407c8be94432d2396c8ae812ad2828695266e591956d1e1e8195628906fce710c4681a3c72cc5f6ea8f1859a99aac22cbd3462be5dd6118bbdf
         
     | 
    
        data/lib/switchman.rb
    CHANGED
    
    
| 
         @@ -87,7 +87,7 @@ module Switchman 
     | 
|
| 
       87 
87 
     | 
    
         
             
                      # Copypasta from Activerecord but with added global_id_for goodness.
         
     | 
| 
       88 
88 
     | 
    
         
             
                      def records_for(ids)
         
     | 
| 
       89 
89 
     | 
    
         
             
                        scope.where(association_key_name => ids).load do |record|
         
     | 
| 
       90 
     | 
    
         
            -
                          global_key = if  
     | 
| 
      
 90 
     | 
    
         
            +
                          global_key = if model.shard_category == :unsharded
         
     | 
| 
       91 
91 
     | 
    
         
             
                                         convert_key(record[association_key_name])
         
     | 
| 
       92 
92 
     | 
    
         
             
                                       else
         
     | 
| 
       93 
93 
     | 
    
         
             
                                         Shard.global_id_for(record[association_key_name], record.shard)
         
     | 
| 
         @@ -51,7 +51,7 @@ module Switchman 
     | 
|
| 
       51 
51 
     | 
    
         | 
| 
       52 
52 
     | 
    
         
             
                  def calculate_simple_average(column_name, distinct)
         
     | 
| 
       53 
53 
     | 
    
         
             
                    # See activerecord#execute_simple_calculation
         
     | 
| 
       54 
     | 
    
         
            -
                    relation =  
     | 
| 
      
 54 
     | 
    
         
            +
                    relation = except(:order)
         
     | 
| 
       55 
55 
     | 
    
         
             
                    column = aggregate_column(column_name)
         
     | 
| 
       56 
56 
     | 
    
         
             
                    relation.select_values = [operation_over_aggregate_column(column, "average", distinct).as("average"),
         
     | 
| 
       57 
57 
     | 
    
         
             
                                              operation_over_aggregate_column(column, "count", distinct).as("count")]
         
     | 
| 
         @@ -250,7 +250,7 @@ module Switchman 
     | 
|
| 
       250 
250 
     | 
    
         
             
                      remove = true if type == :primary &&
         
     | 
| 
       251 
251 
     | 
    
         
             
                          remove_nonlocal_primary_keys &&
         
     | 
| 
       252 
252 
     | 
    
         
             
                          predicate.left.relation.model == klass &&
         
     | 
| 
       253 
     | 
    
         
            -
                          predicate.is_a?(::Arel::Nodes::Equality)
         
     | 
| 
      
 253 
     | 
    
         
            +
                          (predicate.is_a?(::Arel::Nodes::Equality) || predicate.is_a?(::Arel::Nodes::In))
         
     | 
| 
       254 
254 
     | 
    
         | 
| 
       255 
255 
     | 
    
         
             
                      current_source_shard =
         
     | 
| 
       256 
256 
     | 
    
         
             
                          if source_shard
         
     | 
| 
         @@ -265,7 +265,7 @@ module Switchman 
     | 
|
| 
       265 
265 
     | 
    
         
             
                        new_right_value =
         
     | 
| 
       266 
266 
     | 
    
         
             
                          case predicate.right
         
     | 
| 
       267 
267 
     | 
    
         
             
                          when Array
         
     | 
| 
       268 
     | 
    
         
            -
                            predicate.right.map {|val| transpose_predicate_value(val, current_source_shard, target_shard, type, remove) }
         
     | 
| 
      
 268 
     | 
    
         
            +
                            predicate.right.map {|val| transpose_predicate_value(val, current_source_shard, target_shard, type, remove).presence }.compact
         
     | 
| 
       269 
269 
     | 
    
         
             
                          else
         
     | 
| 
       270 
270 
     | 
    
         
             
                            transpose_predicate_value(predicate.right, current_source_shard, target_shard, type, remove)
         
     | 
| 
       271 
271 
     | 
    
         
             
                          end
         
     | 
| 
         @@ -340,7 +340,7 @@ module Switchman 
     | 
|
| 
       340 
340 
     | 
    
         
             
                        value
         
     | 
| 
       341 
341 
     | 
    
         
             
                      else
         
     | 
| 
       342 
342 
     | 
    
         
             
                        local_id = Shard.relative_id_for(current_id, current_shard, target_shard) || current_id
         
     | 
| 
       343 
     | 
    
         
            -
                         
     | 
| 
      
 343 
     | 
    
         
            +
                        return nil if remove_non_local_ids && local_id.is_a?(Integer) && local_id > Shard::IDS_PER_SHARD
         
     | 
| 
       344 
344 
     | 
    
         
             
                        if current_id != local_id
         
     | 
| 
       345 
345 
     | 
    
         
             
                          # make a new bind param
         
     | 
| 
       346 
346 
     | 
    
         
             
                          ::Arel::Nodes::BindParam.new(query_att.class.new(query_att.name, local_id, query_att.type))
         
     | 
| 
         @@ -106,10 +106,62 @@ module Switchman 
     | 
|
| 
       106 
106 
     | 
    
         
             
                        shards.first.activate(klass.shard_category) { yield(self, shards.first) }
         
     | 
| 
       107 
107 
     | 
    
         
             
                      end
         
     | 
| 
       108 
108 
     | 
    
         
             
                    else
         
     | 
| 
       109 
     | 
    
         
            -
                       
     | 
| 
       110 
     | 
    
         
            -
                       
     | 
| 
       111 
     | 
    
         
            -
             
     | 
| 
      
 109 
     | 
    
         
            +
                      result_count = 0
         
     | 
| 
      
 110 
     | 
    
         
            +
                      can_order = false
         
     | 
| 
      
 111 
     | 
    
         
            +
                      result = Shard.with_each_shard(shards, [klass.shard_category]) do
         
     | 
| 
      
 112 
     | 
    
         
            +
                        # don't even query other shards if we're already past the limit
         
     | 
| 
      
 113 
     | 
    
         
            +
                        next if limit_value && result_count >= limit_value && order_values.empty?
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
      
 115 
     | 
    
         
            +
                        relation = shard(Shard.current(klass.shard_category), :to_a)
         
     | 
| 
      
 116 
     | 
    
         
            +
                        # do a minimal query if possible
         
     | 
| 
      
 117 
     | 
    
         
            +
                        relation = relation.limit(limit_value - result_count) if limit_value && !result_count.zero? && order_values.empty?
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
                        shard_results = relation.activate(&block)
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
                        if shard_results.present?
         
     | 
| 
      
 122 
     | 
    
         
            +
                          can_order ||= can_order_cross_shard_results? unless order_values.empty?
         
     | 
| 
      
 123 
     | 
    
         
            +
                          raise OrderOnMultiShardQuery if !can_order && !order_values.empty? && result_count.positive?
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
      
 125 
     | 
    
         
            +
                          result_count += shard_results.is_a?(Array) ? shard_results.length : 1
         
     | 
| 
      
 126 
     | 
    
         
            +
                        end
         
     | 
| 
      
 127 
     | 
    
         
            +
                        shard_results
         
     | 
| 
      
 128 
     | 
    
         
            +
                      end
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
                      result = reorder_cross_shard_results(result) if can_order
         
     | 
| 
      
 131 
     | 
    
         
            +
                      result.slice!(limit_value..-1) if limit_value
         
     | 
| 
      
 132 
     | 
    
         
            +
                      result
         
     | 
| 
      
 133 
     | 
    
         
            +
                    end
         
     | 
| 
      
 134 
     | 
    
         
            +
                  end
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
                  def can_order_cross_shard_results?
         
     | 
| 
      
 137 
     | 
    
         
            +
                    # we only presume to be able to post-sort the most basic of orderings
         
     | 
| 
      
 138 
     | 
    
         
            +
                    order_values.all? { |ov| ov.is_a?(::Arel::Nodes::Ordering) && ov.expr.is_a?(::Arel::Attributes::Attribute) }
         
     | 
| 
      
 139 
     | 
    
         
            +
                  end
         
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
                  def reorder_cross_shard_results(results)
         
     | 
| 
      
 142 
     | 
    
         
            +
                    results.sort! do |l, r|
         
     | 
| 
      
 143 
     | 
    
         
            +
                      result = 0
         
     | 
| 
      
 144 
     | 
    
         
            +
                      order_values.each do |ov|
         
     | 
| 
      
 145 
     | 
    
         
            +
                        if l.respond_to?(ov.expr.name)
         
     | 
| 
      
 146 
     | 
    
         
            +
                          a = l.send(ov.expr.name)
         
     | 
| 
      
 147 
     | 
    
         
            +
                          b = r.send(ov.expr.name)
         
     | 
| 
      
 148 
     | 
    
         
            +
                        else
         
     | 
| 
      
 149 
     | 
    
         
            +
                          a = l.attributes[ov.expr.name]
         
     | 
| 
      
 150 
     | 
    
         
            +
                          b = r.attributes[ov.expr.name]
         
     | 
| 
      
 151 
     | 
    
         
            +
                        end
         
     | 
| 
      
 152 
     | 
    
         
            +
                        next if a == b
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
      
 154 
     | 
    
         
            +
                        if a.nil? || b.nil?
         
     | 
| 
      
 155 
     | 
    
         
            +
                          result = 1 if a.nil?
         
     | 
| 
      
 156 
     | 
    
         
            +
                          result *= -1 if ov.is_a?(::Arel::Nodes::Descending)
         
     | 
| 
      
 157 
     | 
    
         
            +
                        else
         
     | 
| 
      
 158 
     | 
    
         
            +
                          result = a <=> b
         
     | 
| 
      
 159 
     | 
    
         
            +
                        end
         
     | 
| 
      
 160 
     | 
    
         
            +
             
     | 
| 
      
 161 
     | 
    
         
            +
                        result *= -1 if ov.is_a?(::Arel::Nodes::Descending)
         
     | 
| 
      
 162 
     | 
    
         
            +
                        break unless result.zero?
         
     | 
| 
       112 
163 
     | 
    
         
             
                      end
         
     | 
| 
      
 164 
     | 
    
         
            +
                      result
         
     | 
| 
       113 
165 
     | 
    
         
             
                    end
         
     | 
| 
       114 
166 
     | 
    
         
             
                  end
         
     | 
| 
       115 
167 
     | 
    
         
             
                end
         
     | 
    
        data/lib/switchman/version.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: switchman
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 2.0. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 2.0.10
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Cody Cutrer
         
     | 
| 
         @@ -10,7 +10,7 @@ authors: 
     | 
|
| 
       10 
10 
     | 
    
         
             
            autorequire:
         
     | 
| 
       11 
11 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       12 
12 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       13 
     | 
    
         
            -
            date: 2021- 
     | 
| 
      
 13 
     | 
    
         
            +
            date: 2021-06-09 00:00:00.000000000 Z
         
     | 
| 
       14 
14 
     | 
    
         
             
            dependencies:
         
     | 
| 
       15 
15 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       16 
16 
     | 
    
         
             
              name: railties
         
     |