cassandra 0.11.0 → 0.11.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.
Files changed (67) hide show
  1. data/CHANGELOG +10 -0
  2. data/LICENSE +0 -0
  3. data/Manifest +12 -13
  4. data/README.md +344 -0
  5. data/Rakefile +52 -8
  6. data/cassandra.gemspec +5 -5
  7. data/conf/0.6/cassandra.in.sh +0 -0
  8. data/conf/0.6/log4j.properties +0 -0
  9. data/conf/0.6/schema.json +9 -0
  10. data/conf/0.6/storage-conf.xml +10 -0
  11. data/conf/0.7/cassandra.in.sh +0 -0
  12. data/conf/0.7/cassandra.yaml +0 -0
  13. data/conf/0.7/log4j-server.properties +0 -0
  14. data/conf/0.7/schema.json +9 -0
  15. data/conf/0.7/schema.txt +5 -16
  16. data/conf/0.8/cassandra.in.sh +0 -0
  17. data/conf/0.8/cassandra.yaml +1 -1
  18. data/conf/0.8/log4j-server.properties +0 -0
  19. data/conf/0.8/schema.json +19 -1
  20. data/conf/0.8/schema.txt +12 -17
  21. data/lib/cassandra.rb +3 -2
  22. data/lib/cassandra/0.6.rb +0 -0
  23. data/lib/cassandra/0.6/cassandra.rb +57 -6
  24. data/lib/cassandra/0.6/columns.rb +19 -0
  25. data/lib/cassandra/0.6/protocol.rb +2 -1
  26. data/lib/cassandra/0.7.rb +0 -0
  27. data/lib/cassandra/0.7/cassandra.rb +0 -270
  28. data/lib/cassandra/0.7/columns.rb +1 -81
  29. data/lib/cassandra/0.7/protocol.rb +0 -112
  30. data/lib/cassandra/0.8.rb +0 -0
  31. data/lib/cassandra/0.8/cassandra.rb +5 -267
  32. data/lib/cassandra/0.8/columns.rb +1 -81
  33. data/lib/cassandra/0.8/protocol.rb +9 -103
  34. data/lib/cassandra/array.rb +0 -0
  35. data/lib/cassandra/cassandra.rb +715 -92
  36. data/lib/cassandra/{0.7/column_family.rb → column_family.rb} +0 -0
  37. data/lib/cassandra/columns.rb +63 -6
  38. data/lib/cassandra/comparable.rb +0 -0
  39. data/lib/cassandra/constants.rb +0 -0
  40. data/lib/cassandra/debug.rb +0 -0
  41. data/lib/cassandra/helpers.rb +0 -0
  42. data/lib/cassandra/{0.7/keyspace.rb → keyspace.rb} +0 -0
  43. data/lib/cassandra/long.rb +0 -0
  44. data/lib/cassandra/mock.rb +45 -8
  45. data/lib/cassandra/ordered_hash.rb +0 -0
  46. data/lib/cassandra/protocol.rb +119 -0
  47. data/lib/cassandra/time.rb +0 -0
  48. data/test/cassandra_client_test.rb +0 -0
  49. data/test/cassandra_mock_test.rb +3 -0
  50. data/test/cassandra_test.rb +202 -20
  51. data/test/comparable_types_test.rb +0 -0
  52. data/test/eventmachine_test.rb +0 -0
  53. data/test/ordered_hash_test.rb +0 -0
  54. data/test/test_helper.rb +1 -1
  55. data/vendor/0.6/gen-rb/cassandra.rb +0 -0
  56. data/vendor/0.6/gen-rb/cassandra_constants.rb +0 -0
  57. data/vendor/0.6/gen-rb/cassandra_types.rb +0 -0
  58. data/vendor/0.7/gen-rb/cassandra.rb +0 -0
  59. data/vendor/0.7/gen-rb/cassandra_constants.rb +0 -0
  60. data/vendor/0.7/gen-rb/cassandra_types.rb +0 -0
  61. data/vendor/0.8/gen-rb/cassandra.rb +0 -0
  62. data/vendor/0.8/gen-rb/cassandra_constants.rb +0 -0
  63. data/vendor/0.8/gen-rb/cassandra_types.rb +0 -0
  64. metadata +27 -29
  65. data/README.rdoc +0 -99
  66. data/lib/cassandra/0.8/column_family.rb +0 -3
  67. data/lib/cassandra/0.8/keyspace.rb +0 -3
