cassandra_migrations 0.2.2 → 0.2.5

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: d089b09a2a03caa0cb2787d2de0e8d2f2db278bc
4
- data.tar.gz: a1f2fbc186ff690aa33c58306f6d193c19fb3643
3
+ metadata.gz: 2adbd178415bd43d539d236b8a2c46b21e8a7f72
4
+ data.tar.gz: 1216e38539fdebb43798770efdefe8c091c19bb4
5
5
  SHA512:
6
- metadata.gz: c2606317f233f502898569d15903ad5816b106e69cd1d29831677a8215bf38cc0d20bffe8fe4bb76df13619e2728ae796751b9b0246acd3039f469b7c9411ee3
7
- data.tar.gz: 36bae513a0ae96563a2c989148baaa24c9d6bde62baba44fa0fcb03cd2f9a12f286dd37bfb3ba30b1b44c99e40059a6e34870a185faf171a99acbc7797ee42a9
6
+ metadata.gz: 015a4ec736b6900eb9fe8a24da10baea299752718ac025b487decf15fbe5cad684951da2e282af0d8df178b35556f7d32fb1cc7127e79f8313a2e5486ab9ba5a
7
+ data.tar.gz: 276c5d3a589d3e73a9f61f96d8cdc78eb76584d8f23c04cfe05f8db37fae59bca11c0cf8e402d13f972e8af92f21121ad2155a313a650c9bd7fe0fc59e77cbe9
@@ -7,16 +7,18 @@ module CassandraMigrations
7
7
 
8
8
  def create_keyspace!(env)
9
9
  config = Config.configurations[env]
10
+ validate_config(config)
11
+
12
+ execute(
13
+ "CREATE KEYSPACE #{config.keyspace} \
14
+ WITH replication = { \
15
+ 'class':'#{config.replication['class']}', \
16
+ 'replication_factor': #{config.replication['replication_factor']} \
17
+ }"
18
+ )
10
19
  begin
11
- execute(
12
- "CREATE KEYSPACE #{config.keyspace} \
13
- WITH replication = { \
14
- 'class':'#{config.replication['class']}', \
15
- 'replication_factor': #{config.replication['replication_factor']} \
16
- }"
17
- )
18
20
  use(config.keyspace)
19
- rescue Exception => exception
21
+ rescue StandardErorr => exception
20
22
  drop_keyspace!(env)
21
23
  raise exception
22
24
  end
@@ -26,11 +28,28 @@ module CassandraMigrations
26
28
  config = Config.configurations[env]
27
29
  begin
28
30
  execute("DROP KEYSPACE #{config.keyspace}")
29
- rescue ::Cassandra::Errors::QueryError
31
+ rescue ::Cassandra::Errors::ConfigurationError
30
32
  raise Errors::UnexistingKeyspaceError, config.keyspace
31
33
  end
32
34
  end
33
35
 
36
+ private
37
+
38
+ def validate_config(config)
39
+ if config.keyspace.nil?
40
+ raise Errors::MissingConfigurationError.new("Configuration of 'keyspace' is required in config.yml, but none is defined.")
41
+ end
42
+ unless config_includes_replication?(config)
43
+ raise Errors::MissingConfigurationError.new("Configuration for 'replication' is required in config.yml, but none is defined.")
44
+ end
45
+ true
46
+ end
47
+
48
+ def config_includes_replication?(config)
49
+ config.replication &&
50
+ config.replication['class'] &&
51
+ config.replication['replication_factor']
52
+ end
34
53
  end
35
54
  end
36
55
  end
@@ -41,6 +41,7 @@ module CassandraMigrations
41
41
 
42
42
  def select(table, options={})
43
43
  query_string = "SELECT #{options[:projection] || '*'} FROM #{table}"
44
+ options[:secondary_options] ||= {}
44
45
 
45
46
  if options[:selection]
46
47
  query_string << " WHERE #{options[:selection]}"
