datamapper 0.3.2 → 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (180) hide show
  1. data/History.txt +0 -0
  2. data/Manifest.txt +5 -0
  3. data/README.txt +11 -0
  4. data/Rakefile +70 -0
  5. data/lib/datamapper.rb +8 -0
  6. metadata +152 -319
  7. data/CHANGELOG +0 -145
  8. data/FAQ +0 -96
  9. data/MIT-LICENSE +0 -22
  10. data/QUICKLINKS +0 -12
  11. data/README +0 -105
  12. data/environment.rb +0 -62
  13. data/example.rb +0 -156
  14. data/lib/data_mapper.rb +0 -88
  15. data/lib/data_mapper/adapters/abstract_adapter.rb +0 -43
  16. data/lib/data_mapper/adapters/data_object_adapter.rb +0 -480
  17. data/lib/data_mapper/adapters/mysql_adapter.rb +0 -72
  18. data/lib/data_mapper/adapters/postgresql_adapter.rb +0 -258
  19. data/lib/data_mapper/adapters/sql/coersion.rb +0 -134
  20. data/lib/data_mapper/adapters/sql/commands/load_command.rb +0 -545
  21. data/lib/data_mapper/adapters/sql/mappings/associations_set.rb +0 -34
  22. data/lib/data_mapper/adapters/sql/mappings/column.rb +0 -279
  23. data/lib/data_mapper/adapters/sql/mappings/conditions.rb +0 -172
  24. data/lib/data_mapper/adapters/sql/mappings/schema.rb +0 -60
  25. data/lib/data_mapper/adapters/sql/mappings/table.rb +0 -459
  26. data/lib/data_mapper/adapters/sql/quoting.rb +0 -24
  27. data/lib/data_mapper/adapters/sqlite3_adapter.rb +0 -159
  28. data/lib/data_mapper/associations.rb +0 -106
  29. data/lib/data_mapper/associations/belongs_to_association.rb +0 -160
  30. data/lib/data_mapper/associations/has_and_belongs_to_many_association.rb +0 -437
  31. data/lib/data_mapper/associations/has_many_association.rb +0 -283
  32. data/lib/data_mapper/associations/has_n_association.rb +0 -143
  33. data/lib/data_mapper/associations/reference.rb +0 -47
  34. data/lib/data_mapper/attributes.rb +0 -73
  35. data/lib/data_mapper/auto_migrations.rb +0 -36
  36. data/lib/data_mapper/base.rb +0 -17
  37. data/lib/data_mapper/callbacks.rb +0 -107
  38. data/lib/data_mapper/context.rb +0 -112
  39. data/lib/data_mapper/database.rb +0 -234
  40. data/lib/data_mapper/dependency_queue.rb +0 -28
  41. data/lib/data_mapper/embedded_value.rb +0 -145
  42. data/lib/data_mapper/identity_map.rb +0 -47
  43. data/lib/data_mapper/is/tree.rb +0 -121
  44. data/lib/data_mapper/migration.rb +0 -155
  45. data/lib/data_mapper/persistence.rb +0 -852
  46. data/lib/data_mapper/property.rb +0 -310
  47. data/lib/data_mapper/query.rb +0 -164
  48. data/lib/data_mapper/support/blank.rb +0 -35
  49. data/lib/data_mapper/support/connection_pool.rb +0 -117
  50. data/lib/data_mapper/support/enumerable.rb +0 -35
  51. data/lib/data_mapper/support/errors.rb +0 -16
  52. data/lib/data_mapper/support/inflector.rb +0 -265
  53. data/lib/data_mapper/support/object.rb +0 -54
  54. data/lib/data_mapper/support/serialization.rb +0 -96
  55. data/lib/data_mapper/support/silence.rb +0 -10
  56. data/lib/data_mapper/support/string.rb +0 -72
  57. data/lib/data_mapper/support/struct.rb +0 -7
  58. data/lib/data_mapper/support/symbol.rb +0 -82
  59. data/lib/data_mapper/support/typed_set.rb +0 -65
  60. data/lib/data_mapper/types/base.rb +0 -44
  61. data/lib/data_mapper/types/string.rb +0 -34
  62. data/lib/data_mapper/validatable_extensions/errors.rb +0 -12
  63. data/lib/data_mapper/validatable_extensions/macros.rb +0 -7
  64. data/lib/data_mapper/validatable_extensions/validatable_instance_methods.rb +0 -62
  65. data/lib/data_mapper/validatable_extensions/validation_base.rb +0 -18
  66. data/lib/data_mapper/validatable_extensions/validations/formats/email.rb +0 -43
  67. data/lib/data_mapper/validatable_extensions/validations/validates_acceptance_of.rb +0 -7
  68. data/lib/data_mapper/validatable_extensions/validations/validates_confirmation_of.rb +0 -7
  69. data/lib/data_mapper/validatable_extensions/validations/validates_each.rb +0 -7
  70. data/lib/data_mapper/validatable_extensions/validations/validates_format_of.rb +0 -28
  71. data/lib/data_mapper/validatable_extensions/validations/validates_length_of.rb +0 -15
  72. data/lib/data_mapper/validatable_extensions/validations/validates_numericality_of.rb +0 -7
  73. data/lib/data_mapper/validatable_extensions/validations/validates_presence_of.rb +0 -7
  74. data/lib/data_mapper/validatable_extensions/validations/validates_true_for.rb +0 -7
  75. data/lib/data_mapper/validatable_extensions/validations/validates_uniqueness_of.rb +0 -40
  76. data/lib/data_mapper/validations.rb +0 -20
  77. data/lib/data_mapper/validations/number_validator.rb +0 -40
  78. data/lib/data_mapper/validations/string_validator.rb +0 -20
  79. data/lib/data_mapper/validations/validator.rb +0 -13
  80. data/performance.rb +0 -307
  81. data/plugins/can_has_sphinx/LICENSE +0 -23
  82. data/plugins/can_has_sphinx/README +0 -4
  83. data/plugins/can_has_sphinx/REVISION +0 -1
  84. data/plugins/can_has_sphinx/Rakefile +0 -22
  85. data/plugins/can_has_sphinx/init.rb +0 -1
  86. data/plugins/can_has_sphinx/install.rb +0 -1
  87. data/plugins/can_has_sphinx/lib/acts_as_sphinx.rb +0 -123
  88. data/plugins/can_has_sphinx/lib/sphinx.rb +0 -460
  89. data/plugins/can_has_sphinx/scripts/sphinx.sh +0 -47
  90. data/plugins/can_has_sphinx/tasks/acts_as_sphinx_tasks.rake +0 -41
  91. data/profile_data_mapper.rb +0 -40
  92. data/rakefile.rb +0 -159
  93. data/spec/acts_as_tree_spec.rb +0 -67
  94. data/spec/adapters/data_object_adapter_spec.rb +0 -31
  95. data/spec/associations/belongs_to_association_spec.rb +0 -98
  96. data/spec/associations/has_and_belongs_to_many_association_spec.rb +0 -377
  97. data/spec/associations/has_many_association_spec.rb +0 -337
  98. data/spec/attributes_spec.rb +0 -52
  99. data/spec/auto_migrations_spec.rb +0 -101
  100. data/spec/callbacks_spec.rb +0 -186
  101. data/spec/can_has_sphinx.rb +0 -5
  102. data/spec/coersion_spec.rb +0 -41
  103. data/spec/column_spec.rb +0 -114
  104. data/spec/count_command_spec.rb +0 -45
  105. data/spec/database_spec.rb +0 -18
  106. data/spec/dataobjects_spec.rb +0 -27
  107. data/spec/delete_command_spec.rb +0 -11
  108. data/spec/dependency_spec.rb +0 -29
  109. data/spec/embedded_value_spec.rb +0 -161
  110. data/spec/fixtures/animals.yaml +0 -33
  111. data/spec/fixtures/animals_exhibits.yaml +0 -2
  112. data/spec/fixtures/careers.yaml +0 -5
  113. data/spec/fixtures/comments.yaml +0 -1
  114. data/spec/fixtures/exhibits.yaml +0 -90
  115. data/spec/fixtures/fruit.yaml +0 -6
  116. data/spec/fixtures/people.yaml +0 -37
  117. data/spec/fixtures/posts.yaml +0 -3
  118. data/spec/fixtures/projects.yaml +0 -13
  119. data/spec/fixtures/sections.yaml +0 -5
  120. data/spec/fixtures/serializers.yaml +0 -6
  121. data/spec/fixtures/tasks.yaml +0 -6
  122. data/spec/fixtures/tasks_tasks.yaml +0 -2
  123. data/spec/fixtures/tomatoes.yaml +0 -1
  124. data/spec/fixtures/users.yaml +0 -1
  125. data/spec/fixtures/zoos.yaml +0 -24
  126. data/spec/is_a_tree_spec.rb +0 -149
  127. data/spec/legacy_spec.rb +0 -16
  128. data/spec/load_command_spec.rb +0 -322
  129. data/spec/magic_columns_spec.rb +0 -26
  130. data/spec/migration_spec.rb +0 -267
  131. data/spec/mock_adapter.rb +0 -20
  132. data/spec/models/animal.rb +0 -12
  133. data/spec/models/candidate.rb +0 -8
  134. data/spec/models/career.rb +0 -7
  135. data/spec/models/chain.rb +0 -8
  136. data/spec/models/comment.rb +0 -6
  137. data/spec/models/exhibit.rb +0 -14
  138. data/spec/models/fence.rb +0 -7
  139. data/spec/models/fruit.rb +0 -8
  140. data/spec/models/job.rb +0 -8
  141. data/spec/models/person.rb +0 -30
  142. data/spec/models/post.rb +0 -14
  143. data/spec/models/project.rb +0 -41
  144. data/spec/models/sales_person.rb +0 -5
  145. data/spec/models/section.rb +0 -8
  146. data/spec/models/serializer.rb +0 -5
  147. data/spec/models/task.rb +0 -9
  148. data/spec/models/tomato.rb +0 -27
  149. data/spec/models/user.rb +0 -12
  150. data/spec/models/zoo.rb +0 -13
  151. data/spec/natural_key_spec.rb +0 -36
  152. data/spec/paranoia_spec.rb +0 -38
  153. data/spec/persistence_spec.rb +0 -479
  154. data/spec/postgres_spec.rb +0 -96
  155. data/spec/property_spec.rb +0 -151
  156. data/spec/query_spec.rb +0 -77
  157. data/spec/save_command_spec.rb +0 -94
  158. data/spec/schema_spec.rb +0 -8
  159. data/spec/serialize_spec.rb +0 -19
  160. data/spec/single_table_inheritance_spec.rb +0 -43
  161. data/spec/spec_helper.rb +0 -45
  162. data/spec/support/blank_spec.rb +0 -8
  163. data/spec/support/inflector_spec.rb +0 -41
  164. data/spec/support/object_spec.rb +0 -9
  165. data/spec/support/serialization_spec.rb +0 -61
  166. data/spec/support/silence_spec.rb +0 -15
  167. data/spec/support/string_spec.rb +0 -7
  168. data/spec/support/struct_spec.rb +0 -12
  169. data/spec/support/typed_set_spec.rb +0 -66
  170. data/spec/symbolic_operators_spec.rb +0 -27
  171. data/spec/table_spec.rb +0 -79
  172. data/spec/types/string.rb +0 -81
  173. data/spec/validates_confirmation_of_spec.rb +0 -55
  174. data/spec/validates_format_of_spec.rb +0 -78
  175. data/spec/validates_length_of_spec.rb +0 -117
  176. data/spec/validates_uniqueness_of_spec.rb +0 -92
  177. data/spec/validations/number_validator.rb +0 -59
  178. data/spec/validations/string_validator.rb +0 -14
  179. data/spec/validations_spec.rb +0 -141
  180. data/tasks/fixtures.rb +0 -53
