eurydice 1.0.0-java
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.
- data/.gitignore +1 -0
- data/.rspec +3 -0
- data/.rvmrc +1 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +34 -0
- data/README.mdown +25 -0
- data/eurydice.gemspec +24 -0
- data/examples/01_connect.rb +18 -0
- data/examples/02_create_keyspace.rb +19 -0
- data/examples/03_create_column_family.rb +28 -0
- data/examples/04_storing_data.rb +37 -0
- data/examples/05_loading_data.rb +86 -0
- data/examples/06_cluster_info.rb +20 -0
- data/examples/common.rb +5 -0
- data/lib/cassandra.rb +158 -0
- data/lib/eurydice/pelops/cluster.rb +42 -0
- data/lib/eurydice/pelops/column_family.rb +217 -0
- data/lib/eurydice/pelops/keyspace.rb +75 -0
- data/lib/eurydice/pelops.rb +124 -0
- data/lib/eurydice/version.rb +6 -0
- data/lib/eurydice.rb +12 -0
- data/spec/eurydice/pelops/cluster_spec.rb +39 -0
- data/spec/eurydice/pelops/column_family_spec.rb +499 -0
- data/spec/eurydice/pelops/keyspace_spec.rb +91 -0
- data/spec/spec_helper.rb +4 -0
- metadata +99 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
/ext
|
data/.rspec
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm --create use jruby-1.6.2@eurydice
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
eurydice (1.0.0-java)
|
5
|
+
pelops-jars (= 1.2)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: http://rubygems.org/
|
9
|
+
specs:
|
10
|
+
bouncy-castle-java (1.5.0146.1)
|
11
|
+
cassandra-jars (0.8.0-java)
|
12
|
+
diff-lcs (1.1.2)
|
13
|
+
jruby-openssl (0.7.4)
|
14
|
+
bouncy-castle-java
|
15
|
+
pelops-jars (1.2-java)
|
16
|
+
cassandra-jars (~> 0.8.0)
|
17
|
+
rake (0.9.2)
|
18
|
+
rspec (2.6.0)
|
19
|
+
rspec-core (~> 2.6.0)
|
20
|
+
rspec-expectations (~> 2.6.0)
|
21
|
+
rspec-mocks (~> 2.6.0)
|
22
|
+
rspec-core (2.6.4)
|
23
|
+
rspec-expectations (2.6.0)
|
24
|
+
diff-lcs (~> 1.1.2)
|
25
|
+
rspec-mocks (2.6.0)
|
26
|
+
|
27
|
+
PLATFORMS
|
28
|
+
java
|
29
|
+
|
30
|
+
DEPENDENCIES
|
31
|
+
eurydice!
|
32
|
+
jruby-openssl
|
33
|
+
rake
|
34
|
+
rspec
|
data/README.mdown
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# Eurydice
|
2
|
+
|
3
|
+
Eurydice is a Cassandra client library for JRuby built on top of [Pelops](https://github.com/s7/scale7-pelops).
|
4
|
+
|
5
|
+
See the `examples` directory and the specs for usage.
|
6
|
+
|
7
|
+
## Installation & requirements
|
8
|
+
|
9
|
+
Tested with JRuby 1.6.2 in 1.9 mode and Cassandra 0.8.1.
|
10
|
+
|
11
|
+
gem install eurydice
|
12
|
+
|
13
|
+
This will also install two dependencies: `pelops-jars` and `cassandra-jars` which contain the Pelops and Cassandra JAR files.
|
14
|
+
|
15
|
+
## Contributors
|
16
|
+
|
17
|
+
Theo Hultberg, [@iconara](http://twitter.com/iconara)
|
18
|
+
|
19
|
+
## License
|
20
|
+
|
21
|
+
Eurydice is licensed under the [MIT License](http://www.opensource.org/licenses/mit-license.php), the same as Pelops.
|
22
|
+
|
23
|
+
## Eurydice?
|
24
|
+
|
25
|
+
Eurydice was the daughter of Pelops (but she's not _that_ [Eurydice](http://en.wikipedia.org/wiki/Eurydice)).
|
data/eurydice.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
$: << File.expand_path('../lib', __FILE__)
|
4
|
+
|
5
|
+
require 'eurydice/version'
|
6
|
+
|
7
|
+
|
8
|
+
Gem::Specification.new do |s|
|
9
|
+
s.name = 'eurydice'
|
10
|
+
s.version = Eurydice::VERSION
|
11
|
+
s.platform = 'java'
|
12
|
+
s.authors = ['Theo Hultberg']
|
13
|
+
s.email = ['theo@burtcorp.com']
|
14
|
+
s.homepage = 'http://github.com/iconara/eurydice'
|
15
|
+
s.summary = %q{Ruby wrapper for the Pelops library}
|
16
|
+
s.description = %q{}
|
17
|
+
|
18
|
+
s.rubyforge_project = 'eurydice'
|
19
|
+
|
20
|
+
s.add_dependency 'pelops-jars', '= 1.2'
|
21
|
+
|
22
|
+
s.files = `git ls-files`.split("\n")
|
23
|
+
s.require_paths = %w(lib)
|
24
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require_relative 'common'
|
4
|
+
|
5
|
+
|
6
|
+
# Connect to the default host (localhost) and port (9160), these can be
|
7
|
+
# overridden by passing then :host and :port options.
|
8
|
+
cluster = Eurydice.connect
|
9
|
+
|
10
|
+
# Get a reference to a keyspace, it will be created if it does not exist
|
11
|
+
# (pass the option :create => false to not automatically create the keyspace).
|
12
|
+
keyspace = cluster.keyspace('my_keyspace')
|
13
|
+
|
14
|
+
# Clean up by dropping the keyspace
|
15
|
+
keyspace.drop!
|
16
|
+
|
17
|
+
# Finally disconnect everything
|
18
|
+
Eurydice.disconnect!
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require_relative 'common'
|
4
|
+
|
5
|
+
|
6
|
+
cluster = Eurydice.connect
|
7
|
+
|
8
|
+
# Get a reference to a keyspace, but don't automatically create it, instead
|
9
|
+
# we will create it explicitly, and with a few options.
|
10
|
+
keyspace = cluster.keyspace('my_keyspace', :create => false)
|
11
|
+
|
12
|
+
# Create the keyspace with some options, the possible options can be found
|
13
|
+
# here: http://www.datastax.com/docs/0.8/configuration/storage_configuration
|
14
|
+
keyspace.create!(
|
15
|
+
:strategy_class => 'org.apache.cassandra.locator.NetworkTopologyStrategy',
|
16
|
+
:strategy_options => {:replication_factor => 3}
|
17
|
+
)
|
18
|
+
|
19
|
+
keyspace.drop!
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require_relative 'common'
|
4
|
+
|
5
|
+
|
6
|
+
cluster = Eurydice.connect
|
7
|
+
keyspace = cluster.keyspace('my_keyspace')
|
8
|
+
|
9
|
+
# Get a reference to a column family, but don't automatically create it,
|
10
|
+
# instead we will create it explicitly, and with a few options.
|
11
|
+
column_family = keyspace.column_family('my_family', :create => false)
|
12
|
+
|
13
|
+
# Create the column family with some options, the possible options can be found
|
14
|
+
# here: http://www.datastax.com/docs/0.8/configuration/storage_configuration
|
15
|
+
column_family.create!(
|
16
|
+
:key_validation_class => :ascii, # the type of the row keys
|
17
|
+
:comparator_type => :ascii, # the type of the column keys
|
18
|
+
:default_validation_class => :utf8, # the type of the column values
|
19
|
+
:column_metadata => {
|
20
|
+
'name' => {
|
21
|
+
:validation_class => :utf8, # you can declare the types of columns
|
22
|
+
:index_name => 'name_index', # and set up indexing
|
23
|
+
:index_type => :keys
|
24
|
+
}
|
25
|
+
}
|
26
|
+
)
|
27
|
+
|
28
|
+
keyspace.drop!
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require_relative 'common'
|
4
|
+
|
5
|
+
|
6
|
+
cluster = Eurydice.connect
|
7
|
+
keyspace = cluster.keyspace('my_keyspace')
|
8
|
+
column_family = keyspace.column_family('employees')
|
9
|
+
|
10
|
+
# Insert a few rows representing employees
|
11
|
+
column_family.insert('employee:1', {'name' => 'Sam', 'role' => 'Developer'})
|
12
|
+
column_family.insert('employee:2', {'name' => 'Phil', 'role' => 'Accountant'})
|
13
|
+
column_family.insert('employee:3', {'name' => 'Steve', 'role' => 'Developer'})
|
14
|
+
column_family.insert('employee:4', {'name' => 'Julie', 'role' => 'CEO'})
|
15
|
+
|
16
|
+
# #insert is actually an alias for #update, in some cases it feels more
|
17
|
+
# natural to say "insert" than "update", but in the end the operations are the
|
18
|
+
# same -- adding a column to a row (and adding a column that is already there
|
19
|
+
# replaces the old value).
|
20
|
+
column_family.update('employee:3', {'email' => 'steve@acme.com'})
|
21
|
+
column_family.update('employee:3', {'role' => 'tester'})
|
22
|
+
|
23
|
+
# If you want to insert numbers you must be explicit, unfortunately. Use the
|
24
|
+
# :validations option to pass a hash of property types. Currently the only one
|
25
|
+
# besides the default is :long (the default is to make the value a string and
|
26
|
+
# then creating a byte array from the string, this works with the :bytes,
|
27
|
+
# :ascii and :utf8 validations [read "column value types"] if the string has
|
28
|
+
# the right encoding).
|
29
|
+
column_family.update('employee:2', {'age' => 44}, :validations => {'age' => :long})
|
30
|
+
|
31
|
+
# You can specify :consistency_level as :one, :quorum, :all or :any (default is :one)
|
32
|
+
column_family.update('employee:4', {'email' => 'boss@acme.com'}, :consistency_level => :quorum)
|
33
|
+
|
34
|
+
# :cl is an alias for :consistency_level
|
35
|
+
column_family.update('employee:1', {'email' => 'sam@acme.com'}, :cl => :one)
|
36
|
+
|
37
|
+
keyspace.drop!
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require_relative 'common'
|
4
|
+
|
5
|
+
|
6
|
+
cluster = Eurydice.connect
|
7
|
+
keyspace = cluster.keyspace('my_keyspace')
|
8
|
+
column_family = keyspace.column_family('employees', :create => false)
|
9
|
+
column_family.create!(:column_metadata => {'name' => {:validation_class => :utf8, :index_name => 'name_index', :index_type => :keys}})
|
10
|
+
column_family.insert('employee:1', {'name' => 'Sam', 'role' => 'Developer'})
|
11
|
+
column_family.insert('employee:2', {'name' => 'Phil', 'role' => 'Accountant'})
|
12
|
+
column_family.insert('employee:3', {'name' => 'Steve', 'role' => 'Developer'})
|
13
|
+
column_family.insert('employee:4', {'name' => 'Julie', 'role' => 'CEO'})
|
14
|
+
column_family.update('employee:3', {'email' => 'steve@acme.com'})
|
15
|
+
column_family.update('employee:3', {'role' => 'tester'})
|
16
|
+
column_family.update('employee:2', {'age' => 44}, :validations => {'age' => :long})
|
17
|
+
column_family.update('employee:4', {'email' => 'boss@acme.com'}, :consistency_level => :quorum)
|
18
|
+
column_family.update('employee:1', {'email' => 'sam@acme.com'}, :cl => :one)
|
19
|
+
|
20
|
+
# Load a single row
|
21
|
+
employee1 = column_family.get('employee:1')
|
22
|
+
puts "employee:1 => #{employee1['name']}, #{employee1['role']}"
|
23
|
+
|
24
|
+
# Load multiple rows
|
25
|
+
employees = column_family.get(%w(employee:2 employee:3 employee:4))
|
26
|
+
employees.each do |row_key, employee|
|
27
|
+
puts "#{row_key} => #{employee['name']}, #{employee['role']}"
|
28
|
+
end
|
29
|
+
|
30
|
+
puts '---'
|
31
|
+
|
32
|
+
# Load only the specified columns
|
33
|
+
employee1 = column_family.get('employee:1', :columns => %w(name))
|
34
|
+
puts "employee:1 => #{employee1['name']}"
|
35
|
+
|
36
|
+
employees = column_family.get(%w(employee:2 employee:3 employee:4), :columns => %w(name))
|
37
|
+
employees.each do |row_key, employee|
|
38
|
+
puts "#{row_key} => #{employee['name']}"
|
39
|
+
end
|
40
|
+
|
41
|
+
puts '---'
|
42
|
+
|
43
|
+
# Load only the value from a single column
|
44
|
+
employee1_name = column_family.get_column('employee:1', 'name')
|
45
|
+
puts "employee:1 => #{employee1_name}"
|
46
|
+
|
47
|
+
puts '---'
|
48
|
+
|
49
|
+
# If you've stored a number you have to specify :validations when loading, too
|
50
|
+
employee2 = column_family.get('employee:2', :validations => {'age' => :long})
|
51
|
+
puts "employee:2 => #{employee2['name']}, #{employee2['age']}"
|
52
|
+
|
53
|
+
puts '---'
|
54
|
+
|
55
|
+
# You can check if a row exists
|
56
|
+
puts "Is there a employee:5? #{column_family.key?('employee:0') ? 'yes' : 'no'}"
|
57
|
+
|
58
|
+
# #row_exists? is an alias for #key?
|
59
|
+
puts "Is there a employee:1? #{column_family.row_exists?('employee:1') ? 'yes' : 'no'}"
|
60
|
+
|
61
|
+
puts '---'
|
62
|
+
|
63
|
+
# You can specify :consistency_level as :one, :quorum, :all or :any
|
64
|
+
employee1 = column_family.get('employee:1', :consistency_level => :quorum)
|
65
|
+
puts "employee:1 => #{employee1['email']}"
|
66
|
+
|
67
|
+
puts '---'
|
68
|
+
|
69
|
+
# If you have a row with lots of columns, you can iterate over them (in order)
|
70
|
+
# with #each_column. Under the hood they will be loaded in batches
|
71
|
+
column_family.update('employee:5', Hash[(0...1000).map { |i| ["property#{i}", "value#{i}"] }])
|
72
|
+
count = 0
|
73
|
+
column_family.each_column('employee:5') do |column_name, column_value|
|
74
|
+
count += 1
|
75
|
+
end
|
76
|
+
puts "There were #{count} columns"
|
77
|
+
|
78
|
+
puts '---'
|
79
|
+
|
80
|
+
# Cassandra has basic secondary indexes, which can be used when querying
|
81
|
+
column_family.insert('employees:6', {'name' => 'Sam'})
|
82
|
+
column_family.insert('employees:7', {'name' => 'Sam'})
|
83
|
+
employees_named_sam = column_family.get_indexed('name', :==, 'Sam')
|
84
|
+
puts "There are #{employees_named_sam.size} employees named 'Sam'"
|
85
|
+
|
86
|
+
keyspace.drop!
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require_relative 'common'
|
4
|
+
|
5
|
+
|
6
|
+
cluster = Eurydice.connect
|
7
|
+
|
8
|
+
# List the keyspaces
|
9
|
+
puts 'Keyspaces:'
|
10
|
+
cluster.keyspaces.each_with_index do |keyspace_name, i|
|
11
|
+
puts "#{i + 1}: #{keyspace_name}"
|
12
|
+
end
|
13
|
+
|
14
|
+
puts '---'
|
15
|
+
|
16
|
+
# List the nodes in the cluster
|
17
|
+
puts 'Nodes:'
|
18
|
+
cluster.nodes.each_with_index do |node_address, i|
|
19
|
+
puts "#{i + 1}: #{node_address}"
|
20
|
+
end
|
data/examples/common.rb
ADDED
data/lib/cassandra.rb
ADDED
@@ -0,0 +1,158 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Thrift
|
4
|
+
import 'org.apache.thrift.transport.TTransportException'
|
5
|
+
end
|
6
|
+
|
7
|
+
module Cassandra
|
8
|
+
import 'org.apache.cassandra.thrift.ConsistencyLevel'
|
9
|
+
import 'org.apache.cassandra.thrift.IndexType'
|
10
|
+
import 'org.apache.cassandra.thrift.Column'
|
11
|
+
import 'org.apache.cassandra.thrift.KsDef'
|
12
|
+
import 'org.apache.cassandra.thrift.CfDef'
|
13
|
+
import 'org.apache.cassandra.thrift.ColumnDef'
|
14
|
+
import 'org.apache.cassandra.thrift.InvalidRequestException'
|
15
|
+
import 'org.apache.cassandra.thrift.SlicePredicate'
|
16
|
+
import 'org.apache.cassandra.thrift.SliceRange'
|
17
|
+
import 'org.apache.cassandra.thrift.IndexOperator'
|
18
|
+
|
19
|
+
CONSISTENCY_LEVELS = {
|
20
|
+
:one => Cassandra::ConsistencyLevel::ONE,
|
21
|
+
:quorum => Cassandra::ConsistencyLevel::QUORUM,
|
22
|
+
:all => Cassandra::ConsistencyLevel::ALL,
|
23
|
+
:any => Cassandra::ConsistencyLevel::ANY
|
24
|
+
}.freeze
|
25
|
+
|
26
|
+
MARSHAL_TYPES = {
|
27
|
+
:bytes => 'org.apache.cassandra.db.marshal.BytesType'.freeze,
|
28
|
+
:ascii => 'org.apache.cassandra.db.marshal.AsciiType'.freeze,
|
29
|
+
:utf8 => 'org.apache.cassandra.db.marshal.UTF8Type'.freeze,
|
30
|
+
:long => 'org.apache.cassandra.db.marshal.LongType'.freeze,
|
31
|
+
:lexical_uuid => 'org.apache.cassandra.db.marshal.LexicalUUIDType'.freeze,
|
32
|
+
:time_uuid => 'org.apache.cassandra.db.marshal.TimeUUIDType'.freeze
|
33
|
+
}.freeze
|
34
|
+
|
35
|
+
INDEX_OPERATORS = {
|
36
|
+
:== => IndexOperator::EQ,
|
37
|
+
:eq => IndexOperator::EQ,
|
38
|
+
:> => IndexOperator::GT,
|
39
|
+
:gt => IndexOperator::GT,
|
40
|
+
:>= => IndexOperator::GTE,
|
41
|
+
:gte => IndexOperator::GTE,
|
42
|
+
:< => IndexOperator::LT,
|
43
|
+
:lt => IndexOperator::LT,
|
44
|
+
:<= => IndexOperator::LTE,
|
45
|
+
:lte => IndexOperator::LTE
|
46
|
+
}.freeze
|
47
|
+
|
48
|
+
class KsDef
|
49
|
+
def self.from_h(h)
|
50
|
+
ks_def = h.reduce(self.new) do |ks_def, (field_name, field_value)|
|
51
|
+
case field_name.to_sym
|
52
|
+
when :strategy_options
|
53
|
+
field_value = Hash[field_value.map { |k, v| [k.to_s, v.to_s] }]
|
54
|
+
when :column_families
|
55
|
+
field_name = 'cf_defs'
|
56
|
+
field_value = field_value.map { |cf_name, cf_def_h| CfDef.from_h(cf_def_h.merge(:name => cf_name, :keyspace => h[:name])) }
|
57
|
+
end
|
58
|
+
field = self::_Fields.find_by_name(field_name.to_s)
|
59
|
+
raise ArgumentError, %(No field named "#{field_name}") unless field
|
60
|
+
ks_def.set_field_value(field, field_value)
|
61
|
+
ks_def
|
62
|
+
end
|
63
|
+
ks_def.cf_defs = java.util.Collections.emptyList unless ks_def.cf_defs
|
64
|
+
ks_def
|
65
|
+
end
|
66
|
+
|
67
|
+
def to_h
|
68
|
+
self.class.metaDataMap.reduce({}) do |acc, (field, field_meta_data)|
|
69
|
+
field_name = field.field_name.to_sym
|
70
|
+
field_value = get_field_value(field)
|
71
|
+
case field_name.to_sym
|
72
|
+
when :cf_defs
|
73
|
+
cf_hs = field_value.map { |cf_def| cf_def.to_h }
|
74
|
+
acc[:column_families] = Hash[cf_hs.map { |cf_h| [cf_h[:name], cf_h] }]
|
75
|
+
when :strategy_options
|
76
|
+
acc[field_name] = Hash[field_value.map { |pair| [pair.first.to_sym, pair.last] }] # JRuby 1.6.2 Java Map doesn't splat when yielding
|
77
|
+
else
|
78
|
+
acc[field_name] = field_value
|
79
|
+
end
|
80
|
+
acc
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
class CfDef
|
86
|
+
def self.from_h(h)
|
87
|
+
h.reduce(self.new) do |cf_def, (field_name, field_value)|
|
88
|
+
case field_name.to_sym
|
89
|
+
when :column_type
|
90
|
+
field_value = field_value.to_s.capitalize
|
91
|
+
when :key_validation_class, :default_validation_class, :comparator_type, :subcomparator_type
|
92
|
+
field_value = Cassandra::MARSHAL_TYPES.fetch(field_value, field_value)
|
93
|
+
when :column_metadata
|
94
|
+
field_value = field_value.map do |column_name, column_def_h|
|
95
|
+
Cassandra::ColumnDef.from_h(column_def_h.merge(:name => column_name))
|
96
|
+
end
|
97
|
+
end
|
98
|
+
field = self::_Fields.find_by_name(field_name.to_s)
|
99
|
+
raise ArgumentError, %(No field named "#{field_name}") unless field
|
100
|
+
cf_def.set_field_value(field, field_value)
|
101
|
+
cf_def
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def to_h
|
106
|
+
self.class.metaDataMap.reduce({:column_metadata => {}}) do |acc, (field, field_meta_data)|
|
107
|
+
field_name = field.field_name.to_sym
|
108
|
+
case field_name
|
109
|
+
when :column_metadata
|
110
|
+
column_hs = get_field_value(field).map { |col_def| col_def.to_h }
|
111
|
+
acc[field_name] = Hash[column_hs.map { |col_h| [col_h[:name], col_h] }]
|
112
|
+
when :column_type
|
113
|
+
acc[field_name] = get_field_value(field).downcase.to_sym
|
114
|
+
else
|
115
|
+
acc[field_name] = get_field_value(field)
|
116
|
+
end
|
117
|
+
acc
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
class ColumnDef
|
123
|
+
def self.from_h(h)
|
124
|
+
h.reduce(self.new) do |col_def, (field_name, field_value)|
|
125
|
+
case field_name.to_sym
|
126
|
+
when :name
|
127
|
+
field_value = Eurydice::Pelops::ByteHelpers.to_nio_bytes(field_value)
|
128
|
+
when :index_type
|
129
|
+
field_value = Cassandra::IndexType.valueOf(field_value.to_s.upcase)
|
130
|
+
when :validation_class
|
131
|
+
field_value = MARSHAL_TYPES.fetch(field_value, field_value)
|
132
|
+
end
|
133
|
+
field = self::_Fields.find_by_name(field_name.to_s)
|
134
|
+
raise ArgumentError, %(No field named "#{field_name}") unless field
|
135
|
+
col_def.set_field_value(field, field_value)
|
136
|
+
col_def
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def to_h
|
141
|
+
self.class.metaDataMap.reduce({}) do |acc, (field, field_meta_data)|
|
142
|
+
field_name = field.field_name.to_sym
|
143
|
+
acc[field_name] = begin
|
144
|
+
case field_name
|
145
|
+
when :name
|
146
|
+
Eurydice::Pelops::ByteHelpers.nio_bytes_to_s(get_field_value(field))
|
147
|
+
when :index_type
|
148
|
+
value = get_field_value(field)
|
149
|
+
value.toString.downcase.to_sym if value
|
150
|
+
else
|
151
|
+
get_field_value(field)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
acc
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Eurydice
|
4
|
+
module Pelops
|
5
|
+
class Cluster
|
6
|
+
def initialize(cluster, driver=::Pelops::Pelops)
|
7
|
+
@cluster = cluster
|
8
|
+
@driver = driver
|
9
|
+
end
|
10
|
+
|
11
|
+
def connected?
|
12
|
+
@driver.create_cluster_manager(@cluster).cassandra_version
|
13
|
+
true
|
14
|
+
rescue Exception => e
|
15
|
+
false
|
16
|
+
end
|
17
|
+
|
18
|
+
def keyspace(keyspace_name, options={})
|
19
|
+
pool_name = options.fetch(:pool_name, "eurydice_#{keyspace_name}_pool")
|
20
|
+
create = options.fetch(:create, true)
|
21
|
+
@driver.add_pool(pool_name, @cluster, keyspace_name)
|
22
|
+
keyspace = Keyspace.new(keyspace_name, @cluster, pool_name, @driver)
|
23
|
+
keyspace.create! if create && !keyspace.exists?
|
24
|
+
keyspace
|
25
|
+
end
|
26
|
+
|
27
|
+
def keyspaces
|
28
|
+
keyspace_manager.keyspace_names.map { |ks_def| ks_def.name }
|
29
|
+
end
|
30
|
+
|
31
|
+
def nodes
|
32
|
+
@cluster.nodes.map { |n| n.address }
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def keyspace_manager
|
38
|
+
@keyspace_manager ||= @driver.create_keyspace_manager(@cluster)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|