@@ -58,7 +59,40 @@ module CassandraMigrations
58
59
  query_string << " ALLOW FILTERING"
59
60
  end
60
61
 
61
- execute(query_string)
62
+ #Secondary options
63
+ if options[:page_size]
64
+ options[:secondary_options][:page_size] = options[:page_size]
65
+ end
66
+
67
+ if options[:consistency]
68
+ options[:secondary_options][:consistency] = options[:consistency]
69
+ end
70
+
71
+ if options[:trace]
72
+ options[:secondary_options][:trace] = options[:trace]
73
+ end
74
+
75
+ if options[:timeout]
76
+ options[:secondary_options][:timeout] = options[:timeout]
77
+ end
78
+
79
+ if options[:serial_consistency]
80
+ options[:secondary_options][:serial_consistency] = options[:serial_consistency]
81
+ end
82
+
83
+ if options[:paging_state]
84
+ options[:secondary_options][:paging_state] = options[:paging_state]
85
+ end
86
+
87
+ if options[:arguments]
88
+ options[:secondary_options][:arguments] = options[:arguments]
89
+ end
90
+
91
+ if options[:secondary_options].length > 0
92
+ execute(query_string, options[:secondary_options])
93
+ else
94
+ execute(query_string)
95
+ end
62
96
  end
63
97
 
64
98
  def delete!(table, selection, options={})
@@ -93,7 +127,7 @@ module CassandraMigrations
93
127
 
94
128
  def get_column_type(table, column)
95
129
  column_info = client.execute("SELECT VALIDATOR FROM system.schema_columns WHERE keyspace_name = '#{client.keyspace}' AND columnfamily_name = '#{table}' AND column_name = '#{column}'")
