cequel 0.5.6 → 1.0.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. checksums.yaml +7 -0
  2. data/lib/cequel.rb +5 -8
  3. data/lib/cequel/errors.rb +1 -0
  4. data/lib/cequel/metal.rb +17 -0
  5. data/lib/cequel/metal/batch.rb +62 -0
  6. data/lib/cequel/metal/cql_row_specification.rb +26 -0
  7. data/lib/cequel/metal/data_set.rb +461 -0
  8. data/lib/cequel/metal/deleter.rb +47 -0
  9. data/lib/cequel/metal/incrementer.rb +35 -0
  10. data/lib/cequel/metal/inserter.rb +53 -0
  11. data/lib/cequel/metal/keyspace.rb +213 -0
  12. data/lib/cequel/metal/row.rb +48 -0
  13. data/lib/cequel/metal/row_specification.rb +37 -0
  14. data/lib/cequel/metal/statement.rb +30 -0
  15. data/lib/cequel/metal/updater.rb +65 -0
  16. data/lib/cequel/metal/writer.rb +73 -0
  17. data/lib/cequel/model.rb +12 -84
  18. data/lib/cequel/model/association_collection.rb +23 -0
  19. data/lib/cequel/model/associations.rb +84 -80
  20. data/lib/cequel/model/base.rb +74 -0
  21. data/lib/cequel/model/belongs_to_association.rb +31 -0
  22. data/lib/cequel/model/callbacks.rb +14 -10
  23. data/lib/cequel/model/collection.rb +255 -0
  24. data/lib/cequel/model/errors.rb +6 -6
  25. data/lib/cequel/model/has_many_association.rb +26 -0
  26. data/lib/cequel/model/mass_assignment.rb +31 -0
  27. data/lib/cequel/model/persistence.rb +119 -115
  28. data/lib/cequel/model/properties.rb +89 -87
  29. data/lib/cequel/model/railtie.rb +21 -14
  30. data/lib/cequel/model/record_set.rb +285 -0
  31. data/lib/cequel/model/schema.rb +33 -0
  32. data/lib/cequel/model/scoped.rb +5 -48
  33. data/lib/cequel/model/validations.rb +18 -18
  34. data/lib/cequel/schema.rb +15 -0
  35. data/lib/cequel/schema/column.rb +135 -0
  36. data/lib/cequel/schema/create_table_dsl.rb +56 -0
  37. data/lib/cequel/schema/keyspace.rb +50 -0
  38. data/lib/cequel/schema/table.rb +120 -0
  39. data/lib/cequel/schema/table_property.rb +67 -0
  40. data/lib/cequel/schema/table_reader.rb +139 -0
  41. data/lib/cequel/schema/table_synchronizer.rb +114 -0
  42. data/lib/cequel/schema/table_updater.rb +83 -0
  43. data/lib/cequel/schema/table_writer.rb +80 -0
  44. data/lib/cequel/schema/update_table_dsl.rb +60 -0
  45. data/lib/cequel/type.rb +232 -0
  46. data/lib/cequel/version.rb +1 -1
  47. data/spec/environment.rb +5 -1
  48. data/spec/examples/metal/data_set_spec.rb +608 -0
  49. data/spec/examples/model/associations_spec.rb +84 -74
  50. data/spec/examples/model/callbacks_spec.rb +66 -59
  51. data/spec/examples/model/list_spec.rb +393 -0
  52. data/spec/examples/model/map_spec.rb +229 -0
  53. data/spec/examples/model/mass_assignment_spec.rb +55 -0
  54. data/spec/examples/model/naming_spec.rb +11 -4
  55. data/spec/examples/model/persistence_spec.rb +140 -150
  56. data/spec/examples/model/properties_spec.rb +122 -75
  57. data/spec/examples/model/record_set_spec.rb +285 -0
  58. data/spec/examples/model/schema_spec.rb +44 -0
  59. data/spec/examples/model/serialization_spec.rb +20 -14
  60. data/spec/examples/model/set_spec.rb +133 -0
  61. data/spec/examples/model/spec_helper.rb +0 -10
  62. data/spec/examples/model/validations_spec.rb +51 -38
  63. data/spec/examples/schema/table_reader_spec.rb +328 -0
  64. data/spec/examples/schema/table_synchronizer_spec.rb +172 -0
  65. data/spec/examples/schema/table_updater_spec.rb +157 -0
  66. data/spec/examples/schema/table_writer_spec.rb +225 -0
  67. data/spec/examples/spec_helper.rb +29 -0
  68. data/spec/examples/type_spec.rb +204 -0
  69. data/spec/support/helpers.rb +67 -8
  70. metadata +121 -152
  71. data/lib/cequel/batch.rb +0 -58
  72. data/lib/cequel/cql_row_specification.rb +0 -22
  73. data/lib/cequel/data_set.rb +0 -371
  74. data/lib/cequel/keyspace.rb +0 -205
  75. data/lib/cequel/model/class_internals.rb +0 -49
  76. data/lib/cequel/model/column.rb +0 -20
  77. data/lib/cequel/model/counter.rb +0 -35
  78. data/lib/cequel/model/dictionary.rb +0 -126
  79. data/lib/cequel/model/dirty.rb +0 -53
  80. data/lib/cequel/model/dynamic.rb +0 -31
  81. data/lib/cequel/model/inheritable.rb +0 -48
  82. data/lib/cequel/model/instance_internals.rb +0 -23
  83. data/lib/cequel/model/local_association.rb +0 -42
  84. data/lib/cequel/model/magic.rb +0 -79
  85. data/lib/cequel/model/mass_assignment_security.rb +0 -21
  86. data/lib/cequel/model/naming.rb +0 -17
  87. data/lib/cequel/model/observer.rb +0 -42
  88. data/lib/cequel/model/readable_dictionary.rb +0 -182
  89. data/lib/cequel/model/remote_association.rb +0 -40
  90. data/lib/cequel/model/scope.rb +0 -362
  91. data/lib/cequel/model/subclass_internals.rb +0 -45
  92. data/lib/cequel/model/timestamps.rb +0 -52
  93. data/lib/cequel/model/translation.rb +0 -17
  94. data/lib/cequel/row_specification.rb +0 -63
  95. data/lib/cequel/statement.rb +0 -23
  96. data/spec/examples/data_set_spec.rb +0 -444
  97. data/spec/examples/keyspace_spec.rb +0 -84
  98. data/spec/examples/model/counter_spec.rb +0 -94
  99. data/spec/examples/model/dictionary_spec.rb +0 -301
  100. data/spec/examples/model/dirty_spec.rb +0 -39
  101. data/spec/examples/model/dynamic_spec.rb +0 -41
  102. data/spec/examples/model/inheritable_spec.rb +0 -45
  103. data/spec/examples/model/magic_spec.rb +0 -199
  104. data/spec/examples/model/mass_assignment_security_spec.rb +0 -13
  105. data/spec/examples/model/observer_spec.rb +0 -86
  106. data/spec/examples/model/scope_spec.rb +0 -677
  107. data/spec/examples/model/timestamps_spec.rb +0 -52
  108. data/spec/examples/model/translation_spec.rb +0 -23
