Sha256: d52eb6d26b89448530958febbc2bf4b2858826c8c7a28d498549837b57fa5d60

Contents?: true

Size: 1.82 KB

Versions: 5

Compression:

Stored size: 1.82 KB

Contents

# Will fetch the next N values from a sequence and store it in a queue. 
# Now the values will can be fetched from the queue without any database roundtrip. 
# If the queue is empty, the next N values will be fetched from database and stored in the queue.
#
# It's using the DUAL table so it should only work with oracle.
# 
# Author:: Andre Kullmann
#
module ActiveRecord
  module Bulkoperation
    module Util
      class SequenceCache        

        #
        # seq - the sequence name to use with the SequenceCache object
        # refetch - how many values should be fetch from the database with each roundtrip 
        def initialize(seq, prefetch = 10)          
          @seq, @prefetch = seq, prefetch
          @queue = Queue.new
        end

        #
        # return - the next value from the sequence
        def next_value          
          while ( value = next_value_from_queue ).nil?
            fill_queue
          end
          value 
        end

        private

        def next_value_from_queue
	        @queue.pop(true) 
        rescue ThreadError
          nil
        end

        def fill_queue
          fetch.each do |f|
            @queue << f
          end
        end

        def fetch
          if ActiveRecord::Bulkoperation::ActiveRecordVersion >= Gem::Version.new('5.0')
            binds = [ ActiveRecord::Relation::QueryAttribute.new(
              nil, @prefetch, ActiveRecord::Type::Integer.new
            )]
            st = ActiveRecord::Base.connection.exec_query("SELECT #{@seq}.nextval id FROM dual connect by level <= :a", "SQL", binds, prepare: true)
          else
            st = ActiveRecord::Base.connection.exec_query("SELECT #{@seq}.nextval id FROM dual connect by level <= :a", "SQL", [[nil, @prefetch]])            
          end
          st.map {|r| r['id']}
        end
      end
    end
  end
end

Version data entries

5 entries across 5 versions & 1 rubygems

Version Path
activerecord_bulkoperation-0.2.3 lib/activerecord_bulkoperation/util/sequence_cache.rb
activerecord_bulkoperation-0.2.2 lib/activerecord_bulkoperation/util/sequence_cache.rb
activerecord_bulkoperation-0.2.1 lib/activerecord_bulkoperation/util/sequence_cache.rb
activerecord_bulkoperation-0.2.0 lib/activerecord_bulkoperation/util/sequence_cache.rb
activerecord_bulkoperation-0.1.0 lib/activerecord_bulkoperation/util/sequence_cache.rb