cassilds 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/CHANGELOG +53 -0
  2. data/LICENSE +202 -0
  3. data/Manifest +45 -0
  4. data/README.rdoc +83 -0
  5. data/Rakefile +9 -0
  6. data/bin/cassandra_helper +16 -0
  7. data/cassandra.gemspec +46 -0
  8. data/conf/cassandra.in.sh +47 -0
  9. data/conf/cassandra.yaml +113 -0
  10. data/conf/log4j.properties +38 -0
  11. data/conf/storage-conf.xml +342 -0
  12. data/lib/cassandra/0.6/cassandra.rb +68 -0
  13. data/lib/cassandra/0.6/columns.rb +35 -0
  14. data/lib/cassandra/0.6/protocol.rb +92 -0
  15. data/lib/cassandra/0.6.rb +7 -0
  16. data/lib/cassandra/0.7/cassandra.rb +272 -0
  17. data/lib/cassandra/0.7/column_family.rb +3 -0
  18. data/lib/cassandra/0.7/columns.rb +67 -0
  19. data/lib/cassandra/0.7/keyspace.rb +3 -0
  20. data/lib/cassandra/0.7/protocol.rb +139 -0
  21. data/lib/cassandra/0.7.rb +7 -0
  22. data/lib/cassandra/array.rb +8 -0
  23. data/lib/cassandra/cassandra.rb +302 -0
  24. data/lib/cassandra/columns.rb +79 -0
  25. data/lib/cassandra/comparable.rb +28 -0
  26. data/lib/cassandra/constants.rb +11 -0
  27. data/lib/cassandra/debug.rb +9 -0
  28. data/lib/cassandra/helpers.rb +40 -0
  29. data/lib/cassandra/long.rb +58 -0
  30. data/lib/cassandra/mock.rb +326 -0
  31. data/lib/cassandra/ordered_hash.rb +200 -0
  32. data/lib/cassandra/time.rb +11 -0
  33. data/lib/cassandra.rb +39 -0
  34. data/test/cassandra_client_test.rb +20 -0
  35. data/test/cassandra_mock_test.rb +73 -0
  36. data/test/cassandra_test.rb +412 -0
  37. data/test/comparable_types_test.rb +45 -0
  38. data/test/eventmachine_test.rb +42 -0
  39. data/test/ordered_hash_test.rb +380 -0
  40. data/test/test_helper.rb +14 -0
  41. data/vendor/0.6/gen-rb/cassandra.rb +1481 -0
  42. data/vendor/0.6/gen-rb/cassandra_constants.rb +12 -0
  43. data/vendor/0.6/gen-rb/cassandra_types.rb +482 -0
  44. data/vendor/0.7/gen-rb/cassandra.rb +1937 -0
  45. data/vendor/0.7/gen-rb/cassandra_constants.rb +12 -0
  46. data/vendor/0.7/gen-rb/cassandra_types.rb +679 -0
  47. metadata +176 -0
