cequel 0.5.6 → 1.0.0.pre.1
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.
- checksums.yaml +7 -0
- data/lib/cequel.rb +5 -8
- data/lib/cequel/errors.rb +1 -0
- data/lib/cequel/metal.rb +17 -0
- data/lib/cequel/metal/batch.rb +62 -0
- data/lib/cequel/metal/cql_row_specification.rb +26 -0
- data/lib/cequel/metal/data_set.rb +461 -0
- data/lib/cequel/metal/deleter.rb +47 -0
- data/lib/cequel/metal/incrementer.rb +35 -0
- data/lib/cequel/metal/inserter.rb +53 -0
- data/lib/cequel/metal/keyspace.rb +213 -0
- data/lib/cequel/metal/row.rb +48 -0
- data/lib/cequel/metal/row_specification.rb +37 -0
- data/lib/cequel/metal/statement.rb +30 -0
- data/lib/cequel/metal/updater.rb +65 -0
- data/lib/cequel/metal/writer.rb +73 -0
- data/lib/cequel/model.rb +12 -84
- data/lib/cequel/model/association_collection.rb +23 -0
- data/lib/cequel/model/associations.rb +84 -80
- data/lib/cequel/model/base.rb +74 -0
- data/lib/cequel/model/belongs_to_association.rb +31 -0
- data/lib/cequel/model/callbacks.rb +14 -10
- data/lib/cequel/model/collection.rb +255 -0
- data/lib/cequel/model/errors.rb +6 -6
- data/lib/cequel/model/has_many_association.rb +26 -0
- data/lib/cequel/model/mass_assignment.rb +31 -0
- data/lib/cequel/model/persistence.rb +119 -115
- data/lib/cequel/model/properties.rb +89 -87
- data/lib/cequel/model/railtie.rb +21 -14
- data/lib/cequel/model/record_set.rb +285 -0
- data/lib/cequel/model/schema.rb +33 -0
- data/lib/cequel/model/scoped.rb +5 -48
- data/lib/cequel/model/validations.rb +18 -18
- data/lib/cequel/schema.rb +15 -0
- data/lib/cequel/schema/column.rb +135 -0
- data/lib/cequel/schema/create_table_dsl.rb +56 -0
- data/lib/cequel/schema/keyspace.rb +50 -0
- data/lib/cequel/schema/table.rb +120 -0
- data/lib/cequel/schema/table_property.rb +67 -0
- data/lib/cequel/schema/table_reader.rb +139 -0
- data/lib/cequel/schema/table_synchronizer.rb +114 -0
- data/lib/cequel/schema/table_updater.rb +83 -0
- data/lib/cequel/schema/table_writer.rb +80 -0
- data/lib/cequel/schema/update_table_dsl.rb +60 -0
- data/lib/cequel/type.rb +232 -0
- data/lib/cequel/version.rb +1 -1
- data/spec/environment.rb +5 -1
- data/spec/examples/metal/data_set_spec.rb +608 -0
- data/spec/examples/model/associations_spec.rb +84 -74
- data/spec/examples/model/callbacks_spec.rb +66 -59
- data/spec/examples/model/list_spec.rb +393 -0
- data/spec/examples/model/map_spec.rb +229 -0
- data/spec/examples/model/mass_assignment_spec.rb +55 -0
- data/spec/examples/model/naming_spec.rb +11 -4
- data/spec/examples/model/persistence_spec.rb +140 -150
- data/spec/examples/model/properties_spec.rb +122 -75
- data/spec/examples/model/record_set_spec.rb +285 -0
- data/spec/examples/model/schema_spec.rb +44 -0
- data/spec/examples/model/serialization_spec.rb +20 -14
- data/spec/examples/model/set_spec.rb +133 -0
- data/spec/examples/model/spec_helper.rb +0 -10
- data/spec/examples/model/validations_spec.rb +51 -38
- data/spec/examples/schema/table_reader_spec.rb +328 -0
- data/spec/examples/schema/table_synchronizer_spec.rb +172 -0
- data/spec/examples/schema/table_updater_spec.rb +157 -0
- data/spec/examples/schema/table_writer_spec.rb +225 -0
- data/spec/examples/spec_helper.rb +29 -0
- data/spec/examples/type_spec.rb +204 -0
- data/spec/support/helpers.rb +67 -8
- metadata +121 -152
- data/lib/cequel/batch.rb +0 -58
- data/lib/cequel/cql_row_specification.rb +0 -22
- data/lib/cequel/data_set.rb +0 -371
- data/lib/cequel/keyspace.rb +0 -205
- data/lib/cequel/model/class_internals.rb +0 -49
- data/lib/cequel/model/column.rb +0 -20
- data/lib/cequel/model/counter.rb +0 -35
- data/lib/cequel/model/dictionary.rb +0 -126
- data/lib/cequel/model/dirty.rb +0 -53
- data/lib/cequel/model/dynamic.rb +0 -31
- data/lib/cequel/model/inheritable.rb +0 -48
- data/lib/cequel/model/instance_internals.rb +0 -23
- data/lib/cequel/model/local_association.rb +0 -42
- data/lib/cequel/model/magic.rb +0 -79
- data/lib/cequel/model/mass_assignment_security.rb +0 -21
- data/lib/cequel/model/naming.rb +0 -17
- data/lib/cequel/model/observer.rb +0 -42
- data/lib/cequel/model/readable_dictionary.rb +0 -182
- data/lib/cequel/model/remote_association.rb +0 -40
- data/lib/cequel/model/scope.rb +0 -362
- data/lib/cequel/model/subclass_internals.rb +0 -45
- data/lib/cequel/model/timestamps.rb +0 -52
- data/lib/cequel/model/translation.rb +0 -17
- data/lib/cequel/row_specification.rb +0 -63
- data/lib/cequel/statement.rb +0 -23
- data/spec/examples/data_set_spec.rb +0 -444
- data/spec/examples/keyspace_spec.rb +0 -84
- data/spec/examples/model/counter_spec.rb +0 -94
- data/spec/examples/model/dictionary_spec.rb +0 -301
- data/spec/examples/model/dirty_spec.rb +0 -39
- data/spec/examples/model/dynamic_spec.rb +0 -41
- data/spec/examples/model/inheritable_spec.rb +0 -45
- data/spec/examples/model/magic_spec.rb +0 -199
- data/spec/examples/model/mass_assignment_security_spec.rb +0 -13
- data/spec/examples/model/observer_spec.rb +0 -86
- data/spec/examples/model/scope_spec.rb +0 -677
- data/spec/examples/model/timestamps_spec.rb +0 -52
- 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
|
11
|
+
define_model_callbacks :save, :create, :update, :destroy
|
16
12
|
end
|
17
13
|
|
18
|
-
def save(
|
19
|
-
run_callbacks(:save)
|
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
|
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
|
data/lib/cequel/model/errors.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
module Cequel
|
2
|
-
|
2
|
+
|
3
3
|
module Model
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
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
|