lafcadio 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
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