activegroonga 0.0.7 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. data/README.ja.rdoc +4 -1
  2. data/README.rdoc +4 -1
  3. data/Rakefile +18 -4
  4. data/lib/active_groonga.rb +25 -52
  5. data/lib/active_groonga/base.rb +164 -1480
  6. data/lib/active_groonga/callbacks.rb +26 -7
  7. data/lib/active_groonga/database.rb +55 -0
  8. data/lib/active_groonga/{dirty.rb → error.rb} +20 -10
  9. data/lib/active_groonga/locale/en.yml +5 -0
  10. data/lib/active_groonga/migration.rb +44 -113
  11. data/lib/active_groonga/migrator.rb +172 -0
  12. data/lib/active_groonga/persistence.rb +172 -0
  13. data/lib/active_groonga/railtie.rb +66 -0
  14. data/lib/active_groonga/railties/configurable.rb +47 -0
  15. data/lib/active_groonga/railties/groonga.rake +167 -0
  16. data/lib/active_groonga/result_set.rb +89 -0
  17. data/lib/active_groonga/schema.rb +54 -188
  18. data/lib/active_groonga/validations.rb +54 -5
  19. data/lib/active_groonga/vector.rb +64 -0
  20. data/lib/active_groonga/version.rb +3 -3
  21. data/lib/{active_groonga/aggregations.rb → rails/generators/active_groonga.rb} +17 -10
  22. data/lib/rails/generators/active_groonga/migration/column.rb +101 -0
  23. data/lib/rails/generators/active_groonga/migration/migration_generator.rb +53 -0
  24. data/lib/rails/generators/active_groonga/migration/templates/migration.rb +29 -0
  25. data/lib/rails/generators/active_groonga/model/model_generator.rb +60 -0
  26. data/lib/rails/generators/active_groonga/model/templates/migration.rb +16 -0
  27. data/lib/rails/generators/active_groonga/model/templates/model.rb +2 -0
  28. data/lib/rails/generators/active_groonga/model/templates/module.rb +5 -0
  29. data/test-unit-notify/COPYING +502 -0
  30. data/test-unit-notify/Rakefile +47 -0
  31. data/test-unit-notify/lib/test/unit/notify.rb +127 -0
  32. data/test-unit/COPYING +56 -0
  33. data/test-unit/GPL +340 -0
  34. data/test-unit/PSFL +271 -0
  35. data/test-unit/Rakefile +18 -5
  36. data/test-unit/html/bar.svg +153 -0
  37. data/test-unit/html/developer.svg +469 -0
  38. data/test-unit/html/favicon.ico +0 -0
  39. data/test-unit/html/favicon.svg +82 -0
  40. data/test-unit/html/heading-mark.svg +393 -0
  41. data/test-unit/html/index.html +235 -13
  42. data/test-unit/html/index.html.ja +258 -15
  43. data/test-unit/html/install.svg +636 -0
  44. data/test-unit/html/logo.svg +483 -0
  45. data/test-unit/html/test-unit.css +339 -0
  46. data/test-unit/html/tutorial.svg +559 -0
  47. data/test-unit/lib/test/unit.rb +29 -43
  48. data/test-unit/lib/test/unit/assertionfailederror.rb +11 -0
  49. data/test-unit/lib/test/unit/assertions.rb +202 -20
  50. data/test-unit/lib/test/unit/autorunner.rb +51 -20
  51. data/test-unit/lib/test/unit/collector.rb +1 -8
  52. data/test-unit/lib/test/unit/collector/dir.rb +1 -1
  53. data/test-unit/lib/test/unit/collector/load.rb +16 -9
  54. data/test-unit/lib/test/unit/color-scheme.rb +19 -3
  55. data/test-unit/lib/test/unit/diff.rb +240 -38
  56. data/test-unit/lib/test/unit/error.rb +4 -0
  57. data/test-unit/lib/test/unit/failure.rb +31 -5
  58. data/test-unit/lib/test/unit/notification.rb +8 -4
  59. data/test-unit/lib/test/unit/omission.rb +51 -3
  60. data/test-unit/lib/test/unit/pending.rb +4 -0
  61. data/test-unit/lib/test/unit/priority.rb +2 -3
  62. data/test-unit/lib/test/unit/testcase.rb +65 -7
  63. data/test-unit/lib/test/unit/testresult.rb +34 -2
  64. data/test-unit/lib/test/unit/ui/console/testrunner.rb +197 -45
  65. data/test-unit/lib/test/unit/ui/emacs/testrunner.rb +14 -0
  66. data/test-unit/lib/test/unit/ui/tap/testrunner.rb +2 -12
  67. data/test-unit/lib/test/unit/ui/testrunner.rb +33 -0
  68. data/test-unit/lib/test/unit/util/backtracefilter.rb +1 -0
  69. data/test-unit/lib/test/unit/util/output.rb +31 -0
  70. data/test-unit/lib/test/unit/version.rb +1 -1
  71. data/test-unit/sample/{tc_adder.rb → test_adder.rb} +3 -1
  72. data/test-unit/sample/{tc_subtracter.rb → test_subtracter.rb} +3 -1
  73. data/test-unit/sample/test_user.rb +1 -0
  74. data/test-unit/test/collector/test-descendant.rb +2 -4
  75. data/test-unit/test/collector/test-load.rb +121 -8
  76. data/test-unit/test/collector/test_objectspace.rb +7 -5
  77. data/test-unit/test/run-test.rb +2 -0
  78. data/test-unit/test/test-color-scheme.rb +11 -2
  79. data/test-unit/test/test-diff.rb +48 -7
  80. data/test-unit/test/test-omission.rb +1 -1
  81. data/test-unit/test/test-testcase.rb +57 -20
  82. data/test-unit/test/test_assertions.rb +128 -13
  83. data/test-unit/test/ui/test_tap.rb +33 -0
  84. data/test-unit/test/util/test-output.rb +11 -0
  85. data/test/active-groonga-test-utils.rb +50 -36
  86. data/test/fixtures/site.rb +2 -0
  87. data/test/run-test.rb +36 -9
  88. data/test/test-associations.rb +5 -2
  89. data/test/test-base.rb +39 -31
  90. data/test/test-callbacks.rb +13 -3
  91. data/test/test-persistence.rb +53 -0
  92. data/{lib/active_groonga/observer.rb → test/test-result-set.rb} +14 -12
  93. data/test/test-schema.rb +85 -22
  94. data/{lib/active_groonga/rails_support.rb → test/test-validations.rb} +15 -13
  95. metadata +85 -52
  96. data/lib/active_groonga/associations.rb +0 -93
  97. data/lib/active_groonga/associations/belongs_to_association.rb +0 -25
  98. data/lib/active_groonga/attribute_methods.rb +0 -36
  99. data/lib/active_groonga/column.rb +0 -137
  100. data/lib/active_groonga/dynamic_record_expression_builder.rb +0 -40
  101. data/lib/active_groonga/reflection.rb +0 -30
  102. data/lib/active_groonga/schema_dumper.rb +0 -163
  103. data/lib/active_groonga/tasks.rb +0 -16
  104. data/lib/active_groonga/tasks/groonga.rake +0 -164
  105. data/lib/active_groonga/timestamp.rb +0 -30
  106. data/rails/README +0 -28
  107. data/rails/init.rb +0 -70
  108. data/rails_generators/index_table_groonga/USAGE +0 -23
  109. data/rails_generators/index_table_groonga/index_table_groonga_generator.rb +0 -44
  110. data/rails_generators/index_table_groonga/templates/migration.rb +0 -12
  111. data/rails_generators/migration_groonga/USAGE +0 -29
  112. data/rails_generators/migration_groonga/migration_groonga_generator.rb +0 -19
  113. data/rails_generators/migration_groonga/templates/migration.rb +0 -11
  114. data/rails_generators/model_groonga/USAGE +0 -28
  115. data/rails_generators/model_groonga/model_groonga_generator.rb +0 -45
  116. data/rails_generators/model_groonga/templates/fixtures.yml +0 -17
  117. data/rails_generators/model_groonga/templates/migration.rb +0 -16
  118. data/rails_generators/model_groonga/templates/model.rb +0 -2
  119. data/rails_generators/model_groonga/templates/unit_test.rb +0 -8
  120. data/test-unit/html/classic.html +0 -15
  121. data/test-unit/sample/ts_examples.rb +0 -7
  122. 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
