cassandra_migrations 0.1.0 → 0.2.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 937a04d1bf915cd899134c271aa645421259fb3b
4
- data.tar.gz: c0916a9b1fb7be0b142ad0515a3fca628953fe9c
3
+ metadata.gz: c812cb0c202ab7c93f145b144dc36664734588f4
4
+ data.tar.gz: 5aa232dd59bcd781a41b5e6bb7f2fb2b1b50b089
5
5
  SHA512:
6
- metadata.gz: 557970e72c79f1b37035948c3f4990b99afd4a92c0e794d9251a252b9143a7f7a67be3767ef5fdbc4f204a990427d294d2eb351330561eae85935c445a8a571c
7
- data.tar.gz: 38be1b8793e029e2d912699421c572906f60ceca0939b69951b4553e4b2f34fa5a0f51d9d570cfe95bf333add26447cb798afd1bab58c1f27f7730a4c04557dd
6
+ metadata.gz: 3eb66aa211265871e762ad3b56f1df6a79e5a0299174d3454ff38dc2b62eda8d981f591eb51efaa17331e669909c15ee53143b1f049d3440c93bd008aafb6d66
7
+ data.tar.gz: f3768b62b72d021660f7a6ef8bf634585ee777c8a8c84649d70d299b926e960d9121abd5ee35e619427bfaaf61498edbcdd5172dea764c6061679340dcd30f64
@@ -1,15 +1,16 @@
1
1
  # encoding: utf-8
2
+ require 'cassandra'
2
3
 
3
4
  module CassandraMigrations
4
5
  module Cassandra
5
6
  module KeyspaceOperations
6
-
7
+
7
8
  def create_keyspace!(env)
8
9
  config = Config.configurations[env]
9
10
  begin
