activegroonga 0.0.7 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.ja.rdoc +4 -1
- data/README.rdoc +4 -1
- data/Rakefile +18 -4
- data/lib/active_groonga.rb +25 -52
- data/lib/active_groonga/base.rb +164 -1480
- data/lib/active_groonga/callbacks.rb +26 -7
- data/lib/active_groonga/database.rb +55 -0
- data/lib/active_groonga/{dirty.rb → error.rb} +20 -10
- data/lib/active_groonga/locale/en.yml +5 -0
- data/lib/active_groonga/migration.rb +44 -113
- data/lib/active_groonga/migrator.rb +172 -0
- data/lib/active_groonga/persistence.rb +172 -0
- data/lib/active_groonga/railtie.rb +66 -0
- data/lib/active_groonga/railties/configurable.rb +47 -0
- data/lib/active_groonga/railties/groonga.rake +167 -0
- data/lib/active_groonga/result_set.rb +89 -0
- data/lib/active_groonga/schema.rb +54 -188
- data/lib/active_groonga/validations.rb +54 -5
- data/lib/active_groonga/vector.rb +64 -0
- data/lib/active_groonga/version.rb +3 -3
- data/lib/{active_groonga/aggregations.rb → rails/generators/active_groonga.rb} +17 -10
- data/lib/rails/generators/active_groonga/migration/column.rb +101 -0
- data/lib/rails/generators/active_groonga/migration/migration_generator.rb +53 -0
- data/lib/rails/generators/active_groonga/migration/templates/migration.rb +29 -0
- data/lib/rails/generators/active_groonga/model/model_generator.rb +60 -0
- data/lib/rails/generators/active_groonga/model/templates/migration.rb +16 -0
- data/lib/rails/generators/active_groonga/model/templates/model.rb +2 -0
- data/lib/rails/generators/active_groonga/model/templates/module.rb +5 -0
- data/test-unit-notify/COPYING +502 -0
- data/test-unit-notify/Rakefile +47 -0
- data/test-unit-notify/lib/test/unit/notify.rb +127 -0
- data/test-unit/COPYING +56 -0
- data/test-unit/GPL +340 -0
- data/test-unit/PSFL +271 -0
- data/test-unit/Rakefile +18 -5
- data/test-unit/html/bar.svg +153 -0
- data/test-unit/html/developer.svg +469 -0
- data/test-unit/html/favicon.ico +0 -0
- data/test-unit/html/favicon.svg +82 -0
- data/test-unit/html/heading-mark.svg +393 -0
- data/test-unit/html/index.html +235 -13
- data/test-unit/html/index.html.ja +258 -15
- data/test-unit/html/install.svg +636 -0
- data/test-unit/html/logo.svg +483 -0
- data/test-unit/html/test-unit.css +339 -0
- data/test-unit/html/tutorial.svg +559 -0
- data/test-unit/lib/test/unit.rb +29 -43
- data/test-unit/lib/test/unit/assertionfailederror.rb +11 -0
- data/test-unit/lib/test/unit/assertions.rb +202 -20
- data/test-unit/lib/test/unit/autorunner.rb +51 -20
- data/test-unit/lib/test/unit/collector.rb +1 -8
- data/test-unit/lib/test/unit/collector/dir.rb +1 -1
- data/test-unit/lib/test/unit/collector/load.rb +16 -9
- data/test-unit/lib/test/unit/color-scheme.rb +19 -3
- data/test-unit/lib/test/unit/diff.rb +240 -38
- data/test-unit/lib/test/unit/error.rb +4 -0
- data/test-unit/lib/test/unit/failure.rb +31 -5
- data/test-unit/lib/test/unit/notification.rb +8 -4
- data/test-unit/lib/test/unit/omission.rb +51 -3
- data/test-unit/lib/test/unit/pending.rb +4 -0
- data/test-unit/lib/test/unit/priority.rb +2 -3
- data/test-unit/lib/test/unit/testcase.rb +65 -7
- data/test-unit/lib/test/unit/testresult.rb +34 -2
- data/test-unit/lib/test/unit/ui/console/testrunner.rb +197 -45
- data/test-unit/lib/test/unit/ui/emacs/testrunner.rb +14 -0
- data/test-unit/lib/test/unit/ui/tap/testrunner.rb +2 -12
- data/test-unit/lib/test/unit/ui/testrunner.rb +33 -0
- data/test-unit/lib/test/unit/util/backtracefilter.rb +1 -0
- data/test-unit/lib/test/unit/util/output.rb +31 -0
- data/test-unit/lib/test/unit/version.rb +1 -1
- data/test-unit/sample/{tc_adder.rb → test_adder.rb} +3 -1
- data/test-unit/sample/{tc_subtracter.rb → test_subtracter.rb} +3 -1
- data/test-unit/sample/test_user.rb +1 -0
- data/test-unit/test/collector/test-descendant.rb +2 -4
- data/test-unit/test/collector/test-load.rb +121 -8
- data/test-unit/test/collector/test_objectspace.rb +7 -5
- data/test-unit/test/run-test.rb +2 -0
- data/test-unit/test/test-color-scheme.rb +11 -2
- data/test-unit/test/test-diff.rb +48 -7
- data/test-unit/test/test-omission.rb +1 -1
- data/test-unit/test/test-testcase.rb +57 -20
- data/test-unit/test/test_assertions.rb +128 -13
- data/test-unit/test/ui/test_tap.rb +33 -0
- data/test-unit/test/util/test-output.rb +11 -0
- data/test/active-groonga-test-utils.rb +50 -36
- data/test/fixtures/site.rb +2 -0
- data/test/run-test.rb +36 -9
- data/test/test-associations.rb +5 -2
- data/test/test-base.rb +39 -31
- data/test/test-callbacks.rb +13 -3
- data/test/test-persistence.rb +53 -0
- data/{lib/active_groonga/observer.rb → test/test-result-set.rb} +14 -12
- data/test/test-schema.rb +85 -22
- data/{lib/active_groonga/rails_support.rb → test/test-validations.rb} +15 -13
- metadata +85 -52
- data/lib/active_groonga/associations.rb +0 -93
- data/lib/active_groonga/associations/belongs_to_association.rb +0 -25
- data/lib/active_groonga/attribute_methods.rb +0 -36
- data/lib/active_groonga/column.rb +0 -137
- data/lib/active_groonga/dynamic_record_expression_builder.rb +0 -40
- data/lib/active_groonga/reflection.rb +0 -30
- data/lib/active_groonga/schema_dumper.rb +0 -163
- data/lib/active_groonga/tasks.rb +0 -16
- data/lib/active_groonga/tasks/groonga.rake +0 -164
- data/lib/active_groonga/timestamp.rb +0 -30
- data/rails/README +0 -28
- data/rails/init.rb +0 -70
- data/rails_generators/index_table_groonga/USAGE +0 -23
- data/rails_generators/index_table_groonga/index_table_groonga_generator.rb +0 -44
- data/rails_generators/index_table_groonga/templates/migration.rb +0 -12
- data/rails_generators/migration_groonga/USAGE +0 -29
- data/rails_generators/migration_groonga/migration_groonga_generator.rb +0 -19
- data/rails_generators/migration_groonga/templates/migration.rb +0 -11
- data/rails_generators/model_groonga/USAGE +0 -28
- data/rails_generators/model_groonga/model_groonga_generator.rb +0 -45
- data/rails_generators/model_groonga/templates/fixtures.yml +0 -17
- data/rails_generators/model_groonga/templates/migration.rb +0 -16
- data/rails_generators/model_groonga/templates/model.rb +0 -2
- data/rails_generators/model_groonga/templates/unit_test.rb +0 -8
- data/test-unit/html/classic.html +0 -15
- data/test-unit/sample/ts_examples.rb +0 -7
- data/test/test-schema-dumper.rb +0 -48
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2009 Kouhei Sutou <kou@clear-code.com>
|
1
|
+
# Copyright (C) 2009-2010 Kouhei Sutou <kou@clear-code.com>
|
2
2
|
#
|
3
3
|
# This library is free software; you can redistribute it and/or
|
4
4
|
# modify it under the terms of the GNU Lesser General Public
|
@@ -15,12 +15,31 @@
|
|
15
15
|
|
16
16
|
module ActiveGroonga
|
17
17
|
module Callbacks
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
18
|
+
extend ActiveSupport::Concern
|
19
|
+
|
20
|
+
included do
|
21
|
+
extend ActiveModel::Callbacks
|
22
|
+
include ActiveModel::Validations::Callbacks
|
23
|
+
|
24
|
+
define_model_callbacks :initialize, :find, :only => :after
|
25
|
+
define_model_callbacks :save, :create, :update, :destory
|
26
|
+
end
|
27
|
+
|
28
|
+
def destroy #:nodoc:
|
29
|
+
run_callbacks(:destory) {super}
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
def create_or_update #:nodoc:
|
34
|
+
run_callbacks(:save) {super}
|
35
|
+
end
|
36
|
+
|
37
|
+
def create #:nodoc:
|
38
|
+
run_callbacks(:create) {super}
|
39
|
+
end
|
40
|
+
|
41
|
+
def update #:nodoc:
|
42
|
+
run_callbacks(:update) {super}
|
24
43
|
end
|
25
44
|
end
|
26
45
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# Copyright (C) 2010 Kouhei Sutou <kou@clear-code.com>
|
2
|
+
#
|
3
|
+
# This library is free software; you can redistribute it and/or
|
4
|
+
# modify it under the terms of the GNU Lesser General Public
|
5
|
+
# License version 2.1 as published by the Free Software Foundation.
|
6
|
+
#
|
7
|
+
# This library is distributed in the hope that it will be useful,
|
8
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
9
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
10
|
+
# Lesser General Public License for more details.
|
11
|
+
#
|
12
|
+
# You should have received a copy of the GNU Lesser General Public
|
13
|
+
# License along with this library; if not, write to the Free Software
|
14
|
+
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
15
|
+
|
16
|
+
require 'fileutils'
|
17
|
+
|
18
|
+
module ActiveGroonga
|
19
|
+
class Database
|
20
|
+
def initialize(path)
|
21
|
+
@path = path
|
22
|
+
@database = nil
|
23
|
+
end
|
24
|
+
|
25
|
+
def ensure_available
|
26
|
+
return if @database
|
27
|
+
if @path.exist?
|
28
|
+
@database = Groonga::Database.open(@path.to_s,
|
29
|
+
:context => Base.context)
|
30
|
+
else
|
31
|
+
FileUtils.mkdir_p(@path.dirname) unless @path.dirname.exist?
|
32
|
+
@database = Groonga::Database.create(:path => @path.to_s,
|
33
|
+
:context => Base.context)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def remove
|
38
|
+
ensure_available if @path.exist?
|
39
|
+
return if @database.nil?
|
40
|
+
@database.remove
|
41
|
+
@database = nil
|
42
|
+
end
|
43
|
+
|
44
|
+
def close
|
45
|
+
return if @database.nil?
|
46
|
+
@database.close
|
47
|
+
@database = nil
|
48
|
+
end
|
49
|
+
|
50
|
+
def reopen
|
51
|
+
close
|
52
|
+
ensure_available
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2009 Kouhei Sutou <kou@clear-code.com>
|
1
|
+
# Copyright (C) 2009-2010 Kouhei Sutou <kou@clear-code.com>
|
2
2
|
#
|
3
3
|
# This library is free software; you can redistribute it and/or
|
4
4
|
# modify it under the terms of the GNU Lesser General Public
|
@@ -14,17 +14,27 @@
|
|
14
14
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
15
15
|
|
16
16
|
module ActiveGroonga
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
17
|
+
# Generic ActiveGroonga exception class.
|
18
|
+
class Error < StandardError
|
19
|
+
end
|
20
|
+
|
21
|
+
class RecordNotSaved < Error
|
22
|
+
end
|
23
|
+
|
24
|
+
class NoKeyTableError < Error
|
25
|
+
attr_reader :table
|
26
|
+
def initialize(table)
|
27
|
+
@table = table
|
28
|
+
super("table doesn't have key: #{@table}")
|
25
29
|
end
|
30
|
+
end
|
26
31
|
|
27
|
-
|
32
|
+
class KeyOverrideError < Error
|
33
|
+
attr_reader :table, :key
|
34
|
+
def initialize(table, key)
|
35
|
+
@table = table
|
36
|
+
@key = key
|
37
|
+
super("can't override existing record key: #{@table}: <#{@key}>")
|
28
38
|
end
|
29
39
|
end
|
30
40
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2009 Kouhei Sutou <kou@clear-code.com>
|
1
|
+
# Copyright (C) 2009-2010 Kouhei Sutou <kou@clear-code.com>
|
2
2
|
#
|
3
3
|
# This library is free software; you can redistribute it and/or
|
4
4
|
# modify it under the terms of the GNU Lesser General Public
|
@@ -13,137 +13,68 @@
|
|
13
13
|
# License along with this library; if not, write to the Free Software
|
14
14
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
15
15
|
|
16
|
-
# This library includes ActiveRecord based codes temporary.
|
17
|
-
# Here is their copyright and license:
|
18
|
-
#
|
19
|
-
# Copyright (c) 2004-2009 David Heinemeier Hansson
|
20
|
-
#
|
21
|
-
# Permission is hereby granted, free of charge, to any person obtaining
|
22
|
-
# a copy of this software and associated documentation files (the
|
23
|
-
# "Software"), to deal in the Software without restriction, including
|
24
|
-
# without limitation the rights to use, copy, modify, merge, publish,
|
25
|
-
# distribute, sublicense, and/or sell copies of the Software, and to
|
26
|
-
# permit persons to whom the Software is furnished to do so, subject to
|
27
|
-
# the following conditions:
|
28
|
-
#
|
29
|
-
# The above copyright notice and this permission notice shall be
|
30
|
-
# included in all copies or substantial portions of the Software.
|
31
|
-
#
|
32
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
33
|
-
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
34
|
-
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
35
|
-
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
36
|
-
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
37
|
-
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
38
|
-
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
39
|
-
|
40
16
|
module ActiveGroonga
|
41
|
-
class Migration
|
42
|
-
|
43
|
-
undef_method :connection
|
44
|
-
|
45
|
-
def method_missing(method, *arguments, &block)
|
46
|
-
arg_list = arguments.map(&:inspect) * ', '
|
47
|
-
|
48
|
-
say_with_time "#{method}(#{arg_list})" do
|
49
|
-
unless arguments.empty? || method == :execute
|
50
|
-
arguments[0] = Migrator.proper_table_name(arguments.first)
|
51
|
-
end
|
52
|
-
Schema.send(method, *arguments, &block)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
class Migrator < ActiveRecord::Migrator
|
17
|
+
class Migration
|
18
|
+
@@migrations = []
|
59
19
|
class << self
|
60
|
-
def
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
def groonga_schema_migrations_table_name
|
65
|
-
Base.groonga_metadata_table_name(schema_migrations_table_name)
|
20
|
+
def inherited(sub_class)
|
21
|
+
super
|
22
|
+
@@migrations << sub_class
|
66
23
|
end
|
67
24
|
|
68
|
-
def
|
69
|
-
|
70
|
-
table.records.collect {|record| record.key.to_i}.sort
|
25
|
+
def migrations
|
26
|
+
@@migrations
|
71
27
|
end
|
72
28
|
|
73
|
-
def
|
74
|
-
|
75
|
-
if table.nil?
|
76
|
-
0
|
77
|
-
else
|
78
|
-
get_all_versions.max || 0
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
def proper_table_name(name)
|
83
|
-
begin
|
84
|
-
name.table_name
|
85
|
-
rescue
|
86
|
-
"#{Base.table_name_prefix}#{name}#{Base.table_name_suffix}"
|
87
|
-
end
|
29
|
+
def migration_name
|
30
|
+
name.split(/::/).last
|
88
31
|
end
|
89
32
|
end
|
90
33
|
|
91
|
-
|
92
|
-
|
93
|
-
@
|
94
|
-
|
34
|
+
attr_reader :version, :path
|
35
|
+
def initialize(version, path, schema)
|
36
|
+
@version = version
|
37
|
+
@path = path
|
38
|
+
@schema = schema
|
95
39
|
end
|
96
40
|
|
97
|
-
def
|
98
|
-
|
99
|
-
|
41
|
+
def name
|
42
|
+
self.class.migration_name
|
43
|
+
end
|
100
44
|
|
101
|
-
|
102
|
-
|
45
|
+
def migrate(direction)
|
46
|
+
result = nil
|
47
|
+
case direction
|
48
|
+
when :up
|
49
|
+
report("migrating")
|
50
|
+
when :down
|
51
|
+
report("reverting")
|
103
52
|
end
|
104
|
-
|
105
|
-
|
106
|
-
finish = migrations.index(target) || migrations.size - 1
|
107
|
-
runnable = migrations[start..finish]
|
108
|
-
|
109
|
-
# skip the last migration if we're headed down, but not ALL the way down
|
110
|
-
runnable.pop if down? && !target.nil?
|
111
|
-
|
112
|
-
runnable.each do |migration|
|
113
|
-
Base.logger.info "Migrating to #{migration.name} (#{migration.version})"
|
114
|
-
|
115
|
-
# On our way up, we skip migrating the ones we've already migrated
|
116
|
-
next if up? && migrated.include?(migration.version.to_i)
|
117
|
-
|
118
|
-
# On our way down, we skip reverting the ones we've never migrated
|
119
|
-
if down? && !migrated.include?(migration.version.to_i)
|
120
|
-
migration.announce 'never migrated, skipping'; migration.write
|
121
|
-
next
|
122
|
-
end
|
123
|
-
|
124
|
-
begin
|
125
|
-
migration.migrate(@direction)
|
126
|
-
record_version_state_after_migrating(migration.version)
|
127
|
-
rescue => e
|
128
|
-
raise StandardError, "An error has occurred, all later migrations canceled:\n\n#{e}", e.backtrace
|
129
|
-
end
|
53
|
+
time = Benchmark.measure do
|
54
|
+
result = send(direction)
|
130
55
|
end
|
56
|
+
case direction
|
57
|
+
when :up
|
58
|
+
report("migrated (%.4fs)" % time.real)
|
59
|
+
when :down
|
60
|
+
report("reverted (%.4fs)" % time.real)
|
61
|
+
end
|
62
|
+
result
|
131
63
|
end
|
132
64
|
|
133
65
|
private
|
134
|
-
def
|
135
|
-
|
136
|
-
|
66
|
+
def report(message)
|
67
|
+
relative_path = @path.relative_path_from(Rails.root)
|
68
|
+
text = "#{@version} #{name} (#{relative_path}): #{message}"
|
69
|
+
rest_length = [0, 75 - text.length].max
|
70
|
+
puts("== #{text} #{'=' * rest_length}")
|
71
|
+
end
|
137
72
|
|
138
|
-
|
139
|
-
if
|
140
|
-
@
|
141
|
-
table.records.each do |record|
|
142
|
-
record.delete if record.key == version.to_s
|
143
|
-
end
|
73
|
+
def method_missing(name, *args, &block)
|
74
|
+
if @schema.respond_to?(name)
|
75
|
+
@schema.send(name, *args, &block)
|
144
76
|
else
|
145
|
-
|
146
|
-
table.add(version.to_s)
|
77
|
+
super
|
147
78
|
end
|
148
79
|
end
|
149
80
|
end
|
@@ -0,0 +1,172 @@
|
|
1
|
+
# Copyright (C) 2009-2010 Kouhei Sutou <kou@clear-code.com>
|
2
|
+
#
|
3
|
+
# This library is free software; you can redistribute it and/or
|
4
|
+
# modify it under the terms of the GNU Lesser General Public
|
5
|
+
# License version 2.1 as published by the Free Software Foundation.
|
6
|
+
#
|
7
|
+
# This library is distributed in the hope that it will be useful,
|
8
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
9
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
10
|
+
# Lesser General Public License for more details.
|
11
|
+
#
|
12
|
+
# You should have received a copy of the GNU Lesser General Public
|
13
|
+
# License along with this library; if not, write to the Free Software
|
14
|
+
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
15
|
+
|
16
|
+
module ActiveGroonga
|
17
|
+
class DuplicateMigrationVersionError < Error #:nodoc:
|
18
|
+
attr_reader :version, :path
|
19
|
+
def initialize(version, path)
|
20
|
+
@version = version
|
21
|
+
@path = path
|
22
|
+
super("duplicated migration version exists: #{version}: <#{@path}>")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class MigrationEntry
|
27
|
+
attr_reader :version, :path
|
28
|
+
def initialize(migration, version, path)
|
29
|
+
@migration = migration
|
30
|
+
@version = version
|
31
|
+
@path = path
|
32
|
+
end
|
33
|
+
|
34
|
+
def name
|
35
|
+
@migration.migration_name
|
36
|
+
end
|
37
|
+
|
38
|
+
def migrate(direction, schema)
|
39
|
+
migration = @migration.new(@version, @path, schema)
|
40
|
+
migration.migrate(direction)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class SchemaManagementTable
|
45
|
+
TABLE_NAME = "schema_migrations"
|
46
|
+
|
47
|
+
def initialize
|
48
|
+
ensure_table
|
49
|
+
@table = Base.context[TABLE_NAME]
|
50
|
+
end
|
51
|
+
|
52
|
+
def current_version
|
53
|
+
@current_version ||= (migrated_versions.last || [0]).first
|
54
|
+
end
|
55
|
+
|
56
|
+
def migrated_versions
|
57
|
+
@migrated_versions ||= @table.collect do |record|
|
58
|
+
[record.key, record.migrated_at]
|
59
|
+
end.sort_by do |version, migrated_at|
|
60
|
+
version
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def update_version(version)
|
65
|
+
@table.add(version, :migrated_at => Time.now)
|
66
|
+
clear_cache
|
67
|
+
end
|
68
|
+
|
69
|
+
def remove_version(version)
|
70
|
+
@table[version].delete
|
71
|
+
clear_cache
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
def ensure_table
|
76
|
+
Schema.define do |schema|
|
77
|
+
schema.create_table(TABLE_NAME,
|
78
|
+
:type => :hash,
|
79
|
+
:key_type => "UInt64") do |table|
|
80
|
+
table.time("migrated_at")
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def clear_cache
|
86
|
+
@current_version = nil
|
87
|
+
@migrated_versions = nil
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
class Migrator
|
92
|
+
def initialize(direction, migrations_path)
|
93
|
+
@direction = direction
|
94
|
+
@migrations_path = migrations_path
|
95
|
+
unless @migrations_path.is_a?(Pathname)
|
96
|
+
@migrations_path = Pathanme(@migrations_path)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def migrate(target_version=nil)
|
101
|
+
_current_version = current_version
|
102
|
+
migration_entries.each do |entry|
|
103
|
+
if up?
|
104
|
+
next if entry.version <= _current_version
|
105
|
+
else
|
106
|
+
next if entry.version > _current_version
|
107
|
+
end
|
108
|
+
Base.logger.info("Migrating to #{entry.name} (#{entry.version})")
|
109
|
+
active_groonga_schema = Schema.new(:context => Base.context)
|
110
|
+
active_groonga_schema.define do |schema|
|
111
|
+
entry.migrate(@direction, schema)
|
112
|
+
end
|
113
|
+
if up?
|
114
|
+
management_table.update_version(entry.version)
|
115
|
+
else
|
116
|
+
management_table.remove_version(entry.version)
|
117
|
+
end
|
118
|
+
break if entry.version == target_version
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def up?
|
123
|
+
@direction == :up
|
124
|
+
end
|
125
|
+
|
126
|
+
def down?
|
127
|
+
@direction == :down
|
128
|
+
end
|
129
|
+
|
130
|
+
def current_version
|
131
|
+
management_table.current_version
|
132
|
+
end
|
133
|
+
|
134
|
+
def migrated_versions
|
135
|
+
management_table.migrated_versions
|
136
|
+
end
|
137
|
+
|
138
|
+
def management_table
|
139
|
+
@management_table ||= SchemaManagementTable.new
|
140
|
+
end
|
141
|
+
|
142
|
+
private
|
143
|
+
def migration_entries
|
144
|
+
@migration_entries ||= collect_migration_entries
|
145
|
+
end
|
146
|
+
|
147
|
+
def collect_migration_entries
|
148
|
+
migration_entries = []
|
149
|
+
Pathname.glob(@migrations_path + "[0-9]*_[a-z]*.rb").each do |path|
|
150
|
+
if /\A([0-9]+)_([_a-z0-9]+)\.rb\z/ =~ path.basename.to_s
|
151
|
+
version = $1.to_i
|
152
|
+
else
|
153
|
+
next
|
154
|
+
end
|
155
|
+
|
156
|
+
if migration_entries.find {|entry| entry.version == version}
|
157
|
+
raise DuplicateMigrationVersionError.new(version, path)
|
158
|
+
end
|
159
|
+
|
160
|
+
migrations_before = Migration.migrations.dup
|
161
|
+
load(path, true)
|
162
|
+
defined_migrations = Migration.migrations - migrations_before
|
163
|
+
defined_migrations.each do |migration|
|
164
|
+
migration_entries << MigrationEntry.new(migration, version, path)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
migration_entries = migration_entries.sort_by(&:version)
|
169
|
+
down? ? migration_entries.reverse : migration_entries
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|