- class << self
19
- def included(base)
20
- base.class_eval do
21
- include ActiveRecord::Callbacks
22
- end
23
- end
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
- module Dirty
18
- class << self
19
- def included(base)
20
- base.class_eval do
21
- include(ActiveRecord::Dirty)
22
- extend(ClassMethods)
23
- end
24
- end
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
- module ClassMethods
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
@@ -0,0 +1,5 @@
1
+ en:
2
+ activegroonga:
3
+ errors:
4
+ messages:
5
+ missing: is missing
@@ -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 < ActiveRecord::Migration
42
- class << self
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 schema_migrations_table_name
61
- Base.table_name_prefix + 'schema_migrations' + Base.table_name_suffix
62
- end
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 get_all_versions
69
- table = Base.context[groonga_schema_migrations_table_name]
70
- table.records.collect {|record| record.key.to_i}.sort
25
+ def migrations
26
+ @@migrations
71
27
  end
72
28
 
73
- def current_version
74
- table = Base.context[groonga_schema_migrations_table_name]
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
- def initialize(direction, migrations_path, target_version = nil)
92
- Schema.initialize_schema_management_tables
93
- @direction, @migrations_path, @target_version = direction, migrations_path, target_version
94
- FileUtils.mkdir_p(@migrations_path) unless File.exist?(@migrations_path)
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 migrate
98
- current = migrations.detect { |m| m.version == current_version }
99
- target = migrations.detect { |m| m.version == @target_version }
41
+ def name
42
+ self.class.migration_name
43
+ end
100
44
 
101
- if target.nil? && !@target_version.nil? && @target_version > 0
102
- raise UnknownMigrationVersionError.new(@target_version)
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
- start = up? ? 0 : (migrations.index(current) || 0)
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 record_version_state_after_migrating(version)
135
- table_name = self.class.groonga_schema_migrations_table_name
136
- table = Base.context[table_name]
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
- @migrated_versions ||= []
139
- if down?
140
- @migrated_versions.delete(version.to_i)
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
- @migrated_versions.push(version.to_i).sort!
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