cassandra-cql 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +9 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +203 -0
- data/README.rdoc +78 -0
- data/Rakefile +150 -0
- data/cassandra-cql.gemspec +29 -0
- data/lib/cassandra-cql.rb +39 -0
- data/lib/cassandra-cql/database.rb +107 -0
- data/lib/cassandra-cql/result.rb +133 -0
- data/lib/cassandra-cql/row.rb +59 -0
- data/lib/cassandra-cql/schema.rb +108 -0
- data/lib/cassandra-cql/statement.rb +111 -0
- data/lib/cassandra-cql/types/abstract_type.rb +47 -0
- data/lib/cassandra-cql/types/ascii_type.rb +25 -0
- data/lib/cassandra-cql/types/boolean_type.rb +25 -0
- data/lib/cassandra-cql/types/bytes_type.rb +21 -0
- data/lib/cassandra-cql/types/decimal_type.rb +25 -0
- data/lib/cassandra-cql/types/double_type.rb +25 -0
- data/lib/cassandra-cql/types/float_type.rb +25 -0
- data/lib/cassandra-cql/types/integer_type.rb +27 -0
- data/lib/cassandra-cql/types/long_type.rb +27 -0
- data/lib/cassandra-cql/types/utf8_type.rb +25 -0
- data/lib/cassandra-cql/types/uuid_type.rb +27 -0
- data/lib/cassandra-cql/utility.rb +37 -0
- data/lib/cassandra-cql/uuid.rb +21 -0
- data/lib/cassandra-cql/version.rb +19 -0
- data/spec/column_family_spec.rb +105 -0
- data/spec/comparator_spec.rb +225 -0
- data/spec/conf/0.8/cassandra.in.sh +41 -0
- data/spec/conf/0.8/cassandra.yaml +61 -0
- data/spec/conf/0.8/log4j-server.properties +40 -0
- data/spec/conf/0.8/schema.txt +10 -0
- data/spec/conf/1.0/cassandra.in.sh +41 -0
- data/spec/conf/1.0/cassandra.yaml +416 -0
- data/spec/conf/1.0/log4j-server.properties +40 -0
- data/spec/conf/1.0/schema.txt +10 -0
- data/spec/result_spec.rb +173 -0
- data/spec/row_spec.rb +55 -0
- data/spec/rowkey_spec.rb +223 -0
- data/spec/schema_spec.rb +51 -0
- data/spec/spec_helper.rb +23 -0
- data/spec/statement_spec.rb +224 -0
- data/spec/utility_spec.rb +26 -0
- data/spec/uuid_spec.rb +26 -0
- data/spec/validation_spec.rb +250 -0
- data/vendor/gen-rb/cassandra.rb +2212 -0
- data/vendor/gen-rb/cassandra_constants.rb +10 -0
- data/vendor/gen-rb/cassandra_types.rb +854 -0
- metadata +171 -0
@@ -0,0 +1,111 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2011 Inside Systems, Inc.
|
3
|
+
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
you may not use this file except in compliance with the License.
|
6
|
+
You may obtain a copy of the License at
|
7
|
+
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
See the License for the specific language governing permissions and
|
14
|
+
limitations under the License.
|
15
|
+
=end
|
16
|
+
|
17
|
+
module CassandraCQL
|
18
|
+
module Error
|
19
|
+
class InvalidBindVariable < Exception; end
|
20
|
+
class UnescapableObject < Exception; end
|
21
|
+
end
|
22
|
+
|
23
|
+
class Statement
|
24
|
+
|
25
|
+
KS_CHANGE_RE = /^use (\w+)/i
|
26
|
+
KS_DROP_RE = /^drop keyspace (\w+)/i
|
27
|
+
|
28
|
+
attr_reader :statement
|
29
|
+
|
30
|
+
def initialize(handle, statement)
|
31
|
+
@handle = handle
|
32
|
+
prepare(statement)
|
33
|
+
end
|
34
|
+
|
35
|
+
def prepare(statement)
|
36
|
+
@statement = statement
|
37
|
+
end
|
38
|
+
|
39
|
+
def execute(bind_vars=[], options={})
|
40
|
+
if options[:compression]
|
41
|
+
res = Result.new(@handle.execute_cql_query(Utility.compress(self.class.sanitize(@statement, bind_vars)), CassandraCQL::Thrift::Compression::GZIP))
|
42
|
+
else
|
43
|
+
res = Result.new(@handle.execute_cql_query(self.class.sanitize(@statement, bind_vars), CassandraCQL::Thrift::Compression::NONE))
|
44
|
+
end
|
45
|
+
|
46
|
+
# Change our keyspace if required
|
47
|
+
if @statement =~ KS_CHANGE_RE
|
48
|
+
@handle.keyspace = $1
|
49
|
+
elsif @statement =~ KS_DROP_RE
|
50
|
+
@handle.keyspace = nil
|
51
|
+
end
|
52
|
+
|
53
|
+
# We let ints be fetched for now because they'll probably be deprecated later
|
54
|
+
if res.void?
|
55
|
+
nil
|
56
|
+
else
|
57
|
+
res
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def finish
|
62
|
+
true
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.escape(obj)
|
66
|
+
obj.gsub("'", "''")
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.quote(obj)
|
70
|
+
if obj.kind_of?(Array)
|
71
|
+
obj.map { |member| quote(member) }.join(",")
|
72
|
+
elsif obj.kind_of?(String)
|
73
|
+
"'" + obj + "'"
|
74
|
+
elsif obj.kind_of?(Fixnum) or obj.kind_of?(Float)
|
75
|
+
obj
|
76
|
+
else
|
77
|
+
raise Error::UnescapableObject, "Unable to escape object of class #{obj.class}"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.cast_to_cql(obj)
|
82
|
+
if obj.kind_of?(Array)
|
83
|
+
obj.map { |member| cast_to_cql(member) }
|
84
|
+
elsif obj.kind_of?(Fixnum) or obj.kind_of?(Float)
|
85
|
+
obj
|
86
|
+
elsif obj.kind_of?(Time)
|
87
|
+
UUID.new(obj).to_guid
|
88
|
+
elsif obj.kind_of?(UUID)
|
89
|
+
obj.to_guid
|
90
|
+
# There are corner cases where this is an invalid assumption but they are extremely rare.
|
91
|
+
# The alternative is to make the user pack the data on their own .. let's not do that until we have to
|
92
|
+
elsif obj.kind_of?(String) and Utility.binary_data?(obj)
|
93
|
+
escape(obj.unpack('H*')[0])
|
94
|
+
else
|
95
|
+
RUBY_VERSION >= "1.9" ? escape(obj.to_s.dup.force_encoding('ASCII-8BIT')) : escape(obj.to_s.dup)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def self.sanitize(statement, bind_vars=[])
|
100
|
+
bind_vars = bind_vars.dup
|
101
|
+
expected_bind_vars = statement.count("?")
|
102
|
+
|
103
|
+
return statement if expected_bind_vars == 0 and bind_vars.empty?
|
104
|
+
raise Error::InvalidBindVariable, "Wrong number of bound variables (statement expected #{expected_bind_vars}, was #{bind_vars.size})" if expected_bind_vars != bind_vars.size
|
105
|
+
|
106
|
+
statement.gsub(/\?/) {
|
107
|
+
quote(cast_to_cql(bind_vars.shift))
|
108
|
+
}
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2011 Inside Systems, Inc.
|
3
|
+
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
you may not use this file except in compliance with the License.
|
6
|
+
You may obtain a copy of the License at
|
7
|
+
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
See the License for the specific language governing permissions and
|
14
|
+
limitations under the License.
|
15
|
+
=end
|
16
|
+
|
17
|
+
module CassandraCQL
|
18
|
+
module Types
|
19
|
+
class AbstractType
|
20
|
+
def self.cast(value)
|
21
|
+
value
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def self.bytes_to_int(bytes)
|
27
|
+
int = 0
|
28
|
+
values = bytes.unpack('C*')
|
29
|
+
values.each {|v| int = int << 8; int += v; }
|
30
|
+
if bytes[0].ord & 128 != 0
|
31
|
+
int = int - (1 << bytes.length * 8)
|
32
|
+
end
|
33
|
+
int
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.bytes_to_long(bytes)
|
37
|
+
ints = bytes.unpack("NN")
|
38
|
+
val = (ints[0] << 32) + ints[1]
|
39
|
+
if val & 2**63 == 2**63
|
40
|
+
val - 2**64
|
41
|
+
else
|
42
|
+
val
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2011 Inside Systems, Inc.
|
3
|
+
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
you may not use this file except in compliance with the License.
|
6
|
+
You may obtain a copy of the License at
|
7
|
+
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
See the License for the specific language governing permissions and
|
14
|
+
limitations under the License.
|
15
|
+
=end
|
16
|
+
|
17
|
+
module CassandraCQL
|
18
|
+
module Types
|
19
|
+
class AsciiType < AbstractType
|
20
|
+
def self.cast(value)
|
21
|
+
RUBY_VERSION >= "1.9" ? value.to_s.dup.force_encoding('ASCII-8BIT') : value.to_s.dup
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2011 Inside Systems, Inc.
|
3
|
+
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
you may not use this file except in compliance with the License.
|
6
|
+
You may obtain a copy of the License at
|
7
|
+
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
See the License for the specific language governing permissions and
|
14
|
+
limitations under the License.
|
15
|
+
=end
|
16
|
+
|
17
|
+
module CassandraCQL
|
18
|
+
module Types
|
19
|
+
class BooleanType < AbstractType
|
20
|
+
def self.cast(value)
|
21
|
+
value.unpack('C') == [1]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2011 Inside Systems, Inc.
|
3
|
+
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
you may not use this file except in compliance with the License.
|
6
|
+
You may obtain a copy of the License at
|
7
|
+
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
See the License for the specific language governing permissions and
|
14
|
+
limitations under the License.
|
15
|
+
=end
|
16
|
+
|
17
|
+
module CassandraCQL
|
18
|
+
module Types
|
19
|
+
class BytesType < AbstractType; end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2011 Inside Systems, Inc.
|
3
|
+
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
you may not use this file except in compliance with the License.
|
6
|
+
You may obtain a copy of the License at
|
7
|
+
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
See the License for the specific language governing permissions and
|
14
|
+
limitations under the License.
|
15
|
+
=end
|
16
|
+
|
17
|
+
module CassandraCQL
|
18
|
+
module Types
|
19
|
+
class DecimalType < AbstractType
|
20
|
+
def self.cast(value)
|
21
|
+
BigDecimal.new(bytes_to_int(value[4..-1]).to_s) * BigDecimal.new('10')**(bytes_to_int(value[0..3])*-1)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2011 Inside Systems, Inc.
|
3
|
+
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
you may not use this file except in compliance with the License.
|
6
|
+
You may obtain a copy of the License at
|
7
|
+
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
See the License for the specific language governing permissions and
|
14
|
+
limitations under the License.
|
15
|
+
=end
|
16
|
+
|
17
|
+
module CassandraCQL
|
18
|
+
module Types
|
19
|
+
class DoubleType < AbstractType
|
20
|
+
def self.cast(value)
|
21
|
+
value.unpack('G')[0]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2011 Inside Systems, Inc.
|
3
|
+
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
you may not use this file except in compliance with the License.
|
6
|
+
You may obtain a copy of the License at
|
7
|
+
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
See the License for the specific language governing permissions and
|
14
|
+
limitations under the License.
|
15
|
+
=end
|
16
|
+
|
17
|
+
module CassandraCQL
|
18
|
+
module Types
|
19
|
+
class FloatType < AbstractType
|
20
|
+
def self.cast(value)
|
21
|
+
value.unpack('g')[0]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2011 Inside Systems, Inc.
|
3
|
+
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
you may not use this file except in compliance with the License.
|
6
|
+
You may obtain a copy of the License at
|
7
|
+
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
See the License for the specific language governing permissions and
|
14
|
+
limitations under the License.
|
15
|
+
=end
|
16
|
+
|
17
|
+
module CassandraCQL
|
18
|
+
module Types
|
19
|
+
class IntegerType < AbstractType
|
20
|
+
def self.cast(value)
|
21
|
+
bytes_to_int(value)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class Int32Type < IntegerType; end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2011 Inside Systems, Inc.
|
3
|
+
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
you may not use this file except in compliance with the License.
|
6
|
+
You may obtain a copy of the License at
|
7
|
+
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
See the License for the specific language governing permissions and
|
14
|
+
limitations under the License.
|
15
|
+
=end
|
16
|
+
|
17
|
+
module CassandraCQL
|
18
|
+
module Types
|
19
|
+
class LongType < AbstractType
|
20
|
+
def self.cast(value)
|
21
|
+
bytes_to_long(value)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class CounterColumnType < LongType; end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2011 Inside Systems, Inc.
|
3
|
+
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
you may not use this file except in compliance with the License.
|
6
|
+
You may obtain a copy of the License at
|
7
|
+
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
See the License for the specific language governing permissions and
|
14
|
+
limitations under the License.
|
15
|
+
=end
|
16
|
+
|
17
|
+
module CassandraCQL
|
18
|
+
module Types
|
19
|
+
class UTF8Type < AbstractType
|
20
|
+
def self.cast(value)
|
21
|
+
RUBY_VERSION >= "1.9" ? value.to_s.dup.force_encoding('UTF-8') : value.to_s.dup
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2011 Inside Systems, Inc.
|
3
|
+
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
you may not use this file except in compliance with the License.
|
6
|
+
You may obtain a copy of the License at
|
7
|
+
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
See the License for the specific language governing permissions and
|
14
|
+
limitations under the License.
|
15
|
+
=end
|
16
|
+
|
17
|
+
module CassandraCQL
|
18
|
+
module Types
|
19
|
+
class UUIDType < AbstractType
|
20
|
+
def self.cast(value)
|
21
|
+
UUID.new(value)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class TimeUUIDType < UUIDType; end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2011 Inside Systems, Inc.
|
3
|
+
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
you may not use this file except in compliance with the License.
|
6
|
+
You may obtain a copy of the License at
|
7
|
+
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
See the License for the specific language governing permissions and
|
14
|
+
limitations under the License.
|
15
|
+
=end
|
16
|
+
|
17
|
+
require 'zlib'
|
18
|
+
|
19
|
+
module CassandraCQL
|
20
|
+
class Utility
|
21
|
+
def self.compress(source, level=2)
|
22
|
+
Zlib::Deflate.deflate(source, level)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.decompress(source)
|
26
|
+
Zlib::Inflate.inflate(source)
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.binary_data?(string)
|
30
|
+
if RUBY_VERSION >= "1.9"
|
31
|
+
string.encoding.name == "ASCII-8BIT"
|
32
|
+
else
|
33
|
+
string.count("\x00-\x7F", "^ -~\t\r\n").fdiv(string.size) > 0.3 || string.index("\x00") unless string.empty?
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|