skalee-thinking-sphinx 1.3.14.1
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/LICENCE +20 -0
- data/README.textile +201 -0
- data/Rakefile +3 -0
- data/VERSION +1 -0
- data/contribute.rb +385 -0
- data/cucumber.yml +1 -0
- data/features/abstract_inheritance.feature +10 -0
- data/features/alternate_primary_key.feature +27 -0
- data/features/attribute_transformation.feature +22 -0
- data/features/attribute_updates.feature +51 -0
- data/features/deleting_instances.feature +67 -0
- data/features/direct_attributes.feature +11 -0
- data/features/excerpts.feature +13 -0
- data/features/extensible_delta_indexing.feature +9 -0
- data/features/facets.feature +82 -0
- data/features/facets_across_model.feature +29 -0
- data/features/handling_edits.feature +92 -0
- data/features/retry_stale_indexes.feature +24 -0
- data/features/searching_across_models.feature +20 -0
- data/features/searching_by_index.feature +40 -0
- data/features/searching_by_model.feature +175 -0
- data/features/searching_with_find_arguments.feature +56 -0
- data/features/sphinx_detection.feature +25 -0
- data/features/sphinx_scopes.feature +42 -0
- data/features/step_definitions/alpha_steps.rb +16 -0
- data/features/step_definitions/beta_steps.rb +7 -0
- data/features/step_definitions/common_steps.rb +188 -0
- data/features/step_definitions/extensible_delta_indexing_steps.rb +7 -0
- data/features/step_definitions/facet_steps.rb +96 -0
- data/features/step_definitions/find_arguments_steps.rb +36 -0
- data/features/step_definitions/gamma_steps.rb +15 -0
- data/features/step_definitions/scope_steps.rb +15 -0
- data/features/step_definitions/search_steps.rb +89 -0
- data/features/step_definitions/sphinx_steps.rb +35 -0
- data/features/sti_searching.feature +19 -0
- data/features/support/database.example.yml +3 -0
- data/features/support/db/.gitignore +1 -0
- data/features/support/db/fixtures/alphas.rb +10 -0
- data/features/support/db/fixtures/authors.rb +1 -0
- data/features/support/db/fixtures/betas.rb +10 -0
- data/features/support/db/fixtures/boxes.rb +9 -0
- data/features/support/db/fixtures/categories.rb +1 -0
- data/features/support/db/fixtures/cats.rb +3 -0
- data/features/support/db/fixtures/comments.rb +24 -0
- data/features/support/db/fixtures/developers.rb +29 -0
- data/features/support/db/fixtures/dogs.rb +3 -0
- data/features/support/db/fixtures/extensible_betas.rb +10 -0
- data/features/support/db/fixtures/foxes.rb +3 -0
- data/features/support/db/fixtures/gammas.rb +10 -0
- data/features/support/db/fixtures/music.rb +4 -0
- data/features/support/db/fixtures/people.rb +1001 -0
- data/features/support/db/fixtures/posts.rb +6 -0
- data/features/support/db/fixtures/robots.rb +14 -0
- data/features/support/db/fixtures/tags.rb +27 -0
- data/features/support/db/migrations/create_alphas.rb +8 -0
- data/features/support/db/migrations/create_animals.rb +5 -0
- data/features/support/db/migrations/create_authors.rb +3 -0
- data/features/support/db/migrations/create_authors_posts.rb +6 -0
- data/features/support/db/migrations/create_betas.rb +5 -0
- data/features/support/db/migrations/create_boxes.rb +5 -0
- data/features/support/db/migrations/create_categories.rb +3 -0
- data/features/support/db/migrations/create_comments.rb +10 -0
- data/features/support/db/migrations/create_developers.rb +9 -0
- data/features/support/db/migrations/create_extensible_betas.rb +5 -0
- data/features/support/db/migrations/create_gammas.rb +3 -0
- data/features/support/db/migrations/create_genres.rb +3 -0
- data/features/support/db/migrations/create_music.rb +6 -0
- data/features/support/db/migrations/create_people.rb +13 -0
- data/features/support/db/migrations/create_posts.rb +5 -0
- data/features/support/db/migrations/create_robots.rb +4 -0
- data/features/support/db/migrations/create_taggings.rb +5 -0
- data/features/support/db/migrations/create_tags.rb +4 -0
- data/features/support/env.rb +21 -0
- data/features/support/lib/generic_delta_handler.rb +8 -0
- data/features/support/models/alpha.rb +22 -0
- data/features/support/models/animal.rb +5 -0
- data/features/support/models/author.rb +3 -0
- data/features/support/models/beta.rb +8 -0
- data/features/support/models/box.rb +8 -0
- data/features/support/models/cat.rb +3 -0
- data/features/support/models/category.rb +4 -0
- data/features/support/models/comment.rb +10 -0
- data/features/support/models/developer.rb +16 -0
- data/features/support/models/dog.rb +3 -0
- data/features/support/models/extensible_beta.rb +9 -0
- data/features/support/models/fox.rb +5 -0
- data/features/support/models/gamma.rb +5 -0
- data/features/support/models/genre.rb +3 -0
- data/features/support/models/medium.rb +5 -0
- data/features/support/models/music.rb +8 -0
- data/features/support/models/person.rb +23 -0
- data/features/support/models/post.rb +21 -0
- data/features/support/models/robot.rb +12 -0
- data/features/support/models/tag.rb +3 -0
- data/features/support/models/tagging.rb +4 -0
- data/ginger_scenarios.rb +28 -0
- data/init.rb +5 -0
- data/install.rb +5 -0
- data/lib/cucumber/thinking_sphinx/external_world.rb +8 -0
- data/lib/cucumber/thinking_sphinx/internal_world.rb +126 -0
- data/lib/cucumber/thinking_sphinx/sql_logger.rb +20 -0
- data/lib/thinking_sphinx/active_record/attribute_updates.rb +19 -0
- data/lib/thinking_sphinx/active_record/delta.rb +47 -0
- data/lib/thinking_sphinx/active_record/has_many_association.rb +29 -0
- data/lib/thinking_sphinx/active_record/scopes.rb +75 -0
- data/lib/thinking_sphinx/active_record.rb +348 -0
- data/lib/thinking_sphinx/adapters/abstract_adapter.rb +42 -0
- data/lib/thinking_sphinx/adapters/mysql_adapter.rb +54 -0
- data/lib/thinking_sphinx/adapters/postgresql_adapter.rb +143 -0
- data/lib/thinking_sphinx/association.rb +164 -0
- data/lib/thinking_sphinx/attribute.rb +362 -0
- data/lib/thinking_sphinx/auto_version.rb +22 -0
- data/lib/thinking_sphinx/class_facet.rb +15 -0
- data/lib/thinking_sphinx/configuration.rb +300 -0
- data/lib/thinking_sphinx/context.rb +68 -0
- data/lib/thinking_sphinx/core/array.rb +7 -0
- data/lib/thinking_sphinx/core/string.rb +15 -0
- data/lib/thinking_sphinx/deltas/default_delta.rb +62 -0
- data/lib/thinking_sphinx/deltas.rb +28 -0
- data/lib/thinking_sphinx/deploy/capistrano.rb +100 -0
- data/lib/thinking_sphinx/excerpter.rb +22 -0
- data/lib/thinking_sphinx/facet.rb +125 -0
- data/lib/thinking_sphinx/facet_search.rb +136 -0
- data/lib/thinking_sphinx/field.rb +82 -0
- data/lib/thinking_sphinx/index/builder.rb +296 -0
- data/lib/thinking_sphinx/index/faux_column.rb +110 -0
- data/lib/thinking_sphinx/index.rb +157 -0
- data/lib/thinking_sphinx/property.rb +162 -0
- data/lib/thinking_sphinx/rails_additions.rb +150 -0
- data/lib/thinking_sphinx/search.rb +769 -0
- data/lib/thinking_sphinx/search_methods.rb +439 -0
- data/lib/thinking_sphinx/source/internal_properties.rb +46 -0
- data/lib/thinking_sphinx/source/sql.rb +130 -0
- data/lib/thinking_sphinx/source.rb +153 -0
- data/lib/thinking_sphinx/tasks.rb +131 -0
- data/lib/thinking_sphinx/test.rb +52 -0
- data/lib/thinking_sphinx.rb +225 -0
- data/rails/init.rb +16 -0
- data/recipes/thinking_sphinx.rb +3 -0
- data/spec/fixtures/data.sql +32 -0
- data/spec/fixtures/database.yml.default +3 -0
- data/spec/fixtures/models.rb +145 -0
- data/spec/fixtures/structure.sql +125 -0
- data/spec/spec_helper.rb +60 -0
- data/spec/sphinx_helper.rb +81 -0
- data/spec/thinking_sphinx/active_record/delta_spec.rb +128 -0
- data/spec/thinking_sphinx/active_record/has_many_association_spec.rb +55 -0
- data/spec/thinking_sphinx/active_record/scopes_spec.rb +177 -0
- data/spec/thinking_sphinx/active_record_spec.rb +622 -0
- data/spec/thinking_sphinx/association_spec.rb +239 -0
- data/spec/thinking_sphinx/attribute_spec.rb +570 -0
- data/spec/thinking_sphinx/auto_version_spec.rb +39 -0
- data/spec/thinking_sphinx/configuration_spec.rb +234 -0
- data/spec/thinking_sphinx/context_spec.rb +119 -0
- data/spec/thinking_sphinx/core/array_spec.rb +9 -0
- data/spec/thinking_sphinx/core/string_spec.rb +9 -0
- data/spec/thinking_sphinx/excerpter_spec.rb +57 -0
- data/spec/thinking_sphinx/facet_search_spec.rb +176 -0
- data/spec/thinking_sphinx/facet_spec.rb +333 -0
- data/spec/thinking_sphinx/field_spec.rb +154 -0
- data/spec/thinking_sphinx/index/builder_spec.rb +479 -0
- data/spec/thinking_sphinx/index/faux_column_spec.rb +30 -0
- data/spec/thinking_sphinx/index_spec.rb +183 -0
- data/spec/thinking_sphinx/rails_additions_spec.rb +203 -0
- data/spec/thinking_sphinx/search_methods_spec.rb +152 -0
- data/spec/thinking_sphinx/search_spec.rb +1181 -0
- data/spec/thinking_sphinx/source_spec.rb +235 -0
- data/spec/thinking_sphinx_spec.rb +204 -0
- data/tasks/distribution.rb +41 -0
- data/tasks/rails.rake +1 -0
- data/tasks/testing.rb +72 -0
- data/vendor/after_commit/.gitignore +1 -0
- data/vendor/after_commit/lib/after_commit/active_record.rb +122 -0
- data/vendor/after_commit/lib/after_commit/connection_adapters.rb +168 -0
- data/vendor/after_commit/lib/after_commit/test_bypass.rb +30 -0
- data/vendor/after_commit/lib/after_commit.rb +70 -0
- data/vendor/riddle/lib/riddle/0.9.8.rb +1 -0
- data/vendor/riddle/lib/riddle/0.9.9/client/filter.rb +22 -0
- data/vendor/riddle/lib/riddle/0.9.9/client.rb +49 -0
- data/vendor/riddle/lib/riddle/0.9.9/configuration/searchd.rb +28 -0
- data/vendor/riddle/lib/riddle/0.9.9.rb +7 -0
- data/vendor/riddle/lib/riddle/auto_version.rb +11 -0
- data/vendor/riddle/lib/riddle/client/filter.rb +62 -0
- data/vendor/riddle/lib/riddle/client/message.rb +70 -0
- data/vendor/riddle/lib/riddle/client/response.rb +94 -0
- data/vendor/riddle/lib/riddle/client.rb +745 -0
- data/vendor/riddle/lib/riddle/configuration/distributed_index.rb +49 -0
- data/vendor/riddle/lib/riddle/configuration/index.rb +149 -0
- data/vendor/riddle/lib/riddle/configuration/indexer.rb +20 -0
- data/vendor/riddle/lib/riddle/configuration/remote_index.rb +17 -0
- data/vendor/riddle/lib/riddle/configuration/searchd.rb +28 -0
- data/vendor/riddle/lib/riddle/configuration/section.rb +43 -0
- data/vendor/riddle/lib/riddle/configuration/source.rb +23 -0
- data/vendor/riddle/lib/riddle/configuration/sql_source.rb +53 -0
- data/vendor/riddle/lib/riddle/configuration/xml_source.rb +29 -0
- data/vendor/riddle/lib/riddle/configuration.rb +33 -0
- data/vendor/riddle/lib/riddle/controller.rb +78 -0
- data/vendor/riddle/lib/riddle.rb +51 -0
- metadata +312 -0
@@ -0,0 +1,49 @@
|
|
1
|
+
module Riddle
|
2
|
+
class Configuration
|
3
|
+
class DistributedIndex < Riddle::Configuration::Section
|
4
|
+
self.settings = [:type, :local, :agent, :agent_blackhole,
|
5
|
+
:agent_connect_timeout, :agent_query_timeout]
|
6
|
+
|
7
|
+
attr_accessor :name, :local_indexes, :remote_indexes, :agent_blackhole,
|
8
|
+
:agent_connect_timeout, :agent_query_timeout
|
9
|
+
|
10
|
+
def initialize(name)
|
11
|
+
@name = name
|
12
|
+
@local_indexes = []
|
13
|
+
@remote_indexes = []
|
14
|
+
@agent_blackhole = []
|
15
|
+
end
|
16
|
+
|
17
|
+
def type
|
18
|
+
"distributed"
|
19
|
+
end
|
20
|
+
|
21
|
+
def local
|
22
|
+
self.local_indexes
|
23
|
+
end
|
24
|
+
|
25
|
+
def agent
|
26
|
+
agents = remote_indexes.collect { |index| index.remote }.uniq
|
27
|
+
agents.collect { |agent|
|
28
|
+
agent + ":" + remote_indexes.select { |index|
|
29
|
+
index.remote == agent
|
30
|
+
}.collect { |index| index.name }.join(",")
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
def render
|
35
|
+
raise ConfigurationError unless valid?
|
36
|
+
|
37
|
+
(
|
38
|
+
["index #{name}", "{"] +
|
39
|
+
settings_body +
|
40
|
+
["}", ""]
|
41
|
+
).join("\n")
|
42
|
+
end
|
43
|
+
|
44
|
+
def valid?
|
45
|
+
@local_indexes.length > 0 || @remote_indexes.length > 0
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
module Riddle
|
2
|
+
class Configuration
|
3
|
+
class Index < Riddle::Configuration::Section
|
4
|
+
self.settings = [:source, :path, :docinfo, :mlock, :morphology,
|
5
|
+
:min_stemming_len, :stopwords, :wordforms, :exceptions, :min_word_len,
|
6
|
+
:charset_dictpath, :charset_type, :charset_table, :ignore_chars,
|
7
|
+
:min_prefix_len, :min_infix_len, :prefix_fields, :infix_fields,
|
8
|
+
:enable_star, :ngram_len, :ngram_chars, :phrase_boundary,
|
9
|
+
:phrase_boundary_step, :html_strip, :html_index_attrs,
|
10
|
+
:html_remove_elements, :preopen, :ondisk_dict, :inplace_enable,
|
11
|
+
:inplace_hit_gap, :inplace_docinfo_gap, :inplace_reloc_factor,
|
12
|
+
:inplace_write_factor, :index_exact_words, :overshort_step,
|
13
|
+
:stopwords_step]
|
14
|
+
|
15
|
+
attr_accessor :name, :parent, :sources, :path, :docinfo, :mlock,
|
16
|
+
:morphologies, :min_stemming_len, :stopword_files, :wordform_files,
|
17
|
+
:exception_files, :min_word_len, :charset_dictpath, :charset_type,
|
18
|
+
:charset_table, :ignore_characters, :min_prefix_len, :min_infix_len,
|
19
|
+
:prefix_field_names, :infix_field_names, :enable_star, :ngram_len,
|
20
|
+
:ngram_characters, :phrase_boundaries, :phrase_boundary_step,
|
21
|
+
:html_strip, :html_index_attrs, :html_remove_element_tags, :preopen,
|
22
|
+
:ondisk_dict, :inplace_enable, :inplace_hit_gap, :inplace_docinfo_gap,
|
23
|
+
:inplace_reloc_factor, :inplace_write_factor, :index_exact_words,
|
24
|
+
:overshort_step, :stopwords_step
|
25
|
+
|
26
|
+
def initialize(name, *sources)
|
27
|
+
@name = name
|
28
|
+
@sources = sources
|
29
|
+
@morphologies = []
|
30
|
+
@stopword_files = []
|
31
|
+
@wordform_files = []
|
32
|
+
@exception_files = []
|
33
|
+
@ignore_characters = []
|
34
|
+
@prefix_field_names = []
|
35
|
+
@infix_field_names = []
|
36
|
+
@ngram_characters = []
|
37
|
+
@phrase_boundaries = []
|
38
|
+
@html_remove_element_tags = []
|
39
|
+
end
|
40
|
+
|
41
|
+
def source
|
42
|
+
@sources.collect { |s| s.name }
|
43
|
+
end
|
44
|
+
|
45
|
+
def morphology
|
46
|
+
nil_join @morphologies, ", "
|
47
|
+
end
|
48
|
+
|
49
|
+
def morphology=(morphology)
|
50
|
+
@morphologies = nil_split morphology, /,\s?/
|
51
|
+
end
|
52
|
+
|
53
|
+
def stopwords
|
54
|
+
nil_join @stopword_files, " "
|
55
|
+
end
|
56
|
+
|
57
|
+
def stopwords=(stopwords)
|
58
|
+
@stopword_files = nil_split stopwords, ' '
|
59
|
+
end
|
60
|
+
|
61
|
+
def wordforms
|
62
|
+
nil_join @wordform_files, " "
|
63
|
+
end
|
64
|
+
|
65
|
+
def wordforms=(wordforms)
|
66
|
+
@wordform_files = nil_split wordforms, ' '
|
67
|
+
end
|
68
|
+
|
69
|
+
def exceptions
|
70
|
+
nil_join @exception_files, " "
|
71
|
+
end
|
72
|
+
|
73
|
+
def exceptions=(exceptions)
|
74
|
+
@exception_files = nil_split exceptions, ' '
|
75
|
+
end
|
76
|
+
|
77
|
+
def ignore_chars
|
78
|
+
nil_join @ignore_characters, ", "
|
79
|
+
end
|
80
|
+
|
81
|
+
def ignore_chars=(ignore_chars)
|
82
|
+
@ignore_characters = nil_split ignore_chars, /,\s?/
|
83
|
+
end
|
84
|
+
|
85
|
+
def prefix_fields
|
86
|
+
nil_join @prefix_field_names, ", "
|
87
|
+
end
|
88
|
+
|
89
|
+
def infix_fields
|
90
|
+
nil_join @infix_field_names, ", "
|
91
|
+
end
|
92
|
+
|
93
|
+
def ngram_chars
|
94
|
+
nil_join @ngram_characters, ", "
|
95
|
+
end
|
96
|
+
|
97
|
+
def ngram_chars=(ngram_chars)
|
98
|
+
@ngram_characters = nil_split ngram_chars, /,\s?/
|
99
|
+
end
|
100
|
+
|
101
|
+
def phrase_boundary
|
102
|
+
nil_join @phrase_boundaries, ", "
|
103
|
+
end
|
104
|
+
|
105
|
+
def phrase_boundary=(phrase_boundary)
|
106
|
+
@phrase_boundaries = nil_split phrase_boundary, /,\s?/
|
107
|
+
end
|
108
|
+
|
109
|
+
def html_remove_elements
|
110
|
+
nil_join @html_remove_element_tags, ", "
|
111
|
+
end
|
112
|
+
|
113
|
+
def html_remove_elements=(html_remove_elements)
|
114
|
+
@html_remove_element_tags = nil_split html_remove_elements, /,\s?/
|
115
|
+
end
|
116
|
+
|
117
|
+
def render
|
118
|
+
raise ConfigurationError, "#{@name} #{@sources.inspect} #{@path} #{@parent}" unless valid?
|
119
|
+
|
120
|
+
inherited_name = "#{name}"
|
121
|
+
inherited_name << " : #{parent}" if parent
|
122
|
+
(
|
123
|
+
@sources.collect { |s| s.render } +
|
124
|
+
["index #{inherited_name}", "{"] +
|
125
|
+
settings_body +
|
126
|
+
["}", ""]
|
127
|
+
).join("\n")
|
128
|
+
end
|
129
|
+
|
130
|
+
def valid?
|
131
|
+
(!@name.nil?) && (!( @sources.length == 0 || @path.nil? ) || !@parent.nil?)
|
132
|
+
end
|
133
|
+
|
134
|
+
private
|
135
|
+
|
136
|
+
def nil_split(string, pattern)
|
137
|
+
(string || "").split(pattern)
|
138
|
+
end
|
139
|
+
|
140
|
+
def nil_join(array, delimiter)
|
141
|
+
if array.length == 0
|
142
|
+
nil
|
143
|
+
else
|
144
|
+
array.join(delimiter)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Riddle
|
2
|
+
class Configuration
|
3
|
+
class Indexer < Riddle::Configuration::Section
|
4
|
+
self.settings = [:mem_limit, :max_iops, :max_iosize, :max_xmlpipe2_field,
|
5
|
+
:write_buffer]
|
6
|
+
|
7
|
+
attr_accessor *self.settings
|
8
|
+
|
9
|
+
def render
|
10
|
+
raise ConfigurationError unless valid?
|
11
|
+
|
12
|
+
(
|
13
|
+
["indexer", "{"] +
|
14
|
+
settings_body +
|
15
|
+
["}", ""]
|
16
|
+
).join("\n")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Riddle
|
2
|
+
class Configuration
|
3
|
+
class RemoteIndex
|
4
|
+
attr_accessor :address, :port, :name
|
5
|
+
|
6
|
+
def initialize(address, port, name)
|
7
|
+
@address = address
|
8
|
+
@port = port
|
9
|
+
@name = name
|
10
|
+
end
|
11
|
+
|
12
|
+
def remote
|
13
|
+
"#{address}:#{port}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Riddle
|
2
|
+
class Configuration
|
3
|
+
class Searchd < Riddle::Configuration::Section
|
4
|
+
self.settings = [:listen, :address, :port, :log, :query_log,
|
5
|
+
:read_timeout, :client_timeout, :max_children, :pid_file, :max_matches,
|
6
|
+
:seamless_rotate, :preopen_indexes, :unlink_old, :attr_flush_period,
|
7
|
+
:ondisk_dict_default, :max_packet_size, :mva_updates_pool,
|
8
|
+
:crash_log_path, :max_filters, :max_filter_values, :listen_backlog,
|
9
|
+
:read_buffer, :read_unhinted]
|
10
|
+
|
11
|
+
attr_accessor *self.settings
|
12
|
+
|
13
|
+
def render
|
14
|
+
raise ConfigurationError unless valid?
|
15
|
+
|
16
|
+
(
|
17
|
+
["searchd", "{"] +
|
18
|
+
settings_body +
|
19
|
+
["}", ""]
|
20
|
+
).join("\n")
|
21
|
+
end
|
22
|
+
|
23
|
+
def valid?
|
24
|
+
!( @port.nil? || @pid_file.nil? )
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Riddle
|
2
|
+
class Configuration
|
3
|
+
class Section
|
4
|
+
class << self
|
5
|
+
attr_accessor :settings
|
6
|
+
end
|
7
|
+
|
8
|
+
settings = []
|
9
|
+
|
10
|
+
def valid?
|
11
|
+
true
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def settings_body
|
17
|
+
self.class.settings.select { |setting|
|
18
|
+
!send(setting).nil?
|
19
|
+
}.collect { |setting|
|
20
|
+
if send(setting) == ""
|
21
|
+
conf = " #{setting} = "
|
22
|
+
else
|
23
|
+
conf = setting_to_array(setting).collect { |set|
|
24
|
+
" #{setting} = #{set}"
|
25
|
+
}
|
26
|
+
end
|
27
|
+
conf.length == 0 ? nil : conf
|
28
|
+
}.flatten.compact
|
29
|
+
end
|
30
|
+
|
31
|
+
def setting_to_array(setting)
|
32
|
+
value = send(setting)
|
33
|
+
case value
|
34
|
+
when Array then value
|
35
|
+
when TrueClass then [1]
|
36
|
+
when FalseClass then [0]
|
37
|
+
else
|
38
|
+
[value]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Riddle
|
2
|
+
class Configuration
|
3
|
+
class Source < Riddle::Configuration::Section
|
4
|
+
attr_accessor :name, :parent, :type
|
5
|
+
|
6
|
+
def render
|
7
|
+
raise ConfigurationError unless valid?
|
8
|
+
|
9
|
+
inherited_name = "#{name}"
|
10
|
+
inherited_name << " : #{parent}" if parent
|
11
|
+
(
|
12
|
+
["source #{inherited_name}", "{"] +
|
13
|
+
settings_body +
|
14
|
+
["}", ""]
|
15
|
+
).join("\n")
|
16
|
+
end
|
17
|
+
|
18
|
+
def valid?
|
19
|
+
!( @name.nil? || @type.nil? )
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Riddle
|
2
|
+
class Configuration
|
3
|
+
class SQLSource < Riddle::Configuration::Source
|
4
|
+
self.settings = [:type, :sql_host, :sql_user, :sql_pass, :sql_db,
|
5
|
+
:sql_port, :sql_sock, :mysql_connect_flags, :mysql_ssl_cert,
|
6
|
+
:mysql_ssl_key, :mysql_ssl_ca, :odbc_dsn, :sql_query_pre, :sql_query,
|
7
|
+
:sql_query_range, :sql_range_step, :sql_query_killlist, :sql_attr_uint,
|
8
|
+
:sql_attr_bool, :sql_attr_bigint, :sql_attr_timestamp,
|
9
|
+
:sql_attr_str2ordinal, :sql_attr_float, :sql_attr_multi,
|
10
|
+
:sql_query_post, :sql_query_post_index, :sql_ranged_throttle,
|
11
|
+
:sql_query_info, :mssql_winauth, :mssql_unicode, :unpack_zlib,
|
12
|
+
:unpack_mysqlcompress, :unpack_mysqlcompress_maxsize]
|
13
|
+
|
14
|
+
attr_accessor *self.settings
|
15
|
+
|
16
|
+
def initialize(name, type)
|
17
|
+
@name = name
|
18
|
+
@type = type
|
19
|
+
|
20
|
+
@sql_query_pre = []
|
21
|
+
@sql_attr_uint = []
|
22
|
+
@sql_attr_bool = []
|
23
|
+
@sql_attr_bigint = []
|
24
|
+
@sql_attr_timestamp = []
|
25
|
+
@sql_attr_str2ordinal = []
|
26
|
+
@sql_attr_float = []
|
27
|
+
@sql_attr_multi = []
|
28
|
+
@sql_query_post = []
|
29
|
+
@sql_query_post_index = []
|
30
|
+
@unpack_zlib = []
|
31
|
+
@unpack_mysqlcompress = []
|
32
|
+
end
|
33
|
+
|
34
|
+
def sql_query=(query)
|
35
|
+
unless query.nil?
|
36
|
+
max_length = 8178 # max is: 8192 - "sql_query = ".length - "\\\n".length
|
37
|
+
i = max_length
|
38
|
+
while i < query.length
|
39
|
+
i = query.rindex(" ", i)
|
40
|
+
query.insert(i, "\\" + "\n")
|
41
|
+
i = i + max_length
|
42
|
+
end
|
43
|
+
end
|
44
|
+
@sql_query = query
|
45
|
+
end
|
46
|
+
|
47
|
+
def valid?
|
48
|
+
super && (!( @sql_host.nil? || @sql_user.nil? || @sql_db.nil? ||
|
49
|
+
@sql_query.nil? ) || !@parent.nil?)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Riddle
|
2
|
+
class Configuration
|
3
|
+
class XMLSource < Riddle::Configuration::Source
|
4
|
+
self.settings = [:type, :xmlpipe_command, :xmlpipe_field,
|
5
|
+
:xmlpipe_attr_uint, :xmlpipe_attr_bool, :xmlpipe_attr_timestamp,
|
6
|
+
:xmlpipe_attr_str2ordinal, :xmlpipe_attr_float, :xmlpipe_attr_multi,
|
7
|
+
:xmlpipe_fixup_utf8]
|
8
|
+
|
9
|
+
attr_accessor *self.settings
|
10
|
+
|
11
|
+
def initialize(name, type)
|
12
|
+
@name = name
|
13
|
+
@type = type
|
14
|
+
|
15
|
+
@xmlpipe_field = []
|
16
|
+
@xmlpipe_attr_uint = []
|
17
|
+
@xmlpipe_attr_bool = []
|
18
|
+
@xmlpipe_attr_timestamp = []
|
19
|
+
@xmlpipe_attr_str2ordinal = []
|
20
|
+
@xmlpipe_attr_float = []
|
21
|
+
@xmlpipe_attr_multi = []
|
22
|
+
end
|
23
|
+
|
24
|
+
def valid?
|
25
|
+
super && ( !@xmlpipe_command.nil? || !parent.nil? )
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'riddle/configuration/section'
|
2
|
+
|
3
|
+
require 'riddle/configuration/distributed_index'
|
4
|
+
require 'riddle/configuration/index'
|
5
|
+
require 'riddle/configuration/indexer'
|
6
|
+
require 'riddle/configuration/remote_index'
|
7
|
+
require 'riddle/configuration/searchd'
|
8
|
+
require 'riddle/configuration/source'
|
9
|
+
require 'riddle/configuration/sql_source'
|
10
|
+
require 'riddle/configuration/xml_source'
|
11
|
+
|
12
|
+
module Riddle
|
13
|
+
class Configuration
|
14
|
+
class ConfigurationError < StandardError #:nodoc:
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_reader :indexes, :searchd
|
18
|
+
attr_accessor :indexer
|
19
|
+
|
20
|
+
def initialize
|
21
|
+
@indexer = Riddle::Configuration::Indexer.new
|
22
|
+
@searchd = Riddle::Configuration::Searchd.new
|
23
|
+
@indexes = []
|
24
|
+
end
|
25
|
+
|
26
|
+
def render
|
27
|
+
(
|
28
|
+
[@indexer.render, @searchd.render] +
|
29
|
+
@indexes.collect { |index| index.render }
|
30
|
+
).join("\n")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Riddle
|
2
|
+
class Controller
|
3
|
+
attr_accessor :path, :bin_path, :searchd_binary_name, :indexer_binary_name
|
4
|
+
|
5
|
+
def initialize(configuration, path)
|
6
|
+
@configuration = configuration
|
7
|
+
@path = path
|
8
|
+
|
9
|
+
@bin_path = ''
|
10
|
+
@searchd_binary_name = 'searchd'
|
11
|
+
@indexer_binary_name = 'indexer'
|
12
|
+
end
|
13
|
+
|
14
|
+
def sphinx_version
|
15
|
+
`#{indexer} 2>&1`[/^Sphinx (\d\.\d\.\d)/, 1]
|
16
|
+
rescue
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def index(*indexes)
|
21
|
+
options = indexes.last.is_a?(Hash) ? indexes.pop : {}
|
22
|
+
indexes << '--all' if indexes.empty?
|
23
|
+
|
24
|
+
cmd = "#{indexer} --config #{@path} #{indexes.join(' ')}"
|
25
|
+
cmd << " --rotate" if running?
|
26
|
+
options[:verbose] ? system(cmd) : `#{cmd}`
|
27
|
+
end
|
28
|
+
|
29
|
+
def start
|
30
|
+
return if running?
|
31
|
+
|
32
|
+
cmd = "#{searchd} --pidfile --config #{@path}"
|
33
|
+
|
34
|
+
if RUBY_PLATFORM =~ /mswin/
|
35
|
+
system("start /B #{cmd} 1> NUL 2>&1")
|
36
|
+
else
|
37
|
+
`#{cmd}`
|
38
|
+
end
|
39
|
+
|
40
|
+
sleep(1)
|
41
|
+
|
42
|
+
unless running?
|
43
|
+
puts "Failed to start searchd daemon. Check #{@configuration.searchd.log}."
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def stop
|
48
|
+
return unless running?
|
49
|
+
Process.kill('SIGTERM', pid.to_i)
|
50
|
+
rescue Errno::EINVAL
|
51
|
+
Process.kill('SIGKILL', pid.to_i)
|
52
|
+
end
|
53
|
+
|
54
|
+
def pid
|
55
|
+
if File.exists?(@configuration.searchd.pid_file)
|
56
|
+
File.read(@configuration.searchd.pid_file)[/\d+/]
|
57
|
+
else
|
58
|
+
nil
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def running?
|
63
|
+
!!pid && !!Process.kill(0, pid.to_i)
|
64
|
+
rescue
|
65
|
+
false
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def indexer
|
71
|
+
"#{bin_path}#{indexer_binary_name}"
|
72
|
+
end
|
73
|
+
|
74
|
+
def searchd
|
75
|
+
"#{bin_path}#{searchd_binary_name}"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'socket'
|
2
|
+
require 'timeout'
|
3
|
+
|
4
|
+
module Riddle #:nodoc:
|
5
|
+
class ConnectionError < StandardError #:nodoc:
|
6
|
+
#
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.escape_pattern
|
10
|
+
Thread.current[:riddle_escape_pattern] ||= /[\(\)\|\-!@~"&\/]/
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.escape_pattern=(pattern)
|
14
|
+
Thread.current[:riddle_escape_pattern] = pattern
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.escape(string)
|
18
|
+
string.gsub(escape_pattern) { |char| "\\#{char}" }
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.loaded_version
|
22
|
+
@@sphinx_version
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.loaded_version=(version)
|
26
|
+
@@sphinx_version = version
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.version_warning
|
30
|
+
return if loaded_version
|
31
|
+
|
32
|
+
STDERR.puts %Q{
|
33
|
+
Riddle cannot detect Sphinx on your machine, and so can't determine which
|
34
|
+
version of Sphinx you are planning on using. Please use one of the following
|
35
|
+
lines after "require 'riddle'" to avoid this warning.
|
36
|
+
|
37
|
+
require 'riddle/0.9.8'
|
38
|
+
# or
|
39
|
+
require 'riddle/0.9.9'
|
40
|
+
|
41
|
+
}
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
require 'riddle/auto_version'
|
46
|
+
require 'riddle/client'
|
47
|
+
require 'riddle/configuration'
|
48
|
+
require 'riddle/controller'
|
49
|
+
|
50
|
+
Riddle.loaded_version = nil
|
51
|
+
Riddle::AutoVersion.configure
|