cassandra_migrations 0.0.1.pre4 → 0.0.1.pre5
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/bin/prepare_for_cassandra +62 -0
- data/lib/cassandra_migrations.rb +1 -0
- data/lib/cassandra_migrations/cassandra.rb +0 -1
- data/lib/cassandra_migrations/cassandra/queries.rb +8 -1
- data/lib/cassandra_migrations/errors.rb +6 -0
- data/lib/cassandra_migrations/migration.rb +89 -0
- data/lib/cassandra_migrations/migration/column_operations.rb +48 -0
- data/lib/cassandra_migrations/migration/table_definition.rb +111 -0
- data/lib/cassandra_migrations/migration/table_operations.rb +46 -0
- data/lib/cassandra_migrations/migrator.rb +4 -4
- data/lib/cassandra_migrations/railtie.rb +6 -0
- data/lib/cassandra_migrations/railtie/generators/cassandra_migration/USAGE +23 -0
- data/lib/cassandra_migrations/railtie/generators/cassandra_migration/cassandra_migration_generator.rb +18 -0
- data/lib/cassandra_migrations/railtie/generators/cassandra_migration/templates/empty_migration.rb.erb +9 -0
- metadata +27 -2
@@ -0,0 +1,62 @@
|
|
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
|
+
|
data/lib/cassandra_migrations.rb
CHANGED
@@ -10,7 +10,14 @@ module CassandraMigrations
|
|
10
10
|
|
11
11
|
hash.each do |k,v|
|
12
12
|
columns << k.to_s
|
13
|
-
|
13
|
+
|
14
|
+
if v.respond_to?(:strftime)
|
15
|
+
values << "'#{v.strftime('%Y-%m-%d %H:%M:%S%z')}'"
|
16
|
+
elsif v.is_a?(String)
|
17
|
+
values << "'#{v}'"
|
18
|
+
else
|
19
|
+
values << v.to_s
|
20
|
+
end
|
14
21
|
end
|
15
22
|
|
16
23
|
execute("INSERT INTO #{table} (#{columns.join(', ')}) VALUES (#{values.join(', ')})")
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'cassandra_migrations/migration/table_operations'
|
4
|
+
require 'cassandra_migrations/migration/column_operations'
|
5
|
+
|
6
|
+
module CassandraMigrations
|
7
|
+
|
8
|
+
# Base class for all cassandra migration
|
9
|
+
class Migration
|
10
|
+
|
11
|
+
include TableOperations
|
12
|
+
include ColumnOperations
|
13
|
+
|
14
|
+
# Makes +execute+ method directly available to migrations
|
15
|
+
delegate :execute, :to => Cassandra
|
16
|
+
|
17
|
+
# Makes +up+ work if the method in the migration is defined with self.up
|
18
|
+
def up
|
19
|
+
return unless self.class.respond_to?(:up)
|
20
|
+
self.class.instance_to_delegate = self
|
21
|
+
self.class.up
|
22
|
+
end
|
23
|
+
|
24
|
+
# Makes +down+ work if the method in the migration is defined with self.down
|
25
|
+
def down
|
26
|
+
return unless self.class.respond_to?(:down)
|
27
|
+
self.class.instance_to_delegate = self
|
28
|
+
self.class.down
|
29
|
+
end
|
30
|
+
|
31
|
+
# Class variable that holds an instance of Migration when the methods +up+ or
|
32
|
+
# +down+ are called on the class. The class then delegates missing method
|
33
|
+
# calls to this instance.
|
34
|
+
cattr_accessor :instance_to_delegate, :instance_accessor => false
|
35
|
+
|
36
|
+
# Delegate missing method calls to an instance. That's what enables the
|
37
|
+
# writing of migrations using both +def up+ and +def self.up+ sintax.
|
38
|
+
def self.method_missing(name, *args, &block)
|
39
|
+
if instance_to_delegate
|
40
|
+
instance_to_delegate.send(name, *args, &block)
|
41
|
+
else
|
42
|
+
super
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Execute this migration in the named direction.
|
47
|
+
#
|
48
|
+
# The advantage of using this instead of directly calling up or down is that
|
49
|
+
# this method gives informative output and benchmarks the time taken.
|
50
|
+
def migrate(direction)
|
51
|
+
return unless respond_to?(direction)
|
52
|
+
|
53
|
+
case direction
|
54
|
+
when :up then announce_migration "migrating"
|
55
|
+
when :down then announce_migration "reverting"
|
56
|
+
end
|
57
|
+
|
58
|
+
time = Benchmark.measure { send(direction) }
|
59
|
+
|
60
|
+
case direction
|
61
|
+
when :up then announce_migration "migrated (%.4fs)" % time.real; puts
|
62
|
+
when :down then announce_migration "reverted (%.4fs)" % time.real; puts
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
# Generates output labeled with name of migration and a line that goes up
|
69
|
+
# to 75 characters long in the terminal
|
70
|
+
def announce_migration(message)
|
71
|
+
text = "#{name}: #{message}"
|
72
|
+
length = [0, 75 - text.length].max
|
73
|
+
puts "== %s %s" % [text, "=" * length]
|
74
|
+
end
|
75
|
+
|
76
|
+
def announce_operation(message)
|
77
|
+
puts " " + message
|
78
|
+
end
|
79
|
+
|
80
|
+
def announce_suboperation(message)
|
81
|
+
puts " -> " + message
|
82
|
+
end
|
83
|
+
|
84
|
+
# Gets the name of the migration
|
85
|
+
def name
|
86
|
+
self.class.name
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'cassandra_migrations/migration/table_definition'
|
4
|
+
|
5
|
+
module CassandraMigrations
|
6
|
+
class Migration
|
7
|
+
|
8
|
+
# Module grouping methods used in migrations to make table operations like:
|
9
|
+
# - adding/removing columns
|
10
|
+
# - changing column types
|
11
|
+
# - renaming columns
|
12
|
+
module ColumnOperations
|
13
|
+
|
14
|
+
# Adds a column to a table.
|
15
|
+
#
|
16
|
+
# options: same options you would pass to create a table with that column
|
17
|
+
# (i.e. :limit might be applicable)
|
18
|
+
|
19
|
+
def add_column(table_name, column_name, type, options = {})
|
20
|
+
table_definition = TableDefinition.new
|
21
|
+
|
22
|
+
if !table_definition.respond_to?(type)
|
23
|
+
raise Errors::MigrationDefinitionError("Type '#{type}' is not valid for cassandra migration.")
|
24
|
+
end
|
25
|
+
|
26
|
+
table_definition.send(type, column_name, options)
|
27
|
+
|
28
|
+
announce_operation "add_column(#{column_name}, #{type})"
|
29
|
+
|
30
|
+
cql = "ALTER TABLE #{table_name} ADD "
|
31
|
+
cql << table_definition.to_add_column_cql
|
32
|
+
announce_suboperation cql
|
33
|
+
|
34
|
+
execute cql
|
35
|
+
end
|
36
|
+
|
37
|
+
# Removes a column from the table
|
38
|
+
def remove_column(table_name, column_name)
|
39
|
+
announce_operation "drop_table(#{table_name})"
|
40
|
+
|
41
|
+
cql = "ALTER TABLE #{table_name} DROP #{column_name}"
|
42
|
+
announce_suboperation cql
|
43
|
+
|
44
|
+
execute cql
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module CassandraMigrations
|
4
|
+
class Migration
|
5
|
+
|
6
|
+
# Used to define a table in a migration of table creation or to
|
7
|
+
# add columns to an existing table.
|
8
|
+
#
|
9
|
+
# An instance of this class is passed to the block of the method
|
10
|
+
# +create_table+, available on every migration.
|
11
|
+
#
|
12
|
+
# This class is also internally used in the method +add_column+.
|
13
|
+
|
14
|
+
class TableDefinition
|
15
|
+
|
16
|
+
def initialize()
|
17
|
+
@columns_name_type_hash = {}
|
18
|
+
@primary_keys = []
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_create_cql
|
22
|
+
cql = []
|
23
|
+
|
24
|
+
if !@columns_name_type_hash.empty?
|
25
|
+
@columns_name_type_hash.each do |column_name, type|
|
26
|
+
cql << "#{column_name} #{type}"
|
27
|
+
end
|
28
|
+
else
|
29
|
+
raise Errors::MigrationDefinitionError('No columns defined for table.')
|
30
|
+
end
|
31
|
+
|
32
|
+
if !@primary_keys.empty?
|
33
|
+
cql << "PRIMARY KEY(#{@primary_keys.join(', ')})"
|
34
|
+
else
|
35
|
+
raise Errors::MigrationDefinitionError('No primary key defined.')
|
36
|
+
end
|
37
|
+
|
38
|
+
cql.join(', ')
|
39
|
+
end
|
40
|
+
|
41
|
+
def to_add_column_cql
|
42
|
+
cql = ""
|
43
|
+
|
44
|
+
if @columns_name_type_hash.size == 1
|
45
|
+
cql = "#{@columns_name_type_hash.keys.first} #{@columns_name_type_hash.values.first}"
|
46
|
+
elsif @columns_name_type_hash.empty?
|
47
|
+
raise Errors::MigrationDefinitionError('No column to add.')
|
48
|
+
else
|
49
|
+
raise Errors::MigrationDefinitionError('Only one column ca be added at once.')
|
50
|
+
end
|
51
|
+
|
52
|
+
cql
|
53
|
+
end
|
54
|
+
|
55
|
+
def boolean(column_name, options={})
|
56
|
+
@columns_name_type_hash[column_name.to_sym] = :boolean
|
57
|
+
define_primary_keys(column_name) if options[:primary_key]
|
58
|
+
end
|
59
|
+
|
60
|
+
def integer(column_name, options={})
|
61
|
+
if options[:limit].nil? || options[:limit] == 4
|
62
|
+
@columns_name_type_hash[column_name.to_sym] = :int
|
63
|
+
elsif options[:limit] == 8
|
64
|
+
@columns_name_type_hash[column_name.to_sym] = :bigint
|
65
|
+
else
|
66
|
+
raise Errors::MigrationDefinitionError(':limit option should be 4 or 8 for integers.')
|
67
|
+
end
|
68
|
+
define_primary_keys(column_name) if options[:primary_key]
|
69
|
+
end
|
70
|
+
|
71
|
+
def float(column_name, options={})
|
72
|
+
if options[:limit].nil? || options[:limit] == 4
|
73
|
+
@columns_name_type_hash[column_name.to_sym] = :float
|
74
|
+
elsif options[:limit] == 8
|
75
|
+
@columns_name_type_hash[column_name.to_sym] = :double
|
76
|
+
else
|
77
|
+
raise Errors::MigrationDefinitionError(':limit option should be 4 or 8 for floats.')
|
78
|
+
end
|
79
|
+
define_primary_keys(column_name) if options[:primary_key]
|
80
|
+
end
|
81
|
+
|
82
|
+
def string(column_name, options={})
|
83
|
+
@columns_name_type_hash[column_name.to_sym] = :varchar
|
84
|
+
define_primary_keys(column_name) if options[:primary_key]
|
85
|
+
end
|
86
|
+
|
87
|
+
def text(column_name, options={})
|
88
|
+
@columns_name_type_hash[column_name.to_sym] = :text
|
89
|
+
define_primary_keys(column_name) if options[:primary_key]
|
90
|
+
end
|
91
|
+
|
92
|
+
def datetime(column_name, options={})
|
93
|
+
@columns_name_type_hash[column_name.to_sym] = :timestamp
|
94
|
+
define_primary_keys(column_name) if options[:primary_key]
|
95
|
+
end
|
96
|
+
|
97
|
+
def timestamp(column_name, options={})
|
98
|
+
@columns_name_type_hash[column_name.to_sym] = :timestamp
|
99
|
+
define_primary_keys(column_name) if options[:primary_key]
|
100
|
+
end
|
101
|
+
|
102
|
+
def define_primary_keys(*keys)
|
103
|
+
if !@primary_keys.empty?
|
104
|
+
raise Errors::MigrationDefinitionError('Primary key defined twice for the same table.')
|
105
|
+
end
|
106
|
+
|
107
|
+
@primary_keys = keys.flatten
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'cassandra_migrations/migration/table_definition'
|
4
|
+
|
5
|
+
module CassandraMigrations
|
6
|
+
class Migration
|
7
|
+
|
8
|
+
# Module grouping methods used in migrations to make table operations like:
|
9
|
+
# - creating tables
|
10
|
+
# - dropping tables
|
11
|
+
module TableOperations
|
12
|
+
|
13
|
+
# Creates a new table in the keyspace
|
14
|
+
#
|
15
|
+
# options:
|
16
|
+
# - :primary_keys: single value or array (for compound primary keys). If
|
17
|
+
# not defined, some column must be chosen as primary key in the table definition.
|
18
|
+
|
19
|
+
def create_table(table_name, options = {})
|
20
|
+
table_definition = TableDefinition.new
|
21
|
+
table_definition.define_primary_keys(options[:primary_keys]) if options[:primary_keys]
|
22
|
+
|
23
|
+
yield table_definition if block_given?
|
24
|
+
|
25
|
+
announce_operation "create_table(#{table_name})"
|
26
|
+
|
27
|
+
create_cql = "CREATE TABLE #{table_name} ("
|
28
|
+
create_cql << table_definition.to_create_cql
|
29
|
+
create_cql << ")"
|
30
|
+
|
31
|
+
announce_suboperation create_cql
|
32
|
+
|
33
|
+
execute create_cql
|
34
|
+
end
|
35
|
+
|
36
|
+
# Drops a table
|
37
|
+
def drop_table(table_name)
|
38
|
+
announce_operation "drop_table(#{table_name})"
|
39
|
+
drop_cql = "DROP TABLE #{table_name}"
|
40
|
+
announce_suboperation drop_cql
|
41
|
+
|
42
|
+
execute drop_cql
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -31,7 +31,7 @@ module CassandraMigrations
|
|
31
31
|
if !executed_migrations.empty?
|
32
32
|
count.times do |i|
|
33
33
|
if executed_migrations[i]
|
34
|
-
down(executed_migrations[i], executed_migrations[i])
|
34
|
+
down(executed_migrations[i], executed_migrations[i+1])
|
35
35
|
down_count += 1
|
36
36
|
end
|
37
37
|
end
|
@@ -56,7 +56,7 @@ private
|
|
56
56
|
# load migration
|
57
57
|
require migration_name
|
58
58
|
# run migration
|
59
|
-
get_class_from_migration_name(migration_name).up
|
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})
|
@@ -66,8 +66,8 @@ private
|
|
66
66
|
# load migration
|
67
67
|
require migration_name
|
68
68
|
# run migration
|
69
|
-
get_class_from_migration_name(migration_name).down
|
70
|
-
|
69
|
+
get_class_from_migration_name(migration_name).new.migrate(:down)
|
70
|
+
|
71
71
|
# downgrade version
|
72
72
|
if previous_migration_name
|
73
73
|
Cassandra.write!(METADATA_TABLE, {:data_name => 'version', :data_value => get_version_from_migration_name(previous_migration_name).to_s})
|
@@ -0,0 +1,23 @@
|
|
1
|
+
Description:
|
2
|
+
Stubs out a new cassandra migration.
|
3
|
+
|
4
|
+
Pass the migration name, either CamelCased or under_scored. A migration
|
5
|
+
class is generated in db/cassandra_migrate, prefixed by a timestamp of the
|
6
|
+
current date and time
|
7
|
+
|
8
|
+
Example:
|
9
|
+
rails generate migration create_tweets
|
10
|
+
|
11
|
+
This will create:
|
12
|
+
db/cassandra_migrate/20080514090912_create_tweets.rb
|
13
|
+
|
14
|
+
Inside this file we'll have a migration ready for completion:
|
15
|
+
class CreateTweets << CassandraMigrations::Migration
|
16
|
+
def up
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
def down
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class CassandraMigrationGenerator < Rails::Generators::Base
|
2
|
+
source_root File.expand_path('templates', File.dirname(__FILE__))
|
3
|
+
|
4
|
+
argument :migration_name, :type => :string
|
5
|
+
|
6
|
+
# Interpolates template and creates migration in the application
|
7
|
+
#
|
8
|
+
# Any public method in the generator is run automatically when
|
9
|
+
# the generator is run. To understand fully see
|
10
|
+
# http://asciicasts.com/episodes/218-making-generators-in-rails-3
|
11
|
+
|
12
|
+
def generate_migration
|
13
|
+
file_name = "#{Time.current.utc.strftime('%Y%m%d%H%M%S')}_#{migration_name.underscore}"
|
14
|
+
@migration_class_name = migration_name.camelize
|
15
|
+
|
16
|
+
template "empty_migration.rb.erb", "db/cassandra_migrate/#{file_name}.rb"
|
17
|
+
end
|
18
|
+
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.0.1.
|
4
|
+
version: 0.0.1.pre5
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -59,6 +59,22 @@ dependencies:
|
|
59
59
|
- - ~>
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '3.2'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: colorize
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0.5'
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0.5'
|
62
78
|
- !ruby/object:Gem::Dependency
|
63
79
|
name: rspec
|
64
80
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,22 +110,31 @@ dependencies:
|
|
94
110
|
description: A gem to manage Cassandra database schema for Rails. This gem offers
|
95
111
|
migrations and environment specific databases out-of-the-box for Rails users.
|
96
112
|
email: guberthenrique@hotmail.com
|
97
|
-
executables:
|
113
|
+
executables:
|
114
|
+
- prepare_for_cassandra
|
98
115
|
extensions: []
|
99
116
|
extra_rdoc_files: []
|
100
117
|
files:
|
101
118
|
- lib/cassandra_migrations.rb
|
119
|
+
- lib/cassandra_migrations/migration.rb
|
102
120
|
- lib/cassandra_migrations/migrator.rb
|
103
121
|
- lib/cassandra_migrations/cassandra.rb
|
104
122
|
- lib/cassandra_migrations/railtie.rb
|
105
123
|
- lib/cassandra_migrations/cassandra/keyspace_operations.rb
|
106
124
|
- lib/cassandra_migrations/cassandra/queries.rb
|
107
125
|
- lib/cassandra_migrations/config.rb
|
126
|
+
- lib/cassandra_migrations/migration/table_operations.rb
|
127
|
+
- lib/cassandra_migrations/migration/column_operations.rb
|
128
|
+
- lib/cassandra_migrations/migration/table_definition.rb
|
108
129
|
- lib/cassandra_migrations/railtie/initializer.rb
|
130
|
+
- lib/cassandra_migrations/railtie/generators/cassandra_migration/cassandra_migration_generator.rb
|
131
|
+
- lib/cassandra_migrations/railtie/generators/cassandra_migration/templates/empty_migration.rb.erb
|
132
|
+
- lib/cassandra_migrations/railtie/generators/cassandra_migration/USAGE
|
109
133
|
- lib/cassandra_migrations/railtie/tasks.rake
|
110
134
|
- lib/cassandra_migrations/errors.rb
|
111
135
|
- spec/cassandra_migrations_spec.rb
|
112
136
|
- spec/cassandra_migrations/cassandra_spec.rb
|
137
|
+
- bin/prepare_for_cassandra
|
113
138
|
homepage: https://github.com/hsgubert/cassandra_migrations
|
114
139
|
licenses:
|
115
140
|
- MIT
|