activegroonga 0.0.7 → 1.0.0

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.
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
@@ -0,0 +1,89 @@
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
+ module ActiveGroonga
17
+ class ResultSet
18
+ include Enumerable
19
+
20
+ attr_reader :records, :expression, :n_records
21
+ def initialize(records, klass, options={})
22
+ @records = records
23
+ @klass = klass
24
+ @groups = {}
25
+ @expression = options[:expression]
26
+ if @expression.nil? and @records.respond_to?(:expression)
27
+ @expression = @records.expression
28
+ end
29
+ @n_records = options[:n_records] || @records.size
30
+ compute_n_key_nested
31
+ end
32
+
33
+ def paginate(sort_keys, options={})
34
+ records = @records.paginate(sort_keys, options)
35
+ set = self.class.new(records, @klass,
36
+ :expression => @expression)
37
+ set.extend(PaginationProxy)
38
+ set
39
+ end
40
+
41
+ def sort(keys, options={})
42
+ self.class.new(@records.sort(keys, options), @klass,
43
+ :expression => @expression)
44
+ end
45
+
46
+ def group(key)
47
+ @groups[key] ||= @records.group(key)
48
+ end
49
+
50
+ def each
51
+ @records.each do |record|
52
+ object = instantiate(record)
53
+ next if object.nil?
54
+ yield(object)
55
+ end
56
+ end
57
+
58
+ private
59
+ def instantiate(record)
60
+ @n_key_nested.times do
61
+ return nil if record.nil?
62
+ record = record.key
63
+ end
64
+ return nil if record.nil?
65
+ while record.key.is_a?(Groonga::Record)
66
+ record = record.key
67
+ end
68
+ @klass.instantiate(record)
69
+ end
70
+
71
+ def compute_n_key_nested
72
+ @n_key_nested = 0
73
+ return unless @records.respond_to?(:domain)
74
+ domain = @records.domain
75
+ while domain.is_a?(Groonga::Table)
76
+ @n_key_nested += 1
77
+ domain = domain.domain
78
+ end
79
+ end
80
+
81
+ module PaginationProxy
82
+ Groonga::Pagination.instance_methods.each do |method_name|
83
+ define_method(method_name) do
84
+ @records.send(method_name)
85
+ end
86
+ end
87
+ end
88
+ end
89
+ 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,209 +13,75 @@
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
+ require 'active_groonga/migrator'
17
+
16
18
  module ActiveGroonga
17
- module Schema
19
+ class Schema
18
20
  class << self
19
- def define(info={}, &block)
20
- initialize_schema_management_tables
21
- instance_eval(&block)
22
-
23
- unless info[:version].blank?
24
- assume_migrated_upto_version(info[:version])
25
- end
21
+ def define(options={}, &block)
22
+ new(options).define(&block)
26
23
  end
27
24
 
28
- def assume_migrated_upto_version(version)
29
- version = version.to_i
30
- table_name = Migrator.groonga_schema_migrations_table_name
31
-
32
- migrations_table = Base.context[table_name]
33
- migrated = migrations_table.records.collect do |record|
34
- record["version"].to_i
35
- end
36
- versions = Dir['db/migrate/[0-9]*_*.rb'].map do |filename|
37
- filename.split('/').last.split('_').first.to_i
38
- end
39
-
40
- unless migrated.include?(version)
41
- migrations_table.add(version.to_s)
42
- end
43
-
44
- inserted = Set.new
45
- (versions - migrated).each do |v|
46
- if inserted.include?(v)
47
- raise "Duplicate migration #{v}. Please renumber your migrations to resolve the conflict."
48
- elsif v < version
49
- migration = migrations_table.add(v.to_s)
50
- inserted << v
51
- end
52
- end
53
- end
54
-
55
- def initialize_schema_management_tables
56
- initialize_migrations_table
57
- end
58
-
59
- def create_table(name, options={}, &block)
60
- table_file = File.join(Base.tables_directory, "#{name}.groonga")
61
- table_name = Base.groonga_table_name(name)
62
- options = {:path => table_file}.merge(options)
63
- options = default_table_options(options).merge(options)
64
- options = options.merge(:context => Base.context)
65
- Groonga::Schema.create_table(table_name, options) do |table|
66
- block.call(TableDefinitionWrapper.new(table))
25
+ def dump(options={})
26
+ options ||= {}
27
+ if options.is_a?(Hash)
28
+ options = options.dup
29
+ output = options.delete(:output)
30
+ else
31
+ output, options = options, {}
67
32
  end
33
+ new(options).dump(output)
68
34
  end
35
+ end
69
36
 
