module Sequel::Plugins::PagedOperations::DatasetMethods

Public Instance Methods

paged_datasets(opts=OPTS) { || ... } click to toggle source

Yield datasets for subsets of the receiver that are limited to no more than 1000 rows (you can configure the number of rows using :rows_per_page).

Options:

:rows_per_page

The maximum number of rows in each yielded dataset (unless concurrent modifications are made to the table).

# File lib/sequel/plugins/paged_operations.rb, line 90
def paged_datasets(opts=OPTS)
  unless defined?(yield)
    return enum_for(:paged_datasets, opts)
  end

  pk = _paged_operations_pk(:paged_update)
  base_offset_ds = offset_ds = _paged_operations_offset_ds(opts)
  first = nil

  while last = offset_ds.get(pk)
    ds = where(pk < last)
    ds = ds.where(pk >= first) if first
    yield ds
    first = last
    offset_ds = base_offset_ds.where(pk >= first)
  end

  ds = self
  ds = ds.where(pk >= first) if first
  yield ds
  nil
end
paged_delete(opts=OPTS) click to toggle source

Delete all rows of the dataset using using multiple queries so that no more than 1000 rows are deleted at a time (you can configure the number of rows using :rows_per_page).

Options:

:rows_per_page

The maximum number of rows affected by each DELETE query (unless concurrent modifications are made to the table).

# File lib/sequel/plugins/paged_operations.rb, line 120
def paged_delete(opts=OPTS)
  if (db.database_type == :oracle && !supports_fetch_next_rows?) || (db.database_type == :mssql && !is_2012_or_later?)
    raise Error, "paged_delete is not supported on MSSQL/Oracle when using emulated offsets"
  end
  pk = _paged_operations_pk(:paged_delete)
  rows_deleted = 0
  offset_ds = _paged_operations_offset_ds(opts)
  while last = offset_ds.get(pk)
    rows_deleted += where(pk < last).delete
  end
  rows_deleted + delete
end
paged_update(values, opts=OPTS) click to toggle source

Update all rows of the dataset using using multiple queries so that no more than 1000 rows are updated at a time (you can configure the number of rows using :rows_per_page). All arguments are passed to Sequel::Dataset#update.

Options:

:rows_per_page

The maximum number of rows affected by each UPDATE query (unless concurrent modifications are made to the table).

# File lib/sequel/plugins/paged_operations.rb, line 141
def paged_update(values, opts=OPTS)
  rows_updated = 0
  paged_datasets(opts) do |ds|
    rows_updated += ds.update(values)
  end
  rows_updated
end

Private Instance Methods

_paged_operations_offset_ds(opts) click to toggle source

The dataset that will be used by paged_{datasets,delete,update} to get the upper limit for the next query.

# File lib/sequel/plugins/paged_operations.rb, line 171
def _paged_operations_offset_ds(opts)
  if rows_per_page = opts[:rows_per_page]
    raise Error, ":rows_per_page option must be at least 1" unless rows_per_page >= 1
  end
  _force_primary_key_order.offset(rows_per_page || 1000)
end
_paged_operations_pk(meth) click to toggle source

Run some basic checks common to paged_{datasets,delete,update} and return the primary key to operate on as a Sequel::Identifier.

# File lib/sequel/plugins/paged_operations.rb, line 153
def _paged_operations_pk(meth)
  raise Error, "cannot use #{meth} if dataset has a limit or offset" if @opts[:limit] || @opts[:offset]
  if db.database_type == :db2 && db.offset_strategy == :emulate
    raise Error, "the paged_operations plugin is not supported on DB2 when using emulated offsets, set the :offset_strategy Database option to 'limit_offset' or 'offset_fetch'"
  end

  case pk = model.primary_key
  when Symbol
    Sequel.identifier(pk)
  when Array
    raise Error, "cannot use #{meth} on a model with a composite primary key"
  else
    raise Error, "cannot use #{meth} on a model without a primary key"
  end
end