cassandra-cql 1.0.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 (49) hide show
  1. data/.gitignore +9 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE.txt +203 -0
  4. data/README.rdoc +78 -0
  5. data/Rakefile +150 -0
  6. data/cassandra-cql.gemspec +29 -0
  7. data/lib/cassandra-cql.rb +39 -0
  8. data/lib/cassandra-cql/database.rb +107 -0
  9. data/lib/cassandra-cql/result.rb +133 -0
  10. data/lib/cassandra-cql/row.rb +59 -0
  11. data/lib/cassandra-cql/schema.rb +108 -0
  12. data/lib/cassandra-cql/statement.rb +111 -0
  13. data/lib/cassandra-cql/types/abstract_type.rb +47 -0
  14. data/lib/cassandra-cql/types/ascii_type.rb +25 -0
  15. data/lib/cassandra-cql/types/boolean_type.rb +25 -0
  16. data/lib/cassandra-cql/types/bytes_type.rb +21 -0
  17. data/lib/cassandra-cql/types/decimal_type.rb +25 -0
  18. data/lib/cassandra-cql/types/double_type.rb +25 -0
  19. data/lib/cassandra-cql/types/float_type.rb +25 -0
  20. data/lib/cassandra-cql/types/integer_type.rb +27 -0
  21. data/lib/cassandra-cql/types/long_type.rb +27 -0
  22. data/lib/cassandra-cql/types/utf8_type.rb +25 -0
  23. data/lib/cassandra-cql/types/uuid_type.rb +27 -0
  24. data/lib/cassandra-cql/utility.rb +37 -0
  25. data/lib/cassandra-cql/uuid.rb +21 -0
  26. data/lib/cassandra-cql/version.rb +19 -0
  27. data/spec/column_family_spec.rb +105 -0
  28. data/spec/comparator_spec.rb +225 -0
  29. data/spec/conf/0.8/cassandra.in.sh +41 -0
  30. data/spec/conf/0.8/cassandra.yaml +61 -0
  31. data/spec/conf/0.8/log4j-server.properties +40 -0
  32. data/spec/conf/0.8/schema.txt +10 -0
  33. data/spec/conf/1.0/cassandra.in.sh +41 -0
  34. data/spec/conf/1.0/cassandra.yaml +416 -0
  35. data/spec/conf/1.0/log4j-server.properties +40 -0
  36. data/spec/conf/1.0/schema.txt +10 -0
  37. data/spec/result_spec.rb +173 -0
  38. data/spec/row_spec.rb +55 -0
  39. data/spec/rowkey_spec.rb +223 -0
  40. data/spec/schema_spec.rb +51 -0
  41. data/spec/spec_helper.rb +23 -0
  42. data/spec/statement_spec.rb +224 -0
  43. data/spec/utility_spec.rb +26 -0
  44. data/spec/uuid_spec.rb +26 -0
  45. data/spec/validation_spec.rb +250 -0
  46. data/vendor/gen-rb/cassandra.rb +2212 -0
  47. data/vendor/gen-rb/cassandra_constants.rb +10 -0
  48. data/vendor/gen-rb/cassandra_types.rb +854 -0
  49. metadata +171 -0
