Module: CaRuby::Database::Reader

Included in:
CaRuby::Database
Defined in:
lib/caruby/database/reader.rb,
lib/caruby/database/reader_template_builder.rb

Overview

Database query operation mixin.

Defined Under Namespace

Classes: TemplateBuilder

Instance Method Summary collapse

Instance Method Details

#exists?(obj) ⇒ Boolean

Returns whether the given domain object has a database identifier or exists in the database. This method fetches the object from the database if necessary.

Parameters:

  • obj (Jinx::Resource, <Jinx::Resource>)

    the domain object(s) to find

Returns:

  • (Boolean)

    whether the domain object(s) exist in the database



103
104
105
106
107
108
109
110
111
# File 'lib/caruby/database/reader.rb', line 103

def exists?(obj)
  if obj.nil? then
    false
  elsif obj.collection? then
    obj.all? { |item| exists?(item) }
  else
    !!obj.identifier or find(obj).equal?(obj)
  end
end

#find(obj, opts = nil) ⇒ Jinx::Resource?

Fetches the given target domain object from the database. The target domain object class Propertied#searchable_attributes are used in the match. If this domain object does not have a set of searchable attributes with non-nil values, then this method returns nil.

If the :create option is set, then this method creates an object if the find is unsuccessful.

If the fetched domain object is the same class as the target domain object, then the fetched content is merged into the target and this method returns the target. If the fetched domain object is a subclass of the target domain object, then the fetched domain object is returned.

Parameters:

  • obj (Jinx::Resource)

    the target domain object to find

  • opts (Hash, Symbol) (defaults to: nil)

    the find options

Options Hash (opts):

  • :create (Boolean)

    whether to create the object if it is not found

Returns:

  • (Jinx::Resource, nil)

    the domain object if found, nil otherwise

Raises:

  • (DatabaseError)

    if obj is not a domain object or more than object matches the obj attribute values

See Also:



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/caruby/database/reader.rb', line 81

def find(obj, opts=nil)
  return if obj.nil?
  perform(:find, obj) do
    fetched = find_object(obj)
    if fetched.nil? then
      logger.info { "#{obj.qp} not found." }
      create(obj) if Options.get(:create, opts)
    elsif fetched.equal?(obj) then
      logger.info { "Found #{obj}." }
      obj
    else
      logger.info { "Found #{fetched} matching the find template #{obj}." }
      fetched
    end
  end
end

#initializeObject

Adds query capability to this Database.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/caruby/database/reader.rb', line 13

def initialize
  super
  # the query template builder
  @rdr_tmpl_bldr = TemplateBuilder.new
  # the fetch result matcher
  @matcher = FetchedMatcher.new
  # the fetched copier
  copier = Proc.new do |src|
    copy = src.copy
    logger.debug { "Fetched #{src.qp} copied to #{copy.qp}." }
    copy
  end
  # visitor that merges the fetched object graph
  @ftchd_mrg_vstr = Jinx::MergeVisitor.new(:matcher => @matcher, :copier => copier) { |ref| ref.class.fetched_domain_attributes }
end

#query(obj_or_hql, *path) ⇒ <Jinx::Resource>

Returns an array of objects matching the specified query template and attribute path. The obj_or_hql argument is either a domain object template or a Hibernate HQL statement. If obj_or_hql is a String, then the HQL statement String is executed.

Otherwise, the query condition is determined by the values set in the template. The non-nil Propertied#searchable_attributes are used in the query.

The optional path arguments are attribute symbols from the template to the destination class, e.g.:

query(study, :registration, :participant)

returns study registration participants.

Unlike caCORE, the query result reflects the database state, i.e. calling an attribute accessor method on a query result object returns the database value, e.g.:

query(study, :registration).first.participant

has the same content as:

query(study, :registration, :participant).first

By contrast, caCORE API search result property access, by design, fails with an obscure exception when the property is not lazy-loaded in Hibernate.

Parameters:

  • obj_or_hql (Jinx::Resource, String)

    the domain object or HQL to query

  • path (<Property>)

    the attribute path to search

Returns:

  • (<Jinx::Resource>)

    the domain objects which match the query



54
55
56
57
58
59
# File 'lib/caruby/database/reader.rb', line 54

def query(obj_or_hql, *path)
  # the detoxified caCORE query result
  result = query_safe(obj_or_hql, *path)
  # enable change tracking and lazy-loading
  persistify(result)
end