@@ -0,0 +1,342 @@
1
+ <!--
2
+ ~ Licensed to the Apache Software Foundation (ASF) under one
3
+ ~ or more contributor license agreements. See the NOTICE file
4
+ ~ distributed with this work for additional information
5
+ ~ regarding copyright ownership. The ASF licenses this file
6
+ ~ to you under the Apache License, Version 2.0 (the
7
+ ~ "License"); you may not use this file except in compliance
8
+ ~ with the License. You may obtain a copy of the License at
9
+ ~
10
+ ~ http://www.apache.org/licenses/LICENSE-2.0
11
+ ~
12
+ ~ Unless required by applicable law or agreed to in writing,
13
+ ~ software distributed under the License is distributed on an
14
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ ~ KIND, either express or implied. See the License for the
16
+ ~ specific language governing permissions and limitations
17
+ ~ under the License.
18
+ -->
19
+ <Storage>
20
+ <!--======================================================================-->
21
+ <!-- Basic Configuration -->
22
+ <!--======================================================================-->
23
+
24
+ <!--
25
+ ~ The name of this cluster. This is mainly used to prevent machines in
26
+ ~ one logical cluster from joining another.
27
+ -->
28
+ <ClusterName>Test</ClusterName>
29
+
30
+ <!--
31
+ ~ Turn on to make new [non-seed] nodes automatically migrate the right data
32
+ ~ to themselves. (If no InitialToken is specified, they will pick one
33
+ ~ such that they will get half the range of the most-loaded node.)
34
+ ~ If a node starts up without bootstrapping, it will mark itself bootstrapped
35
+ ~ so that you can't subsequently accidently bootstrap a node with
36
+ ~ data on it. (You can reset this by wiping your data and commitlog
37
+ ~ directories.)
38
+ ~
39
+ ~ Off by default so that new clusters and upgraders from 0.4 don't
40
+ ~ bootstrap immediately. You should turn this on when you start adding
41
+ ~ new nodes to a cluster that already has data on it. (If you are upgrading
42
+ ~ from 0.4, start your cluster with it off once before changing it to true.
43
+ ~ Otherwise, no data will be lost but you will incur a lot of unnecessary
44
+ ~ I/O before your cluster starts up.)
45
+ -->
46
+ <AutoBootstrap>false</AutoBootstrap>
47
+
48
+ <!--
49
+ ~ Keyspaces and ColumnFamilies:
50
+ ~ A ColumnFamily is the Cassandra concept closest to a relational
51
+ ~ table. Keyspaces are separate groups of ColumnFamilies. Except in
52
+ ~ very unusual circumstances you will have one Keyspace per application.
53
+
54
+ ~ There is an implicit keyspace named 'system' for Cassandra internals.
55
+ -->
56
+ <Keyspaces>
57
+ <Keyspace Name="Twitter">
58
+ <KeysCachedFraction>0.01</KeysCachedFraction>
59
+ <ColumnFamily CompareWith="UTF8Type" Name="Users" />
60
+ <ColumnFamily CompareWith="UTF8Type" Name="UserAudits" />
61
+ <ColumnFamily CompareWith="UTF8Type" CompareSubcolumnsWith="TimeUUIDType" ColumnType="Super" Name="UserRelationships" />
62
+ <ColumnFamily CompareWith="UTF8Type" Name="Usernames" />
63
+ <ColumnFamily CompareWith="UTF8Type" Name="Statuses" />
64
+ <ColumnFamily CompareWith="UTF8Type" Name="StatusAudits" />
65
+ <ColumnFamily CompareWith="UTF8Type" CompareSubcolumnsWith="TimeUUIDType" ColumnType="Super" Name="StatusRelationships" />
66
+ <ColumnFamily CompareWith="UTF8Type" ColumnType="Super" Name="Index" />
67
+ <ColumnFamily CompareWith="BytesType" ColumnType="Standard" Name="TimelinishThings" />
68
+
69
+ <ReplicaPlacementStrategy>org.apache.cassandra.locator.RackUnawareStrategy</ReplicaPlacementStrategy>
70
+ <ReplicationFactor>1</ReplicationFactor>
71
+ <EndPointSnitch>org.apache.cassandra.locator.EndPointSnitch</EndPointSnitch>
72
+ </Keyspace>
73
+
74
+ <Keyspace Name="Multiblog">
75
+ <KeysCachedFraction>0.01</KeysCachedFraction>
76
+ <ColumnFamily CompareWith="TimeUUIDType" Name="Blogs"/>
77
+ <ColumnFamily CompareWith="TimeUUIDType" Name="Comments"/>
78
+
79
+ <ReplicaPlacementStrategy>org.apache.cassandra.locator.RackUnawareStrategy</ReplicaPlacementStrategy>
80
+ <ReplicationFactor>1</ReplicationFactor>
81
+ <EndPointSnitch>org.apache.cassandra.locator.EndPointSnitch</EndPointSnitch>
82
+ </Keyspace>
83
+
84
+ <Keyspace Name="MultiblogLong">
85
+ <KeysCachedFraction>0.01</KeysCachedFraction>
86
+ <ColumnFamily CompareWith="LongType" Name="Blogs"/>
87
+ <ColumnFamily CompareWith="LongType" Name="Comments"/>
88
+
89
+ <ReplicaPlacementStrategy>org.apache.cassandra.locator.RackUnawareStrategy</ReplicaPlacementStrategy>
90
+ <ReplicationFactor>1</ReplicationFactor>
91
+ <EndPointSnitch>org.apache.cassandra.locator.EndPointSnitch</EndPointSnitch>
92
+ </Keyspace>
93
+
94
+ <Keyspace Name="CassandraObject">
95
+ <KeysCachedFraction>0.01</KeysCachedFraction>
96
+ <ColumnFamily CompareWith="UTF8Type" Name="Customers" />
97
+ <ColumnFamily CompareWith="UTF8Type" CompareSubcolumnsWith="TimeUUIDType" ColumnType="Super" Name="CustomerRelationships" />
98
+ <ColumnFamily CompareWith="TimeUUIDType" Name="CustomersByLastName" />
99
+ <ColumnFamily CompareWith="UTF8Type" Name="Invoices" />
100
+ <ColumnFamily CompareWith="UTF8Type" CompareSubcolumnsWith="TimeUUIDType" ColumnType="Super" Name="InvoiceRelationships" />
101
+ <ColumnFamily CompareWith="UTF8Type" Name="InvoicesByNumber" />
102
+ <ColumnFamily CompareWith="UTF8Type" Name="Payments" />
103
+ <ColumnFamily CompareWith="UTF8Type" Name="Appointments" />
104
+ <!-- <ColumnFamily CompareWith="UTF8Type" Name="FirstNames" /> -->
105
+
106
+ <ReplicaPlacementStrategy>org.apache.cassandra.locator.RackUnawareStrategy</ReplicaPlacementStrategy>
107
+ <ReplicationFactor>1</ReplicationFactor>
108
+ <EndPointSnitch>org.apache.cassandra.locator.EndPointSnitch</EndPointSnitch>
109
+ </Keyspace>
110
+ </Keyspaces>
111
+
112
+ <!--
113
+ ~ Authenticator: any IAuthenticator may be used, including your own as long
114
+ ~ as it is on the classpath. Out of the box, Cassandra provides
115
+ ~ org.apache.cassandra.auth.AllowAllAuthenticator and,
116
+ ~ org.apache.cassandra.auth.SimpleAuthenticator
117
+ ~ (SimpleAuthenticator uses access.properties and passwd.properties by
118
+ ~ default).
119
+ ~
120
+ ~ If you don't specify an authenticator, AllowAllAuthenticator is used.
121
+ -->
122
+ <Authenticator>org.apache.cassandra.auth.AllowAllAuthenticator</Authenticator>
123
+
124
+ <!--
125
+ ~ Partitioner: any IPartitioner may be used, including your own as long
126
+ ~ as it is on the classpath. Out of the box, Cassandra provides
127
+ ~ org.apache.cassandra.dht.RandomPartitioner,
128
+ ~ org.apache.cassandra.dht.OrderPreservingPartitioner, and
129
+ ~ org.apache.cassandra.dht.CollatingOrderPreservingPartitioner.
130
+ ~ (CollatingOPP colates according to EN,US rules, not naive byte
131
+ ~ ordering. Use this as an example if you need locale-aware collation.)
132
+ ~ Range queries require using an order-preserving partitioner.
133
+ ~
134
+ ~ Achtung! Changing this parameter requires wiping your data
135
+ ~ directories, since the partitioner can modify the sstable on-disk
136
+ ~ format.
137
+ -->
138
+ <Partitioner>org.apache.cassandra.dht.RandomPartitioner</Partitioner>
139
+
140
+ <!--
141
+ ~ If you are using an order-preserving partitioner and you know your key
142
+ ~ distribution, you can specify the token for this node to use. (Keys
143
+ ~ are sent to the node with the "closest" token, so distributing your
144
+ ~ tokens equally along the key distribution space will spread keys
145
+ ~ evenly across your cluster.) This setting is only checked the first
146
+ ~ time a node is started.
147
+
148
+ ~ This can also be useful with RandomPartitioner to force equal spacing
149
+ ~ of tokens around the hash space, especially for clusters with a small
150
+ ~ number of nodes.
151
+ -->
152
+ <InitialToken></InitialToken>
153
+
154
+ <!--
155
+ ~ Directories: Specify where Cassandra should store different data on
156
+ ~ disk. Keep the data disks and the CommitLog disks separate for best
157
+ ~ performance
158
+ -->
159
+ <CommitLogDirectory>data/cassandra/commitlog</CommitLogDirectory>
160
+ <DataFileDirectories>
161
+ <DataFileDirectory>data/cassandra/data</DataFileDirectory>
162
+ </DataFileDirectories>
163
+ <CalloutLocation>data/cassandra/callouts</CalloutLocation>
164
+ <StagingFileDirectory>data/cassandra/staging</StagingFileDirectory>
165
+ <SavedCachesDirectory>data/cassandra/saved_caches</SavedCachesDirectory>
166
+
167
+
168
+ <!--
169
+ ~ Addresses of hosts that are deemed contact points. Cassandra nodes
170
+ ~ use this list of hosts to find each other and learn the topology of
171
+ ~ the ring. You must change this if you are running multiple nodes!
172
+ -->
173
+ <Seeds>
174
+ <Seed>127.0.0.1</Seed>
175
+ </Seeds>
176
+
177
+
178
+ <!-- Miscellaneous -->
179
+
180
+ <!-- Time to wait for a reply from other nodes before failing the command -->
181
+ <RpcTimeoutInMillis>5000</RpcTimeoutInMillis>
182
+ <!-- Size to allow commitlog to grow to before creating a new segment -->
183
+ <CommitLogRotationThresholdInMB>128</CommitLogRotationThresholdInMB>
184
+
185
+
186
+ <!-- Local hosts and ports -->
187
+
188
+ <!--
189
+ ~ Address to bind to and tell other nodes to connect to. You _must_
190
+ ~ change this if you want multiple nodes to be able to communicate!
191
+ ~
192
+ ~ Leaving it blank leaves it up to InetAddress.getLocalHost(). This
193
+ ~ will always do the Right Thing *if* the node is properly configured
194
+ ~ (hostname, name resolution, etc), and the Right Thing is to use the
195
+ ~ address associated with the hostname (it might not be).
196
+ -->
197
+ <ListenAddress>localhost</ListenAddress>
198
+ <!-- internal communications port -->
199
+ <StoragePort>7000</StoragePort>
200
+
201
+ <!--
202
+ ~ The address to bind the Thrift RPC service to. Unlike ListenAddress
203
+ ~ above, you *can* specify 0.0.0.0 here if you want Thrift to listen on
204
+ ~ all interfaces.
205
+ ~
206
+ ~ Leaving this blank has the same effect it does for ListenAddress,
207
+ ~ (i.e. it will be based on the configured hostname of the node).
208
+ -->
209
+ <ThriftAddress>localhost</ThriftAddress>
210
+ <!-- Thrift RPC port (the port clients connect to). -->
211
+ <ThriftPort>9160</ThriftPort>
212
+ <!--
213
+ ~ Whether or not to use a framed transport for Thrift. If this option
214
+ ~ is set to true then you must also use a framed transport on the
215
+ ~ client-side, (framed and non-framed transports are not compatible).
216
+ -->
217
+ <ThriftFramedTransport>false</ThriftFramedTransport>
218
+
219
+
220
+ <!--======================================================================-->
221
+ <!-- Memory, Disk, and Performance -->
222
+ <!--======================================================================-->
223
+
224
+ <!--
225
+ ~ Access mode. mmapped i/o is substantially faster, but only practical on
226
+ ~ a 64bit machine (which notably does not include EC2 "small" instances)
227
+ ~ or relatively small datasets. "auto", the safe choice, will enable
228
+ ~ mmapping on a 64bit JVM. Other values are "mmap", "mmap_index_only"
229
+ ~ (which may allow you to get part of the benefits of mmap on a 32bit
230
+ ~ machine by mmapping only index files) and "standard".
231
+ ~ (The buffer size settings that follow only apply to standard,
232
+ ~ non-mmapped i/o.)
233
+ -->
234
+ <DiskAccessMode>auto</DiskAccessMode>
235
+
236
+ <!--
237
+ ~ Buffer size to use when performing contiguous column slices. Increase
238
+ ~ this to the size of the column slices you typically perform.
239
+ ~ (Name-based queries are performed with a buffer size of
240
+ ~ ColumnIndexSizeInKB.)
241
+ -->
242
+ <SlicedBufferSizeInKB>64</SlicedBufferSizeInKB>
243
+
244
+ <!--
245
+ ~ Buffer size to use when flushing memtables to disk. (Only one
246
+ ~ memtable is ever flushed at a time.) Increase (decrease) the index
247
+ ~ buffer size relative to the data buffer if you have few (many)
248
+ ~ columns per key. Bigger is only better _if_ your memtables get large
249
+ ~ enough to use the space. (Check in your data directory after your
250
+ ~ app has been running long enough.) -->
251
+ <FlushDataBufferSizeInMB>32</FlushDataBufferSizeInMB>
252
+ <FlushIndexBufferSizeInMB>8</FlushIndexBufferSizeInMB>
253
+
254
+ <!--
255
+ ~ Add column indexes to a row after its contents reach this size.
256
+ ~ Increase if your column values are large, or if you have a very large
257
+ ~ number of columns. The competing causes are, Cassandra has to
258
+ ~ deserialize this much of the row to read a single column, so you want
259
+ ~ it to be small - at least if you do many partial-row reads - but all
260
+ ~ the index data is read for each access, so you don't want to generate
261
+ ~ that wastefully either.
262
+ -->
263
+ <ColumnIndexSizeInKB>64</ColumnIndexSizeInKB>
264
+
265
+ <!--
266
+ ~ Flush memtable after this much data has been inserted, including
267
+ ~ overwritten data. There is one memtable per column family, and
268
+ ~ this threshold is based solely on the amount of data stored, not
269
+ ~ actual heap memory usage (there is some overhead in indexing the
270
+ ~ columns).
271
+ -->
272
+ <MemtableThroughputInMB>64</MemtableThroughputInMB>
273
+ <!--
274
+ ~ Throughput setting for Binary Memtables. Typically these are
275
+ ~ used for bulk load so you want them to be larger.
276
+ -->
277
+ <BinaryMemtableThroughputInMB>256</BinaryMemtableThroughputInMB>
278
+ <!--
279
+ ~ The maximum number of columns in millions to store in memory per
280
+ ~ ColumnFamily before flushing to disk. This is also a per-memtable
281
+ ~ setting. Use with MemtableThroughputInMB to tune memory usage.
282
+ -->
283
+ <MemtableOperationsInMillions>0.3</MemtableOperationsInMillions>
284
+ <!--
285
+ ~ The maximum time to leave a dirty memtable unflushed.
286
+ ~ (While any affected columnfamilies have unflushed data from a
287
+ ~ commit log segment, that segment cannot be deleted.)
288
+ ~ This needs to be large enough that it won't cause a flush storm
289
+ ~ of all your memtables flushing at once because none has hit
290
+ ~ the size or count thresholds yet. For production, a larger
291
+ ~ value such as 1440 is recommended.
292
+ -->
293
+ <MemtableFlushAfterMinutes>60</MemtableFlushAfterMinutes>
294
+
295
+ <!--
296
+ ~ Unlike most systems, in Cassandra writes are faster than reads, so
297
+ ~ you can afford more of those in parallel. A good rule of thumb is 2
298
+ ~ concurrent reads per processor core. Increase ConcurrentWrites to
299
+ ~ the number of clients writing at once if you enable CommitLogSync +
300
+ ~ CommitLogSyncDelay. -->
301
+ <ConcurrentReads>8</ConcurrentReads>
302
+ <ConcurrentWrites>32</ConcurrentWrites>
303
+
304
+ <!--
305
+ ~ CommitLogSync may be either "periodic" or "batch." When in batch
306
+ ~ mode, Cassandra won't ack writes until the commit log has been
307
+ ~ fsynced to disk. It will wait up to CommitLogSyncBatchWindowInMS
308
+ ~ milliseconds for other writes, before performing the sync.
309
+
310
+ ~ This is less necessary in Cassandra than in traditional databases
311
+ ~ since replication reduces the odds of losing data from a failure
312
+ ~ after writing the log entry but before it actually reaches the disk.
313
+ ~ So the other option is "timed," where writes may be acked immediately
314
+ ~ and the CommitLog is simply synced every CommitLogSyncPeriodInMS
315
+ ~ milliseconds.
316
+ -->
317
+ <CommitLogSync>periodic</CommitLogSync>
318
+ <!--
319
+ ~ Interval at which to perform syncs of the CommitLog in periodic mode.
320
+ ~ Usually the default of 10000ms is fine; increase it if your i/o
321
+ ~ load is such that syncs are taking excessively long times.
322
+ -->
323
+ <CommitLogSyncPeriodInMS>10000</CommitLogSyncPeriodInMS>
324
+ <!--
325
+ ~ Delay (in milliseconds) during which additional commit log entries
326
+ ~ may be written before fsync in batch mode. This will increase
327
+ ~ latency slightly, but can vastly improve throughput where there are
328
+ ~ many writers. Set to zero to disable (each entry will be synced
329
+ ~ individually). Reasonable values range from a minimal 0.1 to 10 or
330
+ ~ even more if throughput matters more than latency.
331
+ -->
332
+ <!-- <CommitLogSyncBatchWindowInMS>1</CommitLogSyncBatchWindowInMS> -->
333
+
334
+ <!--
335
+ ~ Time to wait before garbage-collection deletion markers. Set this to
336
+ ~ a large enough value that you are confident that the deletion marker
337
+ ~ will be propagated to all replicas by the time this many seconds has
338
+ ~ elapsed, even in the face of hardware failures. The default value is
339
+ ~ ten days.
340
+ -->
341
+ <GCGraceSeconds>864000</GCGraceSeconds>
342
+ </Storage>
@@ -0,0 +1,68 @@
1
+ class Cassandra
2
+ def self.DEFAULT_TRANSPORT_WRAPPER
3
+ Thrift::BufferedTransport
4
+ end
5
+
6
+ ## Delete
7
+
8
+ # Remove all rows in the column family you request. Supports options
9
+ # <tt>:consistency</tt> and <tt>:timestamp</tt>.
10
+ # FIXME May not currently delete all records without multiple calls. Waiting
11
+ # for ranged remove support in Cassandra.
12
+ def clear_column_family!(column_family, options = {})
13
+ each_key(column_family) do |key|
14
+ remove(column_family, key, options)
15
+ end
16
+ end
17
+
18
+ # Remove all rows in the keyspace. Supports options <tt>:consistency</tt> and
19
+ # <tt>:timestamp</tt>.
20
+ # FIXME May not currently delete all records without multiple calls. Waiting
21
+ # for ranged remove support in Cassandra.
22
+ def clear_keyspace!(options = {})
23
+ schema.keys.each { |column_family| clear_column_family!(column_family, options) }
24
+ end
25
+
26
+ protected
27
+
28
+ def schema(load=true)
29
+ if !load && !@schema
30
+ []
31
+ else
32
+ @schema ||= client.describe_keyspace(@keyspace)
33
+ end
34
+ end
35
+
36
+ def client
37
+ reconnect! if @client.nil?
38
+ @client
39
+ end
40
+
41
+ def reconnect!
42
+ @servers = all_nodes
43
+ @client = new_client
44
+ check_keyspace
45
+ end
46
+
47
+ def check_keyspace
48
+ unless (keyspaces = client.get_string_list_property("keyspaces")).include?(@keyspace)
49
+ raise AccessError, "Keyspace #{@keyspace.inspect} not found. Available: #{keyspaces.inspect}"
50
+ end
51
+ end
52
+
53
+ def all_nodes
54
+ if @auto_discover_nodes
55
+ temp_client = new_client
56
+ begin
57
+ ips = ::JSON.parse(temp_client.get_string_property('token map')).values
58
+ port = @servers.first.split(':').last
59
+ ips.map{|ip| "#{ip}:#{port}" }
60
+ ensure
61
+ temp_client.disconnect!
62
+ end
63
+ else
64
+ @servers
65
+ end
66
+ end
67
+
68
+ end
@@ -0,0 +1,35 @@
1
+ class Cassandra
2
+ # A bunch of crap, mostly related to introspecting on column types
3
+ module Columns #:nodoc:
4
+ private
5
+
6
+ def _standard_insert_mutation(column_family, column_name, value, timestamp, _=nil)
7
+ CassandraThrift::Mutation.new(
8
+ :column_or_supercolumn => CassandraThrift::ColumnOrSuperColumn.new(
9
+ :column => CassandraThrift::Column.new(
10
+ :name => column_name_class(column_family).new(column_name).to_s,
11
+ :value => value,
12
+ :timestamp => timestamp
13
+ )
14
+ )
15
+ )
16
+ end
17
+
18
+ def _super_insert_mutation(column_family, super_column_name, sub_columns, timestamp, _=nil)
19
+ CassandraThrift::Mutation.new(:column_or_supercolumn =>
20
+ CassandraThrift::ColumnOrSuperColumn.new(
21
+ :super_column => CassandraThrift::SuperColumn.new(
22
+ :name => column_name_class(column_family).new(super_column_name).to_s,
23
+ :columns => sub_columns.collect { |sub_column_name, sub_column_value|
24
+ CassandraThrift::Column.new(
25
+ :name => sub_column_name_class(column_family).new(sub_column_name).to_s,
26
+ :value => sub_column_value.to_s,
27
+ :timestamp => timestamp
28
+ )
29
+ }
30
+ )
31
+ )
32
+ )
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,92 @@
1
+
2
+ class Cassandra
3
+ # Inner methods for actually doing the Thrift calls
4
+ module Protocol #:nodoc:
5
+ private
6
+
7
+ def _mutate(mutation_map, consistency_level)
8
+ client.batch_mutate(@keyspace, mutation_map, consistency_level)
9
+ end
10
+
11
+ def _remove(key, column_path, timestamp, consistency_level)
12
+ client.remove(@keyspace, key, column_path, timestamp, consistency_level)
13
+ end
14
+
15
+ def _count_columns(column_family, key, super_column, consistency)
16
+ client.get_count(@keyspace, key,
17
+ CassandraThrift::ColumnParent.new(:column_family => column_family, :super_column => super_column),
18
+ consistency
19
+ )
20
+ end
21
+
22
+ def _get_columns(column_family, key, columns, sub_columns, consistency)
23
+ result = if is_super(column_family)
24
+ if sub_columns
25
+ columns_to_hash(column_family, client.get_slice(@keyspace, key,
26
+ CassandraThrift::ColumnParent.new(:column_family => column_family, :super_column => columns),
27
+ CassandraThrift::SlicePredicate.new(:column_names => sub_columns),
28
+ consistency))
29
+ else
30
+ columns_to_hash(column_family, client.get_slice(@keyspace, key,
31
+ CassandraThrift::ColumnParent.new(:column_family => column_family),
32
+ CassandraThrift::SlicePredicate.new(:column_names => columns),
33
+ consistency))
34
+ end
35
+ else
36
+ columns_to_hash(column_family, client.get_slice(@keyspace, key,
37
+ CassandraThrift::ColumnParent.new(:column_family => column_family),
38
+ CassandraThrift::SlicePredicate.new(:column_names => columns),
39
+ consistency))
40
+ end
41
+
42
+ klass = column_name_class(column_family)
43
+ (sub_columns || columns).map { |name| result[klass.new(name)] }
44
+ end
45
+
46
+ def _multiget(column_family, keys, column, sub_column, count, start, finish, reversed, consistency)
47
+ # Single values; count and range parameters have no effect
48
+ if is_super(column_family) and sub_column
49
+ column_path = CassandraThrift::ColumnPath.new(:column_family => column_family, :super_column => column, :column => sub_column)
50
+ multi_column_to_hash!(client.multiget(@keyspace, keys, column_path, consistency))
51
+ elsif !is_super(column_family) and column
52
+ column_path = CassandraThrift::ColumnPath.new(:column_family => column_family, :column => column)
53
+ multi_column_to_hash!(client.multiget(@keyspace, keys, column_path, consistency))
54
+
55
+ # Slices
56
+ else
57
+ predicate = CassandraThrift::SlicePredicate.new(:slice_range =>
58
+ CassandraThrift::SliceRange.new(
59
+ :reversed => reversed,
60
+ :count => count,
61
+ :start => start,
62
+ :finish => finish))
63
+
64
+ if is_super(column_family) and column
65
+ column_parent = CassandraThrift::ColumnParent.new(:column_family => column_family, :super_column => column)
66
+ multi_sub_columns_to_hash!(column_family, client.multiget_slice(@keyspace, keys, column_parent, predicate, consistency))
67
+ else
68
+ column_parent = CassandraThrift::ColumnParent.new(:column_family => column_family)
69
+ multi_columns_to_hash!(column_family, client.multiget_slice(@keyspace, keys, column_parent, predicate, consistency))
70
+ end
71
+ end
72
+ end
73
+
74
+ def _get_range(column_family, start, finish, count, consistency)
75
+ column_parent = CassandraThrift::ColumnParent.new(:column_family => column_family)
76
+ predicate = CassandraThrift::SlicePredicate.new(:slice_range => CassandraThrift::SliceRange.new(:start => '', :finish => ''))
77
+ range = CassandraThrift::KeyRange.new(:start_key => start, :end_key => finish, :count => count)
78
+ client.get_range_slices(@keyspace, column_parent, predicate, range, 1)
79
+ end
80
+
81
+ def _get_range_keys(column_family, start, finish, count, consistency)
82
+ _get_range(column_family, start, finish, count, consistency).collect{|i| i.key }
83
+ end
84
+
85
+ def each_key(column_family)
86
+ column_parent = CassandraThrift::ColumnParent.new(:column_family => column_family.to_s)
87
+ predicate = CassandraThrift::SlicePredicate.new(:column_names => [])
88
+ range = CassandraThrift::KeyRange.new(:start_key => '', :end_key => '')
89
+ client.get_range_slices(@keyspace, column_parent, predicate, range, 1).each{|i| yield i.key }
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,7 @@
1
+ class Cassandra
2
+ def self.VERSION
3
+ "0.6"
4
+ end
5
+ end
6
+
7
+ require "#{File.expand_path(File.dirname(__FILE__))}/../cassandra"