eurydice 1.0.0-java
Sign up to get free protection for your applications and to get access to all the features.
- 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
|