@@ -1,310 +0,0 @@
1
-
2
- module DataMapper
3
-
4
- # :include:/QUICKLINKS
5
- #
6
- # = Properties
7
- # A model's properties are not derived from database structure.
8
- # Instead, properties are declared inside it's model's class definition,
9
- # which map to (or generate) fields in a database.
10
- #
11
- # Defining properties explicitly in a model has several advantages.
12
- # It centralizes information about the model
13
- # in a single location, rather than having to dig out migrations, xml,
14
- # or other config files. It also provides the ability to use Ruby's
15
- # access control functions. Finally, since Datamapper only cares about
16
- # properties explicitly defined in your models, Datamappers plays well
17
- # with legacy databases and shares databases easily with other
18
- # applications.
19
- #
20
- # == Declaring Properties
21
- # Inside your class, you call the property method for each property you want to add.
22
- # The only two required arguments are the name and type, everything else is optional.
23
- #
24
- # class Post < DataMapper::Base
25
- # property :title, :string, :nullable => false # Cannot be null
26
- # property :publish, :boolen, :default => false # Default value for new records
27
- # is false
28
- # end
29
- #
30
- # == Limiting Access
31
- # Property access control is uses the same terminology Ruby does. Properties are
32
- # public by default, but can also be declared private or protected as needed
33
- # (via the :accessor option).
34
- #
35
- # class Post < DataMapper::Base
36
- # property :title, :string, :accessor => :private # Both reader and writer are private
37
- # property :body, :text, :accessor => :protected # Both reader and writer are protected
38
- # end
39
- #
40
- # Access control is also analogous to Ruby getters, setters, and accessors, and can
41
- # be declared using :reader and :writer, in addition to :accessor.
42
- #
43
- # class Post < DataMapper::Base
44
- # property :title, :string, :writer => :private # Only writer is private
45
- # property :tags, :string, :reader => :protected # Only reader is protected
46
- # end
47
- #
48
- # == Overriding Accessors
49
- # The accessor for any property can be overridden in the same manner that Ruby class accessors
50
- # can be. After the property is defined, just add your custom accessor:
51
- #
52
- # class Post < DataMapper::Base
53
- # property :title, :string
54
- #
55
- # def title=(new_title)
56
- # raise ArgumentError if new_title != 'Luke is Awesome'
57
- # @title = new_title
58
- # end
59
- # end
60
- #
61
- # == Lazy Loading
62
- # By default, some properties are not loaded when an object is fetched in Datamapper.
63
- # These lazily loaded properties are fetched on demand when their accessor is called
64
- # for the first time (as it is often unnecessary to instantiate -every- property
65
- # -every- time an object is loaded). For instance, text fields are lazy loading by
66
- # default, although you can over-ride this behavior if you wish:
67
- #
68
- # Example:
69
- #
70
- # class Post < DataMapper::Base
71
- # property :title, :string # Loads normally
72
- # property :body, :text # Is lazily loaded by default
73
- # end
74
- #
75
- # If you want to over-ride the lazy loading on any field you can set it to true or
76
- # false with the :lazy option.
77
- #
78
- # class Post < DataMapper::Base
79
- # property :title, :string # Loads normally
80
- # property :body, :text, :lazy => false # The default is now over-ridden
81
- # end
82
- #
83
- # Delaying the request for lazy-loaded attributes even applies to objects accessed through
84
- # associations. In a sense, Datamapper anticipates that you will likely be iterating
85
- # over objects in associations and rolls all of the load commands for lazy-loaded
86
- # properties into one request from the database.
87
- #
88
- # Example:
89
- #
90
- # Widget[1].components # loads when the post object is pulled from database, by default
91
- # Widget[1].components.first.body # loads the values for the body property on all objects in the
92
- # association, rather than just this one.
93
- #
94
- # == Keys
95
- # Properties can be declared as primary or natural keys on a table. By default,
96
- # Datamapper will assume <tt>:id</tt> and create it if you don't have it.
97
- # You can, however, declare a property as the primary key of the table:
98
- #
99
- # property :legacy_pk, :string, :key => true
100
- #
101
- # This is roughly equivalent to Activerecord's <tt>set_primary_key</tt>, though
102
- # non-integer data types may be used, thus Datamapper supports natural keys.
103
- # When a property is declared as a natural key, accessing the object using the
104
- # indexer syntax <tt>Class[key]</tt> remains valid.
105
- #
106
- # User[1] when :id is the primary key on the users table
107
- # User['bill'] when :name is the primary (natural) key on the users table
108
- #
109
- # == Inferred Validations
110
- # When properties are declared with specific column restrictions, Datamapper
111
- # will infer a few validation rules for values assigned to that property.
112
- #
113
- # property :title, :string, :length => 250
114
- # # => infers 'validates_length_of :title, :minimum => 0, :maximum => 250'
115
- #
116
- # property :title, :string, :nullable => false
117
- # # => infers 'validates_presence_of :title
118
- #
119
- # property :email, :string, :format => :email_address
120
- # # => infers 'validates_format_of :email, :with => :email_address
121
- #
122
- # property :title, :string, :length => 255, :nullable => false
123
- # # => infers both 'validates_length_of' as well as 'validates_presence_of'
124
- # # better: property :title, :string, :length => 1..255
125
- #
126
- # For more information about validations, visit the Validatable documentation.
127
- # == Embedded Values
128
- # As an alternative to extraneous has_one relationships, consider using an
129
- # EmbeddedValue.
130
- #
131
- # == Misc. Notes
132
- # * Properties declared as strings will default to a length of 50, rather than 255
133
- # (typical max varchar column size). To overload the default, pass
134
- # <tt>:length => 255</tt> or <tt>:length => 0..255</tt>. Since Datamapper does
135
- # not introspect for properties, this means that legacy database tables may need
136
- # their <tt>:string</tt> columns defined with a <tt>:length</tt> so that DM does
137
- # not inadvertantly truncate data.
138
- # * You may declare a Property with the data-type of <tt>:class</tt>.
139
- # see SingleTableInheritance for more on how to use <tt>:class</tt> columns.
140
- class Property
141
-
142
- # NOTE: check is only for psql, so maybe the postgres adapter should define
143
- # its own property options. currently it will produce a warning tho since
144
- # PROPERTY_OPTIONS is a constant
145
- PROPERTY_OPTIONS = [
146
- :public, :protected, :private, :accessor, :reader, :writer,
147
- :lazy, :default, :nullable, :key, :serial, :column, :size, :length,
148
- :format, :index, :check, :ordinal, :auto_validation
149
- ]
150
-
151
- VISIBILITY_OPTIONS = [:public, :protected, :private]
152
-
153
- def initialize(klass, name, type, options)
154
-
155
- @klass, @name, @type, @options = klass, name.to_sym, type, options
156
- @symbolized_name = name.to_s.sub(/\?$/, '').to_sym
157
-
158
- validate_type!
159
- validate_options!
160
- determine_visibility!
161
-
162
- database.schema[klass].add_column(@symbolized_name, @type, @options)
163
- klass::ATTRIBUTES << @symbolized_name
164
-
165
- create_getter!
166
- create_setter!
167
- auto_validations! unless @options[:auto_validation] == false
168
-
169
- end
170
-
171
- def validate_type! # :nodoc:
172
- adapter_class = database.adapter.class
173
- raise ArgumentError.new("#{@type.inspect} is not a supported type in the database adapter. Valid types are:\n #{adapter_class::TYPES.keys.inspect}") unless adapter_class::TYPES.has_key?(@type)
174
- end
175
-
176
- def validate_options! # :nodoc:
177
- @options.each_pair do |k,v|
178
- raise ArgumentError.new("#{k.inspect} is not a supported option in DataMapper::Property::PROPERTY_OPTIONS") unless PROPERTY_OPTIONS.include?(k)
179
- end
180
- end
181
-
182
- def determine_visibility! # :nodoc:
183
- @reader_visibility = @options[:reader] || @options[:accessor] || :public
184
- @writer_visibility = @options[:writer] || @options[:accessor] || :public
185
- @writer_visibility = :protected if @options[:protected]
186
- @writer_visibility = :private if @options[:private]
187
- raise(ArgumentError.new, "property visibility must be :public, :protected, or :private") unless VISIBILITY_OPTIONS.include?(@reader_visibility) && VISIBILITY_OPTIONS.include?(@writer_visibility)
188
- end
189
-
190
- # defines the getter for the property
191
- def create_getter!
192
- if lazy?
193
- klass.class_eval <<-EOS
194
- #{reader_visibility.to_s}
195
- def #{name}
196
- lazy_load!(#{name.inspect})
197
- class << self;
198
- attr_accessor #{name.inspect}
199
- end
200
- @#{name}
201
- end
202
- EOS
203
- else
204
- klass.class_eval <<-EOS
205
- #{reader_visibility.to_s}
206
- def #{name}
207
- #{instance_variable_name}
208
- end
209
- EOS
210
- end
211
- if type == :boolean
212
- klass.class_eval <<-EOS
213
- #{reader_visibility.to_s}
214
- def #{name.to_s.ensure_ends_with('?')}
215
- #{instance_variable_name}
216
- end
217
- EOS
218
- end
219
- rescue SyntaxError
220
- raise SyntaxError.new(column)
221
- end
222
-
223
- # defines the setter for the property
224
- def create_setter!
225
- if lazy?
226
- klass.class_eval <<-EOS
227
- #{writer_visibility.to_s}
228
- def #{name}=(value)
229
- class << self;
230
- attr_accessor #{name.inspect}
231
- end
232
- @#{name} = value
233
- end
234
- EOS
235
- else
236
- klass.class_eval <<-EOS
237
- #{writer_visibility.to_s}
238
- def #{name}=(value)
239
- #{instance_variable_name} = value
240
- end
241
- EOS
242
- end
243
- rescue SyntaxError
244
- raise SyntaxError.new(column)
245
- end
246
-
247
- # NOTE: :length may also be used in place of :size
248
- AUTO_VALIDATIONS = {
249
- :nullable => lambda { |k,v| "validates_presence_of :#{k}" if v == false },
250
- :size => lambda { |k,v| "validates_length_of :#{k}, " + (v.is_a?(Range) ? ":within => #{v}" : ":maximum => #{v}") },
251
- :format => lambda { |k, v| "validates_format_of :#{k}, :with => #{v.inspect}" }
252
- }
253
-
254
- AUTO_VALIDATIONS[:length] = AUTO_VALIDATIONS[:size].dup
255
-
256
- # defines the inferred validations given a property definition.
257
- def auto_validations!
258
- AUTO_VALIDATIONS.each do |key, value|
259
- next unless options.has_key?(key)
260
- validation = value.call(name, options[key])
261
- next if validation.nil? or validation.empty?
262
- klass.class_eval <<-EOS
263
- begin
264
- #{validation}
265
- rescue ArgumentError => e
266
- throw e unless e.message =~ /specify a unique key/
267
- end
268
- EOS
269
- end
270
- end
271
-
272
- def klass
273
- @klass
274
- end
275
-
276
- def column
277
- column = database.table(klass)[@name]
278
- raise StandardError.new("#{@name.inspect} is not a valid column name") unless column
279
- return column
280
- end
281
-
282
- def name
283
- @name
284
- end
285
-
286
- def instance_variable_name # :nodoc:
287
- column.instance_variable_name
288
- end
289
-
290
- def type
291
- column.type
292
- end
293
-
294
- def options
295
- column.options
296
- end
297
-
298
- def reader_visibility # :nodoc:
299
- @reader_visibility
300
- end
301
-
302
- def writer_visibility # :nodoc:
303
- @writer_visibility
304
- end
305
-
306
- def lazy?
307
- column.lazy?
308
- end
309
- end
310
- end
@@ -1,164 +0,0 @@
1
- module DataMapper
2
-
3
- # This class handles option parsing and SQL generation.
4
- class Query
5
-
6
- # These are the standard finder options
7
- OPTIONS = [
8
- :select, :offset, :limit, :include, :reload, :conditions, :join, :order, :after_row_materialization
9
- ]
10
-
11
- def initialize(adapter, klass, options = {})
12
- # Set some of the standard options
13
- @adapter, @klass = adapter, klass
14
- @from = @adapter.table(@klass)
15
- @parameters = []
16
- @joins = []
17
-
18
- # Parse simple options
19
- @limit = options.fetch(:limit, nil)
20
- @offset = options.fetch(:offset, nil)
21
- @reload = options.fetch(:reload, false)
22
- @order = options.fetch(:order, nil)
23
- @after_row_materialization = options.fetch(:after_row_materialization, nil)
24
-
25
- # Parse :include option
26
- @includes = case include_options = options[:include]
27
- when Array then include_options.dup
28
- when Symbol then [include_options]
29
- when NilClass then []
30
- else raise ArgumentError.new(":include must be an Array, Symbol or nil, but was #{include_options.inspect}")
31
- end
32
-
33
- # Include lazy columns if specified in :include option
34
- @columns = @from.columns.select do |column|
35
- !column.lazy? || @includes.delete(column.name)
36
- end
37
-
38
- # Qualify columns with their table name if joins are present
39
- @qualify = !@includes.empty?
40
-
41
- # Generate SQL for joins
42
- @includes.each do |association_name|
43
- association = @from.associations[association_name]
44
- @joins << association.to_sql
45
- @columns += association.associated_table.columns.select do |column|
46
- !column.lazy?
47
- end
48
- end
49
-
50
- # Prepare conditions for parsing
51
- @conditions = []
52
-
53
- # Each non-standard option is assumed to be a column
54
- options.each_pair do |k,v|
55
- unless OPTIONS.include?(k)
56
- append_condition(k, v)
57
- end
58
- end
59
-
60
- # If a :conditions option is present, parse it
61
- if conditions_option = options[:conditions]
62
- if conditions_option.is_a?(String)
63
- @conditions << conditions_option
64
- else
65
- append_condition(*conditions_option)
66
- end
67
- end
68
-
69
- # If the table is paranoid, add a filter to the conditions
70
- if @from.paranoid?
71
- @conditions << "#{@from.paranoid_column.to_sql(qualify?)} IS NULL OR #{@from.paranoid_column.to_sql(qualify?)} > #{@adapter.class::SYNTAX[:now]}"
72
- end
73
-
74
- end
75
-
76
- # SQL for query
77
- def to_sql
78
- sql = "SELECT #{columns.map { |column| column.to_sql(qualify?) }.join(', ')} FROM #{from.to_sql}"
79
-
80
- sql << " " << joins.join($/) unless joins.empty?
81
- sql << " WHERE (#{conditions.join(") AND (")})" unless conditions.empty?
82
- return sql
83
- end
84
-
85
- # Parameters for query
86
- def parameters
87
- @parameters
88
- end
89
-
90
- private
91
-
92
- # Conditions for the query, in the form of an Array of Strings
93
- def conditions
94
- @conditions
95
- end
96
-
97
- # Determines wether columns should be qualified with their table-names.
98
- def qualify?
99
- @qualify
100
- end
101
-
102
- # The primary table in the FROM clause of the query
103
- def from
104
- @from
105
- end
106
-
107
- # SQL for any joins in the query
108
- def joins
109
- @joins
110
- end
111
-
112
- # Column mappings to be selected
113
- def columns
114
- @columns
115
- end
116
-
117
- def append_condition(clause, value)
118
- case clause
119
- when Symbol::Operator then
120
- operator = case clause.type
121
- when :gt then '>'
122
- when :gte then '>='
123
- when :lt then '<'
124
- when :lte then '<='
125
- when :not then inequality_operator(value)
126
- when :eql then equality_operator(value)
127
- when :like then equality_operator(value, 'LIKE')
128
- when :in then equality_operator(value)
129
- else raise ArgumentError.new('Operator type not supported')
130
- end
131
- @conditions << "#{from[clause].to_sql(qualify?)} #{operator} ?"
132
- @parameters << value
133
- when Symbol then
134
- @conditions << "#{from[clause].to_sql(qualify?)} #{equality_operator(value)} ?"
135
- @parameters << value
136
- when String then
137
- @conditions << clause
138
- value.each { |v| @parameters << v }
139
- when Mappings::Column then
140
- @conditions << "#{clause.to_sql(qualify?)} #{equality_operator(value)} ?"
141
- @parameters << value
142
- else raise "CAN HAS CRASH? #{clause.inspect}"
143
- end
144
- end
145
-
146
- def equality_operator(value, default = '=')
147
- case value
148
- when NilClass then 'IS'
149
- when Array then 'IN'
150
- else default
151
- end
152
- end
153
-
154
- def inequality_operator(value, default = '<>')
155
- case value
156
- when NilClass then 'IS NOT'
157
- when Array then 'NOT IN'
158
- else default
159
- end
160
- end
161
-
162
-
163
- end # class Query
164
- end # module DataMapper