2022-01-01 13:38:12 +00:00
|
|
|
# Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
|
2021-11-30 13:04:17 +00:00
|
|
|
|
|
|
|
# https://github.com/telent/ar-as-batches
|
|
|
|
# TODO: Should be reconsidered with rails 6.1 because then
|
|
|
|
# find_each might be able to handle order as well
|
|
|
|
# e.g. Ticket::Priority.order(updated: :desc).find_each... is not possbile atm with find_each
|
|
|
|
module ActiveRecord
|
|
|
|
module AsBatches
|
|
|
|
class Batch
|
|
|
|
def initialize(arel, args)
|
|
|
|
@offset = arel.offset || 0
|
|
|
|
@limit = arel.limit
|
|
|
|
@size = args[:size] || 100
|
|
|
|
return if !@limit || (@limit > @size)
|
|
|
|
|
|
|
|
@size = @limit
|
|
|
|
end
|
|
|
|
|
|
|
|
def get_records(query)
|
|
|
|
query.offset(@offset).limit(@size).all
|
|
|
|
end
|
|
|
|
|
|
|
|
def as_batches(query, &blk)
|
|
|
|
records = get_records(query)
|
|
|
|
while records.any?
|
|
|
|
@offset += records.size
|
|
|
|
records.each(&blk)
|
|
|
|
|
|
|
|
if @limit
|
|
|
|
@limit -= records.size
|
|
|
|
if @limit < size
|
|
|
|
@size = @limit
|
|
|
|
end
|
|
|
|
|
|
|
|
return if @limit.zero?
|
|
|
|
end
|
|
|
|
|
|
|
|
records = get_records(query)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def as_batches(args = {}, &blk)
|
|
|
|
Batch.new(arel, args).as_batches(self, &blk)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class Relation
|
|
|
|
include AsBatches
|
|
|
|
end
|
|
|
|
end
|