freelancing-god-thinking-sphinx 1.1.18 → 1.1.19
Sign up to get free protection for your applications and to get access to all the features.
- data/README.textile +1 -0
- data/lib/thinking_sphinx.rb +1 -1
- data/lib/thinking_sphinx/association.rb +4 -1
- data/lib/thinking_sphinx/attribute.rb +1 -1
- data/lib/thinking_sphinx/configuration.rb +5 -0
- data/lib/thinking_sphinx/index.rb +2 -1
- data/lib/thinking_sphinx/source/sql.rb +7 -5
- data/spec/unit/thinking_sphinx/attribute_spec.rb +106 -0
- data/spec/unit/thinking_sphinx/configuration_spec.rb +19 -0
- data/spec/unit/thinking_sphinx/index_spec.rb +0 -94
- data/spec/unit/thinking_sphinx/source_spec.rb +52 -0
- metadata +2 -2
data/README.textile
CHANGED
data/lib/thinking_sphinx.rb
CHANGED
@@ -103,13 +103,16 @@ module ThinkingSphinx
|
|
103
103
|
if @reflection.options[:through]
|
104
104
|
@reflection.source_reflection.options[:foreign_key] ||
|
105
105
|
@reflection.source_reflection.primary_key_name
|
106
|
+
elsif @reflection.macro == :has_and_belongs_to_many
|
107
|
+
@reflection.association_foreign_key
|
106
108
|
else
|
107
109
|
nil
|
108
110
|
end
|
109
111
|
end
|
110
112
|
|
111
113
|
def table
|
112
|
-
if @reflection.options[:through]
|
114
|
+
if @reflection.options[:through] ||
|
115
|
+
@reflection.macro == :has_and_belongs_to_many
|
113
116
|
@join.aliased_join_table_name
|
114
117
|
else
|
115
118
|
@join.aliased_table_name
|
@@ -127,7 +127,7 @@ module ThinkingSphinx
|
|
127
127
|
def config_value(offset = nil)
|
128
128
|
if type == :multi
|
129
129
|
multi_config = include_as_association? ? "field" :
|
130
|
-
source_value(offset).gsub(/\n\s*/, " ")
|
130
|
+
source_value(offset).gsub(/\n\s*/, " ").strip
|
131
131
|
"uint #{unique_name} from #{multi_config}"
|
132
132
|
else
|
133
133
|
unique_name
|
@@ -54,6 +54,8 @@ module ThinkingSphinx
|
|
54
54
|
min_infix_len min_prefix_len min_word_len mlock morphology ngram_chars
|
55
55
|
ngram_len phrase_boundary phrase_boundary_step preopen stopwords
|
56
56
|
wordforms )
|
57
|
+
|
58
|
+
CustomOptions = %w( disable_range )
|
57
59
|
|
58
60
|
attr_accessor :config_file, :searchd_log_file, :query_log_file,
|
59
61
|
:pid_file, :searchd_file_path, :address, :port, :allow_star,
|
@@ -149,6 +151,8 @@ module ThinkingSphinx
|
|
149
151
|
# messy dependencies issues).
|
150
152
|
#
|
151
153
|
def load_models
|
154
|
+
return if defined?(Rails) && Rails.configuration.cache_classes
|
155
|
+
|
152
156
|
self.model_directories.each do |base|
|
153
157
|
Dir["#{base}**/*.rb"].each do |file|
|
154
158
|
model_name = file.gsub(/^#{base}([\w_\/\\]+)\.rb/, '\1')
|
@@ -225,6 +229,7 @@ module ThinkingSphinx
|
|
225
229
|
|
226
230
|
set_sphinx_setting self.source_options, key, value, SourceOptions
|
227
231
|
set_sphinx_setting self.index_options, key, value, IndexOptions
|
232
|
+
set_sphinx_setting self.index_options, key, value, CustomOptions
|
228
233
|
set_sphinx_setting @configuration.searchd, key, value
|
229
234
|
set_sphinx_setting @configuration.indexer, key, value
|
230
235
|
end unless conf.nil?
|
@@ -63,7 +63,8 @@ module ThinkingSphinx
|
|
63
63
|
def options
|
64
64
|
all_index_options = ThinkingSphinx::Configuration.instance.index_options.clone
|
65
65
|
@options.keys.select { |key|
|
66
|
-
ThinkingSphinx::Configuration::IndexOptions.include?(key.to_s)
|
66
|
+
ThinkingSphinx::Configuration::IndexOptions.include?(key.to_s) ||
|
67
|
+
ThinkingSphinx::Configuration::CustomOptions.include?(key.to_s)
|
67
68
|
}.each { |key| all_index_options[key.to_sym] = @options[key] }
|
68
69
|
all_index_options
|
69
70
|
end
|
@@ -17,7 +17,7 @@ module ThinkingSphinx
|
|
17
17
|
SELECT #{ sql_select_clause options[:offset] }
|
18
18
|
FROM #{ @model.quoted_table_name }
|
19
19
|
#{ all_associations.collect { |assoc| assoc.to_sql }.join(' ') }
|
20
|
-
|
20
|
+
#{ sql_where_clause(options) }
|
21
21
|
GROUP BY #{ sql_group_clause }
|
22
22
|
SQL
|
23
23
|
|
@@ -30,6 +30,8 @@ GROUP BY #{ sql_group_clause }
|
|
30
30
|
# so pass in :delta => true to get the delta version of the SQL.
|
31
31
|
#
|
32
32
|
def to_sql_query_range(options={})
|
33
|
+
return nil if @index.options[:disable_range]
|
34
|
+
|
33
35
|
min_statement = adapter.convert_nulls(
|
34
36
|
"MIN(#{quote_column(@model.primary_key)})", 1
|
35
37
|
)
|
@@ -65,18 +67,18 @@ GROUP BY #{ sql_group_clause }
|
|
65
67
|
end
|
66
68
|
|
67
69
|
def sql_where_clause(options)
|
68
|
-
logic = [
|
70
|
+
logic = []
|
71
|
+
logic += [
|
69
72
|
"#{@model.quoted_table_name}.#{quote_column(@model.primary_key)} >= $start",
|
70
73
|
"#{@model.quoted_table_name}.#{quote_column(@model.primary_key)} <= $end"
|
71
|
-
]
|
74
|
+
] unless @index.options[:disable_range]
|
72
75
|
|
73
76
|
if self.delta? && !@index.delta_object.clause(@model, options[:delta]).blank?
|
74
77
|
logic << "#{@index.delta_object.clause(@model, options[:delta])}"
|
75
78
|
end
|
76
79
|
|
77
80
|
logic += (@conditions || [])
|
78
|
-
|
79
|
-
logic.join(" AND ")
|
81
|
+
logic.empty? ? "" : "WHERE #{logic.join(' AND ')}"
|
80
82
|
end
|
81
83
|
|
82
84
|
def sql_group_clause
|
@@ -215,6 +215,112 @@ describe ThinkingSphinx::Attribute do
|
|
215
215
|
end
|
216
216
|
end
|
217
217
|
|
218
|
+
describe "MVA with source query" do
|
219
|
+
before :each do
|
220
|
+
@attribute = ThinkingSphinx::Attribute.new(@source,
|
221
|
+
[ThinkingSphinx::Index::FauxColumn.new(:tags, :id)],
|
222
|
+
:as => :tag_ids, :source => :query
|
223
|
+
)
|
224
|
+
end
|
225
|
+
|
226
|
+
it "should use a query" do
|
227
|
+
@attribute.type_to_config.should == :sql_attr_multi
|
228
|
+
|
229
|
+
declaration, query = @attribute.config_value.split('; ')
|
230
|
+
declaration.should == "uint tag_ids from query"
|
231
|
+
query.should == "SELECT `tags`.`person_id` #{ThinkingSphinx.unique_id_expression} AS `id`, `tags`.`id` AS `tag_ids` FROM `tags`"
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
describe "MVA via a HABTM association with a source query" do
|
236
|
+
before :each do
|
237
|
+
@attribute = ThinkingSphinx::Attribute.new(@source,
|
238
|
+
[ThinkingSphinx::Index::FauxColumn.new(:links, :id)],
|
239
|
+
:as => :link_ids, :source => :query
|
240
|
+
)
|
241
|
+
end
|
242
|
+
|
243
|
+
it "should use a ranged query" do
|
244
|
+
@attribute.type_to_config.should == :sql_attr_multi
|
245
|
+
|
246
|
+
declaration, query = @attribute.config_value.split('; ')
|
247
|
+
declaration.should == "uint link_ids from query"
|
248
|
+
query.should == "SELECT `links_people`.`person_id` #{ThinkingSphinx.unique_id_expression} AS `id`, `links_people`.`link_id` AS `link_ids` FROM `links_people`"
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
describe "MVA with ranged source query" do
|
253
|
+
before :each do
|
254
|
+
@attribute = ThinkingSphinx::Attribute.new(@source,
|
255
|
+
[ThinkingSphinx::Index::FauxColumn.new(:tags, :id)],
|
256
|
+
:as => :tag_ids, :source => :ranged_query
|
257
|
+
)
|
258
|
+
end
|
259
|
+
|
260
|
+
it "should use a ranged query" do
|
261
|
+
@attribute.type_to_config.should == :sql_attr_multi
|
262
|
+
|
263
|
+
declaration, query, range_query = @attribute.config_value.split('; ')
|
264
|
+
declaration.should == "uint tag_ids from ranged-query"
|
265
|
+
query.should == "SELECT `tags`.`person_id` #{ThinkingSphinx.unique_id_expression} AS `id`, `tags`.`id` AS `tag_ids` FROM `tags` WHERE `tags`.`person_id` >= $start AND `tags`.`person_id` <= $end"
|
266
|
+
range_query.should == "SELECT MIN(`tags`.`person_id`), MAX(`tags`.`person_id`) FROM `tags`"
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
describe "MVA via a has-many :through with a ranged source query" do
|
271
|
+
before :each do
|
272
|
+
@attribute = ThinkingSphinx::Attribute.new(@source,
|
273
|
+
[ThinkingSphinx::Index::FauxColumn.new(:football_teams, :id)],
|
274
|
+
:as => :football_team_ids, :source => :ranged_query
|
275
|
+
)
|
276
|
+
end
|
277
|
+
|
278
|
+
it "should use a ranged query" do
|
279
|
+
@attribute.type_to_config.should == :sql_attr_multi
|
280
|
+
|
281
|
+
declaration, query, range_query = @attribute.config_value.split('; ')
|
282
|
+
declaration.should == "uint football_team_ids from ranged-query"
|
283
|
+
query.should == "SELECT `tags`.`person_id` #{ThinkingSphinx.unique_id_expression} AS `id`, `tags`.`football_team_id` AS `football_team_ids` FROM `tags` WHERE `tags`.`person_id` >= $start AND `tags`.`person_id` <= $end"
|
284
|
+
range_query.should == "SELECT MIN(`tags`.`person_id`), MAX(`tags`.`person_id`) FROM `tags`"
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
describe "MVA via a has-many :through using a foreign key with a ranged source query" do
|
289
|
+
before :each do
|
290
|
+
@attribute = ThinkingSphinx::Attribute.new(@source,
|
291
|
+
[ThinkingSphinx::Index::FauxColumn.new(:friends, :id)],
|
292
|
+
:as => :friend_ids, :source => :ranged_query
|
293
|
+
)
|
294
|
+
end
|
295
|
+
|
296
|
+
it "should use a ranged query" do
|
297
|
+
@attribute.type_to_config.should == :sql_attr_multi
|
298
|
+
|
299
|
+
declaration, query, range_query = @attribute.config_value.split('; ')
|
300
|
+
declaration.should == "uint friend_ids from ranged-query"
|
301
|
+
query.should == "SELECT `friendships`.`person_id` #{ThinkingSphinx.unique_id_expression} AS `id`, `friendships`.`friend_id` AS `friend_ids` FROM `friendships` WHERE `friendships`.`person_id` >= $start AND `friendships`.`person_id` <= $end"
|
302
|
+
range_query.should == "SELECT MIN(`friendships`.`person_id`), MAX(`friendships`.`person_id`) FROM `friendships`"
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
describe "MVA via a HABTM with a ranged source query" do
|
307
|
+
before :each do
|
308
|
+
@attribute = ThinkingSphinx::Attribute.new(@source,
|
309
|
+
[ThinkingSphinx::Index::FauxColumn.new(:links, :id)],
|
310
|
+
:as => :link_ids, :source => :ranged_query
|
311
|
+
)
|
312
|
+
end
|
313
|
+
|
314
|
+
it "should use a ranged query" do
|
315
|
+
@attribute.type_to_config.should == :sql_attr_multi
|
316
|
+
|
317
|
+
declaration, query, range_query = @attribute.config_value.split('; ')
|
318
|
+
declaration.should == "uint link_ids from ranged-query"
|
319
|
+
query.should == "SELECT `links_people`.`person_id` #{ThinkingSphinx.unique_id_expression} AS `id`, `links_people`.`link_id` AS `link_ids` FROM `links_people` WHERE `links_people`.`person_id` >= $start AND `links_people`.`person_id` <= $end"
|
320
|
+
range_query.should == "SELECT MIN(`links_people`.`person_id`), MAX(`links_people`.`person_id`) FROM `links_people`"
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
218
324
|
describe "with custom queries" do
|
219
325
|
before :each do
|
220
326
|
index = CricketTeam.sphinx_indexes.first
|
@@ -102,6 +102,25 @@ describe ThinkingSphinx::Configuration do
|
|
102
102
|
end
|
103
103
|
end
|
104
104
|
|
105
|
+
describe "index options" do
|
106
|
+
before :each do
|
107
|
+
@settings = {
|
108
|
+
"development" => {"disable_range" => true}
|
109
|
+
}
|
110
|
+
|
111
|
+
open("#{RAILS_ROOT}/config/sphinx.yml", "w") do |f|
|
112
|
+
f.write YAML.dump(@settings)
|
113
|
+
end
|
114
|
+
|
115
|
+
@config = ThinkingSphinx::Configuration.instance
|
116
|
+
@config.send(:parse_config)
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should collect disable_range" do
|
120
|
+
@config.index_options[:disable_range].should be_true
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
105
124
|
it "should insert set index options into the configuration file" do
|
106
125
|
config = ThinkingSphinx::Configuration.instance
|
107
126
|
ThinkingSphinx::Configuration::IndexOptions.each do |option|
|
@@ -42,98 +42,4 @@ describe ThinkingSphinx::Index do
|
|
42
42
|
@index.infix_fields.should_not include(@field_b)
|
43
43
|
end
|
44
44
|
end
|
45
|
-
|
46
|
-
describe "multi-value attribute as ranged-query with has-many association" do
|
47
|
-
before :each do
|
48
|
-
@index = ThinkingSphinx::Index::Builder.generate(Person) do
|
49
|
-
indexes first_name
|
50
|
-
has tags(:id), :as => :tag_ids, :source => :ranged_query
|
51
|
-
end
|
52
|
-
|
53
|
-
@sql = @index.sources.first.to_riddle_for_core(0, 0).sql_query
|
54
|
-
end
|
55
|
-
|
56
|
-
it "should not include attribute in select-clause sql_query" do
|
57
|
-
@sql.should_not match(/tag_ids/)
|
58
|
-
@sql.should_not match(/GROUP_CONCAT\(`tags`.`id`/)
|
59
|
-
end
|
60
|
-
|
61
|
-
it "should not join with association table" do
|
62
|
-
@sql.should_not match(/LEFT OUTER JOIN `tags`/)
|
63
|
-
end
|
64
|
-
|
65
|
-
it "should include sql_attr_multi as ranged-query" do
|
66
|
-
attribute = @index.attributes.detect { |attrib| attrib.unique_name == :tag_ids }
|
67
|
-
attribute.type_to_config.should == :sql_attr_multi
|
68
|
-
|
69
|
-
declaration, query, range_query = attribute.send(:config_value).split('; ')
|
70
|
-
declaration.should == "uint tag_ids from ranged-query"
|
71
|
-
query.should == "SELECT `tags`.`person_id` #{ThinkingSphinx.unique_id_expression} AS `id`, `tags`.`id` AS `tag_ids` FROM `tags` WHERE `tags`.`person_id` >= $start AND `tags`.`person_id` <= $end"
|
72
|
-
range_query.should == "SELECT MIN(`tags`.`person_id`), MAX(`tags`.`person_id`) FROM `tags`"
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
describe "multi-value attribute as ranged-query with has-many-through association" do
|
77
|
-
before :each do
|
78
|
-
@index = ThinkingSphinx::Index::Builder.generate(Person) do
|
79
|
-
indexes first_name
|
80
|
-
has football_teams(:id), :as => :football_teams_ids, :source => :ranged_query
|
81
|
-
end
|
82
|
-
|
83
|
-
@sql = @index.sources.first.to_riddle_for_core(0, 0).sql_query
|
84
|
-
end
|
85
|
-
|
86
|
-
it "should not include attribute in select-clause sql_query" do
|
87
|
-
@sql.should_not match(/football_teams_ids/)
|
88
|
-
@sql.should_not match(/GROUP_CONCAT\(`tags`.`football_team_id`/)
|
89
|
-
end
|
90
|
-
|
91
|
-
it "should not join with association table" do
|
92
|
-
@sql.should_not match(/LEFT OUTER JOIN `tags`/)
|
93
|
-
end
|
94
|
-
|
95
|
-
it "should include sql_attr_multi as ranged-query" do
|
96
|
-
attribute = @index.attributes.detect { |attrib|
|
97
|
-
attrib.unique_name == :football_teams_ids
|
98
|
-
}
|
99
|
-
attribute.type_to_config.should == :sql_attr_multi
|
100
|
-
|
101
|
-
declaration, query, range_query = attribute.send(:config_value).split('; ')
|
102
|
-
declaration.should == "uint football_teams_ids from ranged-query"
|
103
|
-
query.should == "SELECT `tags`.`person_id` #{ThinkingSphinx.unique_id_expression} AS `id`, `tags`.`football_team_id` AS `football_teams_ids` FROM `tags` WHERE `tags`.`person_id` >= $start AND `tags`.`person_id` <= $end"
|
104
|
-
range_query.should == "SELECT MIN(`tags`.`person_id`), MAX(`tags`.`person_id`) FROM `tags`"
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
describe "multi-value attribute as ranged-query with has-many-through association and foreign_key" do
|
109
|
-
before :each do
|
110
|
-
@index = ThinkingSphinx::Index::Builder.generate(Person) do
|
111
|
-
indexes first_name
|
112
|
-
has friends(:id), :as => :friend_ids, :source => :ranged_query
|
113
|
-
end
|
114
|
-
|
115
|
-
@sql = @index.sources.first.to_riddle_for_core(0, 0).sql_query
|
116
|
-
end
|
117
|
-
|
118
|
-
it "should not include attribute in select-clause sql_query" do
|
119
|
-
@sql.should_not match(/friend_ids/)
|
120
|
-
@sql.should_not match(/GROUP_CONCAT\(`friendships`.`friend_id`/)
|
121
|
-
end
|
122
|
-
|
123
|
-
it "should not join with association table" do
|
124
|
-
@sql.should_not match(/LEFT OUTER JOIN `friendships`/)
|
125
|
-
end
|
126
|
-
|
127
|
-
it "should include sql_attr_multi as ranged-query" do
|
128
|
-
attribute = @index.attributes.detect { |attrib|
|
129
|
-
attrib.unique_name == :friend_ids
|
130
|
-
}
|
131
|
-
attribute.type_to_config.should == :sql_attr_multi
|
132
|
-
|
133
|
-
declaration, query, range_query = attribute.send(:config_value).split('; ')
|
134
|
-
declaration.should == "uint friend_ids from ranged-query"
|
135
|
-
query.should == "SELECT `friendships`.`person_id` #{ThinkingSphinx.unique_id_expression} AS `id`, `friendships`.`friend_id` AS `friend_ids` FROM `friendships` WHERE `friendships`.`person_id` >= $start AND `friendships`.`person_id` <= $end"
|
136
|
-
range_query.should == "SELECT MIN(`friendships`.`person_id`), MAX(`friendships`.`person_id`) FROM `friendships`"
|
137
|
-
end
|
138
|
-
end
|
139
45
|
end
|
@@ -37,6 +37,10 @@ describe ThinkingSphinx::Source do
|
|
37
37
|
ThinkingSphinx::Attribute.new(
|
38
38
|
@source, ThinkingSphinx::Index::FauxColumn.new(:tags, :id), :as => :tag_ids
|
39
39
|
)
|
40
|
+
ThinkingSphinx::Attribute.new(
|
41
|
+
@source, ThinkingSphinx::Index::FauxColumn.new(:contacts, :id),
|
42
|
+
:as => :contact_ids, :source => :query
|
43
|
+
)
|
40
44
|
|
41
45
|
@source.conditions << "`birthday` <= NOW()"
|
42
46
|
@source.groupings << "`first_name`"
|
@@ -102,10 +106,18 @@ describe ThinkingSphinx::Source do
|
|
102
106
|
@query.should match(/`tags`.`id`.+ AS `tag_ids`.+FROM/)
|
103
107
|
end
|
104
108
|
|
109
|
+
it "should not match the sourced MVA attribute" do
|
110
|
+
@query.should_not match(/contact_ids/)
|
111
|
+
end
|
112
|
+
|
105
113
|
it "should include joins for required associations" do
|
106
114
|
@query.should match(/LEFT OUTER JOIN `tags`/)
|
107
115
|
end
|
108
116
|
|
117
|
+
it "should not include joins for the sourced MVA attribute" do
|
118
|
+
@query.should_not match(/LEFT OUTER JOIN `contacts`/)
|
119
|
+
end
|
120
|
+
|
109
121
|
it "should include any defined conditions" do
|
110
122
|
@query.should match(/WHERE.+`birthday` <= NOW()/)
|
111
123
|
end
|
@@ -162,4 +174,44 @@ describe ThinkingSphinx::Source do
|
|
162
174
|
end
|
163
175
|
end
|
164
176
|
end
|
177
|
+
|
178
|
+
describe "#to_riddle_for_core with range disabled" do
|
179
|
+
before :each do
|
180
|
+
ThinkingSphinx::Field.new(
|
181
|
+
@source, ThinkingSphinx::Index::FauxColumn.new(:first_name)
|
182
|
+
)
|
183
|
+
end
|
184
|
+
|
185
|
+
describe "set per-index" do
|
186
|
+
before :each do
|
187
|
+
@index.local_options[:disable_range] = true
|
188
|
+
@riddle = @source.to_riddle_for_core(1, 0)
|
189
|
+
end
|
190
|
+
|
191
|
+
it "should not have the range in the sql_query" do
|
192
|
+
@riddle.sql_query.should_not match(/`people`.`id` >= \$start/)
|
193
|
+
@riddle.sql_query.should_not match(/`people`.`id` <= \$end/)
|
194
|
+
end
|
195
|
+
|
196
|
+
it "should not have a sql_query_range" do
|
197
|
+
@riddle.sql_query_range.should be_nil
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
describe "set globally" do
|
202
|
+
before :each do
|
203
|
+
ThinkingSphinx::Configuration.instance.index_options[:disable_range] = true
|
204
|
+
@riddle = @source.to_riddle_for_core(1, 0)
|
205
|
+
end
|
206
|
+
|
207
|
+
it "should not have the range in the sql_query" do
|
208
|
+
@riddle.sql_query.should_not match(/`people`.`id` >= \$start/)
|
209
|
+
@riddle.sql_query.should_not match(/`people`.`id` <= \$end/)
|
210
|
+
end
|
211
|
+
|
212
|
+
it "should not have a sql_query_range" do
|
213
|
+
@riddle.sql_query_range.should be_nil
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
165
217
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: freelancing-god-thinking-sphinx
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.19
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pat Allan
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-06-01 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|