@@ -1,40 +0,0 @@
1
- module Cequel
2
-
3
- module Model
4
-
5
- class RemoteAssociation
6
-
7
- attr_reader :name, :class_name, :dependent
8
-
9
- def initialize(name, owning_class, options)
10
- @name, @owning_class = name, owning_class
11
- @class_name = options[:class_name] || name.to_s.classify.to_sym
12
- @foreign_key_name = options[:foreign_key]
13
- @dependent = options[:dependent]
14
- end
15
-
16
- def scope(instance)
17
- clazz.where(foreign_key_name => instance.__send__(primary_key_name))
18
- end
19
-
20
- def primary_key
21
- @primary_key ||= @owning_class.key_column
22
- end
23
-
24
- def primary_key_name
25
- @primary_key_name ||= primary_key.name
26
- end
27
-
28
- def foreign_key_name
29
- @foreign_key_name ||= :"#{@owning_class.name.underscore}_id"
30
- end
31
-
32
- def clazz
33
- @clazz ||= class_name.to_s.constantize
34
- end
35
-
36
- end
37
-
38
- end
39
-
40
- end
@@ -1,362 +0,0 @@
1
- module Cequel
2
-
3
- module Model
4
-
5
- class Scope < BasicObject
6
-
7
- include ::Enumerable
8
-
9
- def initialize(clazz, data_sets)
10
- @clazz, @data_sets = clazz, data_sets
11
- @index_preference_applied = false
12
- end
13
-
14
- def each(&block)
15
- if block
16
- each_row do |row|
17
- result = hydrate(row)
18
- yield result if result
19
- end
20
- else
21
- ::Enumerator.new(self, :each)
22
- end
23
- end
24
-
25
- def each_row(&block)
26
- if block
27
- apply_index_preference!
28
- @data_sets.each do |data_set|
29
- data_set.each(&block)
30
- end
31
- else
32
- ::Enumerator.new(self, :each_row)
33
- end
34
- end
35
-
36
- def find_in_batches(options = {})
37
- unless ::Kernel.block_given?
38
- return ::Enumerator.new(self, :find_in_batches, options)
39
- end
40
- find_rows_in_batches(options) do |batch|
41
- results = batch.map { |row| hydrate(row) }.compact
42
- yield results if results.any?
43
- end
44
- end
45
-
46
- def find_rows_in_batches(options = {}, &block)
47
- return ::Enumerator.new(self, :find_rows_in_batches, options) if block.nil?
48
- batch_size = options[:batch_size] || 1000
49
- apply_index_preference!
50
- @data_sets.each do |data_set|
51
- keys = lookup_keys(data_set)
52
- if keys
53
- find_rows_in_key_batches(data_set, keys, batch_size, &block)
54
- else
55
- find_rows_in_range_batches(data_set, batch_size, &block)
56
- end
57
- end
58
- nil
59
- end
60
-
61
- def find_each(options = {}, &block)
62
- unless ::Kernel.block_given?
63
- return ::Enumerator.new(self, :find_each, options)
64
- end
65
- find_in_batches(options) { |batch| batch.each(&block) }
66
- end
67
-
68
- def find_each_row(options = {}, &block)
69
- unless ::Kernel.block_given?
70
- return ::Enumerator.new(self, :find_each_row, options)
71
- end
72
- find_rows_in_batches(options) { |batch| batch.each(&block) }
73
- end
74
-
75
- def first
76
- apply_index_preference!
77
- @data_sets.each do |data_set|
78
- row = hydrate(data_set.first)
79
- return row if row
80
- end
81
- nil
82
- end
83
-
84
- def count
85
- if restriction_columns == [@clazz.key_alias]
86
- ::Kernel.raise ::Cequel::Model::InvalidQuery,
87
- "Meaningless to perform count with key row restrictions"
88
- end
89
- apply_index_preference!
90
- @data_sets.inject(0) { |count, data_set| count + data_set.count }
91
- end
92
-
93
- def size
94
- count
95
- end
96
-
97
- def length
98
- to_a.length
99
- end
100
-
101
- def update_all(changes)
102
- keys = keys()
103
- unless keys.empty?
104
- @clazz.column_family.where(key_alias => keys).update(changes)
105
- end
106
- end
107
-
108
- def destroy_all
109
- each { |instance| instance.destroy }
110
- end
111
-
112
- def delete_all
113
- if @data_sets.length == 1
114
- if @data_sets.first.row_specifications.length == 0
115
- return @data_sets.first.truncate
116
- end
117
- end
118
- keys = keys()
119
- if keys.empty?
120
- @data_sets.each { |data_set| data_set.delete }
121
- else
122
- @clazz.column_family.where(key_alias => keys).delete
123
- end
124
- end
125
-
126
- def find(*keys, &block)
127
- if block then super
128
- else with_scope(self) { @clazz.find(*keys) }
129
- end
130
- end
131
-
132
- def any?(&block)
133
- if block then super
134
- else count > 0
135
- end
136
- end
137
-
138
- def none?(&block)
139
- if block then super
140
- else empty?
141
- end
142
- end
143
-
144
- def empty?
145
- count == 0
146
- end
147
-
148
- def one?(&block)
149
- if block then super
150
- else count == 1
151
- end
152
- end
153
-
154
- def keys
155
- key_alias = @clazz.key_alias
156
- [].tap do |keys|
157
- @data_sets.each do |data_set|
158
- lookup_keys = lookup_keys(data_set)
159
- if lookup_keys
160
- keys.concat(lookup_keys)
161
- next
162
- end
163
- data_set.select!(key_alias).each { |row| keys << row[key_alias] }
164
- end
165
- end
166
- end
167
-
168
- def lookup_keys(data_set)
169
- if data_set.row_specifications.length == 1
170
- specification = data_set.row_specifications.first
171
- if specification.respond_to?(:column)
172
- if specification.column == key_alias
173
- ::Kernel.Array(specification.value)
174
- end
175
- end
176
- end
177
- end
178
-
179
- def inspect
180
- to_a.inspect
181
- end
182
-
183
- def ==(other)
184
- to_a == other.to_a
185
- end
186
-
187
- def select(*rows, &block)
188
- if block then super
189
- else scoped { |data_set| data_set.select(*rows) }.validate!
190
- end
191
- end
192
-
193
- def select!(*rows)
194
- scoped { |data_set| data_set.select!(*rows) }.validate!
195
- end
196
-
197
- def consistency(consistency)
198
- scoped { |data_set| data_set.consistency(consistency) }
199
- end
200
-
201
- def where(*row_specification)
202
- if row_specification.length == 1 && ::Hash === row_specification.first
203
- row_specification.first.each_pair.inject(self) do |scope, (column, value)|
204
- scope.where_column_equals(column, value)
205
- end
206
- else
207
- scoped { |data_set| data_set.where(*row_specification) }
208
- end
209
- end
210
-
211
- def where!(*row_specification)
212
- scoped { |data_set| data_set.where!(*row_specification) }
213
- end
214
-
215
- def limit(*row_specification)
216
- scoped { |data_set| data_set.limit(*row_specification) }
217
- end
218
-
219
- def scoped(&block)
220
- new_data_sets = @data_sets.map(&block)
221
- Scope.new(@clazz, new_data_sets)
222
- end
223
-
224
- def nil?
225
- false # for ActiveSupport delegation
226
- end
227
-
228
- def method_missing(method, *args, &block)
229
- if @clazz.respond_to?(method)
230
- @clazz.with_scope(self) do
231
- @clazz.__send__(method, *args, &block)
232
- end
233
- else
234
- super
235
- end
236
- end
237
-
238
- protected
239
-
240
- def validate!
241
- columns = restriction_columns
242
- key_column = restriction_columns.include?(@clazz.key_alias)
243
- non_key_column = restriction_columns.any? do |column|
244
- column != @clazz.key_alias
245
- end
246
- if key_column
247
- if non_key_column
248
- ::Kernel.raise InvalidQuery,
249
- "Can't select by key and non-key columns in the same query"
250
- elsif key_only_select?
251
- ::Kernel.raise InvalidQuery,
252
- "Meaningless to select only key column with key row specification"
253
- end
254
- end
255
- self
256
- end
257
-
258
- def where_column_equals(column, value)
259
- if [] == value
260
- Scope.new(@clazz, [])
261
- elsif column.to_sym != @clazz.key_alias && ::Array === value
262
- new_data_sets = []
263
- @data_sets.each do |data_set|
264
- value.each do |element|
265
- new_data_sets << data_set.where(column => element)
266
- end
267
- end
268
- Scope.new(@clazz, new_data_sets)
269
- else
270
- scoped { |data_set| data_set.where(column => value) }
271
- end.validate!
272
- end
273
-
274
- private
275
-
276
- def find_rows_in_range_batches(data_set, batch_size)
277
- key_alias = @clazz.key_alias
278
- key_alias = key_alias.upcase if key_alias =~ /key/i
279
- scope = data_set.limit(batch_size)
280
- unless data_set.select_columns.empty? ||
281
- data_set.select_columns.include?(key_alias)
282
-
283
- scope = scope.select(key_alias)
284
- end
285
-
286
- batch_scope = scope
287
- last_key = nil
288
- begin
289
- batch_rows = batch_scope.to_a
290
- break if batch_rows.empty?
291
- if batch_rows.first[key_alias] == last_key
292
- yield batch_rows[1..-1]
293
- else
294
- yield batch_rows
295
- end
296
- last_key = batch_rows.last[key_alias]
297
- batch_scope =
298
- scope.where("? > ?", key_alias, last_key)
299
- end while batch_rows.length == batch_size
300
- end
301
-
302
- def find_rows_in_key_batches(data_set, keys, batch_size)
303
- key_alias = @clazz.key_alias
304
- keys.each_slice(batch_size) do |key_slice|
305
- yield data_set.where!(key_alias => key_slice).to_a
306
- end
307
- end
308
-
309
- def key_only_select?
310
- key_only_select = @data_sets.all? do |data_set|
311
- data_set.select_columns == [@clazz.key_alias]
312
- end
313
- end
314
-
315
- def restriction_columns
316
- [].tap do |columns|
317
- @data_sets.each do |data_set|
318
- data_set.row_specifications.each do |specification|
319
- if specification.respond_to?(:column)
320
- columns << specification.column
321
- end
322
- end
323
- end
324
- end
325
- end
326
-
327
- def hydrate(row)
328
- return if row.nil?
329
- key_alias = @clazz.key_alias.to_s
330
- key_alias = key_alias.upcase if key_alias =~ /^key$/i
331
- row.reject! { |k, v| v.nil? }
332
- if row.keys.any? && (key_only_select? || row.keys != [key_alias])
333
- @clazz._hydrate(row)
334
- end
335
- end
336
-
337
- def apply_index_preference!
338
- return if @index_preference_applied
339
- # XXX seems ugly to do the in-place sort here.
340
- preference = @clazz.index_preference_columns
341
- @data_sets.each do |data_set|
342
- data_set.row_specifications.sort! do |spec1, spec2|
343
- if spec1.respond_to?(:column) && spec2.respond_to?(:column)
344
- pref1 = preference.index(spec1.column)
345
- pref2 = preference.index(spec2.column)
346
- if pref1 && pref2 then pref1 - pref2
347
- elsif pref1 then -1
348
- elsif pref2 then 1
349
- else 0
350
- end
351
- else 0
352
- end
353
- end
354
- end
355
- @index_preference_applied = true
356
- end
357
-
358
- end
359
-
360
- end
361
-
362
- end
@@ -1,45 +0,0 @@
1
- module Cequel
2
-
3
- module Model
4
-
5
- class SubclassInternals < ClassInternals
6
-
7
- def initialize(clazz, super_internals)
8
- super(clazz)
9
- @super = super_internals
10
- @columns = {}
11
- end
12
-
13
- def index_preference
14
- @super.index_preference + @index_preference
15
- end
16
-
17
- def key
18
- @super.key
19
- end
20
-
21
- def columns
22
- @super.columns.merge(@columns)
23
- end
24
-
25
- def type_column
26
- @super.type_column
27
- end
28
-
29
- def column_family_name
30
- @super.column_family_name
31
- end
32
-
33
- def base_class
34
- @super.base_class
35
- end
36
-
37
- def associations
38
- @super.associations.merge(super)
39
- end
40
-
41
- end
42
-
43
- end
44
-
45
- end
@@ -1,52 +0,0 @@
1
- module Cequel
2
-
3
- module Model
4
-
5
- module Timestamps
6
-
7
- extend ActiveSupport::Concern
8
-
9
- included do
10
- include CreatedAt
11
- include UpdatedAt
12
- end
13
-
14
- module CreatedAt
15
-
16
- extend ActiveSupport::Concern
17
-
18
- included do
19
- column :created_at, :timestamp
20
- before_create :_set_created_at
21
- end
22
-
23
- private
24
-
25
- def _set_created_at
26
- self.created_at = Time.now
27
- end
28
-
29
- end
30
-
31
- module UpdatedAt
32
-
33
- extend ActiveSupport::Concern
34
-
35
- included do
36
- column :updated_at, :timestamp
37
- before_save :_set_updated_at
38
- end
39
-
40
- private
41
-
42
- def _set_updated_at
43
- self.updated_at = Time.now if transient? || changed?
44
- end
45
-
46
- end
47
-
48
- end
49
-
50
- end
51
-
52
- end