lafcadio 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. data/lib/lafcadio.rb +32 -0
  2. data/lib/lafcadio.rb~ +32 -0
  3. data/lib/lafcadio/TestSuite.rb +16 -0
  4. data/lib/lafcadio/dateTime.rb +2 -0
  5. data/lib/lafcadio/dateTime/Month.rb +93 -0
  6. data/lib/lafcadio/domain.rb +119 -0
  7. data/lib/lafcadio/domain.rb~ +119 -0
  8. data/lib/lafcadio/domain/DomainObject.rb +375 -0
  9. data/lib/lafcadio/domain/DomainObject.rb~ +371 -0
  10. data/lib/lafcadio/domain/MapObject.rb +22 -0
  11. data/lib/lafcadio/domain/ObjectType.rb +80 -0
  12. data/lib/lafcadio/includer.rb +18 -0
  13. data/lib/lafcadio/mock.rb +2 -0
  14. data/lib/lafcadio/mock/MockDbBridge.rb +78 -0
  15. data/lib/lafcadio/mock/MockDbBridge.rb~ +74 -0
  16. data/lib/lafcadio/mock/MockObjectStore.rb +20 -0
  17. data/lib/lafcadio/objectField.rb +14 -0
  18. data/lib/lafcadio/objectField/AutoIncrementField.rb +25 -0
  19. data/lib/lafcadio/objectField/BooleanField.rb +83 -0
  20. data/lib/lafcadio/objectField/DateField.rb +33 -0
  21. data/lib/lafcadio/objectField/DateTimeField.rb +25 -0
  22. data/lib/lafcadio/objectField/DecimalField.rb +41 -0
  23. data/lib/lafcadio/objectField/EmailField.rb +28 -0
  24. data/lib/lafcadio/objectField/EnumField.rb +62 -0
  25. data/lib/lafcadio/objectField/FieldValueError.rb +4 -0
  26. data/lib/lafcadio/objectField/IntegerField.rb +15 -0
  27. data/lib/lafcadio/objectField/LinkField.rb +92 -0
  28. data/lib/lafcadio/objectField/LinkField.rb~ +86 -0
  29. data/lib/lafcadio/objectField/MoneyField.rb +13 -0
  30. data/lib/lafcadio/objectField/MonthField.rb +16 -0
  31. data/lib/lafcadio/objectField/ObjectField.rb +142 -0
  32. data/lib/lafcadio/objectField/PasswordField.rb +29 -0
  33. data/lib/lafcadio/objectField/StateField.rb +13 -0
  34. data/lib/lafcadio/objectField/SubsetLinkField.rb +25 -0
  35. data/lib/lafcadio/objectField/TextField.rb +23 -0
  36. data/lib/lafcadio/objectField/TextListField.rb +21 -0
  37. data/lib/lafcadio/objectField/TimeStampField.rb +15 -0
  38. data/lib/lafcadio/objectStore.rb +100 -0
  39. data/lib/lafcadio/objectStore/Cache.rb +81 -0
  40. data/lib/lafcadio/objectStore/Committer.rb +65 -0
  41. data/lib/lafcadio/objectStore/CouldntMatchObjectTypeError.rb +4 -0
  42. data/lib/lafcadio/objectStore/DbBridge.rb +140 -0
  43. data/lib/lafcadio/objectStore/DbBridge.rb~ +140 -0
  44. data/lib/lafcadio/objectStore/DomainComparable.rb +25 -0
  45. data/lib/lafcadio/objectStore/DomainObjectInitError.rb +9 -0
  46. data/lib/lafcadio/objectStore/DomainObjectNotFoundError.rb +4 -0
  47. data/lib/lafcadio/objectStore/DomainObjectProxy.rb +62 -0
  48. data/lib/lafcadio/objectStore/DomainObjectSqlMaker.rb +74 -0
  49. data/lib/lafcadio/objectStore/ObjectStore.rb +207 -0
  50. data/lib/lafcadio/objectStore/ObjectStore.rb~ +207 -0
  51. data/lib/lafcadio/objectStore/SqlValueConverter.rb +30 -0
  52. data/lib/lafcadio/objectStore/SqlValueConverter.rb~ +30 -0
  53. data/lib/lafcadio/query.rb +203 -0
  54. data/lib/lafcadio/query/Compare.rb +55 -0
  55. data/lib/lafcadio/query/CompoundCondition.rb +39 -0
  56. data/lib/lafcadio/query/Condition.rb +66 -0
  57. data/lib/lafcadio/query/Condition.rb~ +66 -0
  58. data/lib/lafcadio/query/Equals.rb +45 -0
  59. data/lib/lafcadio/query/In.rb +20 -0
  60. data/lib/lafcadio/query/Like.rb +48 -0
  61. data/lib/lafcadio/query/Link.rb +20 -0
  62. data/lib/lafcadio/query/Max.rb +32 -0
  63. data/lib/lafcadio/query/Max.rb~ +25 -0
  64. data/lib/lafcadio/query/Not.rb +21 -0
  65. data/lib/lafcadio/query/Query.rb +92 -0
  66. data/lib/lafcadio/schema.rb +2 -0
  67. data/lib/lafcadio/schema/CreateTableStatement.rb +61 -0
  68. data/lib/lafcadio/schema/CreateTableStatement.rb~ +59 -0
  69. data/lib/lafcadio/test.rb +2 -0
  70. data/lib/lafcadio/test/LafcadioTestCase.rb +17 -0
  71. data/lib/lafcadio/test/testconfig.dat +13 -0
  72. data/lib/lafcadio/util.rb +180 -0
  73. data/lib/lafcadio/util/Context.rb +61 -0
  74. data/lib/lafcadio/util/ContextualService.rb +33 -0
  75. data/lib/lafcadio/util/English.rb +117 -0
  76. data/lib/lafcadio/util/HashOfArrays.rb +48 -0
  77. data/lib/lafcadio/util/LafcadioConfig.rb +25 -0
  78. data/lib/lafcadio/util/QueueHash.rb +67 -0
  79. data/lib/lafcadio/util/UsStates.rb +29 -0
  80. data/lib/lafcadio/xml.rb +2 -0
  81. metadata +135 -0