@@ -1,84 +1,4 @@
1
-
2
1
  class Cassandra
3
- # A bunch of crap, mostly related to introspecting on column types
4
2
  module Columns #:nodoc:
5
-
6
- def is_super(column_family)
7
- @is_super[column_family] ||= column_family_property(column_family, 'column_type') == "Super"
8
- end
9
-
10
- def column_name_class(column_family)
11
- @column_name_class[column_family] ||= column_name_class_for_key(column_family, "comparator_type")
12
- end
13
-
14
- def sub_column_name_class(column_family)
15
- @sub_column_name_class[column_family] ||= column_name_class_for_key(column_family, "subcomparator_type")
16
- end
17
-
18
- def column_family_property(column_family, key)
19
- cfdef = schema.cf_defs.find {|cfdef| cfdef.name == column_family }
20
- unless cfdef
21
- raise AccessError, "Invalid column family \"#{column_family}\""
22
- end
23
- cfdef.send(key)
24
- end
25
-
26
- private
27
-
28
- def _standard_insert_mutation(column_family, column_name, value, timestamp, ttl = nil)
29
- CassandraThrift::Mutation.new(
30
- :column_or_supercolumn => CassandraThrift::ColumnOrSuperColumn.new(
31
- :column => CassandraThrift::Column.new(
32
- :name => column_name_class(column_family).new(column_name).to_s,
33
- :value => value,
34
- :timestamp => timestamp,
35
- :ttl => ttl
36
- )
37
- )
38
- )
39
- end
40
-
41
- def _super_insert_mutation(column_family, super_column_name, sub_columns, timestamp, ttl = nil)
42
- CassandraThrift::Mutation.new(:column_or_supercolumn =>
43
- CassandraThrift::ColumnOrSuperColumn.new(
44
- :super_column => CassandraThrift::SuperColumn.new(
45
- :name => column_name_class(column_family).new(super_column_name).to_s,
46
- :columns => sub_columns.collect { |sub_column_name, sub_column_value|
47
- CassandraThrift::Column.new(
48
- :name => sub_column_name_class(column_family).new(sub_column_name).to_s,
49
- :value => sub_column_value.to_s,
50
- :timestamp => timestamp,
51
- :ttl => ttl
52
- )
53
- }
54
- )
55
- )
56
- )
57
- end
58
-
59
- # General info about a deletion object within a mutation
60
- # timestamp - required. If this is the only param, it will cause deletion of the whole key at that TS
61
- # supercolumn - opt. If passed, the deletes will only occur within that supercolumn (only subcolumns
62
- # will be deleted). Otherwise the normal columns will be deleted.
63
- # predicate - opt. Defines how to match the columns to delete. if supercolumn passed, the slice will
64
- # be scoped to subcolumns of that supercolumn.
65
-
66
- # Deletes a single column from the containing key/CF (and possibly supercolumn), at a given timestamp.
67
- # Although mutations (as opposed to 'remove' calls) support deleting slices and lists of columns in one shot, this is not implemented here.
68
- # The main reason being that the batch function takes removes, but removes don't have that capability...so we'd need to change the remove
69
- # methods to use delete mutation calls...although that might have performance implications. We'll leave that refactoring for later.
70
- def _delete_mutation(cf, column, subcolumn, timestamp, options={})
71
- deletion_hash = {:timestamp => timestamp}
72
- if is_super(cf)
73
- deletion_hash[:super_column] = column if column
74
- deletion_hash[:predicate] = CassandraThrift::SlicePredicate.new(:column_names => [subcolumn]) if subcolumn
75
- else
76
- deletion_hash[:predicate] = CassandraThrift::SlicePredicate.new(:column_names => [column]) if column
77
- end
78
- CassandraThrift::Mutation.new(
79
- :deletion => CassandraThrift::Deletion.new(deletion_hash)
80
- )
81
- end
82
-
83
3
  end
