# Generate next internal id for a given scope and usage.
#
# For currently supported usages, see #usage enum.
#
# The method implements a locking scheme that has the following properties:
# 1) Generated sequence of internal ids is unique per (project, usage)
# 1) Generated sequence of internal ids is unique per (scope and usage)
# 2) The method is thread-safe and may be used in concurrent threads/processes.
# 3) The generated sequence is gapless.
# 4) In the absence of a record in the internal_ids table, one will be created
# and last_value will be calculated on the fly.
defgenerate_next(subject,scope,usage,init)
scope=[scope].flatten.compact
raise'scope is not well-defined, need at least one column for scope (given: 0)'ifscope.empty?
raise"usage #{usage} is unknown. Supported values are InternalId.usages = #{InternalId.usages.keys.to_s}"unlessInternalId.usages.include?(usage.to_sym)
#
# subject: The instance we're generating an internal id for. Gets passed to init if called.
# scope: Attributes that define the scope for id generation.
# usage: Symbol to define the usage of the internal id, see InternalId.usages
# init: Block that gets called to initialize InternalId record if not yet present (optional)