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.
- 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
|
@@ -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
|
-
|
|
19
|
+
class Schema
|
|
18
20
|
class << self
|
|
19
|
-
def define(
|
|
20
|
-
|
|
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
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
end
|
|
82
|
-
end
|
|
44
|
+
def define(&block)
|
|
45
|
+
yield(@schema)
|
|
46
|
+
@schema.define
|
|
47
|
+
update_version if @version
|
|
48
|
+
end
|
|
83
49
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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
|
-
|
|
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
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
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
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
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
|
-
|
|
212
|
-
|
|
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)
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|