rom-cassandra 0.0.1
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 +7 -0
- data/.coveralls.yml +2 -0
- data/.gitignore +9 -0
- data/.metrics +9 -0
- data/.rspec +2 -0
- data/.rubocop.yml +2 -0
- data/.travis.yml +26 -0
- data/.yardopts +3 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +7 -0
- data/Guardfile +14 -0
- data/LICENSE +21 -0
- data/README.md +83 -0
- data/Rakefile +34 -0
- data/config/metrics/STYLEGUIDE +230 -0
- data/config/metrics/cane.yml +5 -0
- data/config/metrics/churn.yml +6 -0
- data/config/metrics/flay.yml +2 -0
- data/config/metrics/metric_fu.yml +14 -0
- data/config/metrics/reek.yml +1 -0
- data/config/metrics/roodi.yml +24 -0
- data/config/metrics/rubocop.yml +84 -0
- data/config/metrics/saikuro.yml +3 -0
- data/config/metrics/simplecov.yml +6 -0
- data/config/metrics/yardstick.yml +37 -0
- data/lib/rom-cassandra.rb +3 -0
- data/lib/rom/cassandra.rb +33 -0
- data/lib/rom/cassandra/commands.rb +53 -0
- data/lib/rom/cassandra/commands/batch.rb +54 -0
- data/lib/rom/cassandra/commands/create.rb +38 -0
- data/lib/rom/cassandra/commands/delete.rb +38 -0
- data/lib/rom/cassandra/commands/update.rb +38 -0
- data/lib/rom/cassandra/dataset.rb +102 -0
- data/lib/rom/cassandra/gateway.rb +115 -0
- data/lib/rom/cassandra/migrations.rb +30 -0
- data/lib/rom/cassandra/migrations/generator.rb +68 -0
- data/lib/rom/cassandra/migrations/generator/migration.erb +32 -0
- data/lib/rom/cassandra/migrations/logger.rb +28 -0
- data/lib/rom/cassandra/migrations/migration.rb +107 -0
- data/lib/rom/cassandra/migrations/migrator.rb +103 -0
- data/lib/rom/cassandra/migrations/runner.rb +119 -0
- data/lib/rom/cassandra/migrations/runner_down.rb +49 -0
- data/lib/rom/cassandra/migrations/runner_up.rb +50 -0
- data/lib/rom/cassandra/query.rb +43 -0
- data/lib/rom/cassandra/relation.rb +88 -0
- data/lib/rom/cassandra/session.rb +50 -0
- data/lib/rom/cassandra/tasks.rb +6 -0
- data/lib/rom/cassandra/version.rb +15 -0
- data/lib/tasks/db.rake +16 -0
- data/rom-cassandra.gemspec +33 -0
- data/spec/config/reset_cluster.rb +28 -0
- data/spec/config/rom.rb +3 -0
- data/spec/config/test_module.rb +7 -0
- data/spec/integration/batch_spec.rb +36 -0
- data/spec/integration/create_spec.rb +33 -0
- data/spec/integration/delete_spec.rb +33 -0
- data/spec/integration/migrate/20150825142003_create_users.rb +24 -0
- data/spec/integration/migrate/20150825142024_create_logs.rb +17 -0
- data/spec/integration/migrate_spec.rb +47 -0
- data/spec/integration/relation_spec.rb +27 -0
- data/spec/integration/update_spec.rb +33 -0
- data/spec/shared/fake_migrate_folder.rb +21 -0
- data/spec/shared/users.rb +20 -0
- data/spec/spec_helper.rb +17 -0
- data/spec/unit/commands/batch_spec.rb +86 -0
- data/spec/unit/commands/create_spec.rb +77 -0
- data/spec/unit/commands/delete_spec.rb +77 -0
- data/spec/unit/commands/update_spec.rb +77 -0
- data/spec/unit/dataset_spec.rb +130 -0
- data/spec/unit/gateway_spec.rb +140 -0
- data/spec/unit/migrations/generator_spec.rb +31 -0
- data/spec/unit/migrations/logger_spec.rb +21 -0
- data/spec/unit/migrations/migration_spec.rb +59 -0
- data/spec/unit/migrations/migrator_spec.rb +120 -0
- data/spec/unit/migrations/runner_down_spec.rb +65 -0
- data/spec/unit/migrations/runner_spec.rb +142 -0
- data/spec/unit/migrations/runner_up_spec.rb +67 -0
- data/spec/unit/query_spec.rb +21 -0
- data/spec/unit/relation_spec.rb +142 -0
- data/spec/unit/session_spec.rb +55 -0
- data/spec/unit/tasks/create_migration_spec.rb +41 -0
- metadata +242 -0
@@ -0,0 +1,103 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module ROM::Cassandra
|
4
|
+
|
5
|
+
module Migrations
|
6
|
+
|
7
|
+
# Class Migrator finds the migration files and migrates Cassandra cluster
|
8
|
+
# to the required version using method [#apply].
|
9
|
+
#
|
10
|
+
# The class is responcible for searching files and deciding,
|
11
|
+
# which of them should be runned up and down. Every single migration
|
12
|
+
# is applied or rolled back using `RunnerUp` and `RunnerDown` classes.
|
13
|
+
#
|
14
|
+
# @example
|
15
|
+
# migrator = Migrator.new(hosts: ["127.0.0.1"], port: 9042)
|
16
|
+
#
|
17
|
+
# # Applies all migrations
|
18
|
+
# migrator.apply
|
19
|
+
#
|
20
|
+
# # Rolls back all migrations
|
21
|
+
# migrator.apply version: 0
|
22
|
+
#
|
23
|
+
# # Moves to the required version (before the year 2016)
|
24
|
+
# migrator.apply version: 20151231235959
|
25
|
+
#
|
26
|
+
class Migrator
|
27
|
+
|
28
|
+
# @!attribute [r] session
|
29
|
+
#
|
30
|
+
# @return [ROM::Cassandra::Session] The session to the Cassandra cluster
|
31
|
+
#
|
32
|
+
attr_reader :session
|
33
|
+
|
34
|
+
# @!attribute [r] logger
|
35
|
+
#
|
36
|
+
# @return [::Logger] The logger used by the migrator
|
37
|
+
#
|
38
|
+
attr_reader :logger
|
39
|
+
|
40
|
+
# @!attribute [r] root
|
41
|
+
#
|
42
|
+
# @return [Array<String>] The root path for migrations
|
43
|
+
#
|
44
|
+
attr_reader :root
|
45
|
+
|
46
|
+
# @!attribute [r] paths
|
47
|
+
#
|
48
|
+
# @return [Array<String>] The list of paths to migration files
|
49
|
+
#
|
50
|
+
attr_reader :paths
|
51
|
+
|
52
|
+
# Initializes a migrator with Cassandra uri settings.
|
53
|
+
#
|
54
|
+
# Can specify logger and path as well.
|
55
|
+
#
|
56
|
+
# @param [ROM::Cassandra::Session] session
|
57
|
+
# @option options [::Logger] :logger
|
58
|
+
# @option options [String] :path
|
59
|
+
#
|
60
|
+
# See [ROM::Cassandra::Session] for other avaliable options for URI
|
61
|
+
#
|
62
|
+
def initialize(session, options = {})
|
63
|
+
@session = session
|
64
|
+
@logger = options.fetch(:logger) { Logger.new }
|
65
|
+
@root = options.fetch(:path) { DEFAULT_PATH }
|
66
|
+
@paths = Dir[File.join(root, "*.rb")].sort
|
67
|
+
end
|
68
|
+
|
69
|
+
# Migrates the Cassandra cluster to selected version
|
70
|
+
#
|
71
|
+
# Applies all migrations if a version is skipped.
|
72
|
+
# Rolls all migrations back if a version is set to 0.
|
73
|
+
#
|
74
|
+
# @option options [Integer, nil] :version
|
75
|
+
#
|
76
|
+
# @return [undefined]
|
77
|
+
#
|
78
|
+
def apply(options = {})
|
79
|
+
version = options.fetch(:version) { ALL_VERSIONS }
|
80
|
+
|
81
|
+
migrate_to version
|
82
|
+
rollback_to version
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def migrate_to(version)
|
88
|
+
paths
|
89
|
+
.reject { |path| GET_VERSION[path] > version }
|
90
|
+
.each { |path| RunnerUp.apply(session, logger, path) }
|
91
|
+
end
|
92
|
+
|
93
|
+
def rollback_to(version)
|
94
|
+
paths
|
95
|
+
.select { |path| GET_VERSION[path] > version }
|
96
|
+
.reverse_each { |path| RunnerDown.apply(session, logger, path) }
|
97
|
+
end
|
98
|
+
|
99
|
+
end # class Migrator
|
100
|
+
|
101
|
+
end # module Migrations
|
102
|
+
|
103
|
+
end # module ROM::Cassandra
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "inflecto"
|
4
|
+
|
5
|
+
module ROM::Cassandra
|
6
|
+
|
7
|
+
module Migrations
|
8
|
+
|
9
|
+
# Base class that loads and runs the migration, registers it in
|
10
|
+
# the Cassandra 'rom.migrations' table, and logs the result.
|
11
|
+
#
|
12
|
+
# As a base class uses the Command pattern to define a sequence of
|
13
|
+
# actions, that should be implemented by the subclasses:
|
14
|
+
# `RunnerUp`, and `RunnderDown`.
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
#
|
18
|
+
class Runner
|
19
|
+
|
20
|
+
# @!attribute [r] session
|
21
|
+
#
|
22
|
+
# @return [ROM::Cassandra::Session]
|
23
|
+
# The session for sending requests to Cassandra
|
24
|
+
#
|
25
|
+
attr_reader :session
|
26
|
+
|
27
|
+
# @!attribute [r] logger
|
28
|
+
#
|
29
|
+
# @return [::Logger] The logger to report results
|
30
|
+
#
|
31
|
+
attr_reader :logger
|
32
|
+
|
33
|
+
# @!attribute [r] version
|
34
|
+
#
|
35
|
+
# @return [Integer] The number of migration
|
36
|
+
#
|
37
|
+
attr_reader :version
|
38
|
+
|
39
|
+
# @!attribute [r] path
|
40
|
+
#
|
41
|
+
# @return [String] The path to the migration file
|
42
|
+
#
|
43
|
+
attr_reader :path
|
44
|
+
|
45
|
+
# @!attribute [r] migration
|
46
|
+
#
|
47
|
+
# @return [ROM::Cassandra::Migrations::Migration]
|
48
|
+
# The migration class
|
49
|
+
#
|
50
|
+
attr_reader :migration
|
51
|
+
|
52
|
+
# Applies the runner to session, logger and migration path
|
53
|
+
#
|
54
|
+
# @param (see #initialize)
|
55
|
+
#
|
56
|
+
# @return (see #call)
|
57
|
+
#
|
58
|
+
def self.apply(session, logger, path)
|
59
|
+
new(session, logger, path).call
|
60
|
+
end
|
61
|
+
|
62
|
+
# Initializes the runner for the session, logger and migration path
|
63
|
+
#
|
64
|
+
# @param [ROM::Cassandra::Session] session
|
65
|
+
# @param [Logger] logger
|
66
|
+
# @param [String] path
|
67
|
+
#
|
68
|
+
def initialize(session, logger, path)
|
69
|
+
@session = session
|
70
|
+
@logger = logger
|
71
|
+
@path = path
|
72
|
+
@version = extract_version
|
73
|
+
@migration = extract_migration if migrate? # defined in a subclass
|
74
|
+
end
|
75
|
+
|
76
|
+
# Runs the sequence of commands to provide migration
|
77
|
+
#
|
78
|
+
# @return [undefined]
|
79
|
+
#
|
80
|
+
def call
|
81
|
+
return unless migration
|
82
|
+
apply # defined in a subclass
|
83
|
+
register # defined in a subclass
|
84
|
+
log # defined in a subclass
|
85
|
+
end
|
86
|
+
|
87
|
+
# Prepares the table and selects version
|
88
|
+
#
|
89
|
+
# @return [Array<Hash>] list of rows with the selected version
|
90
|
+
#
|
91
|
+
def select_version
|
92
|
+
session.call "CREATE KEYSPACE IF NOT EXISTS rom WITH" \
|
93
|
+
" REPLICATION = {'class': 'SimpleStrategy', 'replication_factor': 3};"
|
94
|
+
session.call "CREATE TABLE IF NOT EXISTS rom.migrations" \
|
95
|
+
" (version text, PRIMARY KEY (version));"
|
96
|
+
session.call "SELECT * FROM rom.migrations WHERE" \
|
97
|
+
" version = '#{version}';"
|
98
|
+
end
|
99
|
+
|
100
|
+
private
|
101
|
+
|
102
|
+
def extract_version
|
103
|
+
version = GET_VERSION[path]
|
104
|
+
return version unless version.equal? 0
|
105
|
+
fail NameError.new "invalid version number: '#{path}'"
|
106
|
+
end
|
107
|
+
|
108
|
+
def extract_migration
|
109
|
+
require path
|
110
|
+
basename = File.basename(path, ".rb")
|
111
|
+
class_name = Inflecto.camelize basename[/_.+/][1..-1]
|
112
|
+
Inflecto.constantize(class_name).new(session)
|
113
|
+
end
|
114
|
+
|
115
|
+
end # class Runner
|
116
|
+
|
117
|
+
end # module Migrations
|
118
|
+
|
119
|
+
end # module ROM::Cassandra
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module ROM::Cassandra
|
4
|
+
|
5
|
+
module Migrations
|
6
|
+
|
7
|
+
# Runs migration up, registers it in Cassandra table and logs the change.
|
8
|
+
#
|
9
|
+
# @api private
|
10
|
+
#
|
11
|
+
class RunnerDown < Runner
|
12
|
+
|
13
|
+
# Checks if the version hasn't been registered yet
|
14
|
+
#
|
15
|
+
# @return [Boolean]
|
16
|
+
#
|
17
|
+
def migrate?
|
18
|
+
select_version.any?
|
19
|
+
end
|
20
|
+
|
21
|
+
# Rolls back the migration
|
22
|
+
#
|
23
|
+
# @return [undefined]
|
24
|
+
#
|
25
|
+
def apply
|
26
|
+
migration.down
|
27
|
+
end
|
28
|
+
|
29
|
+
# Removes the version from Cassandra db
|
30
|
+
#
|
31
|
+
# @return [Array] an empty array
|
32
|
+
#
|
33
|
+
def register
|
34
|
+
session.call "DELETE FROM rom.migrations WHERE version = '#{version}';"
|
35
|
+
end
|
36
|
+
|
37
|
+
# Logs the result of the operation
|
38
|
+
#
|
39
|
+
# @return [undefined]
|
40
|
+
#
|
41
|
+
def log
|
42
|
+
logger.info "Roll back migration #{version}\n"
|
43
|
+
end
|
44
|
+
|
45
|
+
end # class RunnerDown
|
46
|
+
|
47
|
+
end # module Migrations
|
48
|
+
|
49
|
+
end # module ROM::Cassandra
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module ROM::Cassandra
|
4
|
+
|
5
|
+
module Migrations
|
6
|
+
|
7
|
+
# Runs migration up, registers it in Cassandra table and logs the change.
|
8
|
+
#
|
9
|
+
# @api private
|
10
|
+
#
|
11
|
+
class RunnerUp < Runner
|
12
|
+
|
13
|
+
# Checks if the version has been registered yet
|
14
|
+
#
|
15
|
+
# @return [Boolean]
|
16
|
+
#
|
17
|
+
def migrate?
|
18
|
+
select_version.empty?
|
19
|
+
end
|
20
|
+
|
21
|
+
# Moves the migration forward
|
22
|
+
#
|
23
|
+
# @return [undefined]
|
24
|
+
#
|
25
|
+
def apply
|
26
|
+
migration.up
|
27
|
+
end
|
28
|
+
|
29
|
+
# Registers the version in Cassandra db
|
30
|
+
#
|
31
|
+
# @return [Array] an empty array
|
32
|
+
#
|
33
|
+
def register
|
34
|
+
session.call "INSERT INTO rom.migrations (version)" \
|
35
|
+
" VALUES ('#{version}');"
|
36
|
+
end
|
37
|
+
|
38
|
+
# Logs the result of the operation
|
39
|
+
#
|
40
|
+
# @return [undefined]
|
41
|
+
#
|
42
|
+
def log
|
43
|
+
logger.info "Apply migration #{version}\n"
|
44
|
+
end
|
45
|
+
|
46
|
+
end # class RunnerUp
|
47
|
+
|
48
|
+
end # module Migrations
|
49
|
+
|
50
|
+
end # module ROM::Cassandra
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "query_builder"
|
4
|
+
|
5
|
+
module ROM::Cassandra
|
6
|
+
|
7
|
+
# Wraps the external CQL query builder
|
8
|
+
#
|
9
|
+
class Query
|
10
|
+
|
11
|
+
# Default CQL statements builder
|
12
|
+
DEFAULT_BUILDER = QueryBuilder::CQL
|
13
|
+
|
14
|
+
# Initializes the object carrying the lazy query
|
15
|
+
#
|
16
|
+
# @param [ROM::Cassandra::Query] query
|
17
|
+
#
|
18
|
+
def initialize(query = nil)
|
19
|
+
@query = query || DEFAULT_BUILDER
|
20
|
+
end
|
21
|
+
|
22
|
+
# Builds the Query statement from the wrapped query
|
23
|
+
#
|
24
|
+
# @return [String]
|
25
|
+
#
|
26
|
+
def to_s
|
27
|
+
@query.to_s
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def respond_to_missing?(name, *)
|
33
|
+
@query.respond_to? name
|
34
|
+
end
|
35
|
+
|
36
|
+
def method_missing(name, *args)
|
37
|
+
updated_query = @query.public_send(name, *args)
|
38
|
+
self.class.new(updated_query)
|
39
|
+
end
|
40
|
+
|
41
|
+
end # class Query
|
42
|
+
|
43
|
+
end # module ROM::Cassandra
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module ROM::Cassandra
|
4
|
+
|
5
|
+
# Relation subclass of Cassandra adapter
|
6
|
+
#
|
7
|
+
# @example
|
8
|
+
# class Users < ROM::Relation[:cassandra]
|
9
|
+
# def last_ten_admins
|
10
|
+
# select(:id, :name)
|
11
|
+
# .where(role: "admin")
|
12
|
+
# .using(consistency: :quorum)
|
13
|
+
# .order(:name, :desc)
|
14
|
+
# .limit(10)
|
15
|
+
# end
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# @api public
|
19
|
+
#
|
20
|
+
class Relation < ROM::Relation
|
21
|
+
|
22
|
+
adapter :cassandra
|
23
|
+
option :source
|
24
|
+
|
25
|
+
# @!attribute [r] source
|
26
|
+
#
|
27
|
+
# @return [ROM::Cassandra::Dataset]
|
28
|
+
# The source dataset before `get` method has been applied
|
29
|
+
#
|
30
|
+
attr_reader :source
|
31
|
+
|
32
|
+
# @private
|
33
|
+
def initialize(*)
|
34
|
+
super
|
35
|
+
return if (@source = options[:source])
|
36
|
+
@source = dataset
|
37
|
+
@dataset = dataset.get
|
38
|
+
end
|
39
|
+
|
40
|
+
# Returns the relation whose source is restricted by `#insert` lazy query
|
41
|
+
#
|
42
|
+
# @return [ROM::Cassandra::Relation]
|
43
|
+
#
|
44
|
+
def insert_query
|
45
|
+
reload source.insert
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns the relation whose source is restricted by `#update` lazy query
|
49
|
+
#
|
50
|
+
# @return [ROM::Cassandra::Relation]
|
51
|
+
#
|
52
|
+
def update_query
|
53
|
+
reload source.update
|
54
|
+
end
|
55
|
+
|
56
|
+
# Returns the relation whose source is restricted by `#delete` lazy query
|
57
|
+
#
|
58
|
+
# @return [ROM::Cassandra::Relation]
|
59
|
+
#
|
60
|
+
def delete_query
|
61
|
+
reload source.delete
|
62
|
+
end
|
63
|
+
|
64
|
+
# Returns the relation whose source is restricted by `#delete` lazy query
|
65
|
+
#
|
66
|
+
# @return [ROM::Cassandra::Relation]
|
67
|
+
#
|
68
|
+
def batch_query
|
69
|
+
reload source.batch
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def respond_to_missing?(name, *)
|
75
|
+
dataset.respond_to? name
|
76
|
+
end
|
77
|
+
|
78
|
+
def method_missing(name, *args)
|
79
|
+
reload dataset.public_send(name, *args)
|
80
|
+
end
|
81
|
+
|
82
|
+
def reload(dataset)
|
83
|
+
Relation.new dataset, source: source
|
84
|
+
end
|
85
|
+
|
86
|
+
end # class Relation
|
87
|
+
|
88
|
+
end # module ROM::Cassandra
|