minisphinx 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/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ *~
2
+ pkg
3
+ Gemfile.lock
data/.rbenv-gemsets ADDED
@@ -0,0 +1 @@
1
+ minisphinx
data/.rbenv-version ADDED
@@ -0,0 +1 @@
1
+ ree-1.8.7-2012.02
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://www.rubygems.org"
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Justin Balthrop
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,9 @@
1
+ minisphinx
2
+ ==========
3
+
4
+ An alternative to Ultrasphinx. But nobody will use it until I write some documentation.
5
+
6
+ COPYRIGHT
7
+ =========
8
+
9
+ Copyright (c) 2009 Justin Balthrop. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require 'rake/testtask'
2
+ require 'bundler/gem_tasks'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs = ['lib']
6
+ t.pattern = 'test/**/*_test.rb'
7
+ t.verbose = false
8
+ end
9
+
10
+ task :default => :test
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
@@ -0,0 +1,14 @@
1
+ indexer {
2
+ mem_limit = 1024M
3
+ }
4
+
5
+ searchd {
6
+ read_timeout = 5
7
+ max_children = 300
8
+ log = <%= RAILS_ROOT %>/log/searchd.log
9
+ max_matches = 100000
10
+ query_log = <%= RAILS_ROOT %>/log/query.log
11
+ seamless_rotate = 1
12
+ listen = 0.0.0.0:3313
13
+ pid_file = <%= RAILS_ROOT %>/log/searchd.pid
14
+ }
@@ -0,0 +1,40 @@
1
+ require 'deep_hash'
2
+
3
+ module Minisphinx
4
+ class Charset
5
+ attr_reader :name, :only, :except
6
+
7
+ def initialize(opts)
8
+ opts = {:name => opts} if opts.kind_of?(Symbol)
9
+ @name = opts[:name]
10
+ @only = Array(opts[:only]).to_set if opts[:only]
11
+ @except = Array(opts[:except]).to_set if opts[:except]
12
+ end
13
+
14
+ def self.charset
15
+ @charset ||= YAML.load_file(RAILS_ROOT + '/config/sphinx/charset.yml')
16
+ end
17
+
18
+ MAX_PER_LINE = 50
19
+ def to_s
20
+ chars = {}
21
+
22
+ self.class.charset[name.to_s].each do |charset|
23
+ charset.each do |group, charset|
24
+ next if except and except.include?(group.to_sym)
25
+ next if only and not only.include?(group.to_sym)
26
+ charset.split(',').each do |char|
27
+ key = char.strip.split('->').first
28
+ chars[key] ||= char
29
+ end
30
+ end
31
+ end
32
+
33
+ lines = []
34
+ chars.values.flatten.sort.each_slice(MAX_PER_LINE) do |line_chars|
35
+ lines << line_chars.join(', ')
36
+ end
37
+ lines.join(", \\\n")
38
+ end
39
+ end
40
+ end
data/lib/minisphinx.rb ADDED
@@ -0,0 +1,243 @@
1
+ module Minisphinx
2
+ def sphinx_source(name, opts)
3
+ opts[:model_class] ||= self
4
+ Minisphinx.sources << Source.new(name, opts)
5
+ end
6
+
7
+ def sphinx_index(name, opts = {})
8
+ Minisphinx.indexes << Index.new(name, opts)
9
+ end
10
+
11
+ def self.indexes; @indexes ||= []; end
12
+ def self.sources; @sources ||= []; end
13
+
14
+ def self.configure(opts)
15
+ template = ['default', RAILS_ENV].collect {|base| RAILS_ROOT + "/config/sphinx/#{base}.conf"}.detect {|file| File.exists?(file)}
16
+
17
+ File.open(opts[:path] + '/sphinx.conf', 'w') do |file|
18
+ file << "# Autogenerated by minisphinx at #{Time.now}\n"
19
+ file << ERB.new(IO.read(template)).result(binding) + "\n" if template
20
+ file << "# Sources\n\n"
21
+ sources.each do |source|
22
+ file << source.configuration(opts)
23
+ end
24
+ file << "# Indexes\n\n"
25
+ indexes.each do |index|
26
+ file << index.configuration(opts)
27
+ end
28
+ end unless opts[:write] == false
29
+ end
30
+
31
+ def self.config_block(head, lines)
32
+ "#{head}\n{\n #{lines.flatten.compact.join("\n ")}\n}\n\n"
33
+ end
34
+
35
+ class Source
36
+ attr_reader :name, :model_class, :fetch_key, :db, :fields, :joins, :config, :delta_field
37
+
38
+ def initialize(name, opts)
39
+ @name = name
40
+ @delta_field = opts.delete(:delta_field)
41
+ @delta_min = opts.delete(:delta_min)
42
+ @fetch_key = opts.delete(:fetch_key) || 'id'
43
+
44
+ @fields = initialize_fields(opts)
45
+ @joins = Array(opts.delete(:joins)) + Array(opts.delete(:join))
46
+ (opts.delete(:include) || []).each do |include_opts|
47
+ @fields.concat initialize_fields(include_opts)
48
+ @joins.concat Array(include_opts.delete(:joins)) + Array(include_opts.delete(:join))
49
+ end
50
+ raise 'at least one field required' if @fields.empty?
51
+ @fields.sort!
52
+
53
+ @model_class = opts.delete(:model_class)
54
+ @table_name = opts.delete(:table_name)
55
+ @db = opts.delete(:db) || model_class.connection.config
56
+ @db = ActiveRecord::Base.configurations["#{db}_#{RAILS_ENV}"] unless db.kind_of?(Hash)
57
+
58
+ @config = self.class.config.merge(opts)
59
+ end
60
+
61
+ def table_name
62
+ @table_name ||= model_class.table_name
63
+ end
64
+
65
+ def type
66
+ db[:adapter] == 'postgresql' ? 'pgsql' : db[:adapter]
67
+ end
68
+
69
+ def configuration(opts)
70
+ str = Minisphinx.config_block("source #{name}_base", [
71
+ "type = #{type}",
72
+ config.collect do |key, value|
73
+ "sql_#{key} = #{value}"
74
+ end,
75
+ "sql_db = #{db[:database]}",
76
+ "sql_host = #{db[:host]}",
77
+ "sql_pass = #{db[:password]}",
78
+ "sql_user = #{db[:username]}",
79
+ "sql_query_info = #{sql_query_info}",
80
+ fields.collect do |field|
81
+ "sql_attr_#{field.type} = #{field.name}" if field.type != :text
82
+ end,
83
+ ])
84
+ str << Minisphinx.config_block("source #{name} : #{name}_base", [
85
+ "sql_query_range = #{sql_query_range}",
86
+ "sql_query = #{sql_query}",
87
+ ])
88
+ if delta_field
89
+ str << Minisphinx.config_block("source #{name}_delta : #{name}_base", [
90
+ "sql_query = #{sql_query_delta(opts[:delta_min])}",
91
+ ])
92
+ end
93
+ str
94
+ end
95
+
96
+ def sql_query_range
97
+ "SELECT coalesce(MIN(#{fetch_key}),1)::bigint, coalesce(MAX(#{fetch_key}),1)::bigint FROM #{table_name}"
98
+ end
99
+
100
+ def sql_query
101
+ "SELECT #{table_name}.id AS doc_id, #{fields.join(', ')} " <<
102
+ "FROM #{table_name} #{joins.join(' ')} WHERE #{fetch_key} >= $start AND #{fetch_key} <= $end"
103
+ end
104
+
105
+ def sql_query_delta(delta_min)
106
+ delta_min = "'#{delta_min.to_s(:db)}'" if delta_min.kind_of?(Time) or delta_min.kind_of?(Date)
107
+ "SELECT #{table_name}.id AS doc_id, #{fields.join(', ')} " <<
108
+ "FROM #{table_name} #{joins.join(' ')} WHERE #{delta_field} >= #{delta_min}"
109
+ end
110
+
111
+ def sql_query_info
112
+ "SELECT * FROM #{table_name} WHERE id = $id"
113
+ end
114
+
115
+ def self.config
116
+ @config ||= {
117
+ :range_step => 5000,
118
+ :ranged_throttle => 0,
119
+ }
120
+ end
121
+
122
+ private
123
+
124
+ def initialize_fields(opts)
125
+ (opts.delete(:fields) || []).collect do |field_opts|
126
+ field_opts = {:field => field_opts} unless field_opts.kind_of?(Hash)
127
+ field_opts[:table_name] = opts[:table_name]
128
+ field_opts[:model_class] = opts[:model_class]
129
+
130
+ if field_opts[:sortable] and not [nil, :text].include?(field_opts[:type])
131
+ raise ":sortable only permitted for :text fields, #{field_opts[:field]} is of type #{field_opts[:type].inspect}"
132
+ end
133
+
134
+ [Field.new(field_opts), field_opts[:sortable] && Field.new(field_opts.merge(:type => :sortable, :suffix => 'sortable'))]
135
+ end.flatten.compact
136
+ end
137
+ end
138
+
139
+ class Field
140
+ attr_reader :model_class, :field, :name, :type
141
+
142
+ TYPE_MAP = {
143
+ :integer => :uint,
144
+ :decimal => :float,
145
+ :boolean => :bool,
146
+ :date => :timestamp,
147
+ :datetime => :timestamp,
148
+ :timestamp => :timestamp,
149
+ :string => :text,
150
+ :sortable => :string,
151
+ }
152
+
153
+ def initialize(opts)
154
+ @model_class = opts[:model_class]
155
+ @table_name = opts[:table_name]
156
+
157
+ @type = opts[:type]
158
+ @name = opts[:as] || opts[:field]
159
+ @name = "#{name}_#{opts[:suffix]}" if opts[:suffix]
160
+ @field = opts[:field]
161
+ @field = "#{table_name}.#{field}" if not field.index(/[\(.\s]/)
162
+ @field = opts[:transform] % field if opts[:transform]
163
+ @field = "UNIX_TIMESTAMP(#{field})" if type == :timestamp
164
+ end
165
+
166
+ def table_name
167
+ @table_name ||= model_class ? model_class.table_name : nil
168
+ end
169
+
170
+ def <=>(other)
171
+ # Sphinx has a bug that messes up your index unless str2ordinal fields come first.
172
+ if type != other.type
173
+ (type == :str2ordinal && -1) || (other.type == :str2ordinal && 1) || (type.to_s <=> other.type.to_s)
174
+ else
175
+ name <=> other.name
176
+ end
177
+ end
178
+
179
+ def type
180
+ if @type.nil? and model_class
181
+ column = model_class.columns_hash[name]
182
+ @type = column.sql_type == 'bigint' ? :bigint : column.type.to_sym
183
+ end
184
+ TYPE_MAP[@type] || @type || :text
185
+ end
186
+
187
+ def to_s
188
+ "#{field} AS #{name}"
189
+ end
190
+ end
191
+
192
+ class Index
193
+ attr_reader :name, :sources, :charset, :ngram, :config, :delta
194
+
195
+ def initialize(name, opts)
196
+ @name = name
197
+ @config = self.class.config.merge(opts)
198
+ @delta = config.delete(:delta)
199
+ @delta = "#{name}_delta" if @delta == true
200
+ @sources = Array(config.delete(:source)) + Array(config.delete(:sources))
201
+ @charset = Minisphinx::Charset.new(config.delete(:charset)) if config[:charset]
202
+ @ngram = Minisphinx::Charset.new(config.delete(:ngram)) if config[:ngram]
203
+ end
204
+
205
+ def configuration(opts)
206
+ path = opts[:path]
207
+ str = Minisphinx.config_block("index #{name}", [
208
+ sources.collect do |source|
209
+ "source = #{source}"
210
+ end,
211
+ "path = #{path}/#{name}",
212
+ config.collect do |key, value|
213
+ "#{key} = #{value}"
214
+ end,
215
+ charset && "charset_table = #{charset}",
216
+ ngram && "ngram_chars = #{ngram}",
217
+ ngram && "ngram_len = 1",
218
+ ])
219
+ if delta
220
+ str << Minisphinx.config_block("index #{delta} : #{name}", [
221
+ sources.collect do |source|
222
+ "source = #{source}_delta"
223
+ end,
224
+ "path = #{path}/#{delta}",
225
+ ])
226
+ end
227
+ str
228
+ end
229
+
230
+ def self.config
231
+ @config ||= {
232
+ :charset_type => 'utf-8',
233
+ :min_word_len => 1,
234
+ :html_strip => 0,
235
+ :docinfo => 'extern',
236
+ }
237
+ end
238
+ end
239
+ end
240
+
241
+ class ActiveRecord::ConnectionAdapters::AbstractAdapter
242
+ attr_reader :config
243
+ end
@@ -0,0 +1,36 @@
1
+ /* Taken from ultrasphinx */
2
+
3
+ /* http://osdir.com/ml/db.postgresql.admIN/2003-08/msg00057.html */
4
+
5
+ CREATE FUNCTION MAKE_CONCAT_WS() RETURNS text AS '
6
+ declare
7
+ v_args int := 32;
8
+ v_first text := ''CREATE FUNCTION CONCAT_WS(text,text,text) RETURNS text AS ''''SELECT CASE WHEN $1 IS NULL THEN NULL WHEN $3 IS NULL THEN $2 ELSE $2 || $1 || $3 END'''' LANGUAGE sql IMMUTABLE'';
9
+ v_part1 text := ''CREATE FUNCTION CONCAT_WS(text,text'';
10
+ v_part2 text := '') RETURNS text AS ''''SELECT CONCAT_WS($1,CONCAT_WS($1,$2'';
11
+ v_part3 text := '')'''' LANGUAGE sql IMMUTABLE'';
12
+ v_sql text;
13
+
14
+ BEGIN
15
+ EXECUTE v_first;
16
+ FOR i IN 4 .. v_args loop
17
+ v_sql := v_part1;
18
+ FOR j IN 3 .. i loop
19
+ v_sql := v_sql || '',text'';
20
+ END loop;
21
+
22
+ v_sql := v_sql || v_part2;
23
+
24
+ FOR j IN 3 .. i - 1 loop
25
+ v_sql := v_sql || '',$'' || j::text;
26
+ END loop;
27
+ v_sql := v_sql || ''),$'' || i::text;
28
+
29
+ v_sql := v_sql || v_part3;
30
+ EXECUTE v_sql;
31
+ END loop;
32
+ RETURN ''OK'';
33
+ END;
34
+ ' LANGUAGE 'plpgsql';
35
+
36
+ SELECT MAKE_CONCAT_WS();
@@ -0,0 +1,16 @@
1
+ /* Taken from ultrasphinx */
2
+
3
+ /* Fake CRC32 */
4
+
5
+ CREATE FUNCTION crc32(text)
6
+ RETURNS bigint AS $$
7
+ DECLARE
8
+ tmp bigint;
9
+ BEGIN
10
+ tmp = (hex_to_int(SUBSTRING(MD5($1) FROM 1 FOR 8))::bigint);
11
+ IF tmp < 0 THEN
12
+ tmp = 4294967296 + tmp;
13
+ END IF;
14
+ return tmp;
15
+ END
16
+ $$ IMMUTABLE STRICT LANGUAGE plpgsql;
@@ -0,0 +1,24 @@
1
+ /* Taken from ultrasphinx */
2
+
3
+ /*
4
+ mysqlcompat-1.0b3
5
+ public domain
6
+ GROUP_CONCAT()
7
+ Note: For DISTINCT and ORDER BY a subquery is required
8
+ */
9
+
10
+ CREATE FUNCTION _group_concat(text, text)
11
+ RETURNS text AS $$
12
+ SELECT CASE
13
+ WHEN $2 IS NULL THEN COALESCE($1, ' ')
14
+ WHEN $1 IS NULL THEN $2
15
+ ELSE $1 operator(pg_catalog.||) ' ' operator(pg_catalog.||) $2
16
+ END
17
+ $$ IMMUTABLE LANGUAGE SQL;
18
+
19
+ CREATE AGGREGATE group_concat (
20
+ BASETYPE = text,
21
+ SFUNC = _group_concat,
22
+ STYPE = text
23
+ );
24
+
@@ -0,0 +1,16 @@
1
+ /* Taken from ultrasphinx */
2
+
3
+ CREATE FUNCTION hex_to_int(varchar) RETURNS int4 AS '
4
+ DECLARE
5
+ h alias for $1;
6
+ exec varchar;
7
+ curs refcursor;
8
+ res int;
9
+ BEGIN
10
+ exec := ''SELECT x'''''' || h || ''''''::int4'';
11
+ OPEN curs FOR EXECUTE exec;
12
+ FETCH curs INTO res;
13
+ CLOSE curs;
14
+ return res;
15
+ END;'
16
+ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
@@ -0,0 +1,13 @@
1
+ /* Taken from ultrasphinx */
2
+
3
+ /*
4
+ mysqlcompat-1.0b3
5
+ public domain
6
+ modified
7
+ UNIX_TIMESTAMP(date)
8
+ */
9
+
10
+ CREATE FUNCTION unix_timestamp(timestamp without time zone)
11
+ RETURNS bigint AS $$
12
+ SELECT EXTRACT(EPOCH FROM $1)::bigint
13
+ $$ VOLATILE LANGUAGE SQL;
@@ -0,0 +1,25 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.name = "minisphinx"
6
+ gem.version = IO.read('VERSION')
7
+ gem.authors = ["Justin Balthrop"]
8
+ gem.email = ["git@justinbalthrop.com"]
9
+ gem.description = %q{A simple Sphinx indexing library for Ruby}
10
+ gem.summary = gem.description
11
+ gem.homepage = "https://github.com/ninjudd/minisphinx"
12
+
13
+ gem.add_development_dependency 'shoulda', '3.0.1'
14
+ gem.add_development_dependency 'mocha'
15
+ gem.add_development_dependency 'rake'
16
+ gem.add_development_dependency 'activerecord-postgresql-adapter'
17
+
18
+ gem.add_dependency 'activerecord', '~> 2.3.9'
19
+ gem.add_dependency 'deep_hash', '0.0.2'
20
+
21
+ gem.files = `git ls-files`.split($/)
22
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
23
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
24
+ gem.require_paths = ["lib"]
25
+ end
@@ -0,0 +1,60 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class MinisphinxTest < Test::Unit::TestCase
4
+ class CreateTables < ActiveRecord::Migration
5
+ def self.up
6
+ create_table :pets do |t|
7
+ t.column :name, :string
8
+ t.column :species, :string
9
+ t.column :breed, :string
10
+ t.column :color, :string
11
+ t.column :gender, :string
12
+ t.column :adopted, :boolean
13
+ end
14
+ end
15
+
16
+ def self.down
17
+ drop_table :pets
18
+ end
19
+ end
20
+
21
+ class Pet < ActiveRecord::Base
22
+ extend Minisphinx
23
+
24
+ def self.initialize_sphinx
25
+ sphinx_source :pets,
26
+ :fetch_key => 'public_id',
27
+ :delta_field => 'CASE WHEN master_profile THEN now() ELSE updated_at END',
28
+ :fields => [
29
+ {:field => 'name', :sortable => true},
30
+ {:field => 'species', :sortable => true},
31
+ {:field => 'breed', :sortable => true},
32
+ {:field => 'gender', :sortable => true},
33
+ {:field => 'adopted', :type => :boolean},
34
+ ]
35
+
36
+ Minisphinx::Index.config[:source ] = :profiles
37
+ Minisphinx::Index.config[:delta ] = true
38
+
39
+ sphinx_index :full
40
+ end
41
+ end
42
+
43
+ context 'with a db connection' do
44
+ setup do
45
+ Dir.mkdir('/tmp/minisphinx-test')
46
+ CreateTables.verbose = false
47
+ CreateTables.up
48
+ end
49
+
50
+ teardown do
51
+ CreateTables.down
52
+ end
53
+
54
+ should "write config" do
55
+ Pet.initialize_sphinx
56
+ Minisphinx.configure(:path => '/tmp/minisphinx-test')
57
+ assert File.exists('/tmp/minisphinx-test/sphinx.conf')
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,23 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+ require 'mocha/setup'
5
+ require 'pp'
6
+
7
+ require 'active_record'
8
+ require 'minisphinx'
9
+ require 'minisphinx/charset'
10
+
11
+ class Test::Unit::TestCase
12
+ end
13
+
14
+ RAILS_ENV = 'test'
15
+ RAILS_ROOT = '/tmp/minisphinx-test'
16
+
17
+ ActiveRecord::Base.establish_connection(
18
+ :adapter => "postgresql",
19
+ :host => "localhost",
20
+ :database => "minisphinx_test"
21
+ )
22
+ ActiveRecord::Migration.verbose = false
23
+ ActiveRecord::Base.connection.client_min_messages = 'panic'
metadata ADDED
@@ -0,0 +1,176 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: minisphinx
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease:
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors:
13
+ - Justin Balthrop
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2013-06-03 00:00:00 -07:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: shoulda
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - "="
28
+ - !ruby/object:Gem::Version
29
+ hash: 5
30
+ segments:
31
+ - 3
32
+ - 0
33
+ - 1
34
+ version: 3.0.1
35
+ type: :development
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: mocha
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 3
46
+ segments:
47
+ - 0
48
+ version: "0"
49
+ type: :development
50
+ version_requirements: *id002
51
+ - !ruby/object:Gem::Dependency
52
+ name: rake
53
+ prerelease: false
54
+ requirement: &id003 !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ hash: 3
60
+ segments:
61
+ - 0
62
+ version: "0"
63
+ type: :development
64
+ version_requirements: *id003
65
+ - !ruby/object:Gem::Dependency
66
+ name: activerecord-postgresql-adapter
67
+ prerelease: false
68
+ requirement: &id004 !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ hash: 3
74
+ segments:
75
+ - 0
76
+ version: "0"
77
+ type: :development
78
+ version_requirements: *id004
79
+ - !ruby/object:Gem::Dependency
80
+ name: activerecord
81
+ prerelease: false
82
+ requirement: &id005 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ~>
86
+ - !ruby/object:Gem::Version
87
+ hash: 17
88
+ segments:
89
+ - 2
90
+ - 3
91
+ - 9
92
+ version: 2.3.9
93
+ type: :runtime
94
+ version_requirements: *id005
95
+ - !ruby/object:Gem::Dependency
96
+ name: deep_hash
97
+ prerelease: false
98
+ requirement: &id006 !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - "="
102
+ - !ruby/object:Gem::Version
103
+ hash: 27
104
+ segments:
105
+ - 0
106
+ - 0
107
+ - 2
108
+ version: 0.0.2
109
+ type: :runtime
110
+ version_requirements: *id006
111
+ description: A simple Sphinx indexing library for Ruby
112
+ email:
113
+ - git@justinbalthrop.com
114
+ executables: []
115
+
116
+ extensions: []
117
+
118
+ extra_rdoc_files: []
119
+
120
+ files:
121
+ - .gitignore
122
+ - .rbenv-gemsets
123
+ - .rbenv-version
124
+ - Gemfile
125
+ - LICENSE
126
+ - README
127
+ - Rakefile
128
+ - VERSION
129
+ - examples/default.conf
130
+ - lib/minisphinx.rb
131
+ - lib/minisphinx/charset.rb
132
+ - lib/mysqlcompat/concat_ws.sql
133
+ - lib/mysqlcompat/crc32.sql
134
+ - lib/mysqlcompat/group_concat.sql
135
+ - lib/mysqlcompat/hex_to_int.sql
136
+ - lib/mysqlcompat/unix_timestamp.sql
137
+ - minisphinx.gemspec
138
+ - test/minisphinx_test.rb
139
+ - test/test_helper.rb
140
+ has_rdoc: true
141
+ homepage: https://github.com/ninjudd/minisphinx
142
+ licenses: []
143
+
144
+ post_install_message:
145
+ rdoc_options: []
146
+
147
+ require_paths:
148
+ - lib
149
+ required_ruby_version: !ruby/object:Gem::Requirement
150
+ none: false
151
+ requirements:
152
+ - - ">="
153
+ - !ruby/object:Gem::Version
154
+ hash: 3
155
+ segments:
156
+ - 0
157
+ version: "0"
158
+ required_rubygems_version: !ruby/object:Gem::Requirement
159
+ none: false
160
+ requirements:
161
+ - - ">="
162
+ - !ruby/object:Gem::Version
163
+ hash: 3
164
+ segments:
165
+ - 0
166
+ version: "0"
167
+ requirements: []
168
+
169
+ rubyforge_project:
170
+ rubygems_version: 1.5.2
171
+ signing_key:
172
+ specification_version: 3
173
+ summary: A simple Sphinx indexing library for Ruby
174
+ test_files:
175
+ - test/minisphinx_test.rb
176
+ - test/test_helper.rb