@@ -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 = 'pkId' )
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
@@ -0,0 +1,30 @@
1
+ module Lafcadio
2
+ class SqlValueConverter #:nodoc:
3
+ attr_reader :objectType, :rowHash
4
+
5
+ def initialize(objectType, rowHash)
6
+ @objectType = objectType
7
+ @rowHash = rowHash
8
+ end
9
+
10
+ def []( key )
11
+ if key == 'pkId'
12
+ if ( field_val = @rowHash[@objectType.sqlPrimaryKeyName] ).nil?
13
+ error_msg = "The field \"" + @objectType.sqlPrimaryKeyName +
14
+ "\" can\'t be found in the table \"" +
15
+ @objectType.tableName + "\"."
16
+ raise FieldMatchError, error_msg, caller
17
+ else
18
+ field_val.to_i
19
+ end
20
+ else
21
+ begin
22
+ field = @objectType.getField( key )
23
+ field.valueFromSQL( @rowHash[ field.dbFieldName ] )
24
+ rescue MissingError
25
+ nil
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,30 @@
1
+ module Lafcadio
2
+ class SqlValueConverter #:nodoc:
3
+ attr_reader :objectType, :rowHash
4
+
5
+ def initialize(objectType, rowHash)
6
+ @objectType = objectType
7
+ @rowHash = rowHash
8
+ end
9
+
10
+ def []( key )
11
+ if key == 'pkId'
12
+ if ( field_val = @rowHash[@objectType.sqlPrimaryKeyName] ).nil?
13
+ error_msg = "The field \"" + @objectType.sqlPrimaryKeyName +
14
+ "\" can\'t be found in the table \"" +
15
+ @objectType.tableName + "\"."
16
+ raise FieldMatchError, error_msg, caller
17
+ else
18
+ field_val.to_i
19
+ end
20
+ else
21
+ begin
22
+ field = @objectType.getField( key )
23
+ field.valueFromSQL( @rowHash[ key ] )
24
+ rescue MissingError
25
+ nil
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,203 @@
1
+ # = Overview
2
+ # By passing a block to ObjectStore, you can write complex, ad-hoc queries in
3
+ # Ruby. This involves a few more keystrokes than writing raw SQL, but also makes
4
+ # it easier to change queries at runtime, and these queries can also be fully
5
+ # tested against the MockObjectStore.
6
+ # big_invoices = object_store.getInvoices { |inv| inv.rate.gt( 50 ) }
7
+ # # => "select * from invoices where rate > 50"
8
+ # This a full-fledged block, so you can pass in values from the calling context.
9
+ # date = Date.new( 2004, 1, 1 )
10
+ # recent_invoices = object_store.getInvoices { |inv| inv.date.gt( date ) }
11
+ # # => "select * from invoices where date > '2004-01-01'"
12
+ #
13
+ # = Query operators
14
+ # You can compare fields either to simple values, or to other fields in the same
15
+ # table.
16
+ # paid_immediately = object_store.getInvoices { |inv|
17
+ # inv.date.equals( inv.paid )
18
+ # }
19
+ # # => "select * from invoices where date = paid"
20
+ #
21
+ # == Numerical comparisons: +lt+, +lte+, +gte+, +gt+
22
+ # +lt+, +lte+, +gte+, and +gt+ stand for "less than", "less than or equal",
23
+ # "greater than or equal", and "greater than", respectively.
24
+ # tiny_invoices = object_store.getInvoices { |inv| inv.rate.lte( 25 ) }
25
+ # # => "select * from invoices where rate <= 25"
26
+ # These comparators work on fields that contain numbers, dates, and even
27
+ # references to other domain objects.
28
+ # for_1st_ten_clients = object_store.getInvoices { |inv|
29
+ # inv.client.lte( 10 )
30
+ # }
31
+ # # => "select * from invoices where client <= 10"
32
+ #
33
+ # == Equality: +equals+
34
+ # full_week_invs = object_store.getInvoices { |inv| inv.hours.equals( 40 ) }
35
+ # # => "select * from invoices where hours = 40"
36
+ # If you're comparing to a domain object you should pass in the object itself.
37
+ # client = object_store.getClient( 99 )
38
+ # invoices = object_store.getInvoices { |inv| inv.client.equals( client ) }
39
+ # # => "select * from invoices where client = 99"
40
+ #
41
+ # == Inclusion: +in+
42
+ # first_three_invs = object_store.getInvoices { |inv| inv.pkId.in( 1, 2, 3 ) }
43
+ # # => "select * from invoices where pkId in ( 1, 2, 3 )"
44
+ #
45
+ # == Text comparison: +like+
46
+ # fname_starts_with_a = object_store.getUsers { |user|
47
+ # user.fname.like( /^a/ )
48
+ # }
49
+ # # => "select * from users where fname like 'a%'"
50
+ # fname_ends_with_a = object_store.getUsers { |user|
51
+ # user.fname.like( /a$/ )
52
+ # }
53
+ # # => "select * from users where fname like '%a'"
54
+ # fname_contains_a = object_store.getUsers { |user|
55
+ # user.fname.like( /a/ )
56
+ # }
57
+ # # => "select * from users where fname like '%a%'"
58
+ # Please note that although we're using the Regexp operators here, these aren't
59
+ # full-fledged regexps. Only ^ and $ work for this.
60
+ #
61
+ # == Compound conditions: <tt>Query.And</tt> and <tt>Query.Or</tt>
62
+ # invoices = object_store.getInvoices { |inv|
63
+ # Query.And( inv.hours.equals( 40 ), inv.rate.equals( 50 ) )
64
+ # }
65
+ # # => "select * from invoices where (hours = 40 and rate = 50)"
66
+ # client99 = object_store.getClient( 99 )
67
+ # invoices = object_store.getInvoices { |inv|
68
+ # Query.Or( inv.hours.equals( 40 ),
69
+ # inv.rate.equals( 50 ),
70
+ # inv.client.equals( client99 ) )
71
+ # }
72
+ # # => "select * from invoices where (hours = 40 or rate = 50 or client = 99)"
73
+ # Note that both compound operators can take 2 or more arguments. Also, they can
74
+ # be nested:
75
+ # invoices = object_store.getInvoices { |inv|
76
+ # Query.And( inv.hours.equals( 40 ),
77
+ # Query.Or( inv.rate.equals( 50 ),
78
+ # inv.client.equals( client99 ) ) )
79
+ # }
80
+ # # => "select * from invoices where (hours = 40 and
81
+ # # (rate = 50 or client = 99))"
82
+ #
83
+ # == Negation: +not+
84
+ # invoices = object_store.getInvoices { |inv| inv.rate.equals( 50 ).not }
85
+ # # => "select * from invoices where rate != 50"
86
+
87
+ require 'lafcadio/includer'
88
+ Includer.include( 'query' )
89
+
90
+ module Lafcadio
91
+ class Query
92
+ def self.And( *conditions ); CompoundCondition.new( *conditions ); end
93
+
94
+ def self.Or( *conditions )
95
+ conditions << CompoundCondition::OR
96
+ CompoundCondition.new( *conditions)
97
+ end
98
+
99
+ class DomainObjectImpostor #:nodoc:
100
+ attr_reader :domainClass
101
+
102
+ def initialize( domainClass )
103
+ @domainClass = domainClass
104
+ end
105
+
106
+ def method_missing( methId, *args )
107
+ fieldName = methId.id2name
108
+ if fieldName == 'pkId'
109
+ ObjectFieldImpostor.new( self, fieldName )
110
+ else
111
+ begin
112
+ classField = @domainClass.getField( fieldName )
113
+ ObjectFieldImpostor.new( self, classField )
114
+ rescue MissingError
115
+ super( methId, *args )
116
+ end
117
+ end
118
+ end
119
+ end
120
+
121
+ class Inferrer #:nodoc:
122
+ def initialize( domainClass, &action )
123
+ @domainClass = domainClass; @action = action
124
+ end
125
+
126
+ def execute
127
+ impostor = DomainObjectImpostor.new( @domainClass )
128
+ condition = @action.call( impostor )
129
+ query = Query.new( @domainClass, condition )
130
+ end
131
+ end
132
+
133
+ class ObjectFieldImpostor #:nodoc:
134
+ def ObjectFieldImpostor.comparators
135
+ {
136
+ 'lt' => Compare::LESS_THAN, 'lte' => Compare::LESS_THAN_OR_EQUAL,
137
+ 'gte' => Compare::GREATER_THAN_OR_EQUAL,
138
+ 'gt' => Compare::GREATER_THAN
139
+ }
140
+ end
141
+
142
+ attr_reader :class_field
143
+
144
+ def initialize( domainObjectImpostor, class_field_or_name )
145
+ @domainObjectImpostor = domainObjectImpostor
146
+ if class_field_or_name == 'pkId'
147
+ @db_field_name = 'pkId'
148
+ else
149
+ @class_field = class_field_or_name
150
+ @db_field_name = class_field_or_name.dbFieldName
151
+ end
152
+ end
153
+
154
+ def method_missing( methId, *args )
155
+ methodName = methId.id2name
156
+ if !ObjectFieldImpostor.comparators.keys.index( methodName ).nil?
157
+ registerCompareCondition( methodName, *args )
158
+ else
159
+ super( methId, *args )
160
+ end
161
+ end
162
+
163
+ def registerCompareCondition( compareStr, searchTerm)
164
+ compareVal = ObjectFieldImpostor.comparators[compareStr]
165
+ Compare.new( @db_field_name, searchTerm,
166
+ @domainObjectImpostor.domainClass, compareVal )
167
+ end
168
+
169
+ def equals( searchTerm )
170
+ Equals.new( @db_field_name, field_or_field_name( searchTerm ),
171
+ @domainObjectImpostor.domainClass )
172
+ end
173
+
174
+ def field_or_field_name( search_term )
175
+ if search_term.class == ObjectFieldImpostor
176
+ search_term.class_field
177
+ else
178
+ search_term
179
+ end
180
+ end
181
+
182
+ def like( regexp )
183
+ if regexp.source =~ /^\^(.*)/
184
+ searchTerm = $1
185
+ matchType = Query::Like::POST_ONLY
186
+ elsif regexp.source =~ /(.*)\$$/
187
+ searchTerm = $1
188
+ matchType = Query::Like::PRE_ONLY
189
+ else
190
+ searchTerm = regexp.source
191
+ matchType = Query::Like::PRE_AND_POST
192
+ end
193
+ Query::Like.new( @db_field_name, searchTerm,
194
+ @domainObjectImpostor.domainClass, matchType )
195
+ end
196
+
197
+ def in( *searchTerms )
198
+ Query::In.new( @db_field_name, searchTerms,
199
+ @domainObjectImpostor.domainClass )
200
+ end
201
+ end
202
+ end
203
+ end