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 options.

[
  [:user, '-u USER', '--user USER', 'the application login user'],
  [:password, '-p PSWD', '--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']
]

Instance Attribute Summary collapse

Class Method 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



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/caruby/database.rb', line 86

def initialize(service_name, opts=nil)
  super()
  # The options can be defined in a block.
  opts ||= yield if block_given?
  if opts.nil? then raise ArgumentError.new("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)
  # The class => service hash is populated with the default 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.



54
55
56
# File 'lib/caruby/database.rb', line 54

def operations
  @operations
end

#persistence_servicesPersistenceService (readonly)

Returns the services used by this database.

Returns:



57
58
59
# File 'lib/caruby/database.rb', line 57

def persistence_services
  @persistence_services
end

Class Method Details

.const_missing(sym) ⇒ Object

Imports the caCORE ClientSession class on demand.



163
164
165
166
167
168
169
# File 'lib/caruby/database.rb', line 163

def self.const_missing(sym)
  if sym == :ClientSession then
    java_import Java::gov.nih.nci.system.comm.client.ClientSession
  else
    super
  end
end

Instance Method Details

#add_persistence_service(service) ⇒ Object

Adds the given service to this database.

Parameters:



158
159
160
# File 'lib/caruby/database.rb', line 158

def add_persistence_service(service)
  @persistence_services << service
end

#closed?Boolean

Returns whether this database is not #open?.

Returns:

  • (Boolean)

    whether this database is not #open?



111
112
113
# File 'lib/caruby/database.rb', line 111

def closed?
  not open?
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



134
135
136
137
138
139
# File 'lib/caruby/database.rb', line 134

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

#open(user = nil, password = nil) {|database| ... } ⇒ Object

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

Parameters:

  • user (String, nil) (defaults to: nil)

    the application login user

  • password (String, nil) (defaults to: nil)

    the application login password

Yields:

  • (database)

    the operation to perform on the database

Yield Parameters:



122
123
124
125
126
127
128
129
130
131
# File 'lib/caruby/database.rb', line 122

def open(user=nil, password=nil)
  raise ArgumentError.new("Database open requires an execution block") unless block_given?
  raise DatabaseError.new("The caRuby application database is already in use.") if open?
  # reset the execution timers
  persistence_services.each { |svc| svc.timer.reset }
  # Start the session.
  start_session(user, password)
  # Call the block and close when done.
  yield(self) ensure close
end

#open?Boolean

Returns whether there is an active session.

Returns:

  • (Boolean)

    whether there is an active session



106
107
108
# File 'lib/caruby/database.rb', line 106

def open?
  !!@session
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



148
149
150
151
152
153
# File 'lib/caruby/database.rb', line 148

def persistence_service(klass)
   unless Class === klass then
     raise ArgumentError.new("#{self} persistence_service argument is not a Class: {#klass.qp}")
   end
   @def_persist_svc
end