Module: Familia::Features::ObjectIdentifier::ModelClassMethods

Defined in:
lib/familia/features/object_identifier.rb

Instance Method Summary collapse

Instance Method Details

#find_by_objid(objid) ⇒ Object?

Find an object by its object identifier

Parameters:

  • objid (String)

    The object identifier to search for

Returns:

  • (Object, nil)

    The object if found, nil otherwise



260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
# File 'lib/familia/features/object_identifier.rb', line 260

def find_by_objid(objid)
  return nil if objid.to_s.empty?

  if Familia.debug?
    reference = caller(1..1).first
    Familia.trace :FIND_BY_OBJID, nil, objid, reference
  end

  # Look up the primary ID from the external ID mapping
  primary_id = objid_lookup[objid]

  # If there is no mapping for this instance's objid, perhaps
  # the object dbkey is already using the objid.
  primary_id = objid if primary_id.nil?

  find_by_id(primary_id)
rescue Familia::NotFound
  # If the object was deleted but mapping wasn't cleaned up
  # we could autoclean here, as long as we log it.
  # objid_lookup.remove_field(objid)
  nil
end

#generate_object_identifierString

Generate a new object identifier using the configured strategy

Returns:

  • (String)

    A new unique identifier



232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
# File 'lib/familia/features/object_identifier.rb', line 232

def generate_object_identifier
  options = feature_options(:object_identifier)
  generator = options[:generator] || DEFAULT_GENERATOR

  case generator
  when :uuid_v7
    SecureRandom.uuid_v7
  when :uuid_v4
    SecureRandom.uuid_v4
  when :hex
    Familia.generate_id(16)
  when Proc
    generator.call
  else
    unless generator.respond_to?(:call)
      raise Familia::Problem, "Invalid object identifier generator: #{generator.inspect}"
    end

    generator.call

  end
end

#objid?(guess) ⇒ Boolean

Check if a string matches the objid format for the Horreum class. The specific class is important b/c each one can have its own type of objid generator.

Parameters:

  • guess (String)

    The string to check

Returns:

  • (Boolean)

    true if the guess matches the objid format, false otherwise



288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
# File 'lib/familia/features/object_identifier.rb', line 288

def objid?(guess)
  return false if guess.to_s.empty?

  options = feature_options(:object_identifier)
  generator = options[:generator] || DEFAULT_GENERATOR

  case generator
  when :uuid_v7, :uuid_v4
    # UUID format: xxxxxxxx-xxxx-Vxxx-xxxx-xxxxxxxxxxxx (36 chars with hyphens)
    # Validate structure and that all characters are valid hex digits
    guess_str = guess.to_s
    return false unless guess_str.length == 36
    return false unless guess_str[8] == '-' && guess_str[13] == '-' && guess_str[18] == '-' && guess_str[23] == '-'

    # Extract segments and validate each is valid hex
    segments = guess_str.split('-')
    return false unless segments.length == 5
    return false unless segments[0] =~ /\A[0-9a-fA-F]{8}\z/  # 8 hex chars
    return false unless segments[1] =~ /\A[0-9a-fA-F]{4}\z/  # 4 hex chars
    return false unless segments[2] =~ /\A[0-9a-fA-F]{4}\z/  # 4 hex chars (includes version)
    return false unless segments[3] =~ /\A[0-9a-fA-F]{4}\z/  # 4 hex chars
    return false unless segments[4] =~ /\A[0-9a-fA-F]{12}\z/ # 12 hex chars

    # Validate version character
    version_char = guess_str[14]
    if generator == :uuid_v7
      version_char == '7'
    else # generator == :uuid_v4
      version_char == '4'
    end
  when :hex
    # Hex format: pure hexadecimal without hyphens
    !!(guess =~ /\A[0-9a-fA-F]+\z/)
  when Proc
    # Cannot determine format for custom Proc generators
    Familia.warn "[objid?] Validation not supported for custom Proc generators on #{name}" if Familia.debug?
    false
  else
    false
  end
end