cassandra 0.11.0 → 0.11.1

Sign up to get free protection for your applications and to get access to all the features.
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