cassandra_migrations 0.1.0 → 0.2.0

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