hallelujah-cassandra-cql 1.0.4
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 +71 -0
- data/Rakefile +151 -0
- data/hallelujah-cassandra-cql.gemspec +33 -0
- data/lib/cassandra-cql.rb +49 -0
- data/lib/cassandra-cql/0.8.rb +7 -0
- data/lib/cassandra-cql/0.8/result.rb +23 -0
- data/lib/cassandra-cql/0.8/statement.rb +38 -0
- data/lib/cassandra-cql/1.0.rb +7 -0
- data/lib/cassandra-cql/1.0/result.rb +6 -0
- data/lib/cassandra-cql/1.0/statement.rb +6 -0
- data/lib/cassandra-cql/1.1.rb +7 -0
- data/lib/cassandra-cql/1.1/result.rb +6 -0
- data/lib/cassandra-cql/1.1/statement.rb +6 -0
- data/lib/cassandra-cql/database.rb +127 -0
- data/lib/cassandra-cql/result.rb +133 -0
- data/lib/cassandra-cql/row.rb +54 -0
- data/lib/cassandra-cql/schema.rb +108 -0
- data/lib/cassandra-cql/statement.rb +116 -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/date_type.rb +25 -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 +249 -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/conf/1.1/cassandra.in.sh +41 -0
- data/spec/conf/1.1/cassandra.yaml +560 -0
- data/spec/conf/1.1/log4j-server.properties +44 -0
- data/spec/conf/1.1/schema.txt +10 -0
- data/spec/database_spec.rb +25 -0
- data/spec/result_spec.rb +173 -0
- data/spec/row_spec.rb +49 -0
- data/spec/rowkey_spec.rb +233 -0
- data/spec/schema_spec.rb +51 -0
- data/spec/spec_helper.rb +30 -0
- data/spec/statement_spec.rb +226 -0
- data/spec/utility_spec.rb +26 -0
- data/spec/uuid_spec.rb +26 -0
- data/spec/validation_spec.rb +272 -0
- data/vendor/0.8/gen-rb/cassandra.rb +2210 -0
- data/vendor/0.8/gen-rb/cassandra_constants.rb +10 -0
- data/vendor/0.8/gen-rb/cassandra_types.rb +811 -0
- data/vendor/1.0/gen-rb/cassandra.rb +2212 -0
- data/vendor/1.0/gen-rb/cassandra_constants.rb +10 -0
- data/vendor/1.0/gen-rb/cassandra_types.rb +854 -0
- data/vendor/1.1/gen-rb/cassandra.rb +2511 -0
- data/vendor/1.1/gen-rb/cassandra_constants.rb +13 -0
- data/vendor/1.1/gen-rb/cassandra_types.rb +928 -0
- metadata +230 -0
@@ -0,0 +1,108 @@
|
|
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
|
+
class Schema
|
19
|
+
attr_reader :schema, :column_families
|
20
|
+
|
21
|
+
def initialize(schema)
|
22
|
+
@schema = schema
|
23
|
+
@column_families = {}
|
24
|
+
@schema.cf_defs.each { |cf|
|
25
|
+
@column_families[cf.name] = ColumnFamily.new(cf)
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
def method_missing(method, *args, &block)
|
30
|
+
if @schema.respond_to?(method)
|
31
|
+
@schema.send(method)
|
32
|
+
else
|
33
|
+
super(method, *args, &block)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_s
|
38
|
+
keyspace
|
39
|
+
end
|
40
|
+
|
41
|
+
def keyspace
|
42
|
+
name
|
43
|
+
end
|
44
|
+
|
45
|
+
def column_family_names
|
46
|
+
@column_families.keys
|
47
|
+
end
|
48
|
+
alias_method :tables, :column_family_names
|
49
|
+
end
|
50
|
+
|
51
|
+
class ColumnFamily
|
52
|
+
attr_reader :cf_def
|
53
|
+
|
54
|
+
def initialize(cf_def)
|
55
|
+
@cf_def = cf_def
|
56
|
+
end
|
57
|
+
|
58
|
+
def method_missing(method, *args, &block)
|
59
|
+
if @cf_def.respond_to?(method)
|
60
|
+
@cf_def.send(method)
|
61
|
+
else
|
62
|
+
super(method, *args, &block)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def columns
|
67
|
+
return @columns if @columns
|
68
|
+
|
69
|
+
@columns = Hash.new(default_validation_class)
|
70
|
+
@cf_def.column_metadata.each do |col|
|
71
|
+
@columns[col.name] = col.validation_class
|
72
|
+
end
|
73
|
+
@columns[key_alias] = key_validation_class
|
74
|
+
|
75
|
+
@columns
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.cast(value, type)
|
79
|
+
return nil if value.nil?
|
80
|
+
|
81
|
+
if CassandraCQL::Types.const_defined?(type)
|
82
|
+
CassandraCQL::Types.const_get(type).cast(value)
|
83
|
+
else
|
84
|
+
CassandraCQL::Types::AbstractType.cast(value)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def name
|
89
|
+
@cf_def.name
|
90
|
+
end
|
91
|
+
|
92
|
+
def type
|
93
|
+
@cf_def.column_type
|
94
|
+
end
|
95
|
+
|
96
|
+
def id
|
97
|
+
@cf_def.id
|
98
|
+
end
|
99
|
+
|
100
|
+
def standard?
|
101
|
+
type == 'Standard'
|
102
|
+
end
|
103
|
+
|
104
|
+
def super?
|
105
|
+
type == 'Super'
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,116 @@
|
|
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
|
+
sanitized_query = self.class.sanitize(@statement, bind_vars)
|
41
|
+
compression_type = CassandraCQL::Thrift::Compression::NONE
|
42
|
+
if options[:compression]
|
43
|
+
compression_type = CassandraCQL::Thrift::Compression::GZIP
|
44
|
+
sanitized_query = Utility.compress(sanitized_query)
|
45
|
+
end
|
46
|
+
|
47
|
+
res = Result.new(@handle.execute_cql_query(sanitized_query, compression_type))
|
48
|
+
|
49
|
+
# Change our keyspace if required
|
50
|
+
if @statement =~ KS_CHANGE_RE
|
51
|
+
@handle.keyspace = $1
|
52
|
+
elsif @statement =~ KS_DROP_RE
|
53
|
+
@handle.keyspace = nil
|
54
|
+
end
|
55
|
+
|
56
|
+
# We let ints be fetched for now because they'll probably be deprecated later
|
57
|
+
if res.void?
|
58
|
+
nil
|
59
|
+
else
|
60
|
+
res
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def finish
|
65
|
+
true
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.escape(obj)
|
69
|
+
obj.gsub("'", "''")
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.quote(obj)
|
73
|
+
if obj.kind_of?(Array)
|
74
|
+
obj.map { |member| quote(member) }.join(",")
|
75
|
+
elsif obj.kind_of?(String)
|
76
|
+
"'" + obj + "'"
|
77
|
+
elsif obj.kind_of?(Fixnum) or obj.kind_of?(Float)
|
78
|
+
obj
|
79
|
+
else
|
80
|
+
raise Error::UnescapableObject, "Unable to escape object of class #{obj.class}"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.cast_to_cql(obj)
|
85
|
+
if obj.kind_of?(Array)
|
86
|
+
obj.map { |member| cast_to_cql(member) }
|
87
|
+
elsif obj.kind_of?(Fixnum) or obj.kind_of?(Float)
|
88
|
+
obj
|
89
|
+
elsif obj.kind_of?(Date)
|
90
|
+
obj.strftime('%Y-%m-%d')
|
91
|
+
elsif obj.kind_of?(Time)
|
92
|
+
(obj.to_f * 1000).to_i
|
93
|
+
elsif obj.kind_of?(UUID)
|
94
|
+
obj.to_guid
|
95
|
+
# There are corner cases where this is an invalid assumption but they are extremely rare.
|
96
|
+
# The alternative is to make the user pack the data on their own .. let's not do that until we have to
|
97
|
+
elsif obj.kind_of?(String) and Utility.binary_data?(obj)
|
98
|
+
escape(obj.unpack('H*')[0])
|
99
|
+
else
|
100
|
+
RUBY_VERSION >= "1.9" ? escape(obj.to_s.dup.force_encoding('ASCII-8BIT')) : escape(obj.to_s.dup)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def self.sanitize(statement, bind_vars=[])
|
105
|
+
bind_vars = bind_vars.dup
|
106
|
+
expected_bind_vars = statement.count("?")
|
107
|
+
|
108
|
+
return statement if expected_bind_vars == 0 and bind_vars.empty?
|
109
|
+
raise Error::InvalidBindVariable, "Wrong number of bound variables (statement expected #{expected_bind_vars}, was #{bind_vars.size})" if expected_bind_vars != bind_vars.size
|
110
|
+
|
111
|
+
statement.gsub(/\?/) {
|
112
|
+
quote(cast_to_cql(bind_vars.shift))
|
113
|
+
}
|
114
|
+
end
|
115
|
+
end
|
116
|
+
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 DateType < AbstractType
|
20
|
+
def self.cast(value)
|
21
|
+
Time.at(bytes_to_long(value) / 1000.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 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
|