70
- def remove_table(name, options={})
71
- options = options.merge(:context => Base.context)
72
- Groonga::Schema.remove_table(name, options)
73
- end
74
- alias_method :drop_table, :remove_table
37
+ def initialize(options={})
38
+ @options = (options || {}).dup
39
+ @version = @options.delete(:version)
40
+ context = @options.delete(:context) || Base.context
41
+ @schema = Groonga::Schema.new(:context => context)
42
+ end
75
43
 
76
- def add_column(table_name, column_name, type, options={})
77
- options_with_context = options.merge(:context => Base.context)
78
- Groonga::Schema.change_table(table_name, options_with_context) do |table|
79
- table = TableDefinitionWrapper.new(table)
80
- table.column(column_name, type, options)
81
- end
82
- end
44
+ def define(&block)
45
+ yield(@schema)
46
+ @schema.define
47
+ update_version if @version
48
+ end
83
49
 
84
- def remove_column(table_name, *column_names)
85
- if column_names.last.is_a?(Hash)
86
- options = columns.pop
50
+ def dump(output=nil)
51
+ dumped_schema = @schema.dump
52
+ return nil if dumped_schema.nil?
53
+
54
+ return_string = false
55
+ if output.nil?
56
+ output = StringIO.new
57
+ return_string = true
58
+ end
59
+ version = @version || management_table.current_version
60
+ output << "ActiveGroonga::Schema.define(:version => #{version}) do |schema|\n"
61
+ output << " schema.instance_eval do\n"
62
+ dumped_schema.each_line do |line|
63
+ if /^\s*$/ =~ line
64
+ output << line
87
65
  else
88
- options = {}
89
- end
90
- options_with_context = options.merge(:context => Base.context)
91
- Groonga::Schema.change_table(table_name, options_with_context) do |table|
92
- column_names.each do |column_name|
93
- table.remove_column(column_name)
94
- end
66
+ output << " #{line}"
95
67
  end
96
68
  end
97
-
98
- def add_index_column(table_name, target_table_name, target_column_name,
99
- options={})
100
- options_for_table = options.reject {|key, value| key == :name}
101
- options_for_table = options_for_table.merge(:context => Base.context)
102
- Groonga::Schema.change_table(table_name, options_for_table) do |table|
103
- table = TableDefinitionWrapper.new(table)
104
- table.index(target_table_name, target_column_name, options)
105
- end
106
- end
107
-
108
- private
109
- def initialize_migrations_table
110
- table_name = Migrator.schema_migrations_table_name
111
- groonga_table_name = Migrator.groonga_schema_migrations_table_name
112
- if Base.context[groonga_table_name].nil?
113
- table_file = File.join(Base.metadata_directory,
114
- "#{table_name}.groonga")
115
- Groonga::Hash.create(:name => groonga_table_name,
116
- :path => table_file,
117
- :key_type => "ShortText")
118
- end
119
- end
120
-
121
- def default_table_options(options)
122
- default_options = {:sub_records => true}
123
- case options[:type]
124
- when :hash, :patricia_trie
125
- default_options[:default_tokenizer] = "TokenBigram"
126
- end
127
- default_options
69
+ output << " end\n"
70
+ output << "end\n"
71
+ if return_string
72
+ output.string
73
+ else
74
+ output
128
75
  end
129
76
  end
130
77
 
131
- class TableDefinitionWrapper
132
- def initialize(definition)
133
- @definition = definition
134
- end
135
-
136
- def column(name, type, options={})
137
- column_file = File.join(Base.columns_directory(@definition.name),
138
- "#{name}.groonga")
139
- options = {:path => column_file}.merge(options)
140
- @definition.column(name, type, options)
141
- end
142
-
143
- def remove_column(name, options={})
144
- @definition.remove_column(name, options)
145
- end
146
- alias_method :remove_index, :remove_column
147
-
148
- def index(target_table_name, target_column_name, options={})
149
- column_name = options.delete(:name)
150
- column_name ||= [target_table_name, target_column_name].join("_")
151
- column_dir = Base.index_columns_directory(@definition.name,
152
- target_table_name.to_s)
153
- column_file = File.join(column_dir, "#{column_name}.groonga")
154
- options = {
155
- :with_position => true,
156
- :path => column_file,
157
- :name => column_name,
158
- }.merge(options)
159
- target_table = @definition.context[target_table_name]
160
- target_column = target_table.column(target_column_name)
161
- @definition.index(target_column, options)
162
- end
163
-
164
- def timestamps(*args)
165
- options = args.extract_options!
166
- column(:created_at, :datetime, options)
167
- column(:updated_at, :datetime, options)
168
- end
169
-
170
- def string(*args)
171
- columns("ShortText", *args)
172
- end
173
-
174
- def text(*args)
175
- columns("Text", *args)
176
- end
177
-
178
- def integer(*args)
179
- columns("Int32", *args)
180
- end
181
-
182
- def float(*args)
183
- columns("Float", *args)
184
- end
185
-
186
- def decimal(*args)
187
- columns("Int64", *args)
188
- end
189
-
190
- def time(*args)
191
- columns("Time", *args)
192
- end
193
- alias_method :datetime, :time
194
- alias_method :timestamp, :time
195
-
196
- def binary(*args)
197
- columns("LongText", *args)
198
- end
199
-
200
- def boolean(*args)
201
- columns("Bool", *args)
202
- end
203
-
204
- def reference(name, table=nil, options={})
205
- table = Base.groonga_table_name(table || name.to_s.pluralize)
206
- column(name, table, options)
207
- end
208
- alias_method :references, :reference
209
- alias_method :belongs_to, :references
78
+ private
79
+ def management_table
80
+ @management_table ||= SchemaManagementTable.new
81
+ end
210
82
 