@@ -0,0 +1,39 @@
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
+ here = File.dirname(__FILE__)
18
+ require "#{here}/../vendor/gen-rb/cassandra"
19
+
20
+ require 'bigdecimal'
21
+ require 'thrift_client'
22
+ require 'cassandra-cql/types/abstract_type'
23
+ require 'cassandra-cql/types/ascii_type'
24
+ require 'cassandra-cql/types/boolean_type'
25
+ require 'cassandra-cql/types/bytes_type'
26
+ require 'cassandra-cql/types/decimal_type'
27
+ require 'cassandra-cql/types/double_type'
28
+ require 'cassandra-cql/types/float_type'
29
+ require 'cassandra-cql/types/integer_type'
30
+ require 'cassandra-cql/types/long_type'
31
+ require 'cassandra-cql/types/utf8_type'
32
+ require 'cassandra-cql/types/uuid_type'
33
+ require 'cassandra-cql/utility'
34
+ require 'cassandra-cql/uuid'
35
+ require 'cassandra-cql/database'
36
+ require 'cassandra-cql/schema'
37
+ require 'cassandra-cql/statement'
38
+ require 'cassandra-cql/result'
39
+ require 'cassandra-cql/row'
@@ -0,0 +1,107 @@
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 InvalidRequestException < Exception; end
20
+ end
21
+
22
+ class Database
23
+ attr_reader :connection, :schema, :keyspace
24
+
25
+ def initialize(servers, options={}, thrift_client_options={})
26
+ @options = {
27
+ :keyspace => 'system'
28
+ }.merge(options)
29
+
30
+ @thrift_client_options = {
31
+ :exception_class_overrides => CassandraCQL::Thrift::InvalidRequestException
32
+ }.merge(thrift_client_options)
33
+
34
+ @keyspace = @options[:keyspace]
35
+ @servers = servers
36
+ connect!
37
+ execute("USE #{@keyspace}")
38
+ end
39
+
40
+ def connect!
41
+ @connection = ThriftClient.new(CassandraCQL::Thrift::Client, @servers, @thrift_client_options)
42
+ obj = self
43
+ @connection.add_callback(:post_connect) do
44
+ execute("USE #{@keyspace}")
45
+ end
46
+ end
47
+
48
+ def disconnect!
49
+ @connection.disconnect! if active?
50
+ end
51
+
52
+ def active?
53
+ # TODO: This should be replaced with a CQL call that doesn't exist yet
54
+ @connection.describe_version
55
+ true
56
+ rescue Exception
57
+ false
58
+ end
59
+ alias_method :ping, :active?
60
+
61
+ def reset!
62
+ disconnect!
63
+ reconnect!
64
+ end
65
+ alias_method :reconnect!, :reset!
66
+
67
+ def prepare(statement, options={}, &block)
68
+ stmt = Statement.new(self, statement)
69
+ if block_given?
70
+ yield stmt
71
+ else
72
+ stmt
73
+ end
74
+ end
75
+
76
+ def execute(statement, *bind_vars)
77
+ result = Statement.new(self, statement).execute(bind_vars)
78
+ if block_given?
79
+ yield result
80
+ else
81
+ result
82
+ end
83
+ rescue CassandraCQL::Thrift::InvalidRequestException
84
+ raise Error::InvalidRequestException.new($!.why)
85
+ end
86
+
87
+ def execute_cql_query(cql, compression=CassandraCQL::Thrift::Compression::NONE)
88
+ @connection.execute_cql_query(cql, compression)
89
+ rescue CassandraCQL::Thrift::InvalidRequestException
90
+ raise Error::InvalidRequestException.new($!.why)
91
+ end
92
+
93
+ def keyspace=(ks)
94
+ @keyspace = (ks.nil? ? nil : ks.to_s)
95
+ end
96
+
97
+ def keyspaces
98
+ # TODO: This should be replaced with a CQL call that doesn't exist yet
99
+ @connection.describe_keyspaces.map { |keyspace| Schema.new(keyspace) }
100
+ end
101
+
102
+ def schema
103
+ # TODO: This should be replaced with a CQL call that doesn't exist yet
104
+ Schema.new(@connection.describe_keyspace(@keyspace))
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,133 @@
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 InvalidResultType < Exception; end
20
+ class InvalidCursor < Exception; end
21
+ end
22
+
23
+ class ResultSchema
24
+ attr_reader :names, :values
25
+
26
+ def initialize(schema)
27
+ # When https://issues.apache.org/jira/browse/CASSANDRA-3436 is resolve, no more need to split/last
28
+ @names = Hash.new(schema.default_name_type.split(".").last)
29
+ schema.name_types.each_pair { |key, type|
30
+ @names[key] = type.split(".").last
31
+ }
32
+ @values = Hash.new(schema.default_value_type.split(".").last)
33
+ schema.value_types.each_pair { |key, type|
34
+ @values[key] = type.split(".").last
35
+ }
36
+ end
37
+ end
38
+
39
+ class Result
40
+ attr_reader :result, :schema, :cursor
41
+
42
+ def initialize(result)
43
+ @result = result
44
+ @schema = ResultSchema.new(result.schema) if rows?
45
+ @cursor = 0
46
+ end
47
+
48
+ def void?
49
+ @result.type == CassandraCQL::Thrift::CqlResultType::VOID
50
+ end
51
+
52
+ def int?
53
+ @result.type == CassandraCQL::Thrift::CqlResultType::INT
54
+ end
55
+
56
+ def rows?
57
+ @result.type == CassandraCQL::Thrift::CqlResultType::ROWS
58
+ end
59
+
60
+ def rows
61
+ @result.rows.size
62
+ end
63
+
64
+ def cursor=(cursor)
65
+ @cursor = cursor.to_i
66
+ rescue Exception => e
67
+ raise Error::InvalidCursor, e.to_s
68
+ end
69
+
70
+ def fetch_row
71
+ case @result.type
72
+ when CassandraCQL::Thrift::CqlResultType::ROWS
73
+ return nil if @cursor >= rows
74
+
75
+ row = Row.new(@result.rows[@cursor], @schema)
76
+ @cursor += 1
77
+ return row
78
+ when CassandraCQL::Thrift::CqlResultType::VOID
79
+ return nil
80
+ when CassandraCQL::Thrift::CqlResultType::INT
81
+ return @result.num
82
+ else
83
+ raise Error::InvalidResultType, "Expects one of 0, 1, 2; was #{@result.type} "
84
+ end
85
+ end
86
+
87
+ def fetch
88
+ if block_given?
89
+ while row = fetch_row
90
+ yield row
91
+ end
92
+ else
93
+ fetch_row
94
+ end
95
+ end
96
+
97
+ def fetch_hash
98
+ if block_given?
99
+ while row = fetch_row
100
+ if row.kind_of?(Fixnum)
101
+ yield({row => row})
102
+ else
103
+ yield row.to_hash
104
+ end
105
+ end
106
+ else
107
+ if (row = fetch_row).kind_of?(Fixnum)
108
+ {row => row}
109
+ else
110
+ row.to_hash
111
+ end
112
+ end
113
+ end
114
+
115
+ def fetch_array
116
+ if block_given?
117
+ while row = fetch_row
118
+ if row.kind_of?(Fixnum)
119
+ yield [row]
120
+ else
121
+ yield row.to_a
122
+ end
123
+ end
124
+ else
125
+ if (row = fetch_row).kind_of?(Fixnum)
126
+ [row]
127
+ else
128
+ row.to_a
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,59 @@
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 Row
19
+ attr_reader :row
20
+
21
+ def initialize(row, schema)
22
+ @row, @schema = row, schema
23
+ end
24
+
25
+ def [](obj)
26
+ # Rows include the row key so we skip the first one
27
+ column_index = obj.kind_of?(Fixnum) ? obj : column_names.index(obj)
28
+ return nil if column_index.nil?
29
+ column_values[column_index]
30
+ end
31
+
32
+ def column_names
33
+ @names ||= @row.columns.map do |column|
34
+ ColumnFamily.cast(column.name, @schema.names[column.name])
35
+ end
36
+ end
37
+
38
+ def column_values
39
+ @values ||= @row.columns.map { |column| ColumnFamily.cast(column.value, @schema.values[column.name]) }
40
+ end
41
+
42
+ def columns
43
+ @row.columns.size
44
+ end
45
+
46
+ def to_a
47
+ column_values
48
+ end
49
+
50
+ # TODO: This should be an ordered hash
51
+ def to_hash
52
+ Hash[([column_names, column_values]).transpose]
53
+ end
54
+
55
+ def key
56
+ ColumnFamily.cast(@row.key, @schema.values[@row.key])
57
+ end
58
+ end
59
+ end
@@ -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