mongoid-giza 0.1.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.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/.travis.yml +6 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +152 -0
- data/Rakefile +11 -0
- data/lib/mongoid/giza.rb +160 -0
- data/lib/mongoid/giza/configuration.rb +136 -0
- data/lib/mongoid/giza/dynamic_index.rb +37 -0
- data/lib/mongoid/giza/index.rb +101 -0
- data/lib/mongoid/giza/index/attribute.rb +39 -0
- data/lib/mongoid/giza/index/field.rb +27 -0
- data/lib/mongoid/giza/indexer.rb +33 -0
- data/lib/mongoid/giza/models/giza_id.rb +27 -0
- data/lib/mongoid/giza/railtie.rb +17 -0
- data/lib/mongoid/giza/search.rb +83 -0
- data/lib/mongoid/giza/version.rb +5 -0
- data/lib/mongoid/giza/xml_pipe2.rb +67 -0
- data/mongoid-giza.gemspec +32 -0
- data/spec/mongoid/giza/configuration_spec.rb +340 -0
- data/spec/mongoid/giza/dynamic_index_spec.rb +32 -0
- data/spec/mongoid/giza/index/attribute_spec.rb +36 -0
- data/spec/mongoid/giza/index/field_spec.rb +25 -0
- data/spec/mongoid/giza/index_spec.rb +162 -0
- data/spec/mongoid/giza/indexer_spec.rb +87 -0
- data/spec/mongoid/giza/models/giza_id_spec.rb +30 -0
- data/spec/mongoid/giza/search_spec.rb +100 -0
- data/spec/mongoid/giza/xml_pipe2_spec.rb +98 -0
- data/spec/mongoid/giza_spec.rb +282 -0
- data/spec/spec_helper.rb +51 -0
- metadata +227 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 150e88a193d198b7ee59e633753808457f01f9d0
|
4
|
+
data.tar.gz: dd2c1cc23492df7aa5e1c3e9c3fd6b13a578486a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 632f8929ab2a00803101594e1dc0e0bdd98164ef984797bb889eaaa4d90ebfef1250e7c94ad3f00f2eadab1313b4b36b49dd9d2969010b585df34a6b10f2bff1
|
7
|
+
data.tar.gz: 5eadf9661bc8697db39111932e5677ed1df5199269cef298fc2cf0788a95de779d1c8a63e3f783bb9877556ce9e3f9d553ecfd07f24ef6f8ef3602fcb5dc6d7e
|
data/.gitignore
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
.ruby-gemset
|
19
|
+
.ruby-version
|
20
|
+
.rspec
|
21
|
+
turbulence
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 YADEV Team
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
# Mongoid::Giza [](https://travis-ci.org/yadevteam/mongoid-giza) [](https://codeclimate.com/github/yadevteam/mongoid-giza) [](https://coveralls.io/r/yadevteam/mongoid-giza)
|
2
|
+
|
3
|
+
Mongoid layer for the Sphinx fulltext search server that supports block fields and dynamic indexes
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem "mongoid-giza"
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install mongoid-giza
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
:warning: **Before proceeding is extremely recommended to read the [Sphinx documentation](http://sphinxsearch.com/docs/current.html) if you are not yet familiar with it. Reading up to chapter 5 is enought to get you going.**
|
22
|
+
|
23
|
+
### Setting up indexes on models
|
24
|
+
|
25
|
+
Use a `sphinx_index` block to create a new index.
|
26
|
+
|
27
|
+
The `sphinx_index` method may receive optional settings that will be set in this index's section or in its source section on the generated sphinx configuration file.
|
28
|
+
These settings take precedence to the defaults defined in `giza.yml`.
|
29
|
+
|
30
|
+
A model may have more than one index, but they need to have different names.
|
31
|
+
If two or more indexes have the same name the last one to be defined is the one which will exist.
|
32
|
+
|
33
|
+
An index name is the name of the class it's defined on unless overwritten by the `name` method inside the index definition block.
|
34
|
+
|
35
|
+
Besides `name`, `field`, `attribute` and `criteria` are the methods avaible inside the index definition block.
|
36
|
+
|
37
|
+
Both `field` and `attribute` take a name as first parameter that may match with a Mongoid field. In this case the value of the field will be used when indexing the objects.
|
38
|
+
The `attribute` method may receive a second paramenter that defines the type of the attribute. If it is ommited, than the type of the Mongoid field will be used.
|
39
|
+
|
40
|
+
At last, both methods may take an block with the object as parameter. The return of the block will be used as the value of the field or attribute when indexing.
|
41
|
+
|
42
|
+
The `criteria` method receives a `Mongoid::Criteria` that will be used to select the objects that will be indexed.
|
43
|
+
It's `Class.all` by default.
|
44
|
+
|
45
|
+
**Example:** Creating a index on the person model
|
46
|
+
|
47
|
+
```
|
48
|
+
class Person
|
49
|
+
include Mongoid::Document
|
50
|
+
include Mongoid::Giza
|
51
|
+
|
52
|
+
field :name
|
53
|
+
field :age, type: Integer
|
54
|
+
|
55
|
+
sphinx_index(enable_star: 1) do
|
56
|
+
field :name
|
57
|
+
field :bio do |person|
|
58
|
+
"#{person.name.capitalize} was born #{person.age.years.days} ago"
|
59
|
+
end
|
60
|
+
attribute :age
|
61
|
+
end
|
62
|
+
end
|
63
|
+
```
|
64
|
+
|
65
|
+
#### Dynamic Indexes
|
66
|
+
|
67
|
+
Because of the schemaless nature of MongoDB, sometimes you may find problems mapping your mongo models to sphinx indexes.
|
68
|
+
To circunvent this limitation Mongoid::Giza supports dynamic indexes.
|
69
|
+
|
70
|
+
When you define a dynamic index, it will generate a regular index based on your definition for each object of the class.
|
71
|
+
This allows the creation of different indexes for objects of the same model that have different dynamic fields.
|
72
|
+
|
73
|
+
Although it's not necessary, dynamic indexes are better used together with a `criteria`,
|
74
|
+
so it's possible to control which objects of the class will be indexed on each determined index.
|
75
|
+
|
76
|
+
To create a dynamic index all that needs to be done is pass the object to the `sphin_index` block.
|
77
|
+
|
78
|
+
**Example:** Creating a dynamic index on the person model.
|
79
|
+
This dynamic index will generate one index for each job that is associated to a person.
|
80
|
+
On each index only the people that have that job will be indexed.
|
81
|
+
Finally each dynamic attribute of the job will be a field on its index.
|
82
|
+
|
83
|
+
```
|
84
|
+
class Job
|
85
|
+
include Mongoid::Document
|
86
|
+
|
87
|
+
field :name
|
88
|
+
# each job object has specific dynamic fields
|
89
|
+
|
90
|
+
has_many :people
|
91
|
+
end
|
92
|
+
|
93
|
+
class Person
|
94
|
+
include Mongoid::Document
|
95
|
+
include Mongoid::Giza
|
96
|
+
|
97
|
+
field :name
|
98
|
+
field :age, type: Integer
|
99
|
+
|
100
|
+
belongs_to :job
|
101
|
+
|
102
|
+
sphinx_index do |person|
|
103
|
+
name person.job.name
|
104
|
+
criteria Person.where(job: person.job)
|
105
|
+
person.job.attributes.except("name").each do |attr, val|
|
106
|
+
field attr.to_sym
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
```
|
111
|
+
|
112
|
+
### Searching
|
113
|
+
|
114
|
+
Use the `search` block on the class that have the indexes where the search should run.
|
115
|
+
It returns a result array, where each position of the array is a [riddle result hash](http://rdoc.info/github/pat/riddle/Riddle/Client#query-instance_method), plus a key with the class name, that has the `Mongoid::Criteria` that selects the matching objects from the mongo database.
|
116
|
+
|
117
|
+
Inside the `search` block use the `fulltext` method to perform a fulltext search.
|
118
|
+
If multiple `fulltext` are called inside a `search` block, then each one will generate a separated query and will return a new position o the results array.
|
119
|
+
|
120
|
+
To filter your search using the attributes defined on the index creation, use the `with` and `without` methods, that accept the name of the attribute and the value or range.
|
121
|
+
|
122
|
+
To order the results, use the `order_by` method, that receives the *attribute* used for sorting and a Symbol, that can be either `:asc` or `:desc`.
|
123
|
+
|
124
|
+
Every other [Riddle::Client](http://rdoc.info/github/pat/riddle/Riddle/Client) setter is avaible without the **=**, to maintain the DSL syntax consistent.
|
125
|
+
|
126
|
+
**Example:** Searching on the person class
|
127
|
+
|
128
|
+
```
|
129
|
+
results = Person.search do
|
130
|
+
fulltext "john"
|
131
|
+
with :age 18..40
|
132
|
+
order_by :age :asc
|
133
|
+
end
|
134
|
+
|
135
|
+
results.first[:Person].each do |person|
|
136
|
+
puts "#{person.name} is #{person.age} years old"
|
137
|
+
end
|
138
|
+
```
|
139
|
+
|
140
|
+
## TODO
|
141
|
+
|
142
|
+
* Support delta indexing
|
143
|
+
* Support RT indexes
|
144
|
+
* Support distributed indexes
|
145
|
+
|
146
|
+
## Contributing
|
147
|
+
|
148
|
+
1. Fork it
|
149
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
150
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
151
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
152
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/lib/mongoid/giza.rb
ADDED
@@ -0,0 +1,160 @@
|
|
1
|
+
require "docile"
|
2
|
+
require "mongoid"
|
3
|
+
require "riddle"
|
4
|
+
require "mongoid/giza/configuration"
|
5
|
+
require "mongoid/giza/dynamic_index"
|
6
|
+
require "mongoid/giza/index"
|
7
|
+
require "mongoid/giza/index/field"
|
8
|
+
require "mongoid/giza/index/attribute"
|
9
|
+
require "mongoid/giza/indexer"
|
10
|
+
require "mongoid/giza/models/giza_id"
|
11
|
+
require "mongoid/giza/railtie" if defined?(Rails)
|
12
|
+
require "mongoid/giza/search"
|
13
|
+
require "mongoid/giza/version"
|
14
|
+
require "mongoid/giza/xml_pipe2"
|
15
|
+
|
16
|
+
module Mongoid
|
17
|
+
|
18
|
+
# Module that should be included in a Mongoid::Document in order to
|
19
|
+
# index fields of documents of this class
|
20
|
+
#
|
21
|
+
# @example Creating a simple index with a full-text field (named fts) and an attribute (named attr)
|
22
|
+
# class Person
|
23
|
+
# include Mongoid::Document
|
24
|
+
# include Mongoid::Giza
|
25
|
+
#
|
26
|
+
# field :name
|
27
|
+
# field :age, type: Integer
|
28
|
+
#
|
29
|
+
# sphinx_index do
|
30
|
+
# field :name
|
31
|
+
# attribute :age
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# @example Searching the previously defined index for people named John between 18 and 59 years old
|
36
|
+
# results = Person.search do
|
37
|
+
# fulltext "john"
|
38
|
+
# with age: 18..59
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# results.first[:Person].first # => First object that matched
|
42
|
+
module Giza
|
43
|
+
extend ActiveSupport::Concern
|
44
|
+
|
45
|
+
included do
|
46
|
+
Mongoid::Giza::GizaID.create(id: name.to_sym)
|
47
|
+
@giza_configuration = Configuration.instance
|
48
|
+
@static_sphinx_indexes = {}
|
49
|
+
@generated_sphinx_indexes = {}
|
50
|
+
@dynamic_sphinx_indexes = []
|
51
|
+
end
|
52
|
+
|
53
|
+
# Retrives the sphinx compatible id of the object.
|
54
|
+
# If the id does not exists yet, it will be generated
|
55
|
+
#
|
56
|
+
# @return [Integer] the object's integer id generated by Giza
|
57
|
+
def giza_id
|
58
|
+
set(:giza_id, GizaID.next_id(self.class.name.to_sym)) if self[:giza_id].nil?
|
59
|
+
self[:giza_id]
|
60
|
+
end
|
61
|
+
|
62
|
+
module ClassMethods
|
63
|
+
attr_reader :static_sphinx_indexes, :generated_sphinx_indexes, :dynamic_sphinx_indexes
|
64
|
+
|
65
|
+
# Class method that defines a index relative to the current class' objects.
|
66
|
+
# If an argument is given in the block then a dynamic index will be created.
|
67
|
+
# Otherwise it will create a static index.
|
68
|
+
#
|
69
|
+
# @param settings [Hash] optional settings for the index and it's source
|
70
|
+
# @param block [Proc] a block that will be evaluated on an {Mongoid::Giza::Index}
|
71
|
+
def sphinx_index(settings = {}, &block)
|
72
|
+
if block_given?
|
73
|
+
if block.arity > 0
|
74
|
+
add_dynamic_sphinx_index(settings, block)
|
75
|
+
else
|
76
|
+
add_static_sphinx_index(settings, block)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Adds an dynamic index to the class.
|
82
|
+
# Will also automatically generate the dynamic index for each object of the class
|
83
|
+
#
|
84
|
+
# @param settings [Hash] settings for the index and it's source
|
85
|
+
# @param block [Proc] a block that will be evaluated on an {Mongoid::Giza::Index}.
|
86
|
+
# The block receives one argument that is the current object of the class for which the index will be generated
|
87
|
+
def add_dynamic_sphinx_index(settings, block)
|
88
|
+
dynamic_index = DynamicIndex.new(self, settings, block)
|
89
|
+
dynamic_sphinx_indexes << dynamic_index
|
90
|
+
process_dynamic_sphinx_index(dynamic_index)
|
91
|
+
end
|
92
|
+
|
93
|
+
# Adds an static index to the class
|
94
|
+
#
|
95
|
+
# @param settings [Hash] settings for the index and it's source
|
96
|
+
# @param block [Proc] a block that will be evaluated on an {Mongoid::Giza::Index}.
|
97
|
+
def add_static_sphinx_index(settings, block)
|
98
|
+
index = Index.new(self, settings)
|
99
|
+
Docile.dsl_eval(index, &block)
|
100
|
+
static_sphinx_indexes[index.name] = index
|
101
|
+
@giza_configuration.add_index(index)
|
102
|
+
end
|
103
|
+
|
104
|
+
# Generates the indexes from the dynamic index and
|
105
|
+
# registers them on the class and on the configuration
|
106
|
+
#
|
107
|
+
# @param dynamic_index [Mongoid::Giza::DynamicIndex] the dynamic index which will generate the static indexes from
|
108
|
+
def process_dynamic_sphinx_index(dynamic_index)
|
109
|
+
generated = dynamic_index.generate!
|
110
|
+
generated_sphinx_indexes.merge!(generated)
|
111
|
+
generated.each { |name, index| @giza_configuration.add_index(index, true) }
|
112
|
+
end
|
113
|
+
|
114
|
+
# Class method that implements a search DSL using a {Mongoid::Giza::Search} object.
|
115
|
+
# The search will run on indexes defined on the class unless it's overwritten using {Mongoid::Giza::Search#indexes=}
|
116
|
+
#
|
117
|
+
# @param block [Proc] a block that will be evaluated on a {Mongoid::Giza::Search}
|
118
|
+
#
|
119
|
+
# @return [Array] an Array with Riddle result hashes containing an additional key with the name of the class.
|
120
|
+
# The value of this aditional key is a Mongoid::Criteria that return the actual objects of the match
|
121
|
+
def search(&block)
|
122
|
+
search = Mongoid::Giza::Search.new(@giza_configuration.searchd.address, @giza_configuration.searchd.port, *sphinx_indexes_names)
|
123
|
+
Docile.dsl_eval(search, &block)
|
124
|
+
results = search.run
|
125
|
+
results.each { |result| result[name.to_sym] = self.in(giza_id: result[:matches].map { |match| match[:doc] }) }
|
126
|
+
end
|
127
|
+
|
128
|
+
# Regenerates all dynamic indexes of the class
|
129
|
+
def regenerate_dynamic_sphinx_indexes
|
130
|
+
generated_sphinx_indexes.clear
|
131
|
+
dynamic_sphinx_indexes.each { |dynamic_index| process_dynamic_sphinx_index(dynamic_index) }
|
132
|
+
end
|
133
|
+
|
134
|
+
# Execute the indexing routines of the indexes defined on the class.
|
135
|
+
# This means (re)create the sphinx configuration file and then execute the indexer program on it.
|
136
|
+
# If no index names are supplied than all indexes defined on the class will be indexed.
|
137
|
+
# If none of the index names supplied are on this class then nothing is indexed
|
138
|
+
#
|
139
|
+
# @param names [Array] a list of index names of this class that will be indexed
|
140
|
+
def sphinx_indexer!(*names)
|
141
|
+
indexes_names = names.length > 0 ? sphinx_indexes_names.select { |name| names.include? name } : sphinx_indexes_names
|
142
|
+
Mongoid::Giza::Indexer.instance.index!(*indexes_names) if indexes_names.length > 0
|
143
|
+
end
|
144
|
+
|
145
|
+
# Retrieves all the sphinx indexes defined on this class, static and dynamic
|
146
|
+
#
|
147
|
+
# @return [Array] an Array of indexes from the current class {Mongoid::Giza::Index}
|
148
|
+
def sphinx_indexes
|
149
|
+
static_sphinx_indexes.merge(generated_sphinx_indexes)
|
150
|
+
end
|
151
|
+
|
152
|
+
# Retrieves all the names of sphinx indexes defined on this class, static and dynamic
|
153
|
+
#
|
154
|
+
# @return [Array] an Array of names of indexes from the current class {Mongoid::Giza::Index}
|
155
|
+
def sphinx_indexes_names
|
156
|
+
static_sphinx_indexes.merge(generated_sphinx_indexes).keys
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
require "erb"
|
2
|
+
require "ostruct"
|
3
|
+
require "yaml"
|
4
|
+
|
5
|
+
module Mongoid
|
6
|
+
module Giza
|
7
|
+
|
8
|
+
# Holds the configuration of the module
|
9
|
+
class Configuration < Riddle::Configuration
|
10
|
+
include Singleton
|
11
|
+
|
12
|
+
attr_reader :source, :index, :file
|
13
|
+
|
14
|
+
# Creates the configuration instance
|
15
|
+
def initialize
|
16
|
+
super
|
17
|
+
@source = Riddle::Configuration::XMLSource.new(:source, :xmlpipe2)
|
18
|
+
@index = Riddle::Configuration::Index.new(:index, @source)
|
19
|
+
@file = OpenStruct.new(output_path: "./sphinx.conf")
|
20
|
+
@static_indexes = {}
|
21
|
+
@generated_indexes = {}
|
22
|
+
end
|
23
|
+
|
24
|
+
# Loads a YAML file with settings defined.
|
25
|
+
# Settings that are not recognized are ignored
|
26
|
+
#
|
27
|
+
# @param path [String] path to the YAML file which contains the settings defined
|
28
|
+
# @param env [String] environment whoose settings will be loaded
|
29
|
+
def load(path, env)
|
30
|
+
YAML.load(File.open(path).read)[env].each do |section_name, settings|
|
31
|
+
section = instance_variable_get("@#{section_name}")
|
32
|
+
if !section.nil?
|
33
|
+
settings.each do |setting, value|
|
34
|
+
method = "#{setting}="
|
35
|
+
section.send(method, value) if section.respond_to?(method)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Adds an index to the sphinx configuration,
|
42
|
+
# so this index can be rendered on the configuration file
|
43
|
+
#
|
44
|
+
# @param index [Mongoid::Giza::Index] the index that will be added to the configuration
|
45
|
+
# @param generated [TrueClass, FalseClass] determines if this index was generated from a {Mongoid::Giza::DynamicIndex}
|
46
|
+
def add_index(index, generated = false)
|
47
|
+
riddle_index = create_index(index)
|
48
|
+
if generated
|
49
|
+
position = register_index(riddle_index, @generated_indexes)
|
50
|
+
else
|
51
|
+
position = register_index(riddle_index, @static_indexes)
|
52
|
+
end
|
53
|
+
indices[position] = riddle_index
|
54
|
+
end
|
55
|
+
|
56
|
+
# Creates a new Riddle::Index based on the given {Mongoid::Giza::Index}
|
57
|
+
#
|
58
|
+
# @param index [Mongoid::Giza::Index] the index to generate the configuration from
|
59
|
+
#
|
60
|
+
# @return [Riddle::Configuration::Index] the created riddle index
|
61
|
+
def create_index(index)
|
62
|
+
source = Riddle::Configuration::XMLSource.new(index.name, :xmlpipe2)
|
63
|
+
riddle_index = Riddle::Configuration::Index.new(index.name, source)
|
64
|
+
apply_default_settings(@index, riddle_index, index)
|
65
|
+
apply_default_settings(@source, source, index)
|
66
|
+
apply_user_settings(index, riddle_index)
|
67
|
+
apply_user_settings(index, source)
|
68
|
+
riddle_index.path = File.join(riddle_index.path, index.name.to_s)
|
69
|
+
riddle_index.charset_type = "utf-8"
|
70
|
+
riddle_index
|
71
|
+
end
|
72
|
+
|
73
|
+
# Adds the riddle index to it's respective collection
|
74
|
+
#
|
75
|
+
# @param index [Riddle::Configuration::Index] the index that will be registrated
|
76
|
+
# @param indexes [Hash] the collection which will hold this index
|
77
|
+
#
|
78
|
+
# @return [Integer] the position where this index should be inserted on the configuration indices array
|
79
|
+
def register_index(index, indexes)
|
80
|
+
position = indexes.has_key?(index.name) ? indices.index(indexes[index.name]) : indices.length
|
81
|
+
indexes[index.name] = index
|
82
|
+
position
|
83
|
+
end
|
84
|
+
|
85
|
+
# Applies the settings defined on an object loaded from the configuration to a Riddle::Configuration::Index or Riddle::Configuration::XMLSource instance.
|
86
|
+
# Used internally by {#add_index} so you should never need to call it directly
|
87
|
+
#
|
88
|
+
# @param default [Riddle::Configuration::Index, Riddle::Configuration::XMLSource] the object that holds the global settings values
|
89
|
+
# @param section [Riddle::Configuration::Index, Riddle::Configuration::XMLSource] the object that settings are being set
|
90
|
+
def apply_default_settings(default, section, index)
|
91
|
+
default.class.settings.each do |setting|
|
92
|
+
method = "#{setting}="
|
93
|
+
value = interpolate_string(default.send("#{setting}"), index)
|
94
|
+
section.send(method, value) if !value.nil? and section.respond_to?(method)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# Applies the settings defined on a {Mongoid::Giza::Index} to the Riddle::Configuration::Index or Riddle::Configuration::XMLSource.
|
99
|
+
# Used internally by {#add_index} so you should never need to call it directly
|
100
|
+
#
|
101
|
+
# @param index [Mongoid::Giza::Index] the index where the settings were defined
|
102
|
+
# @param section [Riddle::Configuration::Index, Riddle::Configuration::XMLSource] where the settings will be applied
|
103
|
+
def apply_user_settings(index, section)
|
104
|
+
index.settings.each do |setting, value|
|
105
|
+
method = "#{setting}="
|
106
|
+
section.send(method, interpolate_string(value, index)) if section.respond_to?(method)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# Interpolates a value if it's a String using ERB.
|
111
|
+
# Useful for defining dynamic settings.
|
112
|
+
# The ERB template may reference to the current {Mongoid::Giza::Index} and it's methods
|
113
|
+
#
|
114
|
+
# @param value [String] the ERB template that will be interpolated
|
115
|
+
# @param index [Mongoid::Giza::Index] the index that will be accessible from the template
|
116
|
+
#
|
117
|
+
# @return [Object] if value was a String and contains ERB syntax than it will beinterpolated and returned.
|
118
|
+
# Otherwise it will return the original value
|
119
|
+
def interpolate_string(value, index)
|
120
|
+
namespace = OpenStruct.new(index: index)
|
121
|
+
value.is_a?(String) ? ERB.new(value).result(namespace.instance_eval { binding }) : value
|
122
|
+
end
|
123
|
+
|
124
|
+
# Renders the configuration to the output_path
|
125
|
+
def render
|
126
|
+
File.open(@file.output_path, "w") { |file| file.write(super) }
|
127
|
+
end
|
128
|
+
|
129
|
+
# Removes all Riddle::Index from the indices Array that where created from a generated {Mongoid::Giza::Index}
|
130
|
+
def clear_generated_indexes
|
131
|
+
@generated_indexes.each { |name, index| indices.delete(index) }
|
132
|
+
@generated_indexes = {}
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|