Class: CaRuby::Database

Inherits:
Object
  • Object
show all
Includes:
Persistifier, Reader, Writer
Defined in:
lib/caruby/database.rb,
lib/caruby/database/reader.rb,
lib/caruby/database/writer.rb,
lib/caruby/database/operation.rb,
lib/caruby/database/lazy_loader.rb,
lib/caruby/database/persistifier.rb,
lib/caruby/database/saved_matcher.rb,
lib/caruby/database/fetched_matcher.rb,
lib/caruby/database/reader_template_builder.rb,
lib/caruby/database/writer_template_builder.rb

Overview

A Database mediates access to a caBIG database. Database is a facade for caBIG application service database operations. Database supports the query, create, update and delete operations supported by the application service.

Database strives to provide a simple WYEIWYG (What You Expect Is What You Get) API, consisting of the following workhorse methods:

  • Reader#query - fetch domain objects which match a template

  • Reader#find - fetch a specific domain object by key

  • Writer#save - if a domain object exists in the database, then update it, otherwise create it

Any domain object can serve as a query argument. If an optional attribute path is specified, then that path is followed to the result, e.g.:

database.query(study, :coordinator)

returns the coordinators of studies which match the study template.

A domain object find argument must contain enough data to determine whether it exists in the database, i.e. the find argument has a database identifier or a complete secondary key.

The Writer#save method creates or updates references as necessary to persist its argument domain object. It is not necessary to fetch references first or follow dependency ordering rules, which can be implicit and tortuous in caBIG applications. Build the object you want to persist and call the store method. Jinx::Resource sets reasonable default values, recognizes application dependencies and steers around caBIG idiosyncracies to the extent possible.

Defined Under Namespace

Modules: Persistifier, Reader, Writer Classes: FetchedMatcher, LazyLoader, Operation, SavedMatcher

Constant Summary collapse

ACCESS_OPTS =

The application and database connection access command line options.

[
  [:user, "--user USER", "the application login user"],
  [:password, "--password PSWD", "the application login password"],
  [:host, "--host HOST", "the application host name"],
  [:port, "--port PORT", "the application port number"],
  [:classpath, "--classpath PATH", "the application client classpath"],
  [:database_host, "--database_host HOST", "the database host name"],
  [:database_type, "--database_type TYPE", "the database type (mysql or oracle)"],
  [:database_driver, "--database_driver DRIVER", "the database driver string"],
  [:database_driver_class, "--database_driver_class CLASS", "the database driver class name"],
  [:database_port, "--database_port PORT", Integer, "the database port number"],
  [:database, "--database NAME", "the database name"],
  [:database_user, "--database_user USER", "the database login user"],
  [:database_password, "--database_password PSWD", "the database login password"]
]

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Reader

#exists?, #find, #query

Methods included from Writer

#create, #delete, #ensure_exists, #save, #update

Methods included from Persistifier

#clear

Constructor Details

#initialize(service_name, opts = nil) { ... } ⇒ Database

Creates a new Database with the specified service name and options.

Examples:

Database.new(:user => 'perdita', :password => 'changeMe')

Parameters:

  • service_name (String)

    the name of the default PersistenceService

  • opts ({Symbol => String}, nil) (defaults to: nil)

    the access options, or nil if specified as a block

Options Hash (opts):

  • :host (String)

    application service host name

  • :login (String)

    application service login user

  • :password (String)

    application service login password

Yields:

  • the access options defined by a block rather than a parameter



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/caruby/database.rb', line 93

def initialize(service_name, opts=nil)
  super()
  # the options can be defined in a block
  opts ||= yield if block_given?
  # import the Java classes on demand
  Database.import_java_classes
  # the fetched object cache
  @defaults = {}
  if opts.nil? then Jinx.fail(ArgumentError, "Missing required database access properties") end
  @user = Options.get(:user, opts)
  @password = Options.get(:password, opts)
  host = Options.get(:host, opts)
  port = Options.get(:port, opts)
  # class => service hash; default is the catissuecore app service
  @def_persist_svc = PersistenceService.new(service_name, :host => host, :port => port)
  @persistence_services = [@def_persist_svc].to_set
  @cls_svc_hash = Hash.new(@def_persist_svc)
  # the create/update nested operations
  @operations = []
  # the objects for which exists? is unsuccessful in the context of a nested operation
  @transients = Set.new
end

Instance Attribute Details

#lazy_loaderLazyLoader (readonly)

Returns this database’s lazy loader.

Returns:



8
9
10
# File 'lib/caruby/database/persistifier.rb', line 8

def lazy_loader
  @lazy_loader
end

#operationsObject (readonly)

Returns the value of attribute operations.



61
62
63
# File 'lib/caruby/database.rb', line 61

def operations
  @operations
end

#persistence_servicesPersistenceService (readonly)

Returns the services used by this database.

Returns:



64
65
66
# File 'lib/caruby/database.rb', line 64

def persistence_services
  @persistence_services
end

Instance Method Details

#add_persistence_service(service) ⇒ Object

Adds the given service to this database.

Parameters:



169
170
171
# File 'lib/caruby/database.rb', line 169

def add_persistence_service(service)
  @persistence_services << service
end

#closeObject

Releases database resources. This method should be called when database interaction is completed.



130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/caruby/database.rb', line 130

def close
  return if @session.nil?
  begin
    @session.terminate_session
  rescue Exception => e
    logger.error("Session termination unsuccessful - #{e.message}")
  end
  # clear the cache
  clear
  logger.info("Disconnected from application server.")
  @session = nil
end

#execution_timeNumeric

Returns the execution time in seconds spent since the last open.

Returns:

  • (Numeric)

    the execution time in seconds spent since the last open



144
145
146
147
148
149
# File 'lib/caruby/database.rb', line 144

def execution_time
  persistence_services.inject(0) do |total, svc|
    st = svc.timer.elapsed
    total + st
  end
end

#open {|database| ... } ⇒ Object

Calls the block given to this method with this database as an argument, and closes the database when done.

Yields:

  • (database)

    the operation to perform on the database

Yield Parameters:



121
122
123
124
125
126
# File 'lib/caruby/database.rb', line 121

def open
  # reset the execution timers
  persistence_services.each { |svc| svc.timer.reset }
  # call the block and close when done
  yield(self) ensure close
end

#persistence_service(klass) ⇒ PersistanceService

Returns the PersistanceService to use for the given Jinx::Resource class. This base method always returns the standard application service. Subclasses can override for specialized services. A session is started on demand if necessary.

Parameters:

  • klass (Class)

    the domain object class

Returns:

  • (PersistanceService)

    the corresponding service



158
159
160
161
162
163
164
# File 'lib/caruby/database.rb', line 158

def persistence_service(klass)
   unless Class === klass then
     Jinx.fail(ArgumentError, "#{self} persistence_service argument is not a Class: {#klass.qp}")
   end
   start_session if @session.nil?
   @def_persist_svc
end