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
@@ -0,0 +1,74 @@
1
+ module Cequel
2
+
3
+ module Model
4
+
5
+ class Base
6
+
7
+ include Cequel::Model::Properties
8
+ include Cequel::Model::Schema
9
+ include Cequel::Model::Persistence
10
+ include Cequel::Model::Associations
11
+ extend Cequel::Model::Scoped
12
+ include Cequel::Model::MassAssignment
13
+ include Cequel::Model::Callbacks
14
+ include Cequel::Model::Validations
15
+ extend ActiveModel::Naming
16
+ include ActiveModel::Serializers::JSON
17
+ include ActiveModel::Serializers::Xml
18
+
19
+ class_attribute :table_name, :connection, :default_attributes,
20
+ :instance_writer => false
21
+
22
+ def self.inherited(base)
23
+ base.table_name = base.name.tableize.to_sym unless base.name.nil?
24
+ base.default_attributes = {}
25
+ end
26
+
27
+ def self.establish_connection(configuration)
28
+ self.connection = Cequel.connect(configuration)
29
+ end
30
+
31
+ class <<self; alias_method :new_empty, :new; end
32
+ def self.new(*args, &block)
33
+ new_empty.tap do |record|
34
+ record.__send__(:initialize_new_record, *args)
35
+ yield record if block_given?
36
+ end
37
+ end
38
+
39
+ def initialize(&block)
40
+ @attributes, @collection_proxies = {}, {}
41
+ instance_eval(&block) if block
42
+ end
43
+
44
+ def inspect
45
+ inspected_attributes = attributes.each_pair.map do |attr, value|
46
+ inspected_value = value.is_a?(CassandraCQL::UUID) ?
47
+ value.to_guid :
48
+ value.inspect
49
+ "#{attr}: #{inspected_value}"
50
+ end
51
+ "#<#{self.class} #{inspected_attributes.join(", ")}>"
52
+ end
53
+
54
+ protected
55
+ attr_reader :collection_proxies
56
+
57
+ private
58
+
59
+ def initialize_new_record(attributes = {})
60
+ @attributes = Marshal.load(Marshal.dump(default_attributes))
61
+ @new_record = true
62
+ yield self if block_given?
63
+ self.attributes = attributes #XXX this should really be in Properties
64
+ loaded!
65
+ self
66
+ end
67
+
68
+ end
69
+
70
+ end
71
+
72
+ Base = Model::Base
73
+
74
+ end
@@ -0,0 +1,31 @@
1
+ module Cequel
2
+
3
+ module Model
4
+
5
+ class BelongsToAssociation
6
+
7
+ extend Forwardable
8
+
9
+ attr_reader :owner_class, :name, :association_class_name
10
+
11
+ def_delegator :association_class, :key_columns, :association_key_columns
12
+
13
+ def initialize(owner_class, name, options = {})
14
+ @owner_class, @name = owner_class, name.to_sym
15
+ @association_class_name =
16
+ options.fetch(:class_name, @name.to_s.classify)
17
+ end
18
+
19
+ def association_class
20
+ @association_class ||= association_class_name.constantize
21
+ end
22
+
23
+ def instance_variable_name
24
+ @instance_variable_name ||= :"@#{name}"
25
+ end
26
+
27
+ end
28
+
29
+ end
30
+
31
+ end
@@ -6,25 +6,29 @@ module Cequel
6
6
 
7
7
  extend ActiveSupport::Concern
8
8
 
9
- HOOKS = [:save, :create, :update, :destroy, :validation]
10
- CALLBACKS = HOOKS.map { |hook| [:"before_#{hook}", :"after_#{hook}"] }.
11
- flatten
12
-
13
9
  included do
14
10
  extend ActiveModel::Callbacks
15
- define_model_callbacks *HOOKS
11
+ define_model_callbacks :save, :create, :update, :destroy
16
12
  end
17
13
 
18
- def save(*args)
19
- run_callbacks(:save) do
20
- run_callbacks(persisted? ? :update : :create) { super }
21
- end
14
+ def save(options = {})
15
+ run_callbacks(:save) { super }
22
16
  end
23
17
 
24
- def destroy(*args)
18
+ def destroy
25
19
  run_callbacks(:destroy) { super }
26
20
  end
27
21
 
