cassandra 0.13.0 → 0.14.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.
- data/CHANGELOG +15 -0
- data/Gemfile +8 -0
- data/Manifest +18 -0
- data/Rakefile +2 -1
- data/cassandra.gemspec +13 -9
- data/conf/0.6/schema.json +2 -2
- data/conf/0.6/storage-conf.xml +18 -18
- data/conf/0.8/schema.json +3 -0
- data/conf/0.8/schema.txt +7 -1
- data/conf/1.0/cassandra.in.sh +41 -0
- data/conf/1.0/cassandra.yaml +415 -0
- data/conf/1.0/log4j-server.properties +40 -0
- data/conf/1.0/schema.json +72 -0
- data/conf/1.0/schema.txt +57 -0
- data/ext/cassandra_native.c +34 -0
- data/ext/extconf.rb +9 -0
- data/lib/cassandra.rb +1 -0
- data/lib/cassandra/0.6/protocol.rb +10 -9
- data/lib/cassandra/cassandra.rb +32 -25
- data/lib/cassandra/columns.rb +38 -13
- data/lib/cassandra/composite.rb +37 -15
- data/lib/cassandra/dynamic_composite.rb +96 -0
- data/lib/cassandra/mock.rb +23 -14
- data/test/cassandra_mock_test.rb +6 -0
- data/test/cassandra_test.rb +390 -49
- data/test/composite_type_test.rb +42 -7
- metadata +47 -21
@@ -0,0 +1,40 @@
|
|
1
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
2
|
+
# or more contributor license agreements. See the NOTICE file
|
3
|
+
# distributed with this work for additional information
|
4
|
+
# regarding copyright ownership. The ASF licenses this file
|
5
|
+
# to you under the Apache License, Version 2.0 (the
|
6
|
+
# "License"); you may not use this file except in compliance
|
7
|
+
# with the License. You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
17
|
+
# for production, you should probably set pattern to %c instead of %l.
|
18
|
+
# (%l is slower.)
|
19
|
+
|
20
|
+
# output messages into a rolling log file as well as stdout
|
21
|
+
log4j.rootLogger=INFO,stdout,R
|
22
|
+
|
23
|
+
# stdout
|
24
|
+
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
25
|
+
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
26
|
+
log4j.appender.stdout.layout.ConversionPattern=%5p %d{HH:mm:ss,SSS} %m%n
|
27
|
+
|
28
|
+
# rolling log file
|
29
|
+
log4j.appender.R=org.apache.log4j.RollingFileAppender
|
30
|
+
log4j.appender.R.maxFileSize=20MB
|
31
|
+
log4j.appender.R.maxBackupIndex=50
|
32
|
+
log4j.appender.R.layout=org.apache.log4j.PatternLayout
|
33
|
+
log4j.appender.R.layout.ConversionPattern=%5p [%t] %d{ISO8601} %F (line %L) %m%n
|
34
|
+
# Edit the next line to point to your logs directory
|
35
|
+
log4j.appender.R.File=data/logs/system.log
|
36
|
+
|
37
|
+
# Application logging options
|
38
|
+
#log4j.logger.org.apache.cassandra=DEBUG
|
39
|
+
#log4j.logger.org.apache.cassandra.db=DEBUG
|
40
|
+
#log4j.logger.org.apache.cassandra.service.StorageProxy=DEBUG
|
@@ -0,0 +1,72 @@
|
|
1
|
+
{"Twitter":{
|
2
|
+
"Users":{
|
3
|
+
"comparator_type":"org.apache.cassandra.db.marshal.UTF8Type",
|
4
|
+
"column_type":"Standard"},
|
5
|
+
"UserAudits":{
|
6
|
+
"comparator_type":"org.apache.cassandra.db.marshal.UTF8Type",
|
7
|
+
"column_type":"Standard"},
|
8
|
+
"UserCounters":{
|
9
|
+
"comparator_type":"org.apache.cassandra.db.marshal.UTF8Type",
|
10
|
+
"column_type":"Standard",
|
11
|
+
"default_validation_class":"CounterColumnType"},
|
12
|
+
"UserCounterAggregates":{
|
13
|
+
"subcomparator_type":"org.apache.cassandra.db.marshal.UTF8Type",
|
14
|
+
"comparator_type":"org.apache.cassandra.db.marshal.UTF8Type",
|
15
|
+
"column_type":"Super",
|
16
|
+
"default_validation_class":"CounterColumnType"},
|
17
|
+
"UserRelationships":{
|
18
|
+
"subcomparator_type":"org.apache.cassandra.db.marshal.TimeUUIDType",
|
19
|
+
"comparator_type":"org.apache.cassandra.db.marshal.UTF8Type",
|
20
|
+
"column_type":"Super"},
|
21
|
+
"Usernames":{
|
22
|
+
"comparator_type":"org.apache.cassandra.db.marshal.UTF8Type",
|
23
|
+
"column_type":"Standard"},
|
24
|
+
"Statuses":{
|
25
|
+
"comparator_type":"org.apache.cassandra.db.marshal.UTF8Type",
|
26
|
+
"column_type":"Standard"},
|
27
|
+
"StatusAudits":{
|
28
|
+
"comparator_type":"org.apache.cassandra.db.marshal.UTF8Type",
|
29
|
+
"column_type":"Standard"},
|
30
|
+
"StatusRelationships":{
|
31
|
+
"subcomparator_type":"org.apache.cassandra.db.marshal.TimeUUIDType",
|
32
|
+
"comparator_type":"org.apache.cassandra.db.marshal.UTF8Type",
|
33
|
+
"column_type":"Super"},
|
34
|
+
"Indexes":{
|
35
|
+
"comparator_type":"org.apache.cassandra.db.marshal.UTF8Type",
|
36
|
+
"column_type":"Super"},
|
37
|
+
"TimelinishThings":{
|
38
|
+
"comparator_type":"org.apache.cassandra.db.marshal.BytesType",
|
39
|
+
"column_type":"Standard"}
|
40
|
+
},
|
41
|
+
"Multiblog":{
|
42
|
+
"Blogs":{
|
43
|
+
"comparator_type":"org.apache.cassandra.db.marshal.TimeUUIDType",
|
44
|
+
"column_type":"Standard"},
|
45
|
+
"Comments":{
|
46
|
+
"comparator_type":"org.apache.cassandra.db.marshal.TimeUUIDType",
|
47
|
+
"column_type":"Standard"}
|
48
|
+
},
|
49
|
+
"MultiblogLong":{
|
50
|
+
"Blogs":{
|
51
|
+
"comparator_type":"org.apache.cassandra.db.marshal.LongType",
|
52
|
+
"column_type":"Standard"},
|
53
|
+
"Comments":{
|
54
|
+
"comparator_type":"org.apache.cassandra.db.marshal.LongType",
|
55
|
+
"column_type":"Standard"}
|
56
|
+
},
|
57
|
+
"TypeConversions":{
|
58
|
+
"UUIDColumnConversion":{
|
59
|
+
"comparator_type":"org.apache.cassandra.db.marshal.TimeUUIDType",
|
60
|
+
"column_type":"Standard"},
|
61
|
+
"SuperUUID":{
|
62
|
+
"subcomparator_type":"org.apache.cassandra.db.marshal.TimeUUIDType",
|
63
|
+
"comparator_type":"org.apache.cassandra.db.marshal.TimeUUIDType",
|
64
|
+
"column_type":"Super"},
|
65
|
+
"CompositeColumnConversion":{
|
66
|
+
"comparator_type":"org.apache.cassandra.db.marshal.CompositeType(org.apache.cassandra.db.marshal.IntegerType,org.apache.cassandra.db.marshal.UTF8Type)",
|
67
|
+
"column_type":"Standard"},
|
68
|
+
"DynamicComposite":{
|
69
|
+
"comparator_type":"org.apache.cassandra.db.marshal.DynamicCompositeType(u=>org.apache.cassandra.db.marshal.UUIDType,t=>org.apache.cassandra.db.marshal.TimeUUIDType,s=>org.apache.cassandra.db.marshal.UTF8Type,b=>org.apache.cassandra.db.marshal.BytesType,a=>org.apache.cassandra.db.marshal.AsciiType,l=>org.apache.cassandra.db.marshal.LongType,x=>org.apache.cassandra.db.marshal.LexicalUUIDType,i=>org.apache.cassandra.db.marshal.IntegerType)",
|
70
|
+
"column_type":"Standard"}
|
71
|
+
}
|
72
|
+
}
|
data/conf/1.0/schema.txt
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
create keyspace Twitter with
|
2
|
+
placement_strategy = 'org.apache.cassandra.locator.SimpleStrategy' AND
|
3
|
+
strategy_options = {replication_factor:1};
|
4
|
+
use Twitter;
|
5
|
+
create column family Users with comparator = 'UTF8Type';
|
6
|
+
create column family UserAudits with comparator = 'UTF8Type';
|
7
|
+
create column family UserCounters with comparator = 'UTF8Type' and
|
8
|
+
default_validation_class = CounterColumnType;
|
9
|
+
create column family UserCounterAggregates with column_type = 'Super'
|
10
|
+
and comparator = 'UTF8Type' and
|
11
|
+
subcomparator = 'UTF8Type' and
|
12
|
+
default_validation_class = CounterColumnType;
|
13
|
+
create column family UserRelationships with
|
14
|
+
comparator = 'UTF8Type' and
|
15
|
+
column_type = 'Super' and
|
16
|
+
subcomparator = 'TimeUUIDType';
|
17
|
+
create column family Usernames with comparator = 'UTF8Type';
|
18
|
+
create column family Statuses
|
19
|
+
with comparator = 'UTF8Type'
|
20
|
+
and column_metadata = [
|
21
|
+
{column_name: 'tags', validation_class: 'BytesType', index_type: 'KEYS'}
|
22
|
+
];
|
23
|
+
create column family StatusAudits with comparator = 'UTF8Type';
|
24
|
+
create column family StatusRelationships with
|
25
|
+
comparator = 'UTF8Type' and
|
26
|
+
column_type = 'Super' and
|
27
|
+
subcomparator = 'TimeUUIDType';
|
28
|
+
create column family Indexes with
|
29
|
+
comparator = 'UTF8Type' and
|
30
|
+
column_type = 'Super';
|
31
|
+
create column family TimelinishThings with
|
32
|
+
comparator = 'BytesType';
|
33
|
+
|
34
|
+
create keyspace Multiblog with
|
35
|
+
placement_strategy = 'org.apache.cassandra.locator.SimpleStrategy' AND
|
36
|
+
strategy_options = {replication_factor:1};
|
37
|
+
use Multiblog;
|
38
|
+
create column family Blogs with comparator = 'TimeUUIDType';
|
39
|
+
create column family Comments with comparator = 'TimeUUIDType';
|
40
|
+
|
41
|
+
|
42
|
+
create keyspace MultiblogLong with
|
43
|
+
placement_strategy = 'org.apache.cassandra.locator.SimpleStrategy' AND
|
44
|
+
strategy_options = {replication_factor:1};
|
45
|
+
use MultiblogLong;
|
46
|
+
create column family Blogs with comparator = 'LongType';
|
47
|
+
create column family Comments with comparator = 'LongType';
|
48
|
+
|
49
|
+
create keyspace TypeConversions with
|
50
|
+
placement_strategy = 'org.apache.cassandra.locator.SimpleStrategy' AND
|
51
|
+
strategy_options = {replication_factor:1};
|
52
|
+
use TypeConversions;
|
53
|
+
create column family UUIDColumnConversion with comparator = TimeUUIDType;
|
54
|
+
create column family SuperUUID with comparator = TimeUUIDType and column_type = Super;
|
55
|
+
create column family CompositeColumnConversion with comparator = 'CompositeType(IntegerType, UTF8Type)';
|
56
|
+
create column family DynamicComposite with comparator ='DynamicCompositeType
|
57
|
+
(a=>AsciiType,b=>BytesType,i=>IntegerType,x=>LexicalUUIDType,l=>LongType,t=>TimeUUIDType,s=>UTF8Type,u=>UUIDType)';
|
@@ -0,0 +1,34 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
#include <arpa/inet.h>
|
3
|
+
|
4
|
+
VALUE parts_ivar_id;
|
5
|
+
|
6
|
+
VALUE rb_cassandra_composite_fast_unpack(VALUE self, VALUE packed_string_value) {
|
7
|
+
int i = 0;
|
8
|
+
int index = 0;
|
9
|
+
int message_length = RSTRING_LEN(packed_string_value);
|
10
|
+
char *packed_string = (char *)RSTRING_PTR(packed_string_value);
|
11
|
+
|
12
|
+
VALUE parts = rb_ary_new();
|
13
|
+
while (index < message_length) {
|
14
|
+
uint16_t length = ntohs(((uint16_t *)(packed_string+index))[0]);
|
15
|
+
VALUE part = rb_str_new("", length);
|
16
|
+
for (i = 0; i < length; i++) {
|
17
|
+
((char *)RSTRING_PTR(part))[i] = packed_string[index+2+i];
|
18
|
+
}
|
19
|
+
rb_ary_push(parts, part);
|
20
|
+
index += length + 3;
|
21
|
+
}
|
22
|
+
|
23
|
+
rb_ivar_set(self, parts_ivar_id, parts);
|
24
|
+
|
25
|
+
return Qnil;
|
26
|
+
}
|
27
|
+
|
28
|
+
void Init_cassandra_native(void) {
|
29
|
+
VALUE cassandra_module = rb_const_get(rb_cObject, rb_intern("Cassandra"));
|
30
|
+
VALUE cassandra_composite_class = rb_define_class_under(cassandra_module, "Composite", rb_cObject);
|
31
|
+
rb_define_method(cassandra_composite_class, "fast_unpack", rb_cassandra_composite_fast_unpack, 1);
|
32
|
+
|
33
|
+
parts_ivar_id = rb_intern("@parts");
|
34
|
+
}
|
data/ext/extconf.rb
ADDED
data/lib/cassandra.rb
CHANGED
@@ -12,7 +12,7 @@ class Cassandra
|
|
12
12
|
client.remove(@keyspace, key, column_path, timestamp, consistency_level)
|
13
13
|
end
|
14
14
|
|
15
|
-
def _count_columns(column_family, key, super_column, consistency)
|
15
|
+
def _count_columns(column_family, key, super_column, start, stop, count, consistency)
|
16
16
|
client.get_count(@keyspace, key,
|
17
17
|
CassandraThrift::ColumnParent.new(:column_family => column_family, :super_column => super_column),
|
18
18
|
consistency
|
@@ -55,11 +55,11 @@ class Cassandra
|
|
55
55
|
|
56
56
|
# Slices
|
57
57
|
else
|
58
|
-
predicate = CassandraThrift::SlicePredicate.new(:slice_range =>
|
58
|
+
predicate = CassandraThrift::SlicePredicate.new(:slice_range =>
|
59
59
|
CassandraThrift::SliceRange.new(
|
60
|
-
:reversed => reversed,
|
61
|
-
:count => count,
|
62
|
-
:start => start,
|
60
|
+
:reversed => reversed,
|
61
|
+
:count => count,
|
62
|
+
:start => start,
|
63
63
|
:finish => finish))
|
64
64
|
|
65
65
|
if is_super(column_family) and column
|
@@ -72,16 +72,17 @@ class Cassandra
|
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
75
|
-
def _get_range(column_family, start_key, finish_key, key_count, columns, start, finish, count, consistency)
|
75
|
+
def _get_range(column_family, start_key, finish_key, key_count, columns, start, finish, count, consistency, reversed=false)
|
76
76
|
column_parent = CassandraThrift::ColumnParent.new(:column_family => column_family)
|
77
77
|
predicate = if columns
|
78
78
|
CassandraThrift::SlicePredicate.new(:column_names => columns)
|
79
79
|
else
|
80
|
-
CassandraThrift::SlicePredicate.new(:slice_range =>
|
80
|
+
CassandraThrift::SlicePredicate.new(:slice_range =>
|
81
81
|
CassandraThrift::SliceRange.new(
|
82
|
-
:start => start,
|
82
|
+
:start => start,
|
83
83
|
:finish => finish,
|
84
|
-
:count => count
|
84
|
+
:count => count,
|
85
|
+
:reversed => reversed))
|
85
86
|
end
|
86
87
|
range = CassandraThrift::KeyRange.new(:start_key => start_key, :end_key => finish_key, :count => key_count)
|
87
88
|
client.get_range_slices(@keyspace, column_parent, predicate, range, consistency)
|
data/lib/cassandra/cassandra.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
Create a new Cassandra client instance. Accepts a keyspace name, and optional host and port.
|
4
4
|
|
5
5
|
client = Cassandra.new('twitter', '127.0.0.1:9160')
|
6
|
-
|
6
|
+
|
7
7
|
If the server requires authentication, you must authenticate before make calls
|
8
8
|
|
9
9
|
client.login!('username','password')
|
@@ -64,6 +64,8 @@ class Cassandra
|
|
64
64
|
:thrift_client_class => ThriftClient
|
65
65
|
}
|
66
66
|
|
67
|
+
THRIFT_DEFAULTS[:protocol] = Thrift::BinaryProtocolAccelerated if Thrift.const_defined?(:BinaryProtocolAccelerated)
|
68
|
+
|
67
69
|
attr_reader :keyspace, :servers, :schema, :thrift_client_options, :thrift_client_class, :auth_request
|
68
70
|
|
69
71
|
def self.DEFAULT_TRANSPORT_WRAPPER
|
@@ -75,6 +77,8 @@ class Cassandra
|
|
75
77
|
@is_super = {}
|
76
78
|
@column_name_class = {}
|
77
79
|
@sub_column_name_class = {}
|
80
|
+
@column_name_maker = {}
|
81
|
+
@sub_column_name_maker = {}
|
78
82
|
@auto_discover_nodes = true
|
79
83
|
thrift_client_options[:transport_wrapper] ||= Cassandra.DEFAULT_TRANSPORT_WRAPPER
|
80
84
|
@thrift_client_options = THRIFT_DEFAULTS.merge(thrift_client_options)
|
@@ -462,7 +466,7 @@ class Cassandra
|
|
462
466
|
|
463
467
|
##
|
464
468
|
# This method is used to delete (actually marking them as deleted with a
|
465
|
-
# tombstone) rows, columns, or super columns depending on the parameters
|
469
|
+
# tombstone) rows, columns, or super columns depending on the parameters
|
466
470
|
# passed. If only a key is passed the entire row will be marked as deleted.
|
467
471
|
# If a column name is passed in that column will be deleted.
|
468
472
|
#
|
@@ -483,14 +487,14 @@ class Cassandra
|
|
483
487
|
column_family, column, sub_column, options = extract_and_validate_params(column_family, key, columns_and_options, WRITE_DEFAULTS)
|
484
488
|
|
485
489
|
if @batch
|
486
|
-
mutation_map =
|
490
|
+
mutation_map =
|
487
491
|
{
|
488
492
|
key => {
|
489
493
|
column_family => [ _delete_mutation(column_family, column, sub_column, options[:timestamp]|| Time.stamp) ]
|
490
494
|
}
|
491
495
|
}
|
492
496
|
@batch << [mutation_map, options[:consistency]]
|
493
|
-
else
|
497
|
+
else
|
494
498
|
# Let's continue using the 'remove' thrift method...not sure about the implications/performance of using the mutate instead
|
495
499
|
# Otherwise we coul get use the mutation_map above, and do _mutate(mutation_map, options[:consistency])
|
496
500
|
args = {:column_family => column_family}
|
@@ -514,8 +518,8 @@ class Cassandra
|
|
514
518
|
# * :consistency - Uses the default read consistency if none specified.
|
515
519
|
#
|
516
520
|
def count_columns(column_family, key, *columns_and_options)
|
517
|
-
column_family, super_column, _, options =
|
518
|
-
extract_and_validate_params(column_family, key, columns_and_options, READ_DEFAULTS)
|
521
|
+
column_family, super_column, _, options =
|
522
|
+
extract_and_validate_params(column_family, key, columns_and_options, READ_DEFAULTS)
|
519
523
|
_count_columns(column_family, key, super_column, options[:start], options[:stop], options[:count], options[:consistency])
|
520
524
|
end
|
521
525
|
|
@@ -538,7 +542,7 @@ class Cassandra
|
|
538
542
|
end
|
539
543
|
|
540
544
|
##
|
541
|
-
# Return a hash of column value pairs for the path you request.
|
545
|
+
# Return a hash of column value pairs for the path you request.
|
542
546
|
#
|
543
547
|
# * column_family - The column_family that you are inserting into.
|
544
548
|
# * key - The row key to insert.
|
@@ -548,8 +552,8 @@ class Cassandra
|
|
548
552
|
# * :consistency - Uses the default read consistency if none specified.
|
549
553
|
#
|
550
554
|
def get_columns(column_family, key, *columns_and_options)
|
551
|
-
column_family, columns, sub_columns, options =
|
552
|
-
extract_and_validate_params(column_family, key, columns_and_options, READ_DEFAULTS)
|
555
|
+
column_family, columns, sub_columns, options =
|
556
|
+
extract_and_validate_params(column_family, key, columns_and_options, READ_DEFAULTS)
|
553
557
|
_get_columns(column_family, key, columns, sub_columns, options[:consistency])
|
554
558
|
end
|
555
559
|
|
@@ -574,7 +578,7 @@ class Cassandra
|
|
574
578
|
##
|
575
579
|
# Return a hash (actually, a Cassandra::OrderedHash) or a single value
|
576
580
|
# representing the element at the column_family:key:[column]:[sub_column]
|
577
|
-
# path you request.
|
581
|
+
# path you request.
|
578
582
|
#
|
579
583
|
# * column_family - The column_family that you are inserting into.
|
580
584
|
# * key - The row key to insert.
|
@@ -613,7 +617,7 @@ class Cassandra
|
|
613
617
|
# * :consistency - Uses the default read consistency if none specified.
|
614
618
|
#
|
615
619
|
def multi_get(column_family, keys, *columns_and_options)
|
616
|
-
column_family, column, sub_column, options =
|
620
|
+
column_family, column, sub_column, options =
|
617
621
|
extract_and_validate_params(column_family, keys, columns_and_options, READ_DEFAULTS)
|
618
622
|
|
619
623
|
hash = _multiget(column_family, keys, column, sub_column, options[:count], options[:start], options[:finish], options[:reversed], options[:consistency])
|
@@ -642,7 +646,7 @@ class Cassandra
|
|
642
646
|
# * :consistency - Uses the default read consistency if none specified.
|
643
647
|
#
|
644
648
|
def exists?(column_family, key, *columns_and_options)
|
645
|
-
column_family, column, sub_column, options =
|
649
|
+
column_family, column, sub_column, options =
|
646
650
|
extract_and_validate_params(column_family, key, columns_and_options, READ_DEFAULTS)
|
647
651
|
result = if column
|
648
652
|
_multiget(column_family, [key], column, sub_column, 1, '', '', false, options[:consistency])[key]
|
@@ -663,7 +667,7 @@ class Cassandra
|
|
663
667
|
# Cassandra#get_range_single will be used.
|
664
668
|
#
|
665
669
|
# The start_key and finish_key parameters are only useful for iterating of all records
|
666
|
-
# as is done in the Cassandra#each and Cassandra#each_key methods if you are using the
|
670
|
+
# as is done in the Cassandra#each and Cassandra#each_key methods if you are using the
|
667
671
|
# RandomPartitioner.
|
668
672
|
#
|
669
673
|
# If the table is partitioned with OrderPreservingPartitioner you may
|
@@ -674,11 +678,11 @@ class Cassandra
|
|
674
678
|
# each record returned.
|
675
679
|
#
|
676
680
|
# Please note that Cassandra returns a row for each row that has existed in the
|
677
|
-
# system since gc_grace_seconds. This is because deleted row keys are marked as
|
681
|
+
# system since gc_grace_seconds. This is because deleted row keys are marked as
|
678
682
|
# deleted, but left in the system until the cluster has had resonable time to replicate the deletion.
|
679
683
|
# This function attempts to suppress deleted rows (actually any row returned without
|
680
684
|
# columns is suppressed).
|
681
|
-
#
|
685
|
+
#
|
682
686
|
# Please note that when enabling the :reversed option, :start and :finish should be swapped (e.g.
|
683
687
|
# reversal happens before selecting the range).
|
684
688
|
#
|
@@ -712,8 +716,8 @@ class Cassandra
|
|
712
716
|
def get_range_single(column_family, options = {})
|
713
717
|
return_empty_rows = options.delete(:return_empty_rows) || false
|
714
718
|
|
715
|
-
column_family, _, _, options =
|
716
|
-
extract_and_validate_params(column_family, "", [options],
|
719
|
+
column_family, _, _, options =
|
720
|
+
extract_and_validate_params(column_family, "", [options],
|
717
721
|
READ_DEFAULTS.merge(:start_key => '',
|
718
722
|
:finish_key => '',
|
719
723
|
:key_count => 100,
|
@@ -847,10 +851,10 @@ class Cassandra
|
|
847
851
|
@batch = []
|
848
852
|
yield(self)
|
849
853
|
compacted_map,seen_clevels = compact_mutations!
|
850
|
-
clevel = if options[:consistency] != nil # Override any clevel from individual mutations if
|
854
|
+
clevel = if options[:consistency] != nil # Override any clevel from individual mutations if
|
851
855
|
options[:consistency]
|
852
856
|
elsif seen_clevels.length > 1 # Cannot choose which CLevel to use if there are several ones
|
853
|
-
raise "Multiple consistency levels used in the batch, and no override...cannot pick one"
|
857
|
+
raise "Multiple consistency levels used in the batch, and no override...cannot pick one"
|
854
858
|
else # if no consistency override has been provided but all the clevels in the batch are the same: use that one
|
855
859
|
seen_clevels.first
|
856
860
|
end
|
@@ -950,7 +954,7 @@ class Cassandra
|
|
950
954
|
|
951
955
|
##
|
952
956
|
# This method is used to query a secondary index with a set of
|
953
|
-
# provided search parameters
|
957
|
+
# provided search parameters.
|
954
958
|
#
|
955
959
|
# Please note that you can either specify a
|
956
960
|
# CassandraThrift::IndexClause or an array of hashes with the
|
@@ -963,7 +967,7 @@ class Cassandra
|
|
963
967
|
# * :comparison - Type of comparison to do.
|
964
968
|
# * options
|
965
969
|
# * :key_count - Set maximum number of rows to return. (Only works if CassandraThrift::IndexClause is not passed in.)
|
966
|
-
# * :
|
970
|
+
# * :start_key - Set starting row key for search. (Only works if CassandraThrift::IndexClause is not passed in.)
|
967
971
|
# * :consistency
|
968
972
|
#
|
969
973
|
# TODO: Supercolumn support.
|
@@ -971,14 +975,17 @@ class Cassandra
|
|
971
975
|
return false if Cassandra.VERSION.to_f < 0.7
|
972
976
|
|
973
977
|
column_family, columns, _, options =
|
974
|
-
extract_and_validate_params(column_family, [], columns_and_options,
|
978
|
+
extract_and_validate_params(column_family, [], columns_and_options,
|
979
|
+
READ_DEFAULTS.merge(:key_count => 100, :start_key => nil, :key_start => nil))
|
980
|
+
|
981
|
+
start_key = options[:start_key] || options[:key_start] || ""
|
975
982
|
|
976
983
|
if index_clause.class != CassandraThrift::IndexClause
|
977
984
|
index_expressions = index_clause.collect do |expression|
|
978
985
|
create_index_expression(expression[:column_name], expression[:value], expression[:comparison])
|
979
986
|
end
|
980
987
|
|
981
|
-
index_clause = create_index_clause(index_expressions,
|
988
|
+
index_clause = create_index_clause(index_expressions, start_key, options[:key_count])
|
982
989
|
end
|
983
990
|
|
984
991
|
key_slices = _get_indexed_slices(column_family, index_clause, columns, options[:count], options[:start],
|
@@ -1005,13 +1012,13 @@ class Cassandra
|
|
1005
1012
|
@batch.each do |mutation_op|
|
1006
1013
|
# A single mutation op looks like:
|
1007
1014
|
# For an insert/update
|
1008
|
-
#[ { key1 =>
|
1015
|
+
#[ { key1 =>
|
1009
1016
|
# { CF1 => [several of CassThrift:Mutation(colname,value,TS,ttl)]
|
1010
1017
|
# CF2 => [several mutations]
|
1011
1018
|
# },
|
1012
1019
|
# key2 => {...} # Not sure if they can come batched like this...so there might only be a single key (and CF)
|
1013
1020
|
# }, # [0]
|
1014
|
-
# consistency # [1]
|
1021
|
+
# consistency # [1]
|
1015
1022
|
#]
|
1016
1023
|
mmap = mutation_op[0] # :remove OR a hash like {"key"=> {"CF"=>[mutationclass1,...] } }
|
1017
1024
|
used_clevels[mutation_op[1]] = true #save the clevel required for this operation
|