84
- end
4
+ end
@@ -1,117 +1,5 @@
1
-
2
1
  class Cassandra
3
2
  # Inner methods for actually doing the Thrift calls
4
3
  module Protocol #:nodoc:
5
- private
6
-
7
- def _mutate(mutation_map, consistency_level)
8
- client.batch_mutate(mutation_map, consistency_level)
9
- end
10
-
11
- def _remove(key, column_path, timestamp, consistency_level)
12
- client.remove(key, column_path, timestamp, consistency_level)
13
- end
14
-
15
- def _count_columns(column_family, key, super_column, consistency)
16
- client.get_count(key,
17
- CassandraThrift::ColumnParent.new(:column_family => column_family, :super_column => super_column),
18
- CassandraThrift::SlicePredicate.new(:slice_range =>
19
- CassandraThrift::SliceRange.new(
20
- :start => '',
21
- :finish => ''
22
- )),
23
- consistency
24
- )
25
- end
26
-
27
- def _get_columns(column_family, key, columns, sub_columns, consistency)
28
- result = if is_super(column_family)
29
- if sub_columns
30
- columns_to_hash(column_family, client.get_slice(key,
31
- CassandraThrift::ColumnParent.new(:column_family => column_family, :super_column => columns),
32
- CassandraThrift::SlicePredicate.new(:column_names => sub_columns),
33
- consistency))
34
- else
35
- columns_to_hash(column_family, client.get_slice(key,
36
- CassandraThrift::ColumnParent.new(:column_family => column_family),
37
- CassandraThrift::SlicePredicate.new(:column_names => columns),
38
- consistency))
39
- end
40
- else
41
- columns_to_hash(column_family, client.get_slice(key,
42
- CassandraThrift::ColumnParent.new(:column_family => column_family),
43
- CassandraThrift::SlicePredicate.new(:column_names => columns),
44
- consistency))
45
- end
46
-
47
- klass = column_name_class(column_family)
48
- (sub_columns || columns).map { |name| result[klass.new(name)] }
49
- end
50
-
51
- def _multiget(column_family, keys, column, sub_column, count, start, finish, reversed, consistency)
52
- # Single values; count and range parameters have no effect
53
- if is_super(column_family) and sub_column
54
- predicate = CassandraThrift::SlicePredicate.new(:column_names => [sub_column])
55
- column_parent = CassandraThrift::ColumnParent.new(:column_family => column_family, :super_column => column)
56
- column_hash = multi_sub_columns_to_hash!(column_family, client.multiget_slice(keys, column_parent, predicate, consistency))
57
-
58
- klass = sub_column_name_class(column_family)
59
- keys.inject({}){|hash, key| hash[key] = column_hash[key][klass.new(sub_column)]; hash}
60
- elsif !is_super(column_family) and column
61
- predicate = CassandraThrift::SlicePredicate.new(:column_names => [column])
62
- column_parent = CassandraThrift::ColumnParent.new(:column_family => column_family)
63
- column_hash = multi_columns_to_hash!(column_family, client.multiget_slice(keys, column_parent, predicate, consistency))
64
-
65
- keys.inject({}){|hash, key| hash[key] = column_hash[key][column]; hash}
66
-
67
- # Slices
68
- else
69
- predicate = CassandraThrift::SlicePredicate.new(:slice_range =>
70
- CassandraThrift::SliceRange.new(
71
- :reversed => reversed,
72
- :count => count,
73
- :start => start,
74
- :finish => finish))
75
-
76
- if is_super(column_family) and column
77
- column_parent = CassandraThrift::ColumnParent.new(:column_family => column_family, :super_column => column)
78
- multi_sub_columns_to_hash!(column_family, client.multiget_slice(keys, column_parent, predicate, consistency))
79
- else
80
- column_parent = CassandraThrift::ColumnParent.new(:column_family => column_family)
81
- multi_columns_to_hash!(column_family, client.multiget_slice(keys, column_parent, predicate, consistency))
82
- end
83
- end
84
- end
85
-
86
- def _get_range(column_family, start_key, finish_key, key_count, columns, start, finish, count, consistency)
87
- column_parent = CassandraThrift::ColumnParent.new(:column_family => column_family)
88
- predicate = if columns
89
- CassandraThrift::SlicePredicate.new(:column_names => columns)
90
- else
91
- CassandraThrift::SlicePredicate.new(:slice_range =>
92
- CassandraThrift::SliceRange.new(
93
- :start => start,
94
- :finish => finish,
95
- :count => count))
96
- end
97
- range = CassandraThrift::KeyRange.new(:start_key => start_key, :end_key => finish_key, :count => key_count)
98
- client.get_range_slices(column_parent, predicate, range, consistency)
99
- end
100
-
101
- # TODO: Supercolumn support
102
- def _get_indexed_slices(column_family, idx_clause, column, count, start, finish, reversed, consistency)
103
- column_parent = CassandraThrift::ColumnParent.new(:column_family => column_family)
104
- if column
105
- predicate = CassandraThrift::SlicePredicate.new(:column_names => [column])
106
- else
107
- predicate = CassandraThrift::SlicePredicate.new(:slice_range =>
108
- CassandraThrift::SliceRange.new(
109
- :reversed => reversed,
110
- :count => count,
111
- :start => start,
112
- :finish => finish))
113
- end
114
- client.get_indexed_slices(column_parent, idx_clause, predicate, consistency)
115
- end
116
4
  end