22
+ protected
23
+
24
+ def create
25
+ run_callbacks(:create) { super }
26
+ end
27
+
28
+ def update
29
+ run_callbacks(:update) { super }
30
+ end
31
+
28
32
  end
29
33
 
30
34
  end
@@ -0,0 +1,255 @@
1
+ require 'delegate'
2
+
3
+ module Cequel
4
+
5
+ module Model
6
+
7
+ module Collection
8
+
9
+ extend ActiveSupport::Concern
10
+ extend Forwardable
11
+
12
+ def_delegators :@model, :loaded?, :updater, :deleter
13
+
14
+ attr_reader :column_name
15
+
16
+ included do
17
+ private
18
+ define_method(
19
+ :method_missing,
20
+ BasicObject.instance_method(:method_missing))
21
+ end
22
+
23
+ def initialize(model, column_name)
24
+ @model, @column_name = model, column_name
25
+ end
26
+
27
+ def inspect
28
+ __getobj__.inspect
29
+ end
30
+
31
+ def loaded!
32
+ modifications.each { |modification| modification.() }.clear
33
+ end
34
+
35
+ def persisted!
36
+ modifications.clear
37
+ end
38
+
39
+ protected
40
+
41
+ def __getobj__
42
+ @model.__send__(:read_attribute, @column_name) ||
43
+ @model.__send__(:write_attribute, @column_name, self.class.empty)
44
+ end
45
+
46
+ def __setobj__(obj)
47
+ raise "Attempted to call __setobj__ on read-only delegate!"
48
+ end
49
+
50
+ private
51
+
52
+ def to_modify(&block)
53
+ if loaded? then block.()
54
+ else modifications << block
55
+ end
56
+ self
57
+ end
58
+
59
+ def modifications
60
+ @modifications ||= []
61
+ end
62
+
63
+ end
64
+
65
+ class List < DelegateClass(Array)
66
+
67
+ include Collection
68
+
69
+ NON_ATOMIC_MUTATORS = [
70
+ :collect!,
71
+ :delete_if,
72
+ :fill,
73
+ :flatten!,
74
+ :insert,
75
+ :keep_if,
76
+ :map!,
77
+ :pop,
78
+ :reject!,
79
+ :reverse!,
80
+ :rotate!,
81
+ :select!,
82
+ :shift,
83
+ :shuffle!,
84
+ :slice!,
85
+ :sort!,
86
+ :sort_by!,
87
+ :uniq!
88
+ ]
89
+ NON_ATOMIC_MUTATORS.
90
+ each { |method| undef_method(method) if method_defined? method }
91
+
92
+ def self.empty; []; end
93
+
94
+ def []=(position, *args)
95
+ if Range === position then first, count = position.first, position.count
96
+ else first, count = position, args[-2]
97
+ end
98
+ element = args[-1]
99
+ if first < 0
100
+ raise ArgumentError,
101
+ "Bad index #{position}: CQL lists do not support negative indices"
102
+ end
103
+ if count.nil?
104
+ updater.list_replace(column_name, first, element)
105
+ else
106
+ element = Array.wrap(element)
107
+ count.times do |i|
108
+ if i < element.length
109
+ updater.list_replace(column_name, first+i, element[i])
110
+ else
111
+ deleter.list_remove_at(column_name, first+i)
112
+ end
113
+ end
114
+ end
115
+ to_modify { super }
116
+ end
117
+
118
+ def clear
119
+ deleter.delete_columns(column_name)
120
+ to_modify { super }
121
+ end
122
+
123
+ def concat(array)
124
+ updater.list_append(column_name, array)
125
+ to_modify { super }
126
+ end
127
+
128
+ def delete(object)
129
+ updater.list_remove(column_name, object)
130
+ to_modify { super }
131
+ end
132
+
133
+ def delete_at(index)
134
+ deleter.list_remove_at(column_name, index)
135
+ to_modify { super }
136
+ end
137
+
138
+ def push(object)
139
+ updater.list_append(column_name, object)
140
+ to_modify { super }
141
+ end
142
+ alias_method :<<, :push
143
+
144
+ def replace(array)
145
+ updater.set(column_name => array)
146
+ to_modify { super }
147
+ end
148
+
149
+ def unshift(*objs)
150
+ updater.list_prepend(column_name, objs.reverse)
151
+ to_modify { super }
152
+ end
153
+
154
+ end
155
+
156
+ class Set < DelegateClass(::Set)
157
+
158
+ include Collection
159
+
160
+ NON_ATOMIC_MUTATORS = [
161
+ :add?,
162
+ :collect!,
163
+ :delete?,
164
+ :delete_if,
165
+ :flatten!,
166
+ :keep_if,
167
+ :map!,
168
+ :reject!,
169
+ :select!
170
+ ]
171
+ NON_ATOMIC_MUTATORS.
172
+ each { |method| undef_method(method) if method_defined? method }
173
+
174
+ def add(object)
175
+ updater.set_add(column_name, object)
176
+ to_modify { super }
177
+ end
178
+
179
+ def clear
180
+ deleter.delete_columns(column_name)
181
+ to_modify { super }
182
+ end
183
+
184
+ def delete(object)
185
+ updater.set_remove(column_name, object)
186
+ to_modify { super }
187
+ end
188
+
189
+ def replace(set)
190
+ updater.set(column_name => set)
191
+ to_modify { super }
192
+ end
193
+
194
+ end
195
+
196
+ class Map < DelegateClass(::Hash)
197
+
198
+ include Collection
199
+
200
+ NON_ATOMIC_MUTATORS = [
201
+ :default,
202
+ :default=,
203
+ :default_proc,
204
+ :default_proc=,
205
+ :delete_if,
206
+ :deep_merge!,
207
+ :except!,
208
+ :extract!,
209
+ :keep_if,
210
+ :reject!,
211
+ :reverse_merge!,
212
+ :reverse_update,
213
+ :select!,
214
+ :shift,
215
+ :slice!,
216
+ :stringify_keys!,
217
+ :symbolize_keys!,
218
+ :to_options!,
219
+ :transform_keys!
220
+ ]
221
+ NON_ATOMIC_MUTATORS.
222
+ each { |method| undef_method(method) if method_defined? method }
223
+
224
+ def []=(key, value)
225
+ updater.map_update(column_name, key => value)
226
+ to_modify { super }
227
+ end
228
+ alias_method :store, :[]=
229
+
230
+ def clear
231
+ deleter.delete_columns(column_name)
232
+ to_modify { super }
233
+ end
234
+
235
+ def delete(key)
236
+ deleter.map_remove(column_name, key)
237
+ to_modify { super }
238
+ end
239
+
240
+ def merge!(hash)
241
+ updater.map_update(column_name, hash)
242
+ to_modify { super }
243
+ end
244
+ alias_method :update, :merge!
245
+
246
+ def replace(hash)
247
+ updater.set(column_name => hash)
248
+ to_modify { super }
249
+ end
250
+
251
+ end
252
+
253
+ end
254
+
255
+ end
@@ -1,12 +1,12 @@
1
1
  module Cequel