10
11
  execute(
11
12
  "CREATE KEYSPACE #{config.keyspace} \
12
- WITH replication = { \
13
+ WITH replication = { \
13
14
  'class':'#{config.replication['class']}', \
14
15
  'replication_factor': #{config.replication['replication_factor']} \
15
16
  }"
@@ -20,16 +21,16 @@ module CassandraMigrations
20
21
  raise exception
21
22
  end
22
23
  end
23
-
24
+
24
25
  def drop_keyspace!(env)
25
26
  config = Config.configurations[env]
26
27
  begin
27
28
  execute("DROP KEYSPACE #{config.keyspace}")
28
- rescue Cql::QueryError
29
+ rescue ::Cassandra::Errors::QueryError
29
30
  raise Errors::UnexistingKeyspaceError, config.keyspace
30
31
  end
31
32
  end
32
-
33
+
33
34
  end
34
35
  end
35
36
  end
@@ -1,7 +1,8 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require 'yaml'
4
- require 'cql'
4
+ require 'cassandra'
5
+ require_relative 'cql-rb-wrapper'
5
6
  require 'cassandra_migrations/cassandra/queries'
6
7
  require 'cassandra_migrations/cassandra/query_result'
7
8
  require 'cassandra_migrations/cassandra/keyspace_operations'
@@ -10,9 +11,9 @@ module CassandraMigrations
10
11
  module Cassandra
11
12
  extend Queries
12
13
  extend KeyspaceOperations
13
-
14
+
14
15
  mattr_accessor :client
15
-
16
+
16
17
  def self.start!
17
18
  begin
18
19
  # setup keyspace use
@@ -20,10 +21,10 @@ module CassandraMigrations
20
21
  rescue Errors::MissingConfigurationError
21
22
  # It's acceptable to not have a configuration file, that's why we rescue this exception.
22
23
  # On the other hand, if the user try to execute a query this same exception won't be rescued
23
- Rails.logger.try(:warn, "There is no config/cassandra.yml. Skipping connection to Cassandra...")
24
+ Rails.logger.try(:warn, "There is no config/cassandra.yml. Skipping connection to Cassandra...")
24
25
  end
25
26
  end
26
-
27
+
27
28
  def self.restart!
28
29
  raise Errors::ClientNotStartedError unless client
29
30
 
@@ -31,7 +32,7 @@ module CassandraMigrations
31
32
  self.client = nil
32
33
  start!
33
34
  end
34
-
35
+
35
36
  def self.shutdown!
36
37
  raise Errors::ClientNotStartedError unless client
37
38
 
@@ -50,7 +51,8 @@ module CassandraMigrations
50
51
 
51
52
  begin
52
53
  client.use(keyspace)
53
- rescue Cql::QueryError # keyspace does not exist
54
+ rescue Exception => e # keyspace does not exist
55
+ puts "#{e} : #{e.message}"
54
56
  raise Errors::UnexistingKeyspaceError, keyspace
55
57
  end
56
58
  end
@@ -60,17 +62,18 @@ module CassandraMigrations
60
62
  Rails.logger.try(:info, "\e[1;35m [Cassandra Migrations] \e[0m #{cql.to_s}")
61
63
  result = client.execute(cql)
62
64
  QueryResult.new(result) if result
63
- end
64
-
65
+ end
66
+
65
67
  private
66
-
68
+
67
69
  def self.connect_to_server
68
- Rails.logger.try(:info, "Connecting to Cassandra on #{Config.host}:#{Config.port}")
69
-
70
+ connection_params = Config.connection_config_for_env
71
+ Rails.logger.try(:info, "Connecting to Cassandra on #{connection_params}")
72
+
70
73
  begin
71
- self.client = Cql::Client.connect(:host => Config.host, :port => Config.port)
72
- rescue Cql::Io::ConnectionError => e
73
- raise Errors::ConnectionError, e.message
74
+ self.client = Client.connect(connection_params)
75
+ rescue Ione::Io::ConnectionError => e
76
+ raise Errors::ConnectionError, e.message
74
77
  end
75
78
  end
76
79
  end
@@ -3,7 +3,15 @@
3
3
  module CassandraMigrations
4
4
  module Config
5
5
 
6
- FIELDS = %w(host port keyspace replication)
6
+ # See valid options at https://github.com/datastax/ruby-driver/blob/master/lib/cassandra.rb#L163
7
+ CASSANDRA_CONNECTION_VALID_FIELDS = [
8
+ :credentials, :auth_provider, :compression, :hosts, :logger, :port,
9
+ :load_balancing_policy, :reconnection_policy, :retry_policy, :listeners,
10
+ :consistency, :trace, :page_size, :compressor, :username, :password,
11
+ :ssl, :server_cert, :client_cert, :private_key, :passphrase,
12
+ :connect_timeout, :futures_factory]
13
+
14
+ FIELDS = CASSANDRA_CONNECTION_VALID_FIELDS.map(&:to_s) + %w(keyspace replication)
7
15
 
8
16
  Configuration = Struct.new(*FIELDS.map(&:to_sym))
9
17
 
@@ -17,7 +25,24 @@ module CassandraMigrations
17
25
  load_config unless configurations
18
26
  self.configurations[Rails.env].send(method_sym)
19
27
  end
20
-
28
+
29
+ def self.connection_config_for_env
30
+ env_config = Hash[self.configurations[Rails.env].each_pair.to_a]
31
+
32
+ # support for old configuration param :port (singular)
33
+ if env_config.include?(:port)
34
+ env_config[:ports] = [env_config[:port]]
35
+ end
36
+
37
+ env_config.keep_if do |k,v|
38
+ CASSANDRA_CONNECTION_VALID_FIELDS.include?(k) && v
39
+ end
40
+
41
+ Hash[self.configurations[Rails.env].each_pair.to_a].keep_if do |k,v|
42
+ CASSANDRA_CONNECTION_VALID_FIELDS.include?(k) && v
43
+ end
44
+ end
45
+
21
46
  private
22
47
 
23
48
  def self.load_config
@@ -32,6 +57,6 @@ module CassandraMigrations
32
57
  raise Errors::MissingConfigurationError
33
58
  end
34
59
  end
35
-
60
+
36
61
  end
37
62
  end
@@ -0,0 +1,92 @@
1
+ # encoding: utf-8
2
+
3
+ require 'cassandra'
4
+ require 'ione'
5
+
6
+ class PreparedStatement
7
+ attr_reader :statement
8
+
9
+ def initialize(client, statement)
10
+ @client = client
11
+ @statement = statement
12
+ end
13
+
14
+ def execute(*args)
15
+ @client.execute(@statement, *args)
16
+ end
17
+ end
18
+
19
+ class BatchStatement
20
+ def initialize(client, batch)
21
+ @client = client
22
+ @batch = batch
23
+ end
24
+
25
+ def execute(options = {})
26
+ @client.execute(@batch, options)
27
+ end
28
+
29
+ def add(*args)
30
+ @batch.add(*args)
31
+ self
32
+ end
33
+ end
34
+
35
+ class Client
36
+ def self.connect(options)
37
+ @cluster = Cassandra.connect(options)
38
+ self.new(@cluster)
39
+ end
40
+
41
+ def use(keyspace)
42
+ if @sessions[keyspace]
43
+ @session = @sessions[keyspace]
44
+ else
45
+ @session = @cluster.connect(keyspace)
46
+ @sessions[keyspace] = @session
47
+ end
48
+ end
49
+
50
+ def initialize(cluster, keyspace = nil)
51
+ @cluster = cluster
52
+ @sessions = {}
53
+ if keyspace
54
+ @session = cluster.connect(keyspace)
55
+ @sessions[keyspace] = @session
56
+ else
57
+ @session = @cluster.connect()
58
+ @sessions[:default] = @session
59
+ end
60
+ end
61
+
62
+ def execute(*args)
63
+ @session.execute(*args)
64
+ end
65
+
66
+ def prepare(statement, options = {})
67
+ s = @session.prepare(statement, options)
68
+ PreparedStatement.new(self, s)
69
+ end
70
+
71
+ def batch(type = :logged, options = {})
72
+ batch = BatchStatement.new(self, @session.send(:"#{type}_batch"))
73
+ if block_given?
74
+ yield(batch)
75
+ batch.execute(options)
76
+ else
77
+ batch
78
+ end
79
+ end
80
+
81
+ def close
82
+ @session.close
83
+ end
84
+
85
+ def keyspace
86
+ @session.keyspace
87
+ end
88
+
89
+ def connected?
90
+ @session.instance_variable_get('@state') == :connected
91
+ end
92
+ end
@@ -15,36 +15,36 @@ module CassandraMigrations
15
15
  end
16
16
  end
17
17
  end
18
-
18
+
19
19
  class ClientNotStartedError < CassandraError
20
20
  def initialize
21
21
  super("Cassandra.start! has not been called yet! Can't execute queries before connecting to server...")
22
22
  end
23
23
  end
24
-
24
+
25
25
  class MissingConfigurationError < CassandraError
26
26
  def initialize(msg=nil)
27
27
  super(msg || "config/cassandra.yml is missing! Run 'prepare_for_cassandra .' in the rails root directory.")
28
28
  end
29
29
  end
30
-
30
+
31
31
  class UnexistingKeyspaceError < CassandraError
32
- def initialize(keyspace)
33
- super("Keyspace #{keyspace} does not exist. Run rake cassandra:create.")
32
+ def initialize(keyspace, e = nil)
33
+ super(%[Keyspace #{keyspace} does not exist. Run rake cassandra:create. #{"(#{e.message})" if e}])
34
34
  end
35
35
  end
36
-
36
+
37
37
  class ConnectionError < CassandraError
38
38
  def initialize(msg)
39
39
  super(msg)
40
40
  end
41
41
  end
42
-
42
+
43
43
  class MigrationDefinitionError < CassandraError
44
44
  def initialize(msg)
45
45
  super(msg)
46
46
  end
47
47
  end
48
-
48
+
49
49
  end
50
50
  end
@@ -78,7 +78,7 @@ module CassandraMigrations
78
78
 
79
79
  if (@columns_name_type_hash.values.include? :counter)
80
80
  non_key_columns = @columns_name_type_hash.keys - @primary_keys
81
- counter_columns = [@columns_name_type_hash.select { |name, type| type == :counter }.first[0]]
81
+ counter_columns = @columns_name_type_hash.select { |name, type| type == :counter }.keys
82
82
  if (non_key_columns - counter_columns).present?
83
83
  raise Errors::MigrationDefinitionError, 'Non key fields not allowed in tables with counter'
84
84
  end
@@ -2,32 +2,32 @@
2
2
 
3
3
  module CassandraMigrations
4
4
  module Migrator
5
-
5
+
6
6
  METADATA_TABLE = 'cassandra_migrations_metadata'
7
-
7
+
8
8
  def self.up_to_latest!
9
9
  current_version = read_current_version
10
-
10
+
11
11
  new_migrations = get_all_migration_names.sort.select do |migration_name|
12
12
  get_version_from_migration_name(migration_name) > current_version
13
13
  end
14
-
14
+
15
15
  if !new_migrations.empty?
16
16
  new_migrations.each { |migration| up(migration) }
17
17
  end
18
-
18
+
19
19
  new_migrations.size
20
20
  end
21
-
21
+
22
22
  def self.rollback!(count=1)
23
23
  current_version = read_current_version
24
-
24
+
25
25
  executed_migrations = get_all_migration_names.sort.reverse.select do |migration_name|
26
26
  get_version_from_migration_name(migration_name) <= current_version
27
27
  end
28
-
28
+
29
29
  down_count = 0
30
-
30
+
31
31
  if !executed_migrations.empty?
32
32
  count.times do |i|
33
33
  if executed_migrations[i]
@@ -36,32 +36,32 @@ module CassandraMigrations
36
36
  end
37
37
  end
38
38
  end
39
-
39
+
40
40
  down_count
41
41
  end
42
-
42
+
43
43
  def self.read_current_version
44
44
  begin
45
45
  Cassandra.select(METADATA_TABLE, :selection => "data_name='version'", :projection => 'data_value').first['data_value'].to_i
46
- rescue Cql::QueryError # table cassandra_migrations_metadata does not exist
47
- Cassandra.execute("CREATE TABLE #{METADATA_TABLE} (data_name varchar PRIMARY KEY, data_value varchar)")
46
+ rescue ::Cassandra::Errors::QueryError => e # table cassandra_migrations_metadata does not exist
47
+ Cassandra.execute("CREATE TABLE #{METADATA_TABLE} (data_name varchar PRIMARY KEY, data_value varchar)")
48
48
  Cassandra.write!(METADATA_TABLE, {:data_name => 'version', :data_value => '0'})
49
49
  return 0
50
50
  end
51
51
  end
52
-
52
+
53
53
  private
54
-
54
+
55
55
  def self.up(migration_name)
56
56
  # load migration
57
57
  require migration_name
58
58
  # run migration
59
59
  get_class_from_migration_name(migration_name).new.migrate(:up)
60
-
60
+
61
61
  # update version
62
62
  Cassandra.write!(METADATA_TABLE, {:data_name => 'version', :data_value => get_version_from_migration_name(migration_name).to_s})
63
63
  end
64
-
64
+
65
65
  def self.down(migration_name, previous_migration_name=nil)
66
66
  # load migration
67
67
  require migration_name
@@ -75,15 +75,15 @@ private
75
75
  Cassandra.write!(METADATA_TABLE, {:data_name => 'version', :data_value => '0'})
76
76
  end
77
77
  end
78
-
78
+
79
79
  def self.get_all_migration_names
80
80
  Dir[Rails.root.join("db", "cassandra_migrate/[0-9]*_*.rb")]
81
81
  end
82
-
82
+
83
83
  def self.get_class_from_migration_name(filename)
84
- filename.match(/[0-9]{14}_(.+)\.rb$/).captures.first.camelize.constantize
85
- end
86
-
84
+ filename.match(/[0-9]{14}_(.+)\.rb$/).captures.first.camelize.constantize
85
+ end
86
+
87
87
  def self.get_version_from_migration_name(migration_name)
88
88
  migration_name.match(/([0-9]{14})_.+\.rb$/).captures.first.to_i
89
89
  end
@@ -1,5 +1,5 @@
1
1
  development:
2
- host: '127.0.0.1'
2
+ hosts: ['127.0.0.1']
3
3
  port: 9042
4
4
  keyspace: 'my_keyspace_name'
5
5
  replication:
@@ -7,15 +7,15 @@ development:
7
7
  replication_factor: 1
8
8
 
9
9
  test:
10
- host: '127.0.0.1'
10
+ hosts: ['127.0.0.1']
11
11
  port: 9042
12
12
  keyspace: 'my_keyspace_name_test'
13
13
  replication:
14
14
  class: 'SimpleStrategy'
15
15
  replication_factor: 1
16
-
16
+
17
17
  production:
18
- host: '127.0.0.1'
18
+ hosts: ['127.0.0.1']
19
19
  port: 9042
20
20
  keyspace: 'my_keyspace_name_production'
21
21
  replication:
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cassandra_migrations
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Henrique Gubert
@@ -9,22 +9,22 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-06-18 00:00:00.000000000 Z
12
+ date: 2014-10-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- name: cql-rb
15
+ name: cassandra-driver
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - '='
18
+ - - "~>"
19
19
  - !ruby/object:Gem::Version
20
- version: 2.0.0
20
+ version: 1.0.0.beta.3
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
- - - '='
25
+ - - "~>"
26
26
  - !ruby/object:Gem::Version
27
- version: 2.0.0
27
+ version: 1.0.0.beta.3
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: rake
30
30
  requirement: !ruby/object:Gem::Requirement
@@ -73,14 +73,14 @@ dependencies:
73
73
  requirements:
74
74
  - - "~>"
75
75
  - !ruby/object:Gem::Version
76
- version: '2.99'
76
+ version: 3.1.0
77
77
  type: :development
78
78
  prerelease: false
79
79
  version_requirements: !ruby/object:Gem::Requirement
80
80
  requirements:
81
81
  - - "~>"
82
82
  - !ruby/object:Gem::Version
83
- version: '2.99'
83
+ version: 3.1.0
84
84
  - !ruby/object:Gem::Dependency
85
85
  name: debugger
86
86
  requirement: !ruby/object:Gem::Requirement
@@ -101,28 +101,28 @@ dependencies:
101
101
  requirements:
102
102
  - - "~>"
103
103
  - !ruby/object:Gem::Version
104
- version: '1.3'
104
+ version: '1.6'
105
105
  type: :development
106
106
  prerelease: false
107
107
  version_requirements: !ruby/object:Gem::Requirement
108
108
  requirements:
109
109
  - - "~>"
110
110
  - !ruby/object:Gem::Version
111
- version: '1.3'
111
+ version: '1.6'
112
112
  - !ruby/object:Gem::Dependency
113
113
  name: simplecov
114
114
  requirement: !ruby/object:Gem::Requirement
115
115
  requirements:
116
116
  - - "~>"
117
117
  - !ruby/object:Gem::Version
118
- version: '0.8'
118
+ version: '0.9'
119
119
  type: :development
120
120
  prerelease: false
121
121
  version_requirements: !ruby/object:Gem::Requirement
122
122
  requirements:
123
123
  - - "~>"
124
124
  - !ruby/object:Gem::Version
125
- version: '0.8'
125
+ version: '0.9'
126
126
  - !ruby/object:Gem::Dependency
127
127
  name: coveralls
128
128
  requirement: !ruby/object:Gem::Requirement
@@ -155,6 +155,7 @@ files:
155
155
  - lib/cassandra_migrations/cassandra/queries.rb
156
156
  - lib/cassandra_migrations/cassandra/query_result.rb
157
157
  - lib/cassandra_migrations/config.rb
158
+ - lib/cassandra_migrations/cql-rb-wrapper.rb
158
159
  - lib/cassandra_migrations/errors.rb
159
160
  - lib/cassandra_migrations/migration.rb
160
161
  - lib/cassandra_migrations/migration/column_operations.rb
@@ -188,7 +189,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
188
189
  version: 1.8.0
189
190
  requirements: []
190
191
  rubyforge_project:
191
- rubygems_version: 2.2.1
192
+ rubygems_version: 2.2.2
192
193
  signing_key:
193
194
  specification_version: 4
194
195
  summary: Cassandra schema management for a multi-environment developer.