117
5
  end
File without changes
@@ -1,272 +1,10 @@
1
1
  class Cassandra
2
2
 
3
- def self.DEFAULT_TRANSPORT_WRAPPER
4
- Thrift::FramedTransport
5
- end
6
-
7
- def login!(username, password)
8
- @auth_request = CassandraThrift::AuthenticationRequest.new
9
- @auth_request.credentials = {'username' => username, 'password' => password}
10
- client.login(@auth_request)
11
- end
12
-
13
- def inspect
14
- "#<Cassandra:#{object_id}, @keyspace=#{keyspace.inspect}, @schema={#{
15
- Array(schema(false).cf_defs).map {|cfdef| ":#{cfdef.name} => #{cfdef.column_type}"}.join(', ')
16
- }}, @servers=#{servers.inspect}>"
17
- end
18
-
19
- def keyspace=(ks)
20
- client.set_keyspace(ks)
21
- @schema = nil; @keyspace = ks
22
- end
23
-
24
- def keyspaces
25
- client.describe_keyspaces.to_a.collect {|ksdef| ksdef.name }
26
- end
27
-
28
- def schema(load=true)
29
- if !load && !@schema
30
- Cassandra::Keyspace.new
31
- else
32
- @schema ||= client.describe_keyspace(@keyspace)
33
- end
34
- end
35
-
36
- def schema_agreement?
37
- client.describe_schema_versions().length == 1
38
- end
39
-
40
- def version
41
- client.describe_version()
42
- end
43
-
44
- def cluster_name
45
- @cluster_name ||= client.describe_cluster_name()
46
- end
47
-
48
- def ring
49
- client.describe_ring(@keyspace)
50
- end
51
-
52
- def partitioner
53
- client.describe_partitioner()
54
- end
55
-
56
- ## Delete
57
-
58
- # Remove all rows in the column family you request.
59
- def truncate!(column_family)
60
- client.truncate(column_family.to_s)
61
- end
62
- alias clear_column_family! truncate!
63
-
64
- # Remove all rows in the keyspace.
65
- def clear_keyspace!
66
- schema.cf_defs.each { |cfdef| truncate!(cfdef.name) }
67
- end
68
-
69
- ### Read
70
-
71
- def add_column_family(cf_def)
72
- begin
73
- res = client.system_add_column_family(cf_def)
74
- rescue CassandraThrift::TimedOutException => te
75
- puts "Timed out: #{te.inspect}"
76
- end
77
- @schema = nil
78
- res
79
- end
80
-
81
- def drop_column_family(cf_name)
82
- begin
83
- res = client.system_drop_column_family(cf_name)
84
- rescue CassandraThrift::TimedOutException => te
85
- puts "Timed out: #{te.inspect}"
86
- end
87
- @schema = nil
88
- res
89
- end
90
-
91
- def rename_column_family(old_name, new_name)
92
- begin
93
- res = client.system_rename_column_family(old_name, new_name)
94
- rescue CassandraThrift::TimedOutException => te
95
- puts "Timed out: #{te.inspect}"
96
- end
97
- @schema = nil
98
- res
99
- end
3
+ ## Counters
100
4
 