2
-
2
+
3
3
  module Model
4
4
 
5
- Error = Class.new(Cequel::Error)
6
- RecordNotFound = Class.new(Error)
7
- RecordInvalid = Class.new(Error)
8
- MissingKey = Class.new(Error)
9
- InvalidQuery = Class.new(Error)
5
+ MissingAttributeError = Class.new(ArgumentError)
6
+ UnknownAttributeError = Class.new(ArgumentError)
7
+ RecordNotFound = Class.new(StandardError)
8
+ InvalidRecordConfiguration = Class.new(StandardError)
9
+ RecordInvalid = Class.new(StandardError)
10
10
 
11
11
  end
12
12
 
@@ -0,0 +1,26 @@
1
+ module Cequel
2
+
3
+ module Model
4
+
5
+ class HasManyAssociation
6
+
7
+ attr_reader :owner_class, :name, :association_class_name
8
+
9
+ def initialize(owner_class, name, options = {})
10
+ @owner_class, @name = owner_class, name
11
+ @association_class_name = options.fetch(:class_name, name.to_s.classify)
12
+ end
13
+
14
+ def association_class
15
+ @association_class ||= association_class_name.constantize
16
+ end
17
+
18
+ def instance_variable_name
19
+ @instance_variable_name ||= :"@#{name}"
20
+ end
21
+
22
+ end
23
+
24
+ end
25
+
26
+ end