Class: Lafcadio::ObjectStore
- Inherits:
-
ContextualService
- Object
- ContextualService
- Lafcadio::ObjectStore
- Defined in:
- lib/lafcadio/objectStore/ObjectStore.rb,
lib/lafcadio/objectStore.rb,
lib/lafcadio/objectStore/Cache.rb
Overview
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
The ObjectStore is a ContextualService, meaning you can’t get an instance by calling ObjectStore.new. Instead, you should call ObjectStore.getObjectStore. (Using a ContextualService makes it easier to make out the ObjectStore for unit tests: See ContextualService for more.)
Dynamic method calls
ObjectStore uses reflection to provide a lot of convenience methods for querying domain objects in a number of ways.
- ObjectStore#get< domain class > (pkId)
-
Retrieves one domain object by pkId. For example,
ObjectStore#getUser( 100 )
will return User 100.
- ObjectStore#get< domain class >s (searchTerm, fieldName = nil)
-
Returns a collection of all instances of that domain class matching that search term. For example,
ObjectStore#getProducts( aProductCategory )
queries MySQL for all products that belong to that product category. You can omit
fieldName
ifsearchTerm
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 “productCategory”.) Otherwise, it’s best to includefieldName
:ObjectStore#getUsers( "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#getInvoices { |invoice|
Query.And( 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)
See lafcadio/query.rb for more.
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#preCommitTrigger and DomainObject#postCommitTrigger for more.
Direct Known Subclasses
Defined Under Namespace
Classes: Cache, MethodDispatch
Class Method Summary collapse
-
.setDbName(dbName) ⇒ Object
:nodoc:.
Instance Method Summary collapse
-
#commit(dbObject) ⇒ Object
Commits a domain object to the database.
-
#flush(dbObject) ⇒ Object
Flushes one domain object from its cache.
-
#get(objectType, pkId) ⇒ Object
Returns the domain object corresponding to the domain class and pkId.
-
#getAll(objectType) ⇒ Object
Returns all domain objects for the given domain class.
-
#getDbBridge ⇒ Object
Returns the DbBridge; this is useful in case you need to use raw SQL for a specific query.
-
#getFiltered(objectTypeName, searchTerm, fieldName = nil) ⇒ Object
:nodoc:.
-
#getMapMatch(objectType, mapped) ⇒ Object
:nodoc:.
-
#getMapObject(objectType, map1, map2) ⇒ Object
:nodoc:.
-
#getMapped(searchTerm, resultTypeName) ⇒ Object
:nodoc:.
-
#getMax(domain_class, field_name = nil) ⇒ Object
Retrieves the maximum value across all instances of one domain class.
-
#getObjects(objectType, pkIds) ⇒ Object
Retrieves a collection of domain objects by
pkId
. -
#getSubset(conditionOrQuery) ⇒ Object
:nodoc:.
-
#initialize(context, dbBridge = nil) ⇒ ObjectStore
constructor
:nodoc:.
-
#last_commit_time(domain_class, pkId) ⇒ Object
:nodoc:.
-
#method_missing(methodId, *args) ⇒ Object
:nodoc:.
-
#set(dbObject) ⇒ Object
Caches one domain object.
-
#updateCacheAfterCommit(committer) ⇒ Object
:nodoc:.
Methods inherited from ContextualService
Constructor Details
#initialize(context, dbBridge = nil) ⇒ ObjectStore
:nodoc:
72 73 74 75 76 |
# File 'lib/lafcadio/objectStore/ObjectStore.rb', line 72 def initialize(context, dbBridge = nil) #:nodoc: super context @dbBridge = dbBridge == nil ? DbBridge.new : dbBridge @cache = ObjectStore::Cache.new( @dbBridge ) end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(methodId, *args) ⇒ Object
:nodoc:
186 187 188 189 190 |
# File 'lib/lafcadio/objectStore/ObjectStore.rb', line 186 def method_missing(methodId, *args) #:nodoc: proc = block_given? ? ( proc { |obj| yield( obj ) } ) : nil dispatch = MethodDispatch.new( methodId, proc, *args ) self.send( dispatch.symbol, *dispatch.args ) end |
Class Method Details
.setDbName(dbName) ⇒ Object
:nodoc:
68 69 70 |
# File 'lib/lafcadio/objectStore/ObjectStore.rb', line 68 def ObjectStore.setDbName(dbName) #:nodoc: DbBridge.setDbName dbName end |
Instance Method Details
#commit(dbObject) ⇒ Object
Commits a domain object to the database. You can also simply call
myDomainObject.commit
80 81 82 83 84 85 |
# File 'lib/lafcadio/objectStore/ObjectStore.rb', line 80 def commit(dbObject) require 'lafcadio/objectStore/Committer' committer = Committer.new dbObject, @dbBridge committer.execute updateCacheAfterCommit( committer ) end |
#flush(dbObject) ⇒ Object
Flushes one domain object from its cache.
88 89 90 |
# File 'lib/lafcadio/objectStore/ObjectStore.rb', line 88 def flush(dbObject) @cache.flush dbObject end |
#get(objectType, pkId) ⇒ Object
Returns the domain object corresponding to the domain class and pkId.
93 94 95 96 97 98 |
# File 'lib/lafcadio/objectStore/ObjectStore.rb', line 93 def get(objectType, pkId) query = Query.new objectType, pkId @cache.getByQuery( query )[0] || ( raise( DomainObjectNotFoundError, "Can't find #{objectType} #{pkId}", caller ) ) end |
#getAll(objectType) ⇒ Object
Returns all domain objects for the given domain class.
101 102 103 104 |
# File 'lib/lafcadio/objectStore/ObjectStore.rb', line 101 def getAll(objectType) query = Query.new( objectType ) @cache.getByQuery( query ) end |
#getDbBridge ⇒ Object
Returns the DbBridge; this is useful in case you need to use raw SQL for a specific query.
108 |
# File 'lib/lafcadio/objectStore/ObjectStore.rb', line 108 def getDbBridge; @dbBridge; end |
#getFiltered(objectTypeName, searchTerm, fieldName = nil) ⇒ Object
:nodoc:
110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/lafcadio/objectStore/ObjectStore.rb', line 110 def getFiltered(objectTypeName, searchTerm, fieldName = nil) #:nodoc: require 'lafcadio/query/Link' objectType = DomainObject.getObjectTypeFromString objectTypeName unless fieldName fieldName = searchTerm.objectType. fieldName = fieldName.decapitalize end if searchTerm.class <= DomainObject condition = Query::Link.new(fieldName, searchTerm, objectType) else condition = Query::Equals.new(fieldName, searchTerm, objectType) end getSubset( condition ) end |
#getMapMatch(objectType, mapped) ⇒ Object
:nodoc:
125 126 127 128 |
# File 'lib/lafcadio/objectStore/ObjectStore.rb', line 125 def getMapMatch(objectType, mapped) #:nodoc: fieldName = mapped.objectType..decapitalize Query::Equals.new(fieldName, mapped, objectType) end |
#getMapObject(objectType, map1, map2) ⇒ Object
:nodoc:
130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/lafcadio/objectStore/ObjectStore.rb', line 130 def getMapObject(objectType, map1, map2) #:nodoc: require 'lafcadio/query/CompoundCondition' unless map1 && map2 raise ArgumentError, "ObjectStore#getMapObject needs two non-nil keys", caller end mapMatch1 = getMapMatch objectType, map1 mapMatch2 = getMapMatch objectType, map2 condition = Query::CompoundCondition.new mapMatch1, mapMatch2 getSubset(condition)[0] end |
#getMapped(searchTerm, resultTypeName) ⇒ Object
:nodoc:
142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/lafcadio/objectStore/ObjectStore.rb', line 142 def getMapped(searchTerm, resultTypeName) #:nodoc: resultType = DomainObject.getObjectTypeFromString resultTypeName coll = [] firstTypeName = searchTerm.class. secondTypeName = resultType. mapTypeName = firstTypeName + secondTypeName getFiltered(mapTypeName, searchTerm).each { |mapObj| coll << mapObj.send( resultType.name.decapitalize ) } coll end |
#getMax(domain_class, field_name = nil) ⇒ Object
Retrieves the maximum value across all instances of one domain class.
ObjectStore#getMax( Client )
returns the highest pkId
in the clients
table.
ObjectStore#getMax( Invoice, "rate" )
will return the highest rate for all invoices.
159 160 161 162 |
# File 'lib/lafcadio/objectStore/ObjectStore.rb', line 159 def getMax( domain_class, field_name = nil ) query = Query::Max.new( domain_class, field_name ) @dbBridge.group_query( query ).only end |
#getObjects(objectType, pkIds) ⇒ Object
Retrieves a collection of domain objects by pkId
.
ObjectStore#getObjects( Clients, [ 1, 2, 3 ] )
166 167 168 169 170 |
# File 'lib/lafcadio/objectStore/ObjectStore.rb', line 166 def getObjects(objectType, pkIds) require 'lafcadio/query/In' condition = Query::In.new('pkId', pkIds, objectType) getSubset condition end |
#getSubset(conditionOrQuery) ⇒ Object
:nodoc:
172 173 174 175 176 177 178 179 180 |
# File 'lib/lafcadio/objectStore/ObjectStore.rb', line 172 def getSubset(conditionOrQuery) #:nodoc: if conditionOrQuery.class <= Query::Condition condition = conditionOrQuery query = Query.new condition.objectType, condition else query = conditionOrQuery end @cache.getByQuery( query ) end |
#last_commit_time(domain_class, pkId) ⇒ Object
:nodoc:
182 183 184 |
# File 'lib/lafcadio/objectStore/ObjectStore.rb', line 182 def last_commit_time( domain_class, pkId ) #:nodoc: @cache.last_commit_time( domain_class, pkId ) end |
#set(dbObject) ⇒ Object
Caches one domain object.
193 194 195 |
# File 'lib/lafcadio/objectStore/ObjectStore.rb', line 193 def set(dbObject) @cache.save dbObject end |
#updateCacheAfterCommit(committer) ⇒ Object
:nodoc:
197 198 199 200 201 202 203 204 205 |
# File 'lib/lafcadio/objectStore/ObjectStore.rb', line 197 def updateCacheAfterCommit( committer ) #:nodoc: if committer.commitType == Committer::UPDATE || committer.commitType == Committer::INSERT set( committer.dbObject ) elsif committer.commitType == Committer::DELETE @cache.flush( committer.dbObject ) end @cache.set_commit_time( committer.dbObject ) end |