101
- def update_column_family(cf_def)
102
- begin
103
- res = client.system_update_column_family(cf_def)
104
- rescue CassandraThrift::TimedOutException => te
105
- puts "Timed out: #{te.inspect}"
106
- end
107
- @schema = nil
108
- res
5
+ # Add a value to the counter in cf:key:super column:column
6
+ def add(column_family, key, value, *columns_and_options)
7
+ column_family, column, sub_column, options = extract_and_validate_params(column_family, key, columns_and_options, WRITE_DEFAULTS)
8
+ _add(column_family, key, column, sub_column, value, options[:consistency])
109
9
  end
110
-
111
- def add_keyspace(ks_def)
112
- begin
113
- res = client.system_add_keyspace(ks_def)
114
- rescue CassandraThrift::TimedOutException => toe
115
- puts "Timed out: #{toe.inspect}"
116
- rescue Thrift::TransportException => te
117
- puts "Timed out: #{te.inspect}"
118
- end
119
- @keyspaces = nil
120
- res
121
- end
122
-
123
- def drop_keyspace(ks_name)
124
- begin
125
- res = client.system_drop_keyspace(ks_name)
126
- rescue CassandraThrift::TimedOutException => toe
127
- puts "Timed out: #{toe.inspect}"
128
- rescue Thrift::TransportException => te
129
- puts "Timed out: #{te.inspect}"
130
- end
131
- keyspace = "system" if ks_name.eql?(@keyspace)
132
- @keyspaces = nil
133
- res
134
- end
135
-
136
- def rename_keyspace(old_name, new_name)
137
- begin
138
- res = client.system_rename_keyspace(old_name, new_name)
139
- rescue CassandraThrift::TimedOutException => toe
140
- puts "Timed out: #{toe.inspect}"
141
- rescue Thrift::TransportException => te
142
- puts "Timed out: #{te.inspect}"
143
- end
144
- keyspace = new_name if old_name.eql?(@keyspace)
145
- @keyspaces = nil
146
- res
147
- end
148
-
149
- def update_keyspace(ks_def)
150
- begin
151
- res = client.system_update_keyspace(ks_def)
152
- rescue CassandraThrift::TimedOutException => toe
153
- puts "Timed out: #{toe.inspect}"
154
- rescue Thrift::TransportException => te
155
- puts "Timed out: #{te.inspect}"
156
- end
157
- @keyspaces = nil
158
- res
159
- end
160
-
161
- # Open a batch operation and yield self. Inserts and deletes will be queued
162
- # until the block closes, and then sent atomically to the server. Supports
163
- # the <tt>:consistency</tt> option, which overrides the consistency set in
164
- # the individual commands.
165
- def batch(options = {})
166
- _, _, _, options =
167
- extract_and_validate_params(schema.cf_defs.first.name, "", [options], WRITE_DEFAULTS)
168
-
169
- @batch = []
170
- yield(self)
171
- compacted_map,seen_clevels = compact_mutations!
172
- clevel = if options[:consistency] != nil # Override any clevel from individual mutations if
173
- options[:consistency]
174
- elsif seen_clevels.length > 1 # Cannot choose which CLevel to use if there are several ones
175
- raise "Multiple consistency levels used in the batch, and no override...cannot pick one"
176
- else # if no consistency override has been provided but all the clevels in the batch are the same: use that one
177
- seen_clevels.first
178
- end
179
-
180
- _mutate(compacted_map,clevel)
181
- ensure
182
- @batch = nil
183
- end
184
-
185
- ### 2ary Indexing
186
-
187
- def create_index(ks_name, cf_name, c_name, v_class)
188
- cf_def = client.describe_keyspace(ks_name).cf_defs.find{|x| x.name == cf_name}
189
- if !cf_def.nil? and !cf_def.column_metadata.find{|x| x.name == c_name}
190
- c_def = CassandraThrift::ColumnDef.new do |cd|
191
- cd.name = c_name
192
- cd.validation_class = "org.apache.cassandra.db.marshal."+v_class
193
- cd.index_type = CassandraThrift::IndexType::KEYS
194
- end
195
- cf_def.column_metadata.push(c_def)
196
- update_column_family(cf_def)
197
- end
198
- end
199
-
200
- def drop_index(ks_name, cf_name, c_name)
201
- cf_def = client.describe_keyspace(ks_name).cf_defs.find{|x| x.name == cf_name}
202
- if !cf_def.nil? and cf_def.column_metadata.find{|x| x.name == c_name}
203
- cf_def.column_metadata.delete_if{|x| x.name == c_name}
204
- update_column_family(cf_def)
205
- end
206
- end
207
-
208
- def create_idx_expr(c_name, value, op)
209
- CassandraThrift::IndexExpression.new(
210
- :column_name => c_name,
211
- :value => value,
212
- :op => (case op
213
- when nil, "EQ", "eq", "=="
214
- CassandraThrift::IndexOperator::EQ
215
- when "GTE", "gte", ">="
216
- CassandraThrift::IndexOperator::GTE
217
- when "GT", "gt", ">"
218
- CassandraThrift::IndexOperator::GT
219
- when "LTE", "lte", "<="
220
- CassandraThrift::IndexOperator::LTE
221
- when "LT", "lt", "<"
222
- CassandraThrift::IndexOperator::LT
223
- end ))
224
- end
225
-
226
- def create_idx_clause(idx_expressions, start = "")
227
- CassandraThrift::IndexClause.new(
228
- :start_key => start,
229
- :expressions => idx_expressions)
230
- end
231
-
232
- # TODO: Supercolumn support.
233
- def get_indexed_slices(column_family, idx_clause, *columns_and_options)
234
- column_family, columns, _, options =
235
- extract_and_validate_params(column_family, [], columns_and_options, READ_DEFAULTS)
236
- key_slices = _get_indexed_slices(column_family, idx_clause, columns, options[:count], options[:start],
237
- options[:finish], options[:reversed], options[:consistency])
238
-
239
- key_slices.inject({}){|h, key_slice| h[key_slice.key] = key_slice.columns; h}
240
- end
241
-
242
- protected
243
-
244
- def client
245
- if @client.nil? || @client.current_server.nil?
246
- reconnect!
247
- @client.set_keyspace(@keyspace)
248
- end
249
- @client
250
- end
251
-
252
- def reconnect!
253
- @servers = all_nodes
254
- @client = new_client
255
- end
256
-
257
- def all_nodes
258
- if @auto_discover_nodes && !@keyspace.eql?("system")
259
- temp_client = new_client
260
- begin
261
- ips = (temp_client.describe_ring(@keyspace).map {|range| range.endpoints}).flatten.uniq
262
- port = @servers.first.split(':').last
263
- ips.map{|ip| "#{ip}:#{port}" }
264
- ensure
265
- temp_client.disconnect!
266
- end
267
- else
268
- @servers
269
- end
270
- end
271
-
272
10
  end