cequel 1.5.0 → 1.6.0
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 +4 -4
- data/Appraisals +4 -17
- data/CHANGELOG.md +8 -0
- data/DRIVER_TODO +5 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +110 -65
- data/README.md +4 -3
- data/Rakefile +39 -3
- data/Vagrantfile +10 -13
- data/cequel.gemspec +42 -0
- data/lib/cequel.rb +2 -2
- data/lib/cequel/metal/data_set.rb +1 -1
- data/lib/cequel/metal/keyspace.rb +23 -15
- data/lib/cequel/metal/logging.rb +1 -1
- data/lib/cequel/metal/request_logger.rb +1 -1
- data/lib/cequel/metal/writer.rb +1 -1
- data/lib/cequel/record.rb +1 -1
- data/lib/cequel/record/association_collection.rb +1 -1
- data/lib/cequel/record/associations.rb +1 -1
- data/lib/cequel/record/belongs_to_association.rb +1 -1
- data/lib/cequel/record/collection.rb +34 -28
- data/lib/cequel/record/data_set_builder.rb +1 -1
- data/lib/cequel/record/lazy_record_collection.rb +1 -1
- data/lib/cequel/record/persistence.rb +4 -2
- data/lib/cequel/record/properties.rb +2 -2
- data/lib/cequel/record/record_set.rb +1 -1
- data/lib/cequel/record/schema.rb +2 -2
- data/lib/cequel/record/scoped.rb +1 -1
- data/lib/cequel/schema/create_table_dsl.rb +1 -1
- data/lib/cequel/schema/keyspace.rb +17 -2
- data/lib/cequel/schema/migration_validator.rb +1 -1
- data/lib/cequel/schema/update_table_dsl.rb +1 -1
- data/lib/cequel/type.rb +5 -5
- data/lib/cequel/util.rb +30 -0
- data/lib/cequel/uuids.rb +5 -5
- data/lib/cequel/version.rb +1 -1
- data/spec/examples/metal/keyspace_spec.rb +1 -1
- data/spec/examples/record/list_spec.rb +9 -0
- data/spec/examples/record/persistence_spec.rb +2 -2
- data/spec/examples/schema/keyspace_spec.rb +1 -2
- data/spec/examples/schema/table_reader_spec.rb +1 -1
- data/spec/examples/spec_helper.rb +3 -0
- data/spec/examples/uuids_spec.rb +1 -1
- data/spec/support/helpers.rb +7 -5
- data/tags +836 -0
- metadata +49 -38
data/Vagrantfile
CHANGED
@@ -11,7 +11,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
|
11
11
|
# please see the online documentation at vagrantup.com.
|
12
12
|
|
13
13
|
# Every Vagrant virtual environment requires a box to build off of.
|
14
|
-
config.vm.box = "
|
14
|
+
config.vm.box = "ubuntu/trusty64"
|
15
15
|
|
16
16
|
# The url from where the 'config.vm.box' box will be fetched if it
|
17
17
|
# doesn't already exist on the user's system.
|
@@ -45,13 +45,9 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
|
45
45
|
# backing providers for Vagrant. These expose provider-specific options.
|
46
46
|
# Example for VirtualBox:
|
47
47
|
#
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
#
|
52
|
-
# # Use VBoxManage to customize the VM. For example to change memory:
|
53
|
-
# vb.customize ["modifyvm", :id, "--memory", "1024"]
|
54
|
-
# end
|
48
|
+
config.vm.provider :virtualbox do |vb|
|
49
|
+
vb.memory = 1024
|
50
|
+
end
|
55
51
|
#
|
56
52
|
# View the documentation for the provider you're using for more
|
57
53
|
# information on available options.
|
@@ -131,14 +127,15 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
|
131
127
|
echo "start on runlevel [2345]
|
132
128
|
stop on runlevel [06]
|
133
129
|
exec /opt/apache-cassandra-$1/bin/cassandra" > /etc/init/cassandra.conf
|
134
|
-
sed -i -e 's
|
135
|
-
sed -i -e 's
|
136
|
-
sed -i -e 's
|
130
|
+
sed -i -e 's/.*broadcast_rpc_address:.*/broadcast_rpc_address: 127.0.0.1/' /opt/apache-cassandra-$1/conf/cassandra.yaml
|
131
|
+
sed -i -e 's/^rpc_address:.*/rpc_address: 0.0.0.0/' /opt/apache-cassandra-$1/conf/cassandra.yaml
|
132
|
+
sed -i -e 's/^start_native_transport:.*/start_native_transport: true/' /opt/apache-cassandra-$1/conf/cassandra.yaml
|
133
|
+
sed -i -e 's/^start_rpc:.*/start_rpc: true/' /opt/apache-cassandra-$1/conf/cassandra.yaml
|
137
134
|
service cassandra start
|
138
135
|
SH
|
139
136
|
|
140
|
-
|
141
|
-
|
137
|
+
versions = File.read(File.expand_path('../.cassandra-versions', __FILE__)).each_line
|
138
|
+
.map(&:strip).grep(/^(1\.2\.|2\.)/)
|
142
139
|
versions.each do |version|
|
143
140
|
java_version = version =~ /^1/ ? '6' : '7'
|
144
141
|
config.vm.define version do |machine|
|
data/cequel.gemspec
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require File.expand_path('../lib/cequel/version', __FILE__)
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = 'cequel'
|
5
|
+
s.version = Cequel::VERSION
|
6
|
+
s.authors = [
|
7
|
+
'Mat Brown', 'Aubrey Holland', 'Keenan Brock', 'Insoo Buzz Jung',
|
8
|
+
'Louis Simoneau', 'Peter Williams', 'Kenneth Hoffman', 'Antti Tapio',
|
9
|
+
'Ilya Bazylchuk', 'Dan Cardamore', 'Kei Kusakari', 'Oleh Novosad',
|
10
|
+
'John Smart', 'Angelo Lakra', 'Olivier Lance', 'Tomohiro Nishimura',
|
11
|
+
'Masaki Takahashi', 'G Gordon Worley III', 'Clark Bremer', 'Tamara Temple',
|
12
|
+
'Long On', 'Lucas Mundim'
|
13
|
+
]
|
14
|
+
s.homepage = "https://github.com/cequel/cequel"
|
15
|
+
s.email = 'mat.a.brown@gmail.com'
|
16
|
+
s.license = 'MIT'
|
17
|
+
s.summary = 'Full-featured, ActiveModel-compliant ORM for Cassandra using CQL3'
|
18
|
+
s.description = <<DESC
|
19
|
+
Cequel is an ActiveRecord-like domain model layer for Cassandra that exposes
|
20
|
+
the robust data modeling capabilities of CQL3, including parent-child
|
21
|
+
relationships via compound primary keys and in-memory atomic manipulation of
|
22
|
+
collection columns.
|
23
|
+
DESC
|
24
|
+
|
25
|
+
s.files = Dir['lib/**/*.rb', 'templates/**/*', 'spec/**/*.rb', '[A-Z]*']
|
26
|
+
s.test_files = Dir['spec/examples/**/*.rb']
|
27
|
+
s.has_rdoc = true
|
28
|
+
s.extra_rdoc_files = 'README.md'
|
29
|
+
s.required_ruby_version = '>= 1.9'
|
30
|
+
s.add_runtime_dependency 'activemodel', '>= 3.1', '< 5.0'
|
31
|
+
s.add_runtime_dependency 'cassandra-driver', '~> 1.0'
|
32
|
+
s.add_development_dependency 'appraisal', '~> 1.0'
|
33
|
+
s.add_development_dependency 'wwtd', '~> 0.5'
|
34
|
+
s.add_development_dependency 'rake', '~> 10.1'
|
35
|
+
s.add_development_dependency 'rspec', '~> 3.1'
|
36
|
+
s.add_development_dependency 'rspec-its', '~> 1.0'
|
37
|
+
s.add_development_dependency 'rubocop', '~> 0.28'
|
38
|
+
s.add_development_dependency 'timecop', '~> 0.7'
|
39
|
+
s.add_development_dependency 'travis', '~> 1.7'
|
40
|
+
s.add_development_dependency 'yard', '~> 0.6'
|
41
|
+
s.requirements << 'Cassandra >= 1.2.0'
|
42
|
+
end
|
data/lib/cequel.rb
CHANGED
@@ -4,13 +4,13 @@ require 'delegate'
|
|
4
4
|
require 'active_support'
|
5
5
|
require 'active_support/deprecation'
|
6
6
|
require 'active_support/core_ext'
|
7
|
-
require '
|
7
|
+
require 'cassandra'
|
8
8
|
|
9
9
|
require 'cequel/errors'
|
10
|
+
require 'cequel/util'
|
10
11
|
require 'cequel/metal'
|
11
12
|
require 'cequel/schema'
|
12
13
|
require 'cequel/type'
|
13
|
-
require 'cequel/util'
|
14
14
|
require 'cequel/uuids'
|
15
15
|
require 'cequel/instrumentation'
|
16
16
|
require 'cequel/record'
|
@@ -9,7 +9,7 @@ module Cequel
|
|
9
9
|
# instance.
|
10
10
|
#
|
11
11
|
class Keyspace
|
12
|
-
extend Forwardable
|
12
|
+
extend Util::Forwardable
|
13
13
|
include Logging
|
14
14
|
include MonitorMixin
|
15
15
|
|
@@ -154,9 +154,7 @@ module Cequel
|
|
154
154
|
#
|
155
155
|
def client
|
156
156
|
synchronize do
|
157
|
-
@client ||=
|
158
|
-
client.use(name) if name
|
159
|
-
end
|
157
|
+
@client ||= cluster.connect(name)
|
160
158
|
end
|
161
159
|
end
|
162
160
|
|
@@ -193,8 +191,9 @@ module Cequel
|
|
193
191
|
log('CQL', statement, *bind_vars) do
|
194
192
|
begin
|
195
193
|
client.execute(sanitize(statement, bind_vars),
|
196
|
-
consistency || default_consistency)
|
197
|
-
rescue
|
194
|
+
consistency: consistency || default_consistency)
|
195
|
+
rescue Cassandra::Errors::NoHostsAvailable,
|
196
|
+
Ione::Io::ConnectionError => e
|
198
197
|
clear_active_connections!
|
199
198
|
raise if retries == 0
|
200
199
|
retries -= 1
|
@@ -213,8 +212,11 @@ module Cequel
|
|
213
212
|
if defined? @client
|
214
213
|
remove_instance_variable(:@client)
|
215
214
|
end
|
216
|
-
if defined? @
|
217
|
-
remove_instance_variable(:@
|
215
|
+
if defined? @client_without_keyspace
|
216
|
+
remove_instance_variable(:@client_without_keyspace)
|
217
|
+
end
|
218
|
+
if defined? @cluster
|
219
|
+
remove_instance_variable(:@cluster)
|
218
220
|
end
|
219
221
|
end
|
220
222
|
|
@@ -235,7 +237,7 @@ module Cequel
|
|
235
237
|
CQL
|
236
238
|
|
237
239
|
log('CQL', statement, [name]) do
|
238
|
-
|
240
|
+
client_without_keyspace.execute(sanitize(statement, [name])).any?
|
239
241
|
end
|
240
242
|
end
|
241
243
|
|
@@ -249,15 +251,21 @@ module Cequel
|
|
249
251
|
def_delegator :lock, :synchronize
|
250
252
|
private :lock
|
251
253
|
|
252
|
-
def
|
254
|
+
def cluster
|
253
255
|
synchronize do
|
254
|
-
@
|
256
|
+
@cluster ||= Cassandra.cluster(client_options)
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
def client_without_keyspace
|
261
|
+
synchronize do
|
262
|
+
@client_without_keyspace ||= cluster.connect
|
255
263
|
end
|
256
264
|
end
|
257
265
|
|
258
266
|
def client_options
|
259
267
|
{hosts: hosts, port: port}.tap do |options|
|
260
|
-
options
|
268
|
+
options.merge!(credentials) if credentials
|
261
269
|
end
|
262
270
|
end
|
263
271
|
|
@@ -272,9 +280,9 @@ module Cequel
|
|
272
280
|
def extract_hosts_and_port(configuration)
|
273
281
|
hosts, ports = [], Set[]
|
274
282
|
ports << configuration[:port] if configuration.key?(:port)
|
275
|
-
|
276
|
-
:host, configuration.fetch(:hosts, '127.0.0.1'))
|
277
|
-
|
283
|
+
host_or_hosts =
|
284
|
+
configuration.fetch(:host, configuration.fetch(:hosts, '127.0.0.1'))
|
285
|
+
Array.wrap(host_or_hosts).each do |host_port|
|
278
286
|
host, port = host_port.split(':')
|
279
287
|
hosts << host
|
280
288
|
if port
|
data/lib/cequel/metal/logging.rb
CHANGED
data/lib/cequel/metal/writer.rb
CHANGED
data/lib/cequel/record.rb
CHANGED
@@ -53,7 +53,7 @@ module Cequel
|
|
53
53
|
#
|
54
54
|
module Collection
|
55
55
|
extend ActiveSupport::Concern
|
56
|
-
extend Forwardable
|
56
|
+
extend Util::Forwardable
|
57
57
|
|
58
58
|
#
|
59
59
|
# @!method loaded?
|
@@ -137,12 +137,16 @@ module Cequel
|
|
137
137
|
def to_modify(&block)
|
138
138
|
if loaded?
|
139
139
|
model.__send__("#{column_name}_will_change!")
|
140
|
-
block.call
|
140
|
+
block.call
|
141
141
|
else modifications << block
|
142
142
|
end
|
143
143
|
self
|
144
144
|
end
|
145
145
|
|
146
|
+
def to_update
|
147
|
+
yield unless model.new_record?
|
148
|
+
end
|
149
|
+
|
146
150
|
def modifications
|
147
151
|
@modifications ||= []
|
148
152
|
end
|
@@ -231,15 +235,17 @@ module Cequel
|
|
231
235
|
"indices"
|
232
236
|
end
|
233
237
|
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
238
|
+
to_update do
|
239
|
+
if count.nil?
|
240
|
+
updater.list_replace(column_name, first, element)
|
241
|
+
else
|
242
|
+
element = Array.wrap(element)
|
243
|
+
count.times do |i|
|
244
|
+
if i < element.length
|
245
|
+
updater.list_replace(column_name, first+i, element[i])
|
246
|
+
else
|
247
|
+
deleter.list_remove_at(column_name, first+i)
|
248
|
+
end
|
243
249
|
end
|
244
250
|
end
|
245
251
|
end
|
@@ -253,7 +259,7 @@ module Cequel
|
|
253
259
|
# @return [List] self
|
254
260
|
#
|
255
261
|
def clear
|
256
|
-
deleter.delete_columns(column_name)
|
262
|
+
to_update { deleter.delete_columns(column_name) }
|
257
263
|
to_modify { super }
|
258
264
|
end
|
259
265
|
|
@@ -265,7 +271,7 @@ module Cequel
|
|
265
271
|
#
|
266
272
|
def concat(array)
|
267
273
|
array = cast_collection(array)
|
268
|
-
updater.list_append(column_name, array)
|
274
|
+
to_update { updater.list_append(column_name, array) }
|
269
275
|
to_modify { super }
|
270
276
|
end
|
271
277
|
|
@@ -277,7 +283,7 @@ module Cequel
|
|
277
283
|
#
|
278
284
|
def delete(object)
|
279
285
|
object = cast_element(object)
|
280
|
-
updater.list_remove(column_name, object)
|
286
|
+
to_update { updater.list_remove(column_name, object) }
|
281
287
|
to_modify { super }
|
282
288
|
end
|
283
289
|
|
@@ -288,7 +294,7 @@ module Cequel
|
|
288
294
|
# @return [List] self
|
289
295
|
#
|
290
296
|
def delete_at(index)
|
291
|
-
deleter.list_remove_at(column_name, index)
|
297
|
+
to_update { deleter.list_remove_at(column_name, index) }
|
292
298
|
to_modify { super }
|
293
299
|
end
|
294
300
|
|
@@ -300,7 +306,7 @@ module Cequel
|
|
300
306
|
#
|
301
307
|
def push(*objects)
|
302
308
|
objects.map! { |object| cast_element(object) }
|
303
|
-
updater.list_append(column_name, objects)
|
309
|
+
to_update { updater.list_append(column_name, objects) }
|
304
310
|
to_modify { super }
|
305
311
|
end
|
306
312
|
alias_method :<<, :push
|
@@ -314,7 +320,7 @@ module Cequel
|
|
314
320
|
#
|
315
321
|
def replace(array)
|
316
322
|
array = cast_collection(array)
|
317
|
-
updater.set(column_name => array)
|
323
|
+
to_update { updater.set(column_name => array) }
|
318
324
|
to_modify { super }
|
319
325
|
end
|
320
326
|
|
@@ -326,7 +332,7 @@ module Cequel
|
|
326
332
|
#
|
327
333
|
def unshift(*objects)
|
328
334
|
objects.map!(&method(:cast_element))
|
329
|
-
updater.list_prepend(column_name, objects.reverse)
|
335
|
+
to_update { updater.list_prepend(column_name, objects.reverse) }
|
330
336
|
to_modify { super }
|
331
337
|
end
|
332
338
|
alias_method :prepend, :unshift
|
@@ -368,7 +374,7 @@ module Cequel
|
|
368
374
|
#
|
369
375
|
def add(object)
|
370
376
|
object = cast_element(object)
|
371
|
-
updater.set_add(column_name, object)
|
377
|
+
to_update { updater.set_add(column_name, object) }
|
372
378
|
to_modify { super }
|
373
379
|
end
|
374
380
|
alias_method :<<, :add
|
@@ -380,7 +386,7 @@ module Cequel
|
|
380
386
|
# @return [Set] self
|
381
387
|
#
|
382
388
|
def clear
|
383
|
-
deleter.delete_columns(column_name)
|
389
|
+
to_update { deleter.delete_columns(column_name) }
|
384
390
|
to_modify { super }
|
385
391
|
end
|
386
392
|
|
@@ -392,7 +398,7 @@ module Cequel
|
|
392
398
|
#
|
393
399
|
def delete(object)
|
394
400
|
object = cast_element(object)
|
395
|
-
updater.set_remove(column_name, object)
|
401
|
+
to_update { updater.set_remove(column_name, object) }
|
396
402
|
to_modify { super }
|
397
403
|
end
|
398
404
|
|
@@ -404,7 +410,7 @@ module Cequel
|
|
404
410
|
#
|
405
411
|
def replace(set)
|
406
412
|
set = cast_collection(set)
|
407
|
-
updater.set(column_name => set)
|
413
|
+
to_update { updater.set(column_name => set) }
|
408
414
|
to_modify { super }
|
409
415
|
end
|
410
416
|
end
|
@@ -419,7 +425,7 @@ module Cequel
|
|
419
425
|
#
|
420
426
|
class Map < DelegateClass(::Hash)
|
421
427
|
include Collection
|
422
|
-
extend Forwardable
|
428
|
+
extend Util::Forwardable
|
423
429
|
|
424
430
|
# These methods involve mutation that cannot be expressed as a CQL
|
425
431
|
# operation, so are not implemented.
|
@@ -456,7 +462,7 @@ module Cequel
|
|
456
462
|
#
|
457
463
|
def []=(key, value)
|
458
464
|
key = cast_key(key)
|
459
|
-
updater.map_update(column_name, key => value)
|
465
|
+
to_update { updater.map_update(column_name, key => value) }
|
460
466
|
to_modify { super }
|
461
467
|
end
|
462
468
|
alias_method :store, :[]=
|
@@ -468,7 +474,7 @@ module Cequel
|
|
468
474
|
# @return [Map] self
|
469
475
|
#
|
470
476
|
def clear
|
471
|
-
deleter.delete_columns(column_name)
|
477
|
+
to_update { deleter.delete_columns(column_name) }
|
472
478
|
to_modify { super }
|
473
479
|
end
|
474
480
|
|
@@ -480,7 +486,7 @@ module Cequel
|
|
480
486
|
#
|
481
487
|
def delete(key)
|
482
488
|
key = cast_key(key)
|
483
|
-
deleter.map_remove(column_name, key)
|
489
|
+
to_update { deleter.map_remove(column_name, key) }
|
484
490
|
to_modify { super }
|
485
491
|
end
|
486
492
|
|
@@ -492,7 +498,7 @@ module Cequel
|
|
492
498
|
#
|
493
499
|
def merge!(hash)
|
494
500
|
hash = cast_collection(hash)
|
495
|
-
updater.map_update(column_name, hash)
|
501
|
+
to_update { updater.map_update(column_name, hash) }
|
496
502
|
to_modify { super }
|
497
503
|
end
|
498
504
|
alias_method :update, :merge!
|
@@ -505,7 +511,7 @@ module Cequel
|
|
505
511
|
#
|
506
512
|
def replace(hash)
|
507
513
|
hash = cast_collection(hash)
|
508
|
-
updater.set(column_name => hash)
|
514
|
+
to_update { updater.set(column_name => hash) }
|
509
515
|
to_modify { super }
|
510
516
|
end
|
511
517
|
|