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



93
94
95
96
97
98
99
100
101
# File 'lib/caruby/database/reader.rb', line 93

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

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

Fetches the given domain object from the database. Only secondary key attributes are used in the match. If no secondary key is defined for the object’s class, then this method returns nil. The #query method is used to fetch records on non-secondary key attributes.

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

Parameters:

  • obj (Jinx::Resource)

    the 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



75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/caruby/database/reader.rb', line 75

def find(obj, opts=nil)
  return if obj.nil?
  perform(:find, obj) do
    if find_object(obj) then
      logger.info { "Found #{obj}." }
      obj
    else
      logger.info { "#{obj.qp} not found." }
      if Options.get(:create, opts) then create(obj) end
    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
  @srch_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