cassilds 0.9.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 (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"