211
- private
212
- def columns(type, *args)
213
- options = args.extract_options!
214
- column_names = args
215
- column_names.each do |name|
216
- column(name, type, options)
217
- end
218
- end
83
+ def update_version
84
+ management_table.update_version(@version)
219
85
  end
220
86
  end
221
87
  end
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2009 Kouhei Sutou <kou@clear-code.com>
1
+ # Copyright (C) 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,13 +14,62 @@
14
14
  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
15
 
16
16
  module ActiveGroonga
17
+ class RecordInvalid < Error
18
+ attr_reader :record
19
+ def initialize(record)
20
+ @record = record
21
+ errors = @record.errors.full_messages.join(", ")
22
+ super(I18n.t("activegroonga.errors.messages.record_invalid",
23
+ :errors => errors))
24
+ end
25
+ end
26
+
17
27
  module Validations
18
- class << self
19
- def included(base)
20
- base.class_eval do
21
- include ActiveRecord::Validations
28
+ extend ActiveSupport::Concern
29
+ include ActiveModel::Validations
30
+
31
+ included do
32
+ validates_presence_of(:key,
33
+ :on => :create,
34
+ :if => lambda {|record| record.table.support_key?})
35
+ end
36
+
37
+ module ClassMethods
38
+ def create!(attributes=nil, &block)
39
+ if attributes.is_a?(Array)
40
+ attributes.collect do |nested_attributes|
41
+ create!(nested_attributes, &block)
42
+ end
43
+ else
44
+ object = new(attributes)
45
+ yield(object) if block_given?
46
+ object.save!
47
+ object
22
48
  end
23
49
  end
24
50
  end
51
+
52
+ def save(options={})
53
+ validate(options) ? super : false
54
+ end
55
+
56
+ def save!(options={})
57
+ validate(options) ? super : raise(RecordInvalid.new(self))
58
+ end
59
+
60
+ def valid?(context=nil)
61
+ context ||= (new_record? ? :create : :update)
62
+ valid = super(context)
63
+ errors.empty? and valid
64
+ end
65
+
66
+ private
67
+ def validate(options={})
68
+ if options[:validate] == false
69
+ true
70
+ else
71
+ valid?(options[:context])
72
+ end
73
+ end
25
74
  end
26
75
  end
@@ -0,0 +1,64 @@
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
+ module ActiveGroonga
17
+ class Vector
18
+ include Enumerable
19
+
20
+ attr_reader :owner, :klass, :values
21
+ def initialize(owner, klass, values=[])
22
+ @owner = owner
23
+ @klass = klass
24
+ @values = values
25
+ @values = [@values] unless @values.is_a?(Array)
26
+ end
27
+
28
+ def build(*args, &block)
29
+ @klass.new(*args, &block)
30
+ end
31
+
32
+ def create(*args, &block)
33
+ @klass.create(*args, &block)
34
+ end
35
+
36
+ def create!(*args, &block)
37
+ @klass.create!(*args, &block)
38
+ end
39
+
40
+ def each
41
+ @values.each do |value|
42
+ yield(instantiate(value))
43
+ end
44
+ end
45
+
46
+ def <<(value)
47
+ value = @klass.create(value) if @owner.persisted?
48
+ @values << value
49
+ end
50
+
51
+ def to_ary
52
+ to_a
53
+ end
54
+
55
+ private
56
+ def instantiate(value)
57
+ if value.is_a?(@klass)
58
+ value
59
+ else
60
+ @klass.instantiate(value)
61
+ end
62
+ end
63
+ end
64
+ end