Class: Udb::TopLevelDatabaseObject

Inherits:
DatabaseObject show all
Extended by:
T::Sig
Defined in:
lib/udb/obj/database_obj.rb,
lib/udb/condition.rb

Overview

base class for any object defined in its own YAML file

expected to contain at least:

$schema:
kind:
name:

Defined Under Namespace

Classes: SchemaError, SchemaValidationError, ValidationError

Instance Attribute Summary

Attributes inherited from DatabaseObject

#arch, #data, #data_path, #long_name, #name

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from DatabaseObject

#<=>, #__source, #cfg_arch, #cfg_arch?, #clone, #defer, #defined_by_condition, #description, #inspect, #kind, #source_line

Constructor Details

#initialize(data, data_path, arch) ⇒ TopLevelDatabaseObject

Returns a new instance of TopLevelDatabaseObject.



457
458
459
# File 'lib/udb/obj/database_obj.rb', line 457

def initialize(data, data_path, arch)
  super(data, data_path, arch, DatabaseObject::Kind.deserialize(T.must_because(data["kind"]) { pp data }))
end

Class Method Details

.create_json_schemer_resolver(udb_resolver) ⇒ Object



382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
# File 'lib/udb/obj/database_obj.rb', line 382

def self.create_json_schemer_resolver(udb_resolver)
  proc do |pattern|
    uri_str = pattern.to_s
    if uri_str =~ /^http/
      JSON.parse(T.must(Net::HTTP.get(pattern)))
    elsif uri_str =~ /^json-schemer:\/\/schema/
      JSON.load_file("#{udb_resolver.schemas_path}#{URI(uri_str).path}")
    else
      # Relative $ref values (e.g. "schema_defs.json") are resolved directly
      # from the schemas directory.
      local_path = udb_resolver.schemas_path / File.basename(uri_str)
      JSON.load_file(local_path)
    end
  end
end

Instance Method Details

#key?(k) ⇒ Boolean

Returns:

  • (Boolean)


468
# File 'lib/udb/obj/database_obj.rb', line 468

def key?(k) = @data.key?(k)

#keysObject



463
# File 'lib/udb/obj/database_obj.rb', line 463

def keys = @data.keys

#validate(resolver) ⇒ Object



401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
# File 'lib/udb/obj/database_obj.rb', line 401

def validate(resolver)
  @@schemas[resolver] ||= {}
  schemas = @@schemas[resolver]
  ref_resolver = TopLevelDatabaseObject.create_json_schemer_resolver(resolver)

  if @data.key?("$schema")
    schema_path = data["$schema"]
    schema_file, obj_path = schema_path.split("#")
    # Strip version prefix (e.g. 'v0.1/ext_schema.json' -> 'ext_schema.json')
    schema_basename = File.basename(schema_file)
    schema =
      if schemas.key?(schema_basename)
        schemas[schema_basename]
      else
        schemas[schema_basename] = JSONSchemer.schema(
          File.read("#{resolver.schemas_path}/#{schema_basename}"),
          regexp_resolver: "ecma",
          ref_resolver:,
          insert_property_defaults: true
        )
        raise SchemaError, T.must(schemas[schema_basename]).validate_schema unless T.must(schemas[schema_basename]).valid_schema?

        schemas[schema_basename]
      end

    unless obj_path.nil?
      obj_path_parts = obj_path.split("/")[1..]

      obj_path_parts.each do |k|
        schema = schema.fetch(k)
      end
    end

    # convert through JSON to handle anything supported in YAML but not JSON
    # (e.g., integer object keys will be converted to strings)
    jsonified_obj = JSON.parse(JSON.generate(@data))

    raise "Nothing there?" if jsonified_obj.nil?

    # Normalize the $schema field to the bare filename before validation so that
    # the schema enum (which lists bare names like 'ext_schema.json#') matches
    # even when the resolved file uses a versioned path like 'v0.1/ext_schema.json#'.
    if jsonified_obj.key?("$schema")
      bare_schema = File.basename(jsonified_obj["$schema"].split("#").first) + "#"
      jsonified_obj = jsonified_obj.merge("$schema" => bare_schema)
    end

    raise SchemaValidationError.new(@data_path, schema.validate(jsonified_obj)) unless schema.valid?(jsonified_obj)
  else
    Udb.logger.warn "No $schema for #{@data_path}"
  end
end