Class Lafcadio::ObjectStore
In: lafcadio/objectStore.rb
Parent: ContextualService::Service

The ObjectStore represents the database in a Lafcadio application.

Configuring the ObjectStore

The ObjectStore depends on a few values being set correctly in the LafcadioConfig file:

dbuser
The database username.
dbpassword
The database password.
dbname
The database name.
dbhost
The database host.

Instantiating ObjectStore

You can’t get an instance of ObjectStore by calling ObjectStore.new. Instead, you should call ObjectStore.get_object_store.

Dynamic method calls

ObjectStore uses reflection to provide a lot of convenience methods for querying domain objects in a number of ways.

ObjectStore#< domain class >( pk_id )
Retrieves one domain object by pk_id. For example,
  ObjectStore#user( 100 )

will return User 100. Note that you can also just user DomainObject.[]:

  User[100]
ObjectStore#< plural of domain class >( searchTerm, fieldName = nil )
Returns a collection of all instances of that domain class matching that search term. For example,
  ObjectStore#products( a_product_category )

queries MySQL for all products that belong to that product category. You can omit fieldName if searchTerm is a non-nil domain object, and the field connecting the first domain class to the second is named after the domain class. (For example, the above line assumes that Product has a field named "product_category".) Otherwise, it’s best to include fieldName:

  ObjectStore#users( "Jones", "lastName" )

Note that these can also be accessed through DomainObject.get:

  Product.get( a_product_category )
  User.get( "Jones", "lastName" )

Querying

ObjectStore can also be used to generate complex, ad-hoc queries which emulate much of the functionality you’d get from writing the SQL yourself. Furthermore, these queries can be run against in-memory data stores, which is particularly useful for tests.

  date = Date.new( 2003, 1, 1 )
  ObjectStore#invoices { |invoice|
    invoice.date.gte( date ) & invoice.rate.equals( 10 ) &
               invoice.hours.equals( 10 )
  }

is the same as

  select * from invoices
  where (date >= '2003-01-01' and rate = 10 and hours = 10)

Note that you can also use DomainObject.get:

  Invoice.get { |invoice|
    invoice.date.gte( date ) & invoice.rate.equals( 10 ) &
               invoice.hours.equals( 10 )
  }

See lafcadio/query.rb for more on the query inference syntax.

SQL Logging

Lafcadio uses log4r to log all of its SQL statements. The simplest way to turn on logging is to set the following values in the LafcadioConfig file:

logSql
Should be set to "y" to turn on logging.
logdir
The directory where log files should be written. Required if logSql is "y"
sqlLogFile
The name of the file (not including its directory) where SQL should be logged. Default is "sql".

Triggers

Domain classes can be set to fire triggers either before or after commits. Since these triggers are executed in Ruby, they’re easy to test. See DomainObject#pre_commit_trigger and DomainObject#post_commit_trigger for more.

Methods

all   db_bridge   db_bridge   db_name=   db_type   db_type=   get   max   mock?   query   transaction  

Public Class methods

Returns the DbBridge; this is useful in case you need to use raw SQL for a specific query.

Returns true if the current stored instance is a MockObjectStore.

Public Instance methods

Returns all domain objects for the given domain class.

Returns the DbBridge; this is useful in case you need to use raw SQL for a specific query.

Returns the domain object corresponding to the domain class and pk_id.

Retrieves the maximum value across all instances of one domain class.

  ObjectStore#max( Client )

returns the highest pk_id in the clients table.

  ObjectStore#max( Invoice, "rate" )

will return the highest rate for all invoices.

Passes a query and selects with it.

  qry = Query.infer( User ) { |user| user.fname.equals( 'Francis' ) }
  francises = ObjectStore.get_object_store.query( qry )

As long as the underlying database table sorts transactions, you can use this to run transactional logic. These transactions will auto commit at the end of the block, and can be rolled back.

  ObjectStore.get_object_store.transaction do |tr|
    Client.new( 'name' => 'Big Co.' ).commit
    tr.rollback
  end   # the client will not be saved to the DB

[Validate]