96
- SYMBOL_FOR_TYPE[column_info.first['validator']]
130
+ SYMBOL_FOR_TYPE[(column_info.first['validator'].split(/[\.(]/) & SYMBOL_FOR_TYPE.keys).first]
97
131
  end
98
132
 
99
133
  def to_cql_value(column, value, table, options={})
@@ -113,13 +147,13 @@ module CassandraMigrations
113
147
  if value == ""
114
148
  value = 'null'
115
149
  else
116
- value = value
150
+ value = value.gsub("'", "''")
117
151
  end
118
152
  end
119
153
  end
120
154
 
121
155
  def string_to_cql(value)
122
- "'#{value}'"
156
+ "'#{value.gsub("'", "''")}'"
123
157
  end
124
158
 
125
159
  def datetime_to_cql(value)
@@ -138,7 +172,7 @@ module CassandraMigrations
138
172
  end
139
173
 
140
174
  def hash_to_cql(value, operation)
141
- "#{operation}{ #{value.reduce([]) {|sum, (key, value)| sum << "'#{key}': '#{value}'" }.join(", ") } }"
175
+ "#{operation}{ #{value.reduce([]) {|sum, (k, v)| sum << "'#{k}': #{to_cql_value(nil, v, nil)}" }.join(", ") } }"
142
176
  end
143
177
 
144
178
  end
@@ -28,8 +28,15 @@ module CassandraMigrations
28
28
  def self.restart!
29
29
  raise Errors::ClientNotStartedError unless client
30
30
 
31
- client.close if client && client.connected?
32
- self.client = nil
31
+ restart
32
+ end
33
+
34
+ def self.restart
35
+ if client
36
+ client.close if client.connected?
37
+ self.client = nil
38
+ end
39
+
33
40
  start!
34
41
  end
35
42
 
@@ -57,10 +64,10 @@ module CassandraMigrations
57
64
  end
58
65
  end
59
66
 
60
- def self.execute(cql)
67
+ def self.execute(*cql)
61
68
  connect_to_server unless client
62
69
  Rails.logger.try(:info, "\e[1;35m [Cassandra Migrations] \e[0m #{cql.to_s}")
63
- result = client.execute(cql)
70
+ result = client.execute(*cql)
64
71
  QueryResult.new(result) if result
65
72
  end
66
73
 
@@ -68,7 +75,6 @@ module CassandraMigrations
68
75
 
69
76
  def self.connect_to_server
70
77
  connection_params = Config.connection_config_for_env
71
- Rails.logger.try(:info, "Connecting to Cassandra on #{connection_params}")
72
78
 
73
79
  begin
74
80
  self.client = Client.connect(connection_params)
@@ -34,13 +34,12 @@ end
34
34
 
35
35
  class Client
36
36
  def self.connect(options)
37
- if defined?(Spring)
38
- Spring.after_fork do
39
- @cluster = Cassandra.cluster(options)
40
- end
41
- else
42
- @cluster = Cassandra.cluster(options)
37
+ Rails.logger.try(:info, "Connecting to Cassandra cluster: #{options}")
38
+
39
+ unless @cluster = Cassandra.cluster(options)
40
+ raise CassandraMigrations::Errors::ClusterError.new(options)
43
41
  end
42
+
44
43
  self.new(@cluster)
45
44
  end
46
45
 
@@ -48,6 +47,7 @@ class Client
48
47
  if @sessions[keyspace]
49
48
  @session = @sessions[keyspace]
50
49
  else
50
+ Rails.logger.try(:info, "Creating Cassandra session: #{keyspace.inspect}")
51
51
  @session = @cluster.connect(keyspace)
52
52
  @sessions[keyspace] = @session
53
53
  end
@@ -57,9 +57,11 @@ class Client
57
57
  @cluster = cluster
58
58
  @sessions = {}
59
59
  if keyspace
60
+ Rails.logger.try(:info, "Creating Cassandra session: #{keyspace.inspect}")
60
61
  @session = cluster.connect(keyspace)
61
62
  @sessions[keyspace] = @session
62
63
  else
64
+ Rails.logger.try(:info, "Creating Cassandra session: [no keyspace]")
63
65
  @session = @cluster.connect()
64
66
  @sessions[:default] = @session
65
67
  end
@@ -85,6 +87,7 @@ class Client
85
87
  end
86
88
 
87
89
  def close
90
+ Rails.logger.try(:info, "Closing Cassandra session: #{@session.inspect}")
88
91
  @session.close
89
92
  end
90
93
 
@@ -34,6 +34,12 @@ module CassandraMigrations
34
34
  end
35
35
  end
36
36
 
37
+ class ClusterError < CassandraError
38
+ def initialize(cluster_opts, e = nil)
39
+ super(%[Could not connect to cluster at #{cluster_opts}. Is Cassandra running? #{"(#{e.message})" if e}])
40
+ end
41
+ end
42
+
37
43
  class ConnectionError < CassandraError
38
44
  def initialize(msg)
39
45
  super(msg)
@@ -65,26 +65,6 @@ module CassandraMigrations
65
65
  execute drop_index_cql
66
66
  end
67
67
 
68
- def create_table(table_name, options = {})
69
- table_definition = TableDefinition.new
70
- table_definition.define_primary_keys(options[:primary_keys]) if options[:primary_keys]
71
- table_definition.define_partition_keys(options[:partition_keys]) if options[:partition_keys]
72
- table_definition.define_options(options[:options]) if options[:options]
73
-
74
- yield table_definition if block_given?
75
-
76
- announce_operation "create_table(#{table_name})"
77
-
78
- create_cql = "CREATE TABLE #{table_name} ("
79
- create_cql << table_definition.to_create_cql
80
- create_cql << ")"
81
- create_cql << table_definition.options
82
-
83
- announce_suboperation create_cql
84
-
85
- execute create_cql
86
- end
87
-
88
68
  end
89
69
  end
90
70
  end
@@ -43,7 +43,7 @@ module CassandraMigrations
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 ::Cassandra::Errors::QueryError => e # table cassandra_migrations_metadata does not exist
46
+ rescue ::Cassandra::Errors::InvalidError => e # table cassandra_migrations_metadata does not exist
47
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
@@ -0,0 +1,11 @@
1
+ Description:
2
+ Generates a default cassandra database configuration
3
+
4
+ Example:
5
+ rails generate cassandra_configuration
6
+
7
+ This will create:
8
+ config/cassandra.yml
9
+
10
+ Inside this file a default configuration will be ready for completion:
11
+
@@ -0,0 +1,32 @@
1
+ class CassandraConfigurationGenerator < Rails::Generators::Base
2
+ source_root File.expand_path('templates', File.dirname(__FILE__))
3
+
4
+ # Creates configuration file and migration directory
5
+ #
6
+ # Any public method in the generator is run automatically when
7
+ # the generator is run. To understand fully see
8
+ # http://asciicasts.com/episodes/218-making-generators-in-rails-3
9
+
10
+ def generate_configuration
11
+ require 'fileutils'
12
+ require 'colorize'
13
+
14
+ # create cassandra.yaml
15
+ if File.exists?(File.expand_path('config/cassandra.yml'))
16
+ puts "[skip] 'config/cassandra.yml' already exists".yellow
17
+ else
18
+ puts "[new] creating 'config/cassandra.yml' (please update with your own configurations!)".green
19
+ template "cassandra.yml", "config/cassandra.yml"
20
+ end
21
+
22
+ # create db/cassandra_migrations
23
+ if File.exists?(File.expand_path('db/cassandra_migrate'))
24
+ puts "[skip] 'db/cassandra_migrate' already exists".yellow
25
+ else
26
+ puts "[new] creating 'db/cassandra_migrate' directory".green
27
+ FileUtils.mkdir(File.expand_path('db/cassandra_migrate'))
28
+ end
29
+
30
+ puts '[done]'.green
31
+ end
32
+ end
@@ -0,0 +1,31 @@
1
+ development:
2
+ hosts:
3
+ - 127.0.0.1
4
+ port: 9042
5
+ keyspace: my_keyspace_dev
6
+ replication:
7
+ class: SimpleStrategy
8
+ replication_factor: 1
9
+
10
+ test:
11
+ hosts:
12
+ - 127.0.0.1
13
+ port: 9042
14
+ keyspace: cassandra_migrations_test
15
+ replication:
16
+ class: 'SimpleStrategy'
17
+ replication_factor: 1
18
+
19
+ production:
20
+ hosts:
21
+ - 'cass1.my_app.biz'
22
+ - 'cass2.my_app.biz'
23
+ - 'cass3.my_app.biz'
24
+ port: 9042
25
+ keyspace: cassandra_migrations_production
26
+ username: myappuser
27
+ password: password1
28
+ replication:
29
+ class: NetworkTopologyStrategy
30
+ datacenter1: 3
31
+ datacenter2: 2
@@ -11,20 +11,19 @@
11
11
 
12
12
  module CassandraMigrations
13
13
 
14
+ Cassandra.start!
15
+
16
+ if defined?(Spring)
17
+ Spring.after_fork do
18
+ Cassandra.restart
19
+ end
20
+ end
21
+
14
22
  if defined?(PhusionPassenger)
15
23
  PhusionPassenger.on_event(:starting_worker_process) do |forked|
16
24
  if forked
17
- if Cassandra.client
18
- Rails.logger.info "Passenger process forked: reconnecting to Cassandra..."
19
- Cassandra.restart!
20
- else
21
- Rails.logger.info "Passenger process forked: connecting to Cassandra..."
22
- Cassandra.start!
23
- end
25
+ Cassandra.restart
24
26
  end
25
27
  end
26
- else
27
- Cassandra.start!
28
28
  end
29
-
30
29
  end
@@ -51,18 +51,26 @@ namespace :cassandra do
51
51
  end
52
52
  end
53
53
 
54
- desc 'Resets and prepares cassandra database (all data will be lost)'
54
+ namespace :migrate do
55
+ desc 'Resets and prepares cassandra database (all data will be lost)'
56
+ task :reset do
57
+ Rake::Task['cassandra:drop'].execute
58
+ Rake::Task['cassandra:create'].execute
59
+ Rake::Task['cassandra:migrate'].execute
60
+ end
61
+ end
62
+
55
63
  task :setup do
56
- Rake::Task['cassandra:drop'].execute
64
+ puts "DEPRECATION WARNING: `cassandra:setup` rake task has been deprecated, use `cassandra:migrate:reset` instead"
57
65
  Rake::Task['cassandra:create'].execute
58
66
  Rake::Task['cassandra:migrate'].execute
59
67
  end
60
68
 
61
69
  namespace :test do
62
- desc 'Load the development schema in to the test keyspace'
70
+ desc 'Load the development schema in to the test keyspace via a full reset'
63
71
  task :prepare do
64
72
  Rails.env = 'test'
65
- Rake::Task['cassandra:setup'].execute
73
+ Rake::Task['cassandra:migrate:reset'].execute
66
74
  end
67
75
  end
68
76
 
@@ -71,4 +79,6 @@ namespace :cassandra do
71
79
  puts "Current version: #{CassandraMigrations::Migrator.read_current_version}"
72
80
  end
73
81
 
82
+ task
83
+
74
84
  end
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.2.2
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Henrique Gubert
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-03-01 00:00:00.000000000 Z
12
+ date: 2015-11-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: cassandra-driver
@@ -82,19 +82,19 @@ dependencies:
82
82
  - !ruby/object:Gem::Version
83
83
  version: 3.1.0
84
84
  - !ruby/object:Gem::Dependency
85
- name: debugger
85
+ name: byebug
86
86
  requirement: !ruby/object:Gem::Requirement
87
87
  requirements:
88
88
  - - "~>"
89
89
  - !ruby/object:Gem::Version
90
- version: '1.6'
90
+ version: '8.2'
91
91
  type: :development
92
92
  prerelease: false
93
93
  version_requirements: !ruby/object:Gem::Requirement
94
94
  requirements:
95
95
  - - "~>"
96
96
  - !ruby/object:Gem::Version
97
- version: '1.6'
97
+ version: '8.2'
98
98
  - !ruby/object:Gem::Dependency
99
99
  name: bundler
100
100
  requirement: !ruby/object:Gem::Requirement
@@ -142,12 +142,10 @@ description: A gem to manage Cassandra database schema for Rails. This gem offer
142
142
  email:
143
143
  - guberthenrique@hotmail.com
144
144
  - bsbodden@integrallis.com
145
- executables:
146
- - prepare_for_cassandra
145
+ executables: []
147
146
  extensions: []
148
147
  extra_rdoc_files: []
149
148
  files:
150
- - bin/prepare_for_cassandra
151
149
  - lib/cassandra_migrations.rb
152
150
  - lib/cassandra_migrations/capistrano.rb
153
151
  - lib/cassandra_migrations/cassandra.rb
@@ -163,12 +161,14 @@ files:
163
161
  - lib/cassandra_migrations/migration/table_operations.rb
164
162
  - lib/cassandra_migrations/migrator.rb
165
163
  - lib/cassandra_migrations/railtie.rb
164
+ - lib/cassandra_migrations/railtie/generators/cassandra_configuration/USAGE
165
+ - lib/cassandra_migrations/railtie/generators/cassandra_configuration/cassandra_configuration_generator.rb
166
+ - lib/cassandra_migrations/railtie/generators/cassandra_configuration/templates/cassandra.yml
166
167
  - lib/cassandra_migrations/railtie/generators/cassandra_migration/USAGE
167
168
  - lib/cassandra_migrations/railtie/generators/cassandra_migration/cassandra_migration_generator.rb
168
169
  - lib/cassandra_migrations/railtie/generators/cassandra_migration/templates/empty_migration.rb.erb
169
170
  - lib/cassandra_migrations/railtie/initializer.rb
170
171
  - lib/cassandra_migrations/railtie/tasks.rake
171
- - template/cassandra.yml
172
172
  homepage: https://github.com/hsgubert/cassandra_migrations
173
173
  licenses:
174
174
  - MIT
@@ -189,7 +189,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
189
189
  version: 1.8.0
190
190
  requirements: []
191
191
  rubyforge_project:
192
- rubygems_version: 2.2.2
192
+ rubygems_version: 2.4.8
193
193
  signing_key:
194
194
  specification_version: 4
195
195
  summary: Cassandra schema management for a multi-environment developer.
@@ -1,62 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'optparse'
4
- require 'fileutils'
5
- require 'colorize'
6
-
7
- OptionParser.new do |opts|
8
- opts.banner = "Usage: #{File.basename($0)} [path]"
9
-
10
- opts.on("-h", "--help", "Displays this help info") do
11
- puts opts
12
- exit 0
13
- end
14
-
15
- begin
16
- opts.parse!(ARGV)
17
- rescue OptionParser::ParseError => e
18
- warn e.message
19
- puts opts
20
- exit 1
21
- end
22
- end
23
-
24
- if ARGV.empty?
25
- abort "Please specify the directory of a rails appilcation, e.g. `#{File.basename($0)} .'"
26
- elsif !File.directory?(ARGV.first)
27
- abort "`#{ARGV.first}' is not a directory."
28
- elsif ARGV.length > 1
29
- abort "Too many arguments; please specify only the directory of the rails application."
30
- end
31
-
32
- rails_root = ARGV.first
33
-
34
- # create cassandra.yaml
35
- if File.exists?(File.expand_path('config/cassandra.yml', rails_root))
36
- puts "[skip] 'config/cassandra.yml' already exists".yellow
37
- else
38
- puts "[new] creating 'config/cassandra.yml' (please update with your own configurations!)".green
39
- FileUtils.cp(
40
- File.expand_path('../template/cassandra.yml', File.dirname(__FILE__)),
41
- File.expand_path('config/cassandra.yml', rails_root)
42
- )
43
- end
44
-
45
- # create db/cassandra_migrations
46
- if File.exists?(File.expand_path('db/cassandra_migrate', rails_root))
47
- puts "[skip] 'db/cassandra_migrate' already exists".yellow
48
- else
49
- puts "[new] creating 'db/cassandra_migrate' directory".green
50
- FileUtils.mkdir(File.expand_path('db/cassandra_migrate', rails_root))
51
- end
52
-
53
- puts '[done] prepared for cassandra!'.green
54
- puts ''
55
- puts 'Your steps from here are:'.green
56
- puts ' 1. configure '.green + 'config/cassandra.yml'.red
57
- puts ' 2. run '.green + 'rake cassandra:setup'.red + ' and try starting your application'.green
58
- puts ' 3. create your first migration with '.green + 'rails g cassandra_migration'.red
59
- puts ' 4. apply your migration with '.green + 'rake cassandra:migrate'.red
60
- puts ' 5. run '.green + 'rake cassandra:test:prepare'.red + ' and start testing'.green
61
- puts ' 6. have lots of fun!'.green.blink
62
-
@@ -1,23 +0,0 @@
1
- development:
2
- hosts: ['127.0.0.1']
3
- port: 9042
4
- keyspace: 'my_keyspace_name'
5
- replication:
6
- class: 'SimpleStrategy'
7
- replication_factor: 1
8
-
9
- test:
10
- hosts: ['127.0.0.1']
11
- port: 9042
12
- keyspace: 'my_keyspace_name_test'
13
- replication:
14
- class: 'SimpleStrategy'
15
- replication_factor: 1
16
-
17
- production:
18
- hosts: ['127.0.0.1']
19
- port: 9042
20
- keyspace: 'my_keyspace_name_production'
21
- replication:
22
- class: 'SimpleStrategy'
23
- replication_factor: 1