couch-migrate 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.rspec +1 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +39 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +19 -0
- data/Rakefile +46 -0
- data/VERSION +1 -0
- data/couch-migrate.gemspec +84 -0
- data/db/migrate/1_test.rb +3 -0
- data/lib/couch-migrate.rb +2 -0
- data/lib/couch_migrate/base_executer.rb +35 -0
- data/lib/couch_migrate/base_migrater.rb +96 -0
- data/lib/couch_migrate/base_persisted_list.rb +52 -0
- data/lib/couch_migrate/couch_executer.rb +10 -0
- data/lib/couch_migrate/couch_migrater.rb +15 -0
- data/lib/couch_migrate/couch_persisted_list.rb +36 -0
- data/lib/couch_migrate/couchrest_model/extend.rb +16 -0
- data/lib/couch_migrate/file_migrater.rb +14 -0
- data/lib/couch_migrate/file_persisted_list.rb +35 -0
- data/lib/couch_migrate_railtie.rb +8 -0
- data/lib/tasks/couch_migrate.rake +40 -0
- data/spec/couch_migrate/base_executer_spec.rb +93 -0
- data/spec/couch_migrate/base_migrater_spec.rb +91 -0
- data/spec/couch_migrate/base_persisted_list_spec.rb +44 -0
- data/spec/couch_migrate/couch_migrater_spec.rb +84 -0
- data/spec/couch_migrate/couch_persisted_list_spec.rb +40 -0
- data/spec/couch_migrate/file_migrater_spec.rb +87 -0
- data/spec/couch_migrate/file_persisted_list_spec.rb +42 -0
- data/spec/spec_helper.rb +11 -0
- metadata +148 -0
data/.document
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
couchrest (1.1.2)
|
5
|
+
mime-types (~> 1.15)
|
6
|
+
multi_json (~> 1.0.0)
|
7
|
+
rest-client (~> 1.6.1)
|
8
|
+
diff-lcs (1.1.3)
|
9
|
+
git (1.2.5)
|
10
|
+
jeweler (1.6.4)
|
11
|
+
bundler (~> 1.0)
|
12
|
+
git (>= 1.2.5)
|
13
|
+
rake
|
14
|
+
mime-types (1.16)
|
15
|
+
multi_json (1.0.3)
|
16
|
+
rake (0.9.2)
|
17
|
+
rcov (0.9.10)
|
18
|
+
rest-client (1.6.7)
|
19
|
+
mime-types (>= 1.16)
|
20
|
+
rspec (2.3.0)
|
21
|
+
rspec-core (~> 2.3.0)
|
22
|
+
rspec-expectations (~> 2.3.0)
|
23
|
+
rspec-mocks (~> 2.3.0)
|
24
|
+
rspec-core (2.3.1)
|
25
|
+
rspec-expectations (2.3.0)
|
26
|
+
diff-lcs (~> 1.1.2)
|
27
|
+
rspec-mocks (2.3.0)
|
28
|
+
yard (0.6.8)
|
29
|
+
|
30
|
+
PLATFORMS
|
31
|
+
ruby
|
32
|
+
|
33
|
+
DEPENDENCIES
|
34
|
+
bundler (~> 1.0.0)
|
35
|
+
couchrest
|
36
|
+
jeweler (~> 1.6.4)
|
37
|
+
rcov
|
38
|
+
rspec (~> 2.3.0)
|
39
|
+
yard (~> 0.6.0)
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Greg Edwards
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
= couch-migrate
|
2
|
+
|
3
|
+
Description goes here.
|
4
|
+
|
5
|
+
== Contributing to couch-migrate
|
6
|
+
|
7
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
8
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
9
|
+
* Fork the project
|
10
|
+
* Start a feature/bugfix branch
|
11
|
+
* Commit and push until you are happy with your contribution
|
12
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
13
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
14
|
+
|
15
|
+
== Copyright
|
16
|
+
|
17
|
+
Copyright (c) 2011 Greg Edwards. See LICENSE.txt for
|
18
|
+
further details.
|
19
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
import 'lib/tasks/couch_migrate.rake'
|
14
|
+
|
15
|
+
task 'environment' do
|
16
|
+
end
|
17
|
+
|
18
|
+
require 'jeweler'
|
19
|
+
Jeweler::Tasks.new do |gem|
|
20
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
21
|
+
gem.name = "couch-migrate"
|
22
|
+
gem.homepage = "https://github.com/gedwards/couch-migrate"
|
23
|
+
gem.license = "MIT"
|
24
|
+
gem.summary = %Q{A simple migration system for CouchDB}
|
25
|
+
gem.description = %Q{A simple migration system for CouchDB.}
|
26
|
+
gem.email = "greg@greglearns.com"
|
27
|
+
gem.authors = ["Greg Edwards"]
|
28
|
+
# dependencies defined in Gemfile
|
29
|
+
end
|
30
|
+
Jeweler::RubygemsDotOrgTasks.new
|
31
|
+
|
32
|
+
require 'rspec/core'
|
33
|
+
require 'rspec/core/rake_task'
|
34
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
35
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
36
|
+
end
|
37
|
+
|
38
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
39
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
40
|
+
spec.rcov = true
|
41
|
+
end
|
42
|
+
|
43
|
+
task :default => :spec
|
44
|
+
|
45
|
+
require 'yard'
|
46
|
+
YARD::Rake::YardocTask.new
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.0.0
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{couch-migrate}
|
8
|
+
s.version = "1.0.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Greg Edwards"]
|
12
|
+
s.date = %q{2011-09-20}
|
13
|
+
s.description = %q{A simple migration system for CouchDB.}
|
14
|
+
s.email = %q{greg@greglearns.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".rspec",
|
22
|
+
"Gemfile",
|
23
|
+
"Gemfile.lock",
|
24
|
+
"LICENSE.txt",
|
25
|
+
"README.rdoc",
|
26
|
+
"Rakefile",
|
27
|
+
"VERSION",
|
28
|
+
"couch-migrate.gemspec",
|
29
|
+
"db/migrate/1_test.rb",
|
30
|
+
"lib/couch-migrate.rb",
|
31
|
+
"lib/couch_migrate/base_executer.rb",
|
32
|
+
"lib/couch_migrate/base_migrater.rb",
|
33
|
+
"lib/couch_migrate/base_persisted_list.rb",
|
34
|
+
"lib/couch_migrate/couch_executer.rb",
|
35
|
+
"lib/couch_migrate/couch_migrater.rb",
|
36
|
+
"lib/couch_migrate/couch_persisted_list.rb",
|
37
|
+
"lib/couch_migrate/couchrest_model/extend.rb",
|
38
|
+
"lib/couch_migrate/file_migrater.rb",
|
39
|
+
"lib/couch_migrate/file_persisted_list.rb",
|
40
|
+
"lib/couch_migrate_railtie.rb",
|
41
|
+
"lib/tasks/couch_migrate.rake",
|
42
|
+
"spec/couch_migrate/base_executer_spec.rb",
|
43
|
+
"spec/couch_migrate/base_migrater_spec.rb",
|
44
|
+
"spec/couch_migrate/base_persisted_list_spec.rb",
|
45
|
+
"spec/couch_migrate/couch_migrater_spec.rb",
|
46
|
+
"spec/couch_migrate/couch_persisted_list_spec.rb",
|
47
|
+
"spec/couch_migrate/file_migrater_spec.rb",
|
48
|
+
"spec/couch_migrate/file_persisted_list_spec.rb",
|
49
|
+
"spec/spec_helper.rb"
|
50
|
+
]
|
51
|
+
s.homepage = %q{https://github.com/gedwards/couch-migrate}
|
52
|
+
s.licenses = ["MIT"]
|
53
|
+
s.require_paths = ["lib"]
|
54
|
+
s.rubygems_version = %q{1.6.2}
|
55
|
+
s.summary = %q{A simple migration system for CouchDB}
|
56
|
+
|
57
|
+
if s.respond_to? :specification_version then
|
58
|
+
s.specification_version = 3
|
59
|
+
|
60
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
61
|
+
s.add_runtime_dependency(%q<couchrest>, [">= 0"])
|
62
|
+
s.add_development_dependency(%q<rspec>, ["~> 2.3.0"])
|
63
|
+
s.add_development_dependency(%q<yard>, ["~> 0.6.0"])
|
64
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
65
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
|
66
|
+
s.add_development_dependency(%q<rcov>, [">= 0"])
|
67
|
+
else
|
68
|
+
s.add_dependency(%q<couchrest>, [">= 0"])
|
69
|
+
s.add_dependency(%q<rspec>, ["~> 2.3.0"])
|
70
|
+
s.add_dependency(%q<yard>, ["~> 0.6.0"])
|
71
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
72
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
73
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
74
|
+
end
|
75
|
+
else
|
76
|
+
s.add_dependency(%q<couchrest>, [">= 0"])
|
77
|
+
s.add_dependency(%q<rspec>, ["~> 2.3.0"])
|
78
|
+
s.add_dependency(%q<yard>, ["~> 0.6.0"])
|
79
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
80
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
81
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module CouchMigrate
|
2
|
+
class BaseExecuter
|
3
|
+
def initialize(enabled, str, filename = "")
|
4
|
+
raise "'enabled' argument must be an Array of symbols (such as [:up, :down] or []" unless enabled.is_a?(Array)
|
5
|
+
@migration_str = str
|
6
|
+
@enabled = enabled
|
7
|
+
@filename = filename
|
8
|
+
self
|
9
|
+
end
|
10
|
+
|
11
|
+
def go
|
12
|
+
Namespaced.module_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
13
|
+
def self.up
|
14
|
+
yield if #{@enabled.include?(:up)}
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.down
|
18
|
+
yield if #{@enabled.include?(:down)}
|
19
|
+
end
|
20
|
+
|
21
|
+
# convenience method for migration files to use
|
22
|
+
def self.use_couchrest_model
|
23
|
+
require 'couch_migrate/couchrest_model/extend.rb'
|
24
|
+
end
|
25
|
+
|
26
|
+
EOS
|
27
|
+
|
28
|
+
Namespaced.module_eval(@migration_str, @filename)
|
29
|
+
end
|
30
|
+
|
31
|
+
module Namespaced
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module CouchMigrate
|
2
|
+
class BaseMigrater
|
3
|
+
attr_reader :failed_migration
|
4
|
+
|
5
|
+
def initialize(persisted_list = nil, executer = nil, migration_directory = "db/migrations")
|
6
|
+
@raw_migrations = []
|
7
|
+
@completed_migrations = persisted_list || BasePersistedList.new
|
8
|
+
@executer = executer || BaseExecuter
|
9
|
+
directory(migration_directory)
|
10
|
+
self
|
11
|
+
end
|
12
|
+
|
13
|
+
def migrate(*args)
|
14
|
+
migration_reserved_args= [:quiet]
|
15
|
+
executer_args = args - migration_reserved_args
|
16
|
+
|
17
|
+
@failed_migration, completed = nil, []
|
18
|
+
direction, action, migrations = if args.include?(:down)
|
19
|
+
[:down, :remove, [completed_migrations.last]]
|
20
|
+
else
|
21
|
+
[:up, :add, pending_migrations]
|
22
|
+
end
|
23
|
+
|
24
|
+
migrations.compact.each do |migration|
|
25
|
+
begin
|
26
|
+
puts '-'*40, "Migration #{direction} (#{migration})" unless args.include?(:quiet)
|
27
|
+
str = File.read(@directory + migration)
|
28
|
+
@executer.new(executer_args, str, migration).go
|
29
|
+
completed << migration
|
30
|
+
puts '-'*40 unless args.include?(:quiet)
|
31
|
+
rescue Exception => e
|
32
|
+
@failed_migration = migration
|
33
|
+
puts '-'*5,"FAILURE in migration #{direction} (#{migration}) with message:", e.message, '-'*5, e.backtrace[0...10], '-'*40 unless args.include?(:quiet)
|
34
|
+
return {success: completed, failed: [@failed_migration]}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
return completed.empty? ? {} : {success: completed}
|
39
|
+
ensure
|
40
|
+
@completed_migrations.send(action, completed)
|
41
|
+
end
|
42
|
+
|
43
|
+
def directory(path=nil)
|
44
|
+
return @directory if path.nil?
|
45
|
+
@directory = Pathname.new(path)
|
46
|
+
refresh_raw_migrations
|
47
|
+
self
|
48
|
+
end
|
49
|
+
|
50
|
+
def reset
|
51
|
+
@completed_migrations.reset
|
52
|
+
self
|
53
|
+
end
|
54
|
+
|
55
|
+
def reload
|
56
|
+
refresh_raw_migrations
|
57
|
+
self
|
58
|
+
end
|
59
|
+
|
60
|
+
def refresh_raw_migrations(arr=nil)
|
61
|
+
raise "argument must be an array" unless arr.nil? || arr.is_a?(Array)
|
62
|
+
arr ||= Pathname.new(@directory).children(with_directory = false) rescue []
|
63
|
+
@raw_migrations = filter_and_sort(arr)
|
64
|
+
self
|
65
|
+
end
|
66
|
+
|
67
|
+
def raw_migrations(arr=nil)
|
68
|
+
return @raw_migrations if arr.nil?
|
69
|
+
refresh_raw_migrations(arr)
|
70
|
+
self
|
71
|
+
end
|
72
|
+
|
73
|
+
def completed_migrations(arr=nil)
|
74
|
+
return @completed_migrations.get if arr.nil?
|
75
|
+
@completed_migrations.set(arr)
|
76
|
+
self
|
77
|
+
end
|
78
|
+
|
79
|
+
def pending_migrations
|
80
|
+
raw_migrations - completed_migrations
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
def filter_and_sort(arr= [])
|
86
|
+
# discard invalid formats, then sort numerically by first number, then alphabetically for remainder
|
87
|
+
format = /(\d+)_(.*)\.rb/
|
88
|
+
arr.map do |e|
|
89
|
+
name = Pathname.new(e).basename.to_s
|
90
|
+
match = format.match(name)
|
91
|
+
[name, match[1], match[2]] rescue nil
|
92
|
+
end.compact.sort_by{|e| [e[1].to_i, e[2]] }.map{|e| e[0] }
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module CouchMigrate
|
2
|
+
class BasePersistedList
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@list = []
|
6
|
+
end
|
7
|
+
|
8
|
+
def get
|
9
|
+
read
|
10
|
+
@list
|
11
|
+
end
|
12
|
+
|
13
|
+
def set(arr)
|
14
|
+
raise "argument must be an array" unless arr.is_a?(Array)
|
15
|
+
@list = arr.dup
|
16
|
+
write
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def add(arr)
|
21
|
+
raise "argument must be an array" unless arr.is_a?(Array)
|
22
|
+
@list.concat(arr).uniq!
|
23
|
+
write
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
def remove(arr)
|
28
|
+
raise "argument must be an array" unless arr.is_a?(Array)
|
29
|
+
@list -= arr
|
30
|
+
write
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
def reset
|
35
|
+
@list = []
|
36
|
+
cleanup
|
37
|
+
self
|
38
|
+
end
|
39
|
+
|
40
|
+
protected
|
41
|
+
|
42
|
+
def read
|
43
|
+
end
|
44
|
+
|
45
|
+
def write
|
46
|
+
end
|
47
|
+
|
48
|
+
def cleanup
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require_relative 'base_migrater'
|
2
|
+
|
3
|
+
module CouchMigrate
|
4
|
+
class CouchMigrater < BaseMigrater
|
5
|
+
def initialize(database, migration_directory="db/migrate")
|
6
|
+
persisted_list = CouchMigrate::CouchPersistedList.new(database)
|
7
|
+
executer = CouchMigrate::CouchExecuter
|
8
|
+
super(persisted_list, executer, migration_directory)
|
9
|
+
self
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'couchrest'
|
2
|
+
|
3
|
+
module CouchMigrate
|
4
|
+
class CouchPersistedList < BasePersistedList
|
5
|
+
DocName = 'migrations'
|
6
|
+
MigrationField = 'completed'
|
7
|
+
|
8
|
+
def initialize(database)
|
9
|
+
@db = CouchRest.database!(database) # find or create
|
10
|
+
raise "db cannot be created using url #{database}" if @db.nil?
|
11
|
+
super()
|
12
|
+
self
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def read
|
18
|
+
@list = @db.get(DocName)[MigrationField] rescue []
|
19
|
+
end
|
20
|
+
|
21
|
+
def write
|
22
|
+
doc = @db.get(DocName) rescue {'_id' => DocName}
|
23
|
+
doc[MigrationField] = @list
|
24
|
+
@db.save_doc(doc)
|
25
|
+
end
|
26
|
+
|
27
|
+
def cleanup
|
28
|
+
@list = []
|
29
|
+
write
|
30
|
+
self
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# use "use_couchrest_model" in the DSL or
|
2
|
+
# include this module in a migration to use CouchRest::Model
|
3
|
+
if defined?(CouchRest::CouchRest::Model)
|
4
|
+
module CouchRest
|
5
|
+
module Model
|
6
|
+
class Base
|
7
|
+
before_save :rewrite_type_for_migration_classes
|
8
|
+
|
9
|
+
def rewrite_type_for_migration_classes
|
10
|
+
class_name = self.class.to_s.sub(/CouchMigrate::BaseExecuter::Namespaced::/, '')
|
11
|
+
self['type'] = class_name
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require_relative 'base_migrater'
|
2
|
+
|
3
|
+
module CouchMigrate
|
4
|
+
class FileMigrater < BaseMigrater
|
5
|
+
def initialize(migration_directory="db/migrate")
|
6
|
+
persisted_list = CouchMigrate::FilePersistedList.new(migration_directory)
|
7
|
+
executer = CouchMigrate::CouchExecuter
|
8
|
+
super(persisted_list, executer, migration_directory)
|
9
|
+
self
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module CouchMigrate
|
5
|
+
class FilePersistedList < BasePersistedList
|
6
|
+
def initialize(directory="db/migrate")
|
7
|
+
super()
|
8
|
+
path = Pathname.new(directory)
|
9
|
+
path.mkpath
|
10
|
+
@path = path+"meta.yml"
|
11
|
+
read
|
12
|
+
self
|
13
|
+
end
|
14
|
+
|
15
|
+
protected
|
16
|
+
|
17
|
+
def read
|
18
|
+
@data = YAML.load(File.read(@path)) rescue {}
|
19
|
+
@data[:complete] ||= []
|
20
|
+
@list = @data[:complete]
|
21
|
+
end
|
22
|
+
|
23
|
+
def write
|
24
|
+
@data[:complete] = @list
|
25
|
+
File.open(@path,"w"){|f| f<< YAML.dump(@data) }
|
26
|
+
end
|
27
|
+
|
28
|
+
def cleanup
|
29
|
+
@path.delete rescue nil
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require_relative '../couch-migrate'
|
2
|
+
|
3
|
+
def migrater
|
4
|
+
$db_path = 'http://127.0.0.1:5984/couch-migrate_development'
|
5
|
+
migrater = CouchMigrate::CouchMigrater.new($db_path)
|
6
|
+
end
|
7
|
+
|
8
|
+
namespace :couch_migrate do
|
9
|
+
|
10
|
+
desc 'migrate all pending migrations'
|
11
|
+
|
12
|
+
namespace :test do
|
13
|
+
|
14
|
+
task :migrate => ['migrate:up']
|
15
|
+
|
16
|
+
namespace :migrate do
|
17
|
+
desc 'couchdb migration up'
|
18
|
+
task 'up' => [:environment, :url] do
|
19
|
+
migrater.migrate(:up)
|
20
|
+
end
|
21
|
+
|
22
|
+
desc 'couchdb migration down'
|
23
|
+
task 'down' => [:environment, :url] do
|
24
|
+
migrater.migrate(:down)
|
25
|
+
end
|
26
|
+
|
27
|
+
desc 'couchdb migration down, then up'
|
28
|
+
task 'redo' => [:environment, :url] do
|
29
|
+
migrater.migrate(:down)
|
30
|
+
migrater.migrate(:up)
|
31
|
+
end
|
32
|
+
|
33
|
+
desc 'print couchdb URL'
|
34
|
+
task 'url' => :environment do
|
35
|
+
$stderr.puts("CouchDB URL: #{$db_path}")
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
require 'couch-migrate'
|
3
|
+
|
4
|
+
describe "CouchMigrate::BaseExecuter" do
|
5
|
+
subject{ CouchMigrate::BaseExecuter }
|
6
|
+
let(:msg) { "this line was executed by the script" }
|
7
|
+
let(:execution_verification) { "raise '#{msg}'" }
|
8
|
+
|
9
|
+
describe "#go" do
|
10
|
+
let(:enabled) { [] }
|
11
|
+
it "executes a string (typically loaded from a script file)" do
|
12
|
+
lambda{ subject.new(enabled, execution_verification).go }.should raise_error(RuntimeError,msg)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "enables classes to be defined" do
|
16
|
+
script =<<-EOS
|
17
|
+
class Foo
|
18
|
+
def test; #{execution_verification} end
|
19
|
+
end
|
20
|
+
up do
|
21
|
+
Foo.new.test
|
22
|
+
end
|
23
|
+
EOS
|
24
|
+
lambda{ subject.new([:up], script).go }.should raise_error(RuntimeError,msg)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "enables classes to be defined, and they are namespaced" do
|
28
|
+
script =<<-EOS
|
29
|
+
class NamespacedFoo
|
30
|
+
def test; end
|
31
|
+
end
|
32
|
+
up do
|
33
|
+
NamespacedFoo.new.test
|
34
|
+
# puts Module.constants.grep(/NamespacedFoo/).inspect
|
35
|
+
# puts Namespaced.constants.grep(/NamespacedFoo/).inspect
|
36
|
+
# puts BaseExecuter::Namespaced.constants.grep(/NamespacedFoo/).inspect
|
37
|
+
# puts BaseExecuter.constants.grep(/NamespacedFoo/).inspect
|
38
|
+
# puts
|
39
|
+
end
|
40
|
+
EOS
|
41
|
+
|
42
|
+
subject.new([:up], script).go
|
43
|
+
|
44
|
+
# puts Module.constants.grep(/Foo/).inspect
|
45
|
+
# puts BaseExecuter::Namespaced.constants.grep(/Foo/).inspect
|
46
|
+
# puts BaseExecuter.constants.grep(/Foo/).inspect
|
47
|
+
|
48
|
+
Module.constants.include?(:NamespacedFoo).should == false
|
49
|
+
CouchMigrate::BaseExecuter.constants.include?(:NamespacedFoo).should == false
|
50
|
+
CouchMigrate::BaseExecuter::Namespaced.constants.include?(:NamespacedFoo).should == true
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "#up" do
|
55
|
+
context "when enabled" do
|
56
|
+
let(:enabled) { [:up] }
|
57
|
+
|
58
|
+
it "executes its block of code" do
|
59
|
+
lambda{ subject.new(enabled,"up do raise '#{msg}' end").go }.should raise_error(RuntimeError,msg)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context "when disabled" do
|
64
|
+
let(:enabled) { [] }
|
65
|
+
|
66
|
+
it "does not executes its block of code" do
|
67
|
+
lambda{ subject.new(enabled,"up do raise '#{msg}' end").go }.should_not raise_error(RuntimeError,msg)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "#down" do
|
74
|
+
context "when enabled" do
|
75
|
+
let(:enabled) { [:down] }
|
76
|
+
|
77
|
+
it "executes its block of code" do
|
78
|
+
lambda{ subject.new(enabled,"down do raise '#{msg}' end").go }.should raise_error(RuntimeError,msg)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context "when disabled" do
|
83
|
+
let(:enabled) { [] }
|
84
|
+
|
85
|
+
it "does not executes its block of code" do
|
86
|
+
lambda{ subject.new(enabled,"down do raise '#{msg}' end").go }.should_not raise_error(RuntimeError,msg)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
require 'couch-migrate'
|
3
|
+
|
4
|
+
describe "BaseMigrater", "#migrate" do
|
5
|
+
subject { CouchMigrate::BaseMigrater.new }
|
6
|
+
|
7
|
+
let(:file_name_1){ "1_migration_a.rb" }
|
8
|
+
let(:file_name_2){ "2_migration_b.rb" }
|
9
|
+
let(:file_name_3){ "3_migration_b.rb" }
|
10
|
+
|
11
|
+
it "can set migrations from a list" do
|
12
|
+
subject.raw_migrations.should == []
|
13
|
+
|
14
|
+
subject.raw_migrations([file_name_1, file_name_2]).raw_migrations.should == [file_name_1,file_name_2]
|
15
|
+
end
|
16
|
+
|
17
|
+
context "interacting with the file system" do
|
18
|
+
let(:path){ Pathname.new("spec/tmp") }
|
19
|
+
let(:file_1){ path + file_name_1 }
|
20
|
+
let(:file_2){ path + file_name_2 }
|
21
|
+
let(:file_3){ path + file_name_3 }
|
22
|
+
|
23
|
+
before(:all) do
|
24
|
+
path.mkpath
|
25
|
+
File.open(file_3,"w"){|f| f << "up do end" }
|
26
|
+
File.open(file_2,"w"){|f| f << "up do raise '2 simulated failure' end" }
|
27
|
+
File.open(file_1,"w"){|f| f << "up do end" }
|
28
|
+
end
|
29
|
+
|
30
|
+
after(:all) do
|
31
|
+
file_1.delete
|
32
|
+
file_2.delete
|
33
|
+
file_3.delete
|
34
|
+
path.rmdir rescue nil
|
35
|
+
end
|
36
|
+
|
37
|
+
it "reads the db/migrations directory to generate a list of potential migrations to run" do
|
38
|
+
subject.directory(path).raw_migrations.should == [file_name_1, file_name_2, file_name_3]
|
39
|
+
subject.directory(path).pending_migrations.should == [file_name_1, file_name_2, file_name_3]
|
40
|
+
end
|
41
|
+
|
42
|
+
it "stops when a migration file exits with an error, not processing any subsequent files afterwards" do
|
43
|
+
subject.directory(path).pending_migrations.should == [file_name_1, file_name_2, file_name_3]
|
44
|
+
subject.migrate(:quiet, :up).should == {success: [file_name_1], failed: [file_name_2]}
|
45
|
+
subject.failed_migration.should == file_name_2
|
46
|
+
subject.pending_migrations.should == [file_name_2, file_name_3]
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
it "does not execute migrations that have already been run" do
|
52
|
+
subject.raw_migrations([file_name_1, file_name_2]).completed_migrations([file_name_1]).pending_migrations.should == [file_name_2]
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "BaseMigrater", "sorting and filtering" do
|
58
|
+
subject { CouchMigrate::BaseMigrater.new }
|
59
|
+
|
60
|
+
it "sorts on migration numbers" do
|
61
|
+
subject.raw_migrations(['2_name.rb','1_name.rb', '3_name.rb'])
|
62
|
+
subject.pending_migrations.should == ['1_name.rb','2_name.rb', '3_name.rb']
|
63
|
+
end
|
64
|
+
|
65
|
+
it "sorts on title if migration numbers are the same" do
|
66
|
+
subject.raw_migrations(['2_a_name.rb','2_b_name.rb'])
|
67
|
+
subject.raw_migrations.should == ['2_a_name.rb','2_b_name.rb']
|
68
|
+
end
|
69
|
+
|
70
|
+
it "sorts on title if migration numbers are the same (version 2)" do
|
71
|
+
subject.raw_migrations(['2_b_name.rb','2_a_name.rb'])
|
72
|
+
subject.raw_migrations.should == ['2_a_name.rb','2_b_name.rb']
|
73
|
+
end
|
74
|
+
|
75
|
+
it "sorts migration numbers numerically, not alphabetically" do
|
76
|
+
subject.raw_migrations(['10_name.rb','2_name.rb'])
|
77
|
+
subject.raw_migrations.should == ['2_name.rb', '10_name.rb']
|
78
|
+
end
|
79
|
+
|
80
|
+
it "sorts migration numbers numerically, not alphabetically (version 2)" do
|
81
|
+
subject.raw_migrations(['2_name.rb','10_name.rb'])
|
82
|
+
subject.raw_migrations.should == ['2_name.rb', '10_name.rb']
|
83
|
+
end
|
84
|
+
|
85
|
+
it "ignores files that do not have follow the migrationOrder_migration_title format" do
|
86
|
+
subject.raw_migrations(['2_name.rb','a_bad_name.rb'])
|
87
|
+
subject.raw_migrations.should == ['2_name.rb']
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
require 'couch-migrate'
|
3
|
+
|
4
|
+
describe CouchMigrate::BasePersistedList do
|
5
|
+
|
6
|
+
it "starts off with an empty value/list" do
|
7
|
+
subject.get.should == []
|
8
|
+
end
|
9
|
+
|
10
|
+
it "can set values" do
|
11
|
+
arr = [1,2,3]
|
12
|
+
subject.set(arr).get.should == arr
|
13
|
+
end
|
14
|
+
|
15
|
+
it "can append values" do
|
16
|
+
arr = [1,2,3]
|
17
|
+
more = [4,5]
|
18
|
+
expected = [1,2,3,4,5]
|
19
|
+
|
20
|
+
subject.set(arr).add(more)
|
21
|
+
subject.get.should == expected
|
22
|
+
end
|
23
|
+
|
24
|
+
it "can remove values" do
|
25
|
+
arr = [1,2,3]
|
26
|
+
remove = [2,3]
|
27
|
+
expected = [1]
|
28
|
+
|
29
|
+
subject.set(arr).remove(remove)
|
30
|
+
subject.get.should == expected
|
31
|
+
end
|
32
|
+
|
33
|
+
it "can be reset" do
|
34
|
+
subject.set([1,2,3]).reset
|
35
|
+
subject.get.should == []
|
36
|
+
end
|
37
|
+
|
38
|
+
it "is chainable" do
|
39
|
+
subject.set([1]).add([2]).get.should == [1,2]
|
40
|
+
subject.set([1]).add([2]).reset.get.should == []
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
require 'couch-migrate'
|
3
|
+
|
4
|
+
describe "CouchMigrater", "#migrate" do
|
5
|
+
|
6
|
+
|
7
|
+
context "interacting with the file system" do
|
8
|
+
subject { CouchMigrate::CouchMigrater }
|
9
|
+
let(:db_path) { 'http://127.0.0.1:5984/couch-migrate_test' }
|
10
|
+
let(:path){ Pathname.new("spec/tmp") }
|
11
|
+
|
12
|
+
let(:file_name_1){ "1_migration_a.rb" }
|
13
|
+
let(:file_name_2){ "2_migration_b.rb" }
|
14
|
+
let(:file_name_3){ "3_migration_b.rb" }
|
15
|
+
let(:file_path_1){ path + file_name_1 }
|
16
|
+
let(:file_path_2){ path + file_name_2 }
|
17
|
+
let(:file_path_3){ path + file_name_3 }
|
18
|
+
|
19
|
+
before(:each) do
|
20
|
+
migrater.reset # clear pre-existing migration meta data
|
21
|
+
path.mkpath
|
22
|
+
file_path_1.delete rescue nil
|
23
|
+
file_path_2.delete rescue nil
|
24
|
+
file_path_3.delete rescue nil
|
25
|
+
end
|
26
|
+
|
27
|
+
after(:each) do
|
28
|
+
# migrater.reset # remove meta file
|
29
|
+
file_path_1.delete rescue nil
|
30
|
+
file_path_2.delete rescue nil
|
31
|
+
file_path_3.delete rescue nil
|
32
|
+
path.rmdir rescue nil
|
33
|
+
end
|
34
|
+
|
35
|
+
def migrater
|
36
|
+
# allows new migrations to be picked up
|
37
|
+
res = subject.new(db_path, path)
|
38
|
+
res
|
39
|
+
end
|
40
|
+
|
41
|
+
it "handles a sequence of migration added over time" do
|
42
|
+
params = [:up, :quiet]
|
43
|
+
down_params = [:down, :quiet]
|
44
|
+
|
45
|
+
# should succeed
|
46
|
+
File.open(file_path_1,"w"){|f| f << "up do end" }
|
47
|
+
migrater.migrate(*params).should == {success: [file_name_1]}
|
48
|
+
|
49
|
+
# should do nothing
|
50
|
+
migrater.migrate(*params).should == {}
|
51
|
+
|
52
|
+
# should fail
|
53
|
+
File.open(file_path_2,"w"){|f| f << "up do raise '2 simulated failure' end" }
|
54
|
+
migrater.migrate(*params).should == {success: [], failed: [file_name_2]}
|
55
|
+
|
56
|
+
# should pass now
|
57
|
+
File.open(file_path_2,"w"){|f| f << "up do end" }
|
58
|
+
migrater.migrate(*params).should == {success: [file_name_2]}
|
59
|
+
|
60
|
+
# should succeed
|
61
|
+
File.open(file_path_3,"w"){|f| f << "up do end" }
|
62
|
+
migrater.migrate(*params).should == {success: [file_name_3]}
|
63
|
+
|
64
|
+
# should do nothing
|
65
|
+
migrater.migrate(*params).should == {}
|
66
|
+
|
67
|
+
# resetting the migration causes all to be run next time
|
68
|
+
migrater.reset
|
69
|
+
migrater.migrate(*params).should == {success: [file_name_1, file_name_2, file_name_3]}
|
70
|
+
|
71
|
+
# Down * 3
|
72
|
+
migrater.migrate(*down_params).should == {success: [file_name_3]}
|
73
|
+
migrater.migrate(*down_params).should == {success: [file_name_2]}
|
74
|
+
migrater.migrate(*down_params).should == {success: [file_name_1]}
|
75
|
+
|
76
|
+
# Down does nothing
|
77
|
+
migrater.migrate(*down_params).should == {}
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
require 'couch-migrate'
|
3
|
+
|
4
|
+
describe CouchMigrate::CouchPersistedList do
|
5
|
+
let(:db_path) { 'http://127.0.0.1:5984/couch-migrate_test' }
|
6
|
+
subject { CouchMigrate::CouchPersistedList.new(db_path) }
|
7
|
+
|
8
|
+
before(:each) do
|
9
|
+
subject.reset
|
10
|
+
end
|
11
|
+
|
12
|
+
it "starts off with an empty value/list" do
|
13
|
+
subject.get.should == []
|
14
|
+
end
|
15
|
+
|
16
|
+
it "can set values" do
|
17
|
+
arr = [1,2,3]
|
18
|
+
subject.set(arr).get.should == arr
|
19
|
+
end
|
20
|
+
|
21
|
+
it "can append values" do
|
22
|
+
arr = [1,2,3]
|
23
|
+
more = [4,5]
|
24
|
+
expected = [1,2,3,4,5]
|
25
|
+
|
26
|
+
subject.set(arr).add(more)
|
27
|
+
subject.get.should == expected
|
28
|
+
end
|
29
|
+
|
30
|
+
it "can be reset" do
|
31
|
+
subject.set([1,2,3]).reset
|
32
|
+
subject.get.should == []
|
33
|
+
end
|
34
|
+
|
35
|
+
it "is chainable" do
|
36
|
+
subject.set([1]).add([2]).get.should == [1,2]
|
37
|
+
subject.set([1]).add([2]).reset.get.should == []
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
require 'couch-migrate'
|
3
|
+
|
4
|
+
describe "FileMigrater", "#migrate" do
|
5
|
+
|
6
|
+
|
7
|
+
context "interacting with the file system" do
|
8
|
+
subject { CouchMigrate::FileMigrater }
|
9
|
+
let(:path){ Pathname.new("spec/tmp") }
|
10
|
+
|
11
|
+
let(:file_name_1){ "1_migration_a.rb" }
|
12
|
+
let(:file_name_2){ "2_migration_b.rb" }
|
13
|
+
let(:file_name_3){ "3_migration_b.rb" }
|
14
|
+
let(:file_path_1){ path + file_name_1 }
|
15
|
+
let(:file_path_2){ path + file_name_2 }
|
16
|
+
let(:file_path_3){ path + file_name_3 }
|
17
|
+
|
18
|
+
before(:each) do
|
19
|
+
migrater.reset # clear pre-existing migration meta data
|
20
|
+
path.mkpath
|
21
|
+
file_path_1.delete rescue nil
|
22
|
+
file_path_2.delete rescue nil
|
23
|
+
file_path_3.delete rescue nil
|
24
|
+
end
|
25
|
+
|
26
|
+
after(:each) do
|
27
|
+
migrater.reset # remove meta file
|
28
|
+
file_path_1.delete rescue nil
|
29
|
+
file_path_2.delete rescue nil
|
30
|
+
file_path_3.delete rescue nil
|
31
|
+
path.rmdir rescue nil
|
32
|
+
end
|
33
|
+
|
34
|
+
def migrater
|
35
|
+
# allows new migrations to be picked up
|
36
|
+
subject.new(path)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "handles a sequence of migration added over time" do
|
40
|
+
up_params = [:up, :quiet]
|
41
|
+
down_params = [:down, :quiet]
|
42
|
+
|
43
|
+
# should succeed
|
44
|
+
File.open(file_path_1,"w"){|f| f << "up do end" }
|
45
|
+
migrater.migrate(*up_params).should == {success: [file_name_1]}
|
46
|
+
|
47
|
+
# should do nothing
|
48
|
+
migrater.migrate(*up_params).should == {}
|
49
|
+
|
50
|
+
# should fail
|
51
|
+
File.open(file_path_2,"w"){|f| f << "up do raise '2 simulated failure' end" }
|
52
|
+
migrater.migrate(*up_params).should == {success: [], failed: [file_name_2]}
|
53
|
+
|
54
|
+
# should pass now
|
55
|
+
File.open(file_path_2,"w"){|f| f << "up do end" }
|
56
|
+
migrater.migrate(*up_params).should == {success: [file_name_2]}
|
57
|
+
|
58
|
+
# Down
|
59
|
+
migrater.migrate(*down_params).should == {success: [file_name_2]}
|
60
|
+
|
61
|
+
# up
|
62
|
+
migrater.migrate(*up_params).should == {success: [file_name_2]}
|
63
|
+
|
64
|
+
# should succeed
|
65
|
+
File.open(file_path_3,"w"){|f| f << "up do end" }
|
66
|
+
migrater.migrate(*up_params).should == {success: [file_name_3]}
|
67
|
+
|
68
|
+
# should do nothing
|
69
|
+
migrater.migrate(*up_params).should == {}
|
70
|
+
|
71
|
+
# resetting the migration causes all to be run next time
|
72
|
+
migrater.reset
|
73
|
+
migrater.migrate(*up_params).should == {success: [file_name_1, file_name_2, file_name_3]}
|
74
|
+
|
75
|
+
# Down * 3
|
76
|
+
migrater.migrate(*down_params).should == {success: [file_name_3]}
|
77
|
+
migrater.migrate(*down_params).should == {success: [file_name_2]}
|
78
|
+
migrater.migrate(*down_params).should == {success: [file_name_1]}
|
79
|
+
|
80
|
+
# Down does nothing
|
81
|
+
migrater.migrate(*down_params).should == {}
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
require 'couch-migrate'
|
3
|
+
require 'pathname'
|
4
|
+
|
5
|
+
describe CouchMigrate::FilePersistedList do
|
6
|
+
let(:path){ Pathname.new("spec/tmp") }
|
7
|
+
subject { CouchMigrate::FilePersistedList.new(path) }
|
8
|
+
|
9
|
+
after(:all) do
|
10
|
+
Pathname.new(path).delete
|
11
|
+
end
|
12
|
+
|
13
|
+
it "starts off with an empty value/list" do
|
14
|
+
subject.get.should == []
|
15
|
+
end
|
16
|
+
|
17
|
+
it "can set values" do
|
18
|
+
arr = [1,2,3]
|
19
|
+
subject.set(arr).get.should == arr
|
20
|
+
end
|
21
|
+
|
22
|
+
it "can append values" do
|
23
|
+
arr = [1,2,3]
|
24
|
+
more = [4,5]
|
25
|
+
expected = [1,2,3,4,5]
|
26
|
+
|
27
|
+
subject.set(arr).add(more)
|
28
|
+
subject.get.should == expected
|
29
|
+
end
|
30
|
+
|
31
|
+
it "can be reset" do
|
32
|
+
subject.set([1,2,3]).reset
|
33
|
+
subject.get.should == []
|
34
|
+
end
|
35
|
+
|
36
|
+
it "is chainable" do
|
37
|
+
subject.set([1]).add([2]).get.should == [1,2]
|
38
|
+
subject.set([1]).add([2]).reset.get.should == []
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
require 'rspec'
|
4
|
+
|
5
|
+
# Requires supporting files with custom matchers and macros, etc,
|
6
|
+
# in ./support/ and its subdirectories.
|
7
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
8
|
+
|
9
|
+
RSpec.configure do |config|
|
10
|
+
|
11
|
+
end
|
metadata
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: couch-migrate
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Greg Edwards
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-09-20 00:00:00.000000000 -06:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: couchrest
|
17
|
+
requirement: &2157870300 !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: *2157870300
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: rspec
|
28
|
+
requirement: &2157869180 !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.3.0
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: *2157869180
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: yard
|
39
|
+
requirement: &2157868040 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ~>
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: 0.6.0
|
45
|
+
type: :development
|
46
|
+
prerelease: false
|
47
|
+
version_requirements: *2157868040
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: bundler
|
50
|
+
requirement: &2157866720 !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ~>
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 1.0.0
|
56
|
+
type: :development
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: *2157866720
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: jeweler
|
61
|
+
requirement: &2157865660 !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
63
|
+
requirements:
|
64
|
+
- - ~>
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: 1.6.4
|
67
|
+
type: :development
|
68
|
+
prerelease: false
|
69
|
+
version_requirements: *2157865660
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: rcov
|
72
|
+
requirement: &2157864760 !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
type: :development
|
79
|
+
prerelease: false
|
80
|
+
version_requirements: *2157864760
|
81
|
+
description: A simple migration system for CouchDB.
|
82
|
+
email: greg@greglearns.com
|
83
|
+
executables: []
|
84
|
+
extensions: []
|
85
|
+
extra_rdoc_files:
|
86
|
+
- LICENSE.txt
|
87
|
+
- README.rdoc
|
88
|
+
files:
|
89
|
+
- .document
|
90
|
+
- .rspec
|
91
|
+
- Gemfile
|
92
|
+
- Gemfile.lock
|
93
|
+
- LICENSE.txt
|
94
|
+
- README.rdoc
|
95
|
+
- Rakefile
|
96
|
+
- VERSION
|
97
|
+
- couch-migrate.gemspec
|
98
|
+
- db/migrate/1_test.rb
|
99
|
+
- lib/couch-migrate.rb
|
100
|
+
- lib/couch_migrate/base_executer.rb
|
101
|
+
- lib/couch_migrate/base_migrater.rb
|
102
|
+
- lib/couch_migrate/base_persisted_list.rb
|
103
|
+
- lib/couch_migrate/couch_executer.rb
|
104
|
+
- lib/couch_migrate/couch_migrater.rb
|
105
|
+
- lib/couch_migrate/couch_persisted_list.rb
|
106
|
+
- lib/couch_migrate/couchrest_model/extend.rb
|
107
|
+
- lib/couch_migrate/file_migrater.rb
|
108
|
+
- lib/couch_migrate/file_persisted_list.rb
|
109
|
+
- lib/couch_migrate_railtie.rb
|
110
|
+
- lib/tasks/couch_migrate.rake
|
111
|
+
- spec/couch_migrate/base_executer_spec.rb
|
112
|
+
- spec/couch_migrate/base_migrater_spec.rb
|
113
|
+
- spec/couch_migrate/base_persisted_list_spec.rb
|
114
|
+
- spec/couch_migrate/couch_migrater_spec.rb
|
115
|
+
- spec/couch_migrate/couch_persisted_list_spec.rb
|
116
|
+
- spec/couch_migrate/file_migrater_spec.rb
|
117
|
+
- spec/couch_migrate/file_persisted_list_spec.rb
|
118
|
+
- spec/spec_helper.rb
|
119
|
+
has_rdoc: true
|
120
|
+
homepage: https://github.com/gedwards/couch-migrate
|
121
|
+
licenses:
|
122
|
+
- MIT
|
123
|
+
post_install_message:
|
124
|
+
rdoc_options: []
|
125
|
+
require_paths:
|
126
|
+
- lib
|
127
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
128
|
+
none: false
|
129
|
+
requirements:
|
130
|
+
- - ! '>='
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '0'
|
133
|
+
segments:
|
134
|
+
- 0
|
135
|
+
hash: 952696308215902437
|
136
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
requirements: []
|
143
|
+
rubyforge_project:
|
144
|
+
rubygems_version: 1.6.2
|
145
|
+
signing_key:
|
146
|
+
specification_version: 3
|
147
|
+
summary: A simple migration system for CouchDB
|
148
|
+
test_files: []
|