lafcadio 0.4.3
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/lafcadio.rb +32 -0
- data/lib/lafcadio.rb~ +32 -0
- data/lib/lafcadio/TestSuite.rb +16 -0
- data/lib/lafcadio/dateTime.rb +2 -0
- data/lib/lafcadio/dateTime/Month.rb +93 -0
- data/lib/lafcadio/domain.rb +119 -0
- data/lib/lafcadio/domain.rb~ +119 -0
- data/lib/lafcadio/domain/DomainObject.rb +375 -0
- data/lib/lafcadio/domain/DomainObject.rb~ +371 -0
- data/lib/lafcadio/domain/MapObject.rb +22 -0
- data/lib/lafcadio/domain/ObjectType.rb +80 -0
- data/lib/lafcadio/includer.rb +18 -0
- data/lib/lafcadio/mock.rb +2 -0
- data/lib/lafcadio/mock/MockDbBridge.rb +78 -0
- data/lib/lafcadio/mock/MockDbBridge.rb~ +74 -0
- data/lib/lafcadio/mock/MockObjectStore.rb +20 -0
- data/lib/lafcadio/objectField.rb +14 -0
- data/lib/lafcadio/objectField/AutoIncrementField.rb +25 -0
- data/lib/lafcadio/objectField/BooleanField.rb +83 -0
- data/lib/lafcadio/objectField/DateField.rb +33 -0
- data/lib/lafcadio/objectField/DateTimeField.rb +25 -0
- data/lib/lafcadio/objectField/DecimalField.rb +41 -0
- data/lib/lafcadio/objectField/EmailField.rb +28 -0
- data/lib/lafcadio/objectField/EnumField.rb +62 -0
- data/lib/lafcadio/objectField/FieldValueError.rb +4 -0
- data/lib/lafcadio/objectField/IntegerField.rb +15 -0
- data/lib/lafcadio/objectField/LinkField.rb +92 -0
- data/lib/lafcadio/objectField/LinkField.rb~ +86 -0
- data/lib/lafcadio/objectField/MoneyField.rb +13 -0
- data/lib/lafcadio/objectField/MonthField.rb +16 -0
- data/lib/lafcadio/objectField/ObjectField.rb +142 -0
- data/lib/lafcadio/objectField/PasswordField.rb +29 -0
- data/lib/lafcadio/objectField/StateField.rb +13 -0
- data/lib/lafcadio/objectField/SubsetLinkField.rb +25 -0
- data/lib/lafcadio/objectField/TextField.rb +23 -0
- data/lib/lafcadio/objectField/TextListField.rb +21 -0
- data/lib/lafcadio/objectField/TimeStampField.rb +15 -0
- data/lib/lafcadio/objectStore.rb +100 -0
- data/lib/lafcadio/objectStore/Cache.rb +81 -0
- data/lib/lafcadio/objectStore/Committer.rb +65 -0
- data/lib/lafcadio/objectStore/CouldntMatchObjectTypeError.rb +4 -0
- data/lib/lafcadio/objectStore/DbBridge.rb +140 -0
- data/lib/lafcadio/objectStore/DbBridge.rb~ +140 -0
- data/lib/lafcadio/objectStore/DomainComparable.rb +25 -0
- data/lib/lafcadio/objectStore/DomainObjectInitError.rb +9 -0
- data/lib/lafcadio/objectStore/DomainObjectNotFoundError.rb +4 -0
- data/lib/lafcadio/objectStore/DomainObjectProxy.rb +62 -0
- data/lib/lafcadio/objectStore/DomainObjectSqlMaker.rb +74 -0
- data/lib/lafcadio/objectStore/ObjectStore.rb +207 -0
- data/lib/lafcadio/objectStore/ObjectStore.rb~ +207 -0
- data/lib/lafcadio/objectStore/SqlValueConverter.rb +30 -0
- data/lib/lafcadio/objectStore/SqlValueConverter.rb~ +30 -0
- data/lib/lafcadio/query.rb +203 -0
- data/lib/lafcadio/query/Compare.rb +55 -0
- data/lib/lafcadio/query/CompoundCondition.rb +39 -0
- data/lib/lafcadio/query/Condition.rb +66 -0
- data/lib/lafcadio/query/Condition.rb~ +66 -0
- data/lib/lafcadio/query/Equals.rb +45 -0
- data/lib/lafcadio/query/In.rb +20 -0
- data/lib/lafcadio/query/Like.rb +48 -0
- data/lib/lafcadio/query/Link.rb +20 -0
- data/lib/lafcadio/query/Max.rb +32 -0
- data/lib/lafcadio/query/Max.rb~ +25 -0
- data/lib/lafcadio/query/Not.rb +21 -0
- data/lib/lafcadio/query/Query.rb +92 -0
- data/lib/lafcadio/schema.rb +2 -0
- data/lib/lafcadio/schema/CreateTableStatement.rb +61 -0
- data/lib/lafcadio/schema/CreateTableStatement.rb~ +59 -0
- data/lib/lafcadio/test.rb +2 -0
- data/lib/lafcadio/test/LafcadioTestCase.rb +17 -0
- data/lib/lafcadio/test/testconfig.dat +13 -0
- data/lib/lafcadio/util.rb +180 -0
- data/lib/lafcadio/util/Context.rb +61 -0
- data/lib/lafcadio/util/ContextualService.rb +33 -0
- data/lib/lafcadio/util/English.rb +117 -0
- data/lib/lafcadio/util/HashOfArrays.rb +48 -0
- data/lib/lafcadio/util/LafcadioConfig.rb +25 -0
- data/lib/lafcadio/util/QueueHash.rb +67 -0
- data/lib/lafcadio/util/UsStates.rb +29 -0
- data/lib/lafcadio/xml.rb +2 -0
- metadata +135 -0
@@ -0,0 +1,140 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
require 'dbi'
|
4
|
+
require_gem 'log4r'
|
5
|
+
require 'lafcadio/util/LafcadioConfig'
|
6
|
+
|
7
|
+
module Lafcadio
|
8
|
+
class DbBridge #:nodoc:
|
9
|
+
@@dbh = nil
|
10
|
+
@@lastPkIdInserted = nil
|
11
|
+
@@dbName = nil
|
12
|
+
@@connectionClass = DBI
|
13
|
+
|
14
|
+
def DbBridge.setDbName(dbName)
|
15
|
+
@@dbName = dbName
|
16
|
+
end
|
17
|
+
|
18
|
+
def DbBridge._load(aString)
|
19
|
+
aString =~ /dbh:/
|
20
|
+
dbString = $'
|
21
|
+
begin
|
22
|
+
dbh = Marshal.load(dbString)
|
23
|
+
rescue TypeError
|
24
|
+
dbh = nil
|
25
|
+
end
|
26
|
+
new dbh
|
27
|
+
end
|
28
|
+
|
29
|
+
def DbBridge.flushConnection
|
30
|
+
@@dbh = nil
|
31
|
+
end
|
32
|
+
|
33
|
+
def DbBridge.setConnectionClass( aClass )
|
34
|
+
@@connectionClass = aClass
|
35
|
+
end
|
36
|
+
|
37
|
+
def DbBridge.disconnect
|
38
|
+
@@dbh.disconnect if @@dbh
|
39
|
+
end
|
40
|
+
|
41
|
+
def initialize(dbh = nil)
|
42
|
+
if dbh == nil
|
43
|
+
if @@dbh == nil
|
44
|
+
config = LafcadioConfig.new
|
45
|
+
dbName = @@dbName || config['dbname']
|
46
|
+
dbAndHost = nil
|
47
|
+
if dbName && config['dbhost']
|
48
|
+
dbAndHost = "dbi:Mysql:#{ dbName }:#{ config['dbhost'] }"
|
49
|
+
else
|
50
|
+
dbAndHost = "dbi:#{config['dbconn']}"
|
51
|
+
end
|
52
|
+
@@dbh = @@connectionClass.connect( dbAndHost, config['dbuser'],
|
53
|
+
config['dbpassword'] )
|
54
|
+
end
|
55
|
+
else
|
56
|
+
@@dbh = dbh
|
57
|
+
end
|
58
|
+
@dbh = @@dbh
|
59
|
+
ObjectSpace.define_finalizer( self, proc { |id| DbBridge.disconnect } )
|
60
|
+
end
|
61
|
+
|
62
|
+
def maybeLog(sql)
|
63
|
+
config = LafcadioConfig.new
|
64
|
+
if config['logSql'] == 'y'
|
65
|
+
sqllog = Log4r::Logger['sql'] || Log4r::Logger.new( 'sql' )
|
66
|
+
filename = File.join( config['logdir'], config['sqlLogFile'] || 'sql' )
|
67
|
+
outputter = Log4r::FileOutputter.new( 'outputter',
|
68
|
+
{ :filename => filename } )
|
69
|
+
sqllog.outputters = outputter
|
70
|
+
sqllog.info sql
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def commit(dbObject)
|
75
|
+
require 'lafcadio/objectStore/DomainObjectSqlMaker'
|
76
|
+
sqlMaker = DomainObjectSqlMaker.new(dbObject)
|
77
|
+
sqlMaker.sqlStatements.each { |sql, binds| executeCommit( sql, binds ) }
|
78
|
+
if sqlMaker.sqlStatements[0].first =~ /insert/
|
79
|
+
sql = 'select last_insert_id()'
|
80
|
+
result = executeSelect( sql )
|
81
|
+
@@lastPkIdInserted = result[0]['last_insert_id()'].to_i
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def executeCommit( sql, binds )
|
86
|
+
@dbh.do( sql, *binds )
|
87
|
+
end
|
88
|
+
|
89
|
+
def getCollectionByQuery(query)
|
90
|
+
require 'lafcadio/objectStore/SqlValueConverter'
|
91
|
+
objectType = query.objectType
|
92
|
+
coll = []
|
93
|
+
objects = []
|
94
|
+
result = executeSelect query.toSql
|
95
|
+
result.each { |row_hash|
|
96
|
+
converter = SqlValueConverter.new(objectType, row_hash)
|
97
|
+
obj = objectType.new converter
|
98
|
+
objects << obj
|
99
|
+
}
|
100
|
+
coll = coll.concat objects
|
101
|
+
coll
|
102
|
+
end
|
103
|
+
|
104
|
+
def executeSelect(sql)
|
105
|
+
maybeLog sql
|
106
|
+
begin
|
107
|
+
@dbh.select_all( sql )
|
108
|
+
rescue DBI::DatabaseError => e
|
109
|
+
raise $!.to_s + ": #{ e.errstr }"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def _dump(aDepth)
|
114
|
+
if @db.respond_to? '_dump'
|
115
|
+
dbDump = @db._dump
|
116
|
+
else
|
117
|
+
dbDump = @db.class.to_s
|
118
|
+
end
|
119
|
+
"dbh:#{dbDump}"
|
120
|
+
end
|
121
|
+
|
122
|
+
def lastPkIdInserted
|
123
|
+
@@lastPkIdInserted
|
124
|
+
end
|
125
|
+
|
126
|
+
def group_query( query )
|
127
|
+
row = executeSelect( query.toSql )[0]
|
128
|
+
result = []
|
129
|
+
row.each { |val|
|
130
|
+
if query.field_name != 'pkId'
|
131
|
+
a_field = query.objectType.getField( query.field_name )
|
132
|
+
result << a_field.valueFromSQL( val )
|
133
|
+
else
|
134
|
+
result << val.to_i
|
135
|
+
end
|
136
|
+
}
|
137
|
+
result
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Lafcadio
|
2
|
+
module DomainComparable
|
3
|
+
include Comparable
|
4
|
+
|
5
|
+
# A DomainObject or DomainObjectProxy is compared by +objectType+ and by
|
6
|
+
# +pkId+.
|
7
|
+
def <=>(anOther)
|
8
|
+
if anOther.respond_to?( 'objectType' )
|
9
|
+
if self.objectType == anOther.objectType
|
10
|
+
self.pkId <=> anOther.pkId
|
11
|
+
else
|
12
|
+
self.objectType.name <=> anOther.objectType.name
|
13
|
+
end
|
14
|
+
else
|
15
|
+
nil
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def eql?(otherObj)
|
20
|
+
self == otherObj
|
21
|
+
end
|
22
|
+
|
23
|
+
def hash; "#{ self.class.name } #{ pkId }".hash; end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'lafcadio/objectStore/DomainComparable'
|
2
|
+
|
3
|
+
module Lafcadio
|
4
|
+
# The DomainObjectProxy is used when retrieving domain objects that are
|
5
|
+
# linked to other domain objects with LinkFields. In terms of +objectType+ and
|
6
|
+
# +pkId+, a DomainObjectProxy instance looks to the outside world like the
|
7
|
+
# domain object it's supposed to represent. It only retrieves its domain
|
8
|
+
# object from the database when member data is requested.
|
9
|
+
#
|
10
|
+
# In normal usage you will probably never manipulate a DomainObjectProxy
|
11
|
+
# directly, but you may discover it by accident by calling
|
12
|
+
# DomainObjectProxy#class (or DomainObject#class) instead of
|
13
|
+
# DomainObjectProxy#objectType (or DomainObjectProxy#objectType).
|
14
|
+
class DomainObjectProxy
|
15
|
+
include DomainComparable
|
16
|
+
|
17
|
+
attr_accessor :objectType, :pkId
|
18
|
+
|
19
|
+
def initialize(objectTypeOrDbObject, pkId = nil)
|
20
|
+
if pkId
|
21
|
+
@objectType = objectTypeOrDbObject
|
22
|
+
@pkId = pkId
|
23
|
+
elsif objectTypeOrDbObject.class < DomainObject
|
24
|
+
@dbObject = objectTypeOrDbObject
|
25
|
+
@d_obj_retrieve_time = Time.now
|
26
|
+
@objectType = @dbObject.class
|
27
|
+
@pkId = @dbObject.pkId
|
28
|
+
else
|
29
|
+
raise ArgumentError
|
30
|
+
end
|
31
|
+
@dbObject = nil
|
32
|
+
end
|
33
|
+
|
34
|
+
def getDbObject
|
35
|
+
object_store = ObjectStore.getObjectStore
|
36
|
+
if @dbObject.nil? || needs_refresh?
|
37
|
+
@dbObject = object_store.get(@objectType, @pkId)
|
38
|
+
@d_obj_retrieve_time = Time.now
|
39
|
+
|
40
|
+
end
|
41
|
+
@dbObject
|
42
|
+
end
|
43
|
+
|
44
|
+
def method_missing(methodId, *args)
|
45
|
+
getDbObject.send(methodId.id2name, *args)
|
46
|
+
end
|
47
|
+
|
48
|
+
def needs_refresh?
|
49
|
+
object_store = ObjectStore.getObjectStore
|
50
|
+
last_commit_time = object_store.last_commit_time( @objectType, @pkId )
|
51
|
+
!last_commit_time.nil? && last_commit_time > @d_obj_retrieve_time
|
52
|
+
end
|
53
|
+
|
54
|
+
def to_s
|
55
|
+
getDbObject.to_s
|
56
|
+
end
|
57
|
+
|
58
|
+
def hash
|
59
|
+
getDbObject.hash
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'lafcadio/objectStore/DomainObjectInitError'
|
2
|
+
|
3
|
+
module Lafcadio
|
4
|
+
class DomainObjectSqlMaker #:nodoc:
|
5
|
+
attr_reader :bindValues
|
6
|
+
|
7
|
+
def initialize(obj); @obj = obj; end
|
8
|
+
|
9
|
+
def insertSQL(objectType)
|
10
|
+
fields = objectType.classFields
|
11
|
+
nameValuePairs = getNameValuePairs(objectType)
|
12
|
+
if objectType.isBasedOn?
|
13
|
+
nameValuePairs[objectType.sqlPrimaryKeyName] = 'LAST_INSERT_ID()'
|
14
|
+
end
|
15
|
+
fieldNameStr = nameValuePairs.keys.join ", "
|
16
|
+
fieldValueStr = nameValuePairs.values.join ", "
|
17
|
+
"insert into #{ objectType.tableName}(#{fieldNameStr}) " +
|
18
|
+
"values(#{fieldValueStr})"
|
19
|
+
end
|
20
|
+
|
21
|
+
def getNameValuePairs(objectType)
|
22
|
+
require 'lafcadio/util/QueueHash'
|
23
|
+
nameValues = []
|
24
|
+
objectType.classFields.each { |field|
|
25
|
+
value = @obj.send(field.name)
|
26
|
+
unless field.dbWillAutomaticallyWrite
|
27
|
+
nameValues << field.nameForSQL
|
28
|
+
nameValues <<(field.valueForSQL(value))
|
29
|
+
end
|
30
|
+
if field.bind_write?
|
31
|
+
@bindValues << value
|
32
|
+
end
|
33
|
+
}
|
34
|
+
QueueHash.new( *nameValues )
|
35
|
+
end
|
36
|
+
|
37
|
+
def updateSQL(objectType)
|
38
|
+
nameValueStrings = []
|
39
|
+
nameValuePairs = getNameValuePairs(objectType)
|
40
|
+
nameValuePairs.each { |key, value|
|
41
|
+
nameValueStrings << "#{key}=#{ value }"
|
42
|
+
}
|
43
|
+
allNameValues = nameValueStrings.join ', '
|
44
|
+
"update #{ objectType.tableName} set #{allNameValues} " +
|
45
|
+
"where #{ objectType.sqlPrimaryKeyName}=#{@obj.pkId}"
|
46
|
+
end
|
47
|
+
|
48
|
+
def deleteSql(objectType)
|
49
|
+
"delete from #{ objectType.tableName} " +
|
50
|
+
"where #{ objectType.sqlPrimaryKeyName }=#{ @obj.pkId }"
|
51
|
+
end
|
52
|
+
|
53
|
+
def sqlStatements
|
54
|
+
statements = []
|
55
|
+
if @obj.errorMessages.size > 0
|
56
|
+
raise DomainObjectInitError, @obj.errorMessages, caller
|
57
|
+
end
|
58
|
+
@obj.class.selfAndConcreteSuperclasses.each { |objectType|
|
59
|
+
@bindValues = []
|
60
|
+
if @obj.pkId == nil
|
61
|
+
statement = insertSQL(objectType)
|
62
|
+
else
|
63
|
+
if @obj.delete
|
64
|
+
statement = deleteSql(objectType)
|
65
|
+
else
|
66
|
+
statement = updateSQL(objectType)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
statements << [statement, @bindValues]
|
70
|
+
}
|
71
|
+
statements.reverse
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,207 @@
|
|
1
|
+
require 'lafcadio'
|
2
|
+
|
3
|
+
module Lafcadio
|
4
|
+
# The ObjectStore represents the database in a Lafcadio application.
|
5
|
+
#
|
6
|
+
# = Configuring the ObjectStore
|
7
|
+
# The ObjectStore depends on a few values being set correctly in the
|
8
|
+
# LafcadioConfig file:
|
9
|
+
# [dbuser] The database username.
|
10
|
+
# [dbpassword] The database password.
|
11
|
+
# [dbname] The database name.
|
12
|
+
# [dbhost] The database host.
|
13
|
+
#
|
14
|
+
# = Instantiating ObjectStore
|
15
|
+
# The ObjectStore is a ContextualService, meaning you can't get an instance by
|
16
|
+
# calling ObjectStore.new. Instead, you should call
|
17
|
+
# ObjectStore.getObjectStore. (Using a ContextualService makes it easier to
|
18
|
+
# make out the ObjectStore for unit tests: See ContextualService for more.)
|
19
|
+
#
|
20
|
+
# = Dynamic method calls
|
21
|
+
# ObjectStore uses reflection to provide a lot of convenience methods for
|
22
|
+
# querying domain objects in a number of ways.
|
23
|
+
# [ObjectStore#get< domain class > (pkId)]
|
24
|
+
# Retrieves one domain object by pkId. For example,
|
25
|
+
# ObjectStore#getUser( 100 )
|
26
|
+
# will return User 100.
|
27
|
+
# [ObjectStore#get< domain class >s (searchTerm, fieldName = nil)]
|
28
|
+
# Returns a collection of all instances of that domain class matching that
|
29
|
+
# search term. For example,
|
30
|
+
# ObjectStore#getProducts( aProductCategory )
|
31
|
+
# queries MySQL for all products that belong to that product category. You
|
32
|
+
# can omit +fieldName+ if +searchTerm+ is a non-nil domain object, and the
|
33
|
+
# field connecting the first domain class to the second is named after the
|
34
|
+
# domain class. (For example, the above line assumes that Product has a
|
35
|
+
# field named "productCategory".) Otherwise, it's best to include
|
36
|
+
# +fieldName+:
|
37
|
+
# ObjectStore#getUsers( "Jones", "lastName" )
|
38
|
+
#
|
39
|
+
# = Querying
|
40
|
+
# ObjectStore can also be used to generate complex, ad-hoc queries which
|
41
|
+
# emulate much of the functionality you'd get from writing the SQL yourself.
|
42
|
+
# Furthermore, these queries can be run against in-memory data stores, which
|
43
|
+
# is particularly useful for tests.
|
44
|
+
# date = Date.new( 2003, 1, 1 )
|
45
|
+
# ObjectStore#getInvoices { |invoice|
|
46
|
+
# Query.And( invoice.date.gte( date ), invoice.rate.equals( 10 ),
|
47
|
+
# invoice.hours.equals( 10 ) )
|
48
|
+
# }
|
49
|
+
# is the same as
|
50
|
+
# select * from invoices
|
51
|
+
# where (date >= '2003-01-01' and rate = 10 and hours = 10)
|
52
|
+
# See lafcadio/query.rb for more.
|
53
|
+
#
|
54
|
+
# = SQL Logging
|
55
|
+
# Lafcadio uses log4r to log all of its SQL statements. The simplest way to
|
56
|
+
# turn on logging is to set the following values in the LafcadioConfig file:
|
57
|
+
# [logSql] Should be set to "y" to turn on logging.
|
58
|
+
# [logdir] The directory where log files should be written. Required if
|
59
|
+
# +logSql+ is "y"
|
60
|
+
# [sqlLogFile] The name of the file (not including its directory) where SQL
|
61
|
+
# should be logged. Default is "sql".
|
62
|
+
#
|
63
|
+
# = Triggers
|
64
|
+
# Domain classes can be set to fire triggers either before or after commits.
|
65
|
+
# Since these triggers are executed in Ruby, they're easy to test. See
|
66
|
+
# DomainObject#preCommitTrigger and DomainObject#postCommitTrigger for more.
|
67
|
+
class ObjectStore < ContextualService
|
68
|
+
def ObjectStore.setDbName(dbName) #:nodoc:
|
69
|
+
DbBridge.setDbName dbName
|
70
|
+
end
|
71
|
+
|
72
|
+
def initialize(context, dbBridge = nil) #:nodoc:
|
73
|
+
super context
|
74
|
+
@dbBridge = dbBridge == nil ? DbBridge.new : dbBridge
|
75
|
+
@cache = ObjectStore::Cache.new( @dbBridge )
|
76
|
+
end
|
77
|
+
|
78
|
+
# Commits a domain object to the database. You can also simply call
|
79
|
+
# myDomainObject.commit
|
80
|
+
def commit(dbObject)
|
81
|
+
require 'lafcadio/objectStore/Committer'
|
82
|
+
committer = Committer.new dbObject, @dbBridge
|
83
|
+
committer.execute
|
84
|
+
updateCacheAfterCommit( committer )
|
85
|
+
end
|
86
|
+
|
87
|
+
# Flushes one domain object from its cache.
|
88
|
+
def flush(dbObject)
|
89
|
+
@cache.flush dbObject
|
90
|
+
end
|
91
|
+
|
92
|
+
# Returns the domain object corresponding to the domain class and pkId.
|
93
|
+
def get(objectType, pkId)
|
94
|
+
query = Query.new objectType, pkId
|
95
|
+
@cache.getByQuery( query )[0] ||
|
96
|
+
( raise( DomainObjectNotFoundError,
|
97
|
+
"Can't find #{objectType} #{pkId}", caller ) )
|
98
|
+
end
|
99
|
+
|
100
|
+
# Returns all domain objects for the given domain class.
|
101
|
+
def getAll(objectType)
|
102
|
+
query = Query.new( objectType )
|
103
|
+
@cache.getByQuery( query )
|
104
|
+
end
|
105
|
+
|
106
|
+
# Returns the DbBridge; this is useful in case you need to use raw SQL for a
|
107
|
+
# specific query.
|
108
|
+
def getDbBridge; @dbBridge; end
|
109
|
+
|
110
|
+
def getFiltered(objectTypeName, searchTerm, fieldName = nil) #:nodoc:
|
111
|
+
require 'lafcadio/query/Link'
|
112
|
+
objectType = DomainObject.getObjectTypeFromString objectTypeName
|
113
|
+
unless fieldName
|
114
|
+
fieldName = searchTerm.objectType.bareName
|
115
|
+
fieldName = fieldName.decapitalize
|
116
|
+
end
|
117
|
+
if searchTerm.class <= DomainObject
|
118
|
+
condition = Query::Link.new(fieldName, searchTerm, objectType)
|
119
|
+
else
|
120
|
+
condition = Query::Equals.new(fieldName, searchTerm, objectType)
|
121
|
+
end
|
122
|
+
getSubset( condition )
|
123
|
+
end
|
124
|
+
|
125
|
+
def getMapMatch(objectType, mapped) #:nodoc:
|
126
|
+
fieldName = mapped.objectType.bareName.decapitalize
|
127
|
+
Query::Equals.new(fieldName, mapped, objectType)
|
128
|
+
end
|
129
|
+
|
130
|
+
def getMapObject(objectType, map1, map2) #:nodoc:
|
131
|
+
require 'lafcadio/query/CompoundCondition'
|
132
|
+
unless map1 && map2
|
133
|
+
raise ArgumentError,
|
134
|
+
"ObjectStore#getMapObject needs two non-nil keys", caller
|
135
|
+
end
|
136
|
+
mapMatch1 = getMapMatch objectType, map1
|
137
|
+
mapMatch2 = getMapMatch objectType, map2
|
138
|
+
condition = Query::CompoundCondition.new mapMatch1, mapMatch2
|
139
|
+
getSubset(condition)[0]
|
140
|
+
end
|
141
|
+
|
142
|
+
def getMapped(searchTerm, resultTypeName) #:nodoc:
|
143
|
+
resultType = DomainObject.getObjectTypeFromString resultTypeName
|
144
|
+
coll = []
|
145
|
+
firstTypeName = searchTerm.class.bareName
|
146
|
+
secondTypeName = resultType.bareName
|
147
|
+
mapTypeName = firstTypeName + secondTypeName
|
148
|
+
getFiltered(mapTypeName, searchTerm).each { |mapObj|
|
149
|
+
coll << mapObj.send( resultType.name.decapitalize )
|
150
|
+
}
|
151
|
+
coll
|
152
|
+
end
|
153
|
+
|
154
|
+
# Retrieves the maximum value across all instances of one domain class.
|
155
|
+
# ObjectStore#getMax( Client )
|
156
|
+
# returns the highest +pkId+ in the +clients+ table.
|
157
|
+
# ObjectStore#getMax( Invoice, "rate" )
|
158
|
+
# will return the highest rate for all invoices.
|
159
|
+
def getMax( domain_class, field_name = nil )
|
160
|
+
query = Query::Max.new( domain_class, field_name )
|
161
|
+
@dbBridge.group_query( query ).only
|
162
|
+
end
|
163
|
+
|
164
|
+
# Retrieves a collection of domain objects by +pkId+.
|
165
|
+
# ObjectStore#getObjects( Clients, [ 1, 2, 3 ] )
|
166
|
+
def getObjects(objectType, pkIds)
|
167
|
+
require 'lafcadio/query/In'
|
168
|
+
condition = Query::In.new('pkId', pkIds, objectType)
|
169
|
+
getSubset condition
|
170
|
+
end
|
171
|
+
|
172
|
+
def getSubset(conditionOrQuery) #:nodoc:
|
173
|
+
if conditionOrQuery.class <= Query::Condition
|
174
|
+
condition = conditionOrQuery
|
175
|
+
query = Query.new condition.objectType, condition
|
176
|
+
else
|
177
|
+
query = conditionOrQuery
|
178
|
+
end
|
179
|
+
@cache.getByQuery( query )
|
180
|
+
end
|
181
|
+
|
182
|
+
def last_commit_time( domain_class, pkId ) #:nodoc:
|
183
|
+
@cache.last_commit_time( domain_class, pkId )
|
184
|
+
end
|
185
|
+
|
186
|
+
def method_missing(methodId, *args) #:nodoc:
|
187
|
+
proc = block_given? ? ( proc { |obj| yield( obj ) } ) : nil
|
188
|
+
dispatch = MethodDispatch.new( methodId, proc, *args )
|
189
|
+
self.send( dispatch.symbol, *dispatch.args )
|
190
|
+
end
|
191
|
+
|
192
|
+
# Caches one domain object.
|
193
|
+
def set(dbObject)
|
194
|
+
@cache.save dbObject
|
195
|
+
end
|
196
|
+
|
197
|
+
def updateCacheAfterCommit( committer ) #:nodoc:
|
198
|
+
if committer.commitType == Committer::UPDATE ||
|
199
|
+
committer.commitType == Committer::INSERT
|
200
|
+
set( committer.dbObject )
|
201
|
+
elsif committer.commitType == Committer::DELETE
|
202
|
+
@cache.flush( committer.dbObject )
|
203
|
+
end
|
204
|
+
@cache.set_commit_time( committer.dbObject )
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|