picky 3.2.0 → 3.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. data/aux/picky/cli.rb +3 -1
  2. data/lib/picky/backends/backend.rb +16 -0
  3. data/lib/picky/backends/file/basic.rb +18 -9
  4. data/lib/picky/backends/file/json.rb +1 -0
  5. data/lib/picky/backends/file.rb +8 -4
  6. data/lib/picky/backends/helpers/file.rb +6 -0
  7. data/lib/picky/backends/memory/basic.rb +10 -2
  8. data/lib/picky/backends/memory/json.rb +1 -6
  9. data/lib/picky/backends/memory/marshal.rb +1 -6
  10. data/lib/picky/backends/memory/text.rb +1 -0
  11. data/lib/picky/backends/memory.rb +8 -4
  12. data/lib/picky/backends/redis/basic.rb +12 -9
  13. data/lib/picky/backends/redis.rb +10 -4
  14. data/lib/picky/bundle.rb +14 -0
  15. data/lib/picky/bundle_indexed.rb +110 -0
  16. data/lib/picky/bundle_indexing.rb +177 -0
  17. data/lib/picky/bundle_realtime.rb +80 -0
  18. data/lib/picky/categories.rb +5 -1
  19. data/lib/picky/category.rb +12 -20
  20. data/lib/picky/category_indexed.rb +3 -6
  21. data/lib/picky/category_indexing.rb +19 -18
  22. data/lib/picky/category_realtime.rb +5 -10
  23. data/lib/picky/extensions/symbol.rb +1 -1
  24. data/lib/picky/generators/partial/default.rb +1 -1
  25. data/lib/picky/generators/partial/postfix.rb +30 -0
  26. data/lib/picky/generators/partial/substring.rb +8 -2
  27. data/lib/picky/index.rb +3 -3
  28. data/lib/picky/index_indexing.rb +3 -2
  29. data/lib/picky/indexers/base.rb +0 -8
  30. data/lib/picky/indexers/parallel.rb +1 -1
  31. data/lib/picky/loader.rb +15 -15
  32. data/lib/picky/query/qualifier_category_mapper.rb +1 -1
  33. data/lib/picky/rack/harakiri.rb +3 -1
  34. data/lib/picky/sources/db.rb +11 -0
  35. data/lib/picky/statistics.rb +2 -2
  36. data/lib/picky/tokenizer.rb +1 -1
  37. data/lib/picky/tokenizers/location.rb +1 -1
  38. data/lib/picky/wrappers/bundle/calculation.rb +45 -0
  39. data/lib/picky/wrappers/bundle/delegators.rb +69 -0
  40. data/lib/picky/wrappers/bundle/exact_partial.rb +38 -0
  41. data/lib/picky/{indexed/wrappers → wrappers}/bundle/location.rb +6 -4
  42. data/lib/picky/wrappers/bundle/wrapper.rb +29 -0
  43. data/lib/picky/wrappers/category/exact_first.rb +55 -0
  44. data/lib/picky/wrappers/category/location.rb +33 -0
  45. data/lib/picky/{sources/wrappers → wrappers/sources}/base.rb +7 -3
  46. data/lib/picky/{sources/wrappers → wrappers/sources}/location.rb +3 -3
  47. data/lib/picky.rb +10 -11
  48. data/spec/aux/picky/cli_spec.rb +5 -5
  49. data/spec/lib/backends/backend_spec.rb +39 -0
  50. data/spec/lib/backends/file/basic_spec.rb +59 -0
  51. data/spec/lib/backends/file_spec.rb +105 -0
  52. data/spec/lib/backends/memory/basic_spec.rb +43 -15
  53. data/spec/lib/backends/memory_spec.rb +108 -54
  54. data/spec/lib/backends/redis/basic_spec.rb +81 -57
  55. data/spec/lib/backends/redis_spec.rb +120 -66
  56. data/spec/lib/category_indexed_spec.rb +12 -12
  57. data/spec/lib/category_indexing_spec.rb +23 -23
  58. data/spec/lib/category_spec.rb +14 -14
  59. data/spec/lib/cores_spec.rb +2 -2
  60. data/spec/lib/extensions/object_spec.rb +7 -7
  61. data/spec/lib/generators/partial/postfix_spec.rb +131 -0
  62. data/spec/lib/generators/partial/substring_spec.rb +29 -4
  63. data/spec/lib/generators/weights_generator_spec.rb +3 -3
  64. data/spec/lib/index_indexing_spec.rb +11 -15
  65. data/spec/lib/index_spec.rb +8 -8
  66. data/spec/lib/indexed/bundle_realtime_spec.rb +18 -18
  67. data/spec/lib/indexed/bundle_spec.rb +21 -21
  68. data/spec/lib/indexed/wrappers/bundle/calculation_spec.rb +9 -9
  69. data/spec/lib/indexed/wrappers/bundle/wrapper_spec.rb +8 -8
  70. data/spec/lib/indexed/wrappers/exact_first_spec.rb +16 -16
  71. data/spec/lib/indexers/base_spec.rb +6 -25
  72. data/spec/lib/indexes_spec.rb +33 -22
  73. data/spec/lib/indexing/bundle_partial_generation_speed_spec.rb +2 -2
  74. data/spec/lib/indexing/bundle_spec.rb +27 -28
  75. data/spec/lib/sources/wrappers/base_spec.rb +7 -7
  76. data/spec/lib/sources/wrappers/location_spec.rb +8 -8
  77. metadata +48 -38
  78. data/lib/picky/indexed/bundle.rb +0 -125
  79. data/lib/picky/indexed/bundle_realtime.rb +0 -76
  80. data/lib/picky/indexed/wrappers/bundle/calculation.rb +0 -47
  81. data/lib/picky/indexed/wrappers/bundle/wrapper.rb +0 -47
  82. data/lib/picky/indexed/wrappers/category/location.rb +0 -31
  83. data/lib/picky/indexed/wrappers/exact_first.rb +0 -59
  84. data/lib/picky/indexing/bundle.rb +0 -183
  85. data/lib/picky/indexing/wrappers/category/location.rb +0 -29
@@ -0,0 +1,80 @@
1
+ module Picky
2
+
3
+ class Bundle
4
+
5
+ # Removes the given id from the indexes.
6
+ #
7
+ def remove id
8
+ # Is it anywhere?
9
+ #
10
+ syms = @realtime_mapping[id]
11
+ return unless syms
12
+
13
+ syms.each do |sym|
14
+ ids = @inverted[sym]
15
+ ids.delete id
16
+
17
+ encoded = self.similarity_strategy.encoded sym
18
+
19
+ if ids.empty?
20
+ @inverted.delete sym
21
+ @weights.delete sym
22
+ # Since no element uses this sym anymore, we can delete the similarity for it.
23
+ # TODO Not really. Since multiple syms can point to the same encoded.
24
+ @similarity.delete encoded
25
+ else
26
+ @weights[sym] = self.weights_strategy.weight_for ids.size
27
+ end
28
+ end
29
+
30
+ @realtime_mapping.delete id
31
+ end
32
+
33
+ # Returns a reference to the array where the id has been added.
34
+ #
35
+ def add id, sym
36
+ ary = @inverted[sym]
37
+
38
+ syms = @realtime_mapping[id]
39
+ syms = (@realtime_mapping[id] = []) unless syms # TODO Nicefy.
40
+
41
+ # Inverted.
42
+ #
43
+ ids = if syms.include? sym
44
+ ids = @inverted[sym]
45
+ ids.delete id # Move id
46
+ ids.unshift id # to front
47
+ else
48
+ syms << sym
49
+ ids = @inverted[sym] ||= []
50
+ ids.unshift id
51
+ end
52
+
53
+ # Weights.
54
+ #
55
+ @weights[sym] = self.weights_strategy.weight_for ids.size
56
+
57
+ # Similarity.
58
+ #
59
+ if encoded = self.similarity_strategy.encoded(sym)
60
+ similarity = @similarity[encoded] ||= []
61
+ if similarity.include? sym
62
+ similarity.delete sym # Not completely correct, as others will also be affected, but meh.
63
+ similarity.unshift sym #
64
+ else
65
+ similarity.unshift sym
66
+ end
67
+ end
68
+ end
69
+
70
+ # Partializes the text and then adds each.
71
+ #
72
+ def add_partialized id, text
73
+ self.partial_strategy.each_partial text do |partial_text|
74
+ add id, partial_text
75
+ end
76
+ end
77
+
78
+ end
79
+
80
+ end
@@ -9,8 +9,12 @@ module Picky
9
9
  :map,
10
10
  :to => :categories
11
11
 
12
- each_delegate :reindex,
12
+ each_delegate :cache,
13
+ :dump,
13
14
  :each_category,
15
+ :empty,
16
+ :index,
17
+ :reindex,
14
18
  :to => :categories
15
19
 
16
20
  # A list of indexed categories.
@@ -2,7 +2,9 @@ module Picky
2
2
 
3
3
  class Category
4
4
 
5
- attr_reader :name
5
+ attr_reader :name,
6
+ :exact,
7
+ :partial
6
8
 
7
9
  # Mandatory params:
8
10
  # * name: Category name to use as identifier and file names.
@@ -38,20 +40,12 @@ module Picky
38
40
  no_partial = Generators::Partial::None.new
39
41
  no_similarity = Generators::Similarity::None.new
40
42
 
41
- @indexing_exact = Indexing::Bundle.new :exact, self, index.backend, weights, no_partial, similarity, options
42
- @indexing_partial = Indexing::Bundle.new :partial, self, index.backend, weights, partial, no_similarity, options
43
-
44
- # Indexed.
45
- #
46
- @indexed_exact = Indexed::Bundle.new :exact, self, index.backend, weights, no_partial, similarity
43
+ @exact = Bundle.new :exact, self, index.backend, weights, no_partial, similarity, options
47
44
  if partial.use_exact_for_partial?
48
- @indexed_partial = @indexed_exact
45
+ @partial = Wrappers::Bundle::ExactPartial.new @exact
49
46
  else
50
- @indexed_partial = Indexed::Bundle.new :partial, self, index.backend, weights, partial, no_similarity
47
+ @partial = Bundle.new :partial, self, index.backend, weights, partial, no_similarity, options
51
48
  end
52
-
53
- # @exact = exact_lambda.call(@exact, @partial) if exact_lambda = options[:exact_lambda]
54
- # @partial = partial_lambda.call(@exact, @partial) if partial_lambda = options[:partial_lambda]
55
49
  end
56
50
 
57
51
  # Indexes and reloads the category.
@@ -61,6 +55,11 @@ module Picky
61
55
  reload
62
56
  end
63
57
 
58
+ def dump
59
+ exact.dump
60
+ partial.dump
61
+ end
62
+
64
63
  # Index name.
65
64
  #
66
65
  def index_name
@@ -98,17 +97,10 @@ module Picky
98
97
  @prepared_index_file ||= Backends::Memory::Text.new prepared_index_path
99
98
  @prepared_index_file.open &block
100
99
  end
101
- # Creates the index directory including all necessary paths above it.
102
- #
103
- # Note: Interface method called by any indexers.
104
- #
105
- def prepare_index_directory
106
- FileUtils.mkdir_p index_directory
107
- end
108
100
 
109
101
  # The index directory for this category.
110
102
  #
111
- # TODO Push down into files?
103
+ # TODO Push down into files? Yes.
112
104
  #
113
105
  def index_directory
114
106
  @index_directory ||= "#{PICKY_ROOT}/index/#{PICKY_ENVIRONMENT}/#{@index.name}"
@@ -4,15 +4,12 @@ module Picky
4
4
  #
5
5
  class Category
6
6
 
7
- attr_reader :indexed_exact,
8
- :indexed_partial
9
-
10
7
  # Loads the index from cache.
11
8
  #
12
9
  def load_from_cache
13
10
  timed_exclaim %Q{"#{identifier}": Loading index from cache.}
14
- indexed_exact.load
15
- indexed_partial.load
11
+ exact.load
12
+ partial.load
16
13
  end
17
14
  alias reload load_from_cache
18
15
 
@@ -31,7 +28,7 @@ module Picky
31
28
  # Returns the right index bundle for this token.
32
29
  #
33
30
  def bundle_for token
34
- token.partial? ? indexed_partial : indexed_exact
31
+ token.partial? ? partial : exact
35
32
  end
36
33
 
37
34
  # Returns a combination for the token,
@@ -4,8 +4,8 @@ module Picky
4
4
  #
5
5
  class Category
6
6
 
7
- attr_reader :indexing_exact,
8
- :indexing_partial
7
+ attr_reader :exact,
8
+ :partial
9
9
 
10
10
  # Prepares and caches this category.
11
11
  #
@@ -19,10 +19,15 @@ module Picky
19
19
  # Indexes, creates the "prepared_..." file.
20
20
  #
21
21
  def prepare
22
+ empty
22
23
  with_data_snapshot do
23
24
  indexer.index [self]
24
25
  end
25
26
  end
27
+ def empty
28
+ exact.empty
29
+ partial.empty_configuration
30
+ end
26
31
 
27
32
  # Take a data snapshot if the source offers it.
28
33
  #
@@ -42,23 +47,19 @@ module Picky
42
47
  generate_caches_from_source
43
48
  generate_partial
44
49
  generate_caches_from_memory
45
- dump_caches
50
+ dump
46
51
  timed_exclaim %Q{"#{identifier}": Caching finished.}
47
52
  end
48
53
  # Generate the cache data.
49
54
  #
50
55
  def generate_caches_from_source
51
- indexing_exact.generate_caches_from_source
56
+ exact.generate_caches_from_source
52
57
  end
53
58
  def generate_partial
54
- indexing_partial.generate_partial_from indexing_exact.inverted
59
+ partial.generate_partial_from exact.inverted
55
60
  end
56
61
  def generate_caches_from_memory
57
- indexing_partial.generate_caches_from_memory
58
- end
59
- def dump_caches
60
- indexing_exact.dump
61
- indexing_partial.dump
62
+ partial.generate_caches_from_memory
62
63
  end
63
64
 
64
65
  # Return an appropriate source.
@@ -111,16 +112,16 @@ module Picky
111
112
  #
112
113
  def check
113
114
  timed_exclaim "Checking #{identifier}."
114
- indexing_exact.raise_unless_cache_exists
115
- indexing_partial.raise_unless_cache_exists
115
+ exact.raise_unless_cache_exists
116
+ partial.raise_unless_cache_exists
116
117
  end
117
118
 
118
119
  # Deletes the caches.
119
120
  #
120
121
  def clear
121
122
  timed_exclaim "Deleting #{identifier}."
122
- indexing_exact.delete
123
- indexing_partial.delete
123
+ exact.delete
124
+ partial.delete
124
125
  end
125
126
 
126
127
  # Backup the caches.
@@ -128,8 +129,8 @@ module Picky
128
129
  #
129
130
  def backup
130
131
  timed_exclaim "Backing up #{identifier}."
131
- indexing_exact.backup
132
- indexing_partial.backup
132
+ exact.backup
133
+ partial.backup
133
134
  end
134
135
 
135
136
  # Restore the caches.
@@ -137,8 +138,8 @@ module Picky
137
138
  #
138
139
  def restore
139
140
  timed_exclaim "Restoring #{identifier}."
140
- indexing_exact.restore
141
- indexing_partial.restore
141
+ exact.restore
142
+ partial.restore
142
143
  end
143
144
 
144
145
  end
@@ -6,15 +6,15 @@ module Picky
6
6
  # given id.
7
7
  #
8
8
  def remove id
9
- indexed_exact.remove id
10
- indexed_partial.remove id
9
+ exact.remove id
10
+ partial.remove id
11
11
  end
12
12
 
13
13
  # Adds and indexes this category of the
14
14
  # given object.
15
15
  #
16
16
  def add object
17
- tokens, _ = tokenizer.tokenize object.send(from).to_s
17
+ tokens, _ = tokenizer.tokenize object.send(from)
18
18
  add_tokenized object.id, tokens
19
19
  end
20
20
 
@@ -33,13 +33,8 @@ module Picky
33
33
  tokens.each do |text|
34
34
  next unless text
35
35
  text = text.to_sym
36
- indexed_exact.add id, text
37
-
38
- # TODO Refactor. Push into indexed_partial?
39
- #
40
- indexed_partial.partial_strategy.each_partial text do |partial_text|
41
- indexed_partial.add id, partial_text
42
- end
36
+ exact.add id, text
37
+ partial.add_partialized id, text
43
38
  end
44
39
  end
45
40
 
@@ -19,7 +19,7 @@ class Symbol # :nodoc:all
19
19
 
20
20
  # :keys.each_intoken # => yields each of [:keys, :key, :eys, :ke, :ey, :ys, :k, :e, :y, :s]
21
21
  # :keys.each_intoken(2) # => yields each of [:keys, :key, :eys, :ke, :ey, :ys]
22
- # :keys.each_intoken(2, 3) # => yields each of [:keys, :key, :eys]
22
+ # :keys.each_intoken(2, 3) # => yields each of [:key, :eys, :ke, :ey, :ys]
23
23
  # :keys.each_intoken(10, 12) # => yields nothing (min larger than sym)
24
24
  #
25
25
  def each_intoken min_length = 1, max_length = -1
@@ -2,7 +2,7 @@ module Picky
2
2
 
3
3
  module Generators
4
4
  module Partial
5
- Default = Substring.new from: -3, to: -1
5
+ Default = Postfix.new from: -3
6
6
  end
7
7
  end
8
8
 
@@ -0,0 +1,30 @@
1
+ module Picky
2
+
3
+ module Generators
4
+
5
+ module Partial
6
+
7
+ class Postfix < Substring
8
+
9
+ # The from option signifies where in the symbol it
10
+ # will start in generating the subtokens.
11
+ #
12
+ # Examples:
13
+ #
14
+ # With :hello
15
+ # * from: 1 # => [:hello, :hell, :hel, :he, :h]
16
+ # * from: 4 # => [:hello, :hell]
17
+ #
18
+ def initialize options = {}
19
+ options[:to] = -1
20
+
21
+ super options
22
+ end
23
+
24
+ end
25
+
26
+ end
27
+
28
+ end
29
+
30
+ end
@@ -18,8 +18,14 @@ module Picky
18
18
  token.each_subtoken @from, &block
19
19
  end
20
20
  else
21
- def each_subtoken token, &block
22
- token[0..@to].intern.each_subtoken @from, &block
21
+ if @from < 0 && @to < 0
22
+ def each_subtoken token, &block
23
+ token[0..@to].intern.each_subtoken @from - @to - 1, &block
24
+ end
25
+ else
26
+ def each_subtoken token, &block
27
+ token[0..@to].intern.each_subtoken @from, &block
28
+ end
23
29
  end
24
30
  end
25
31
 
data/lib/picky/index.rb CHANGED
@@ -90,6 +90,7 @@ module Picky
90
90
  :categories
91
91
 
92
92
  delegate :[],
93
+ :dump,
93
94
  :each_category,
94
95
  :to => :categories
95
96
 
@@ -102,7 +103,7 @@ module Picky
102
103
  # * source: Where the data comes from, e.g. Sources::CSV.new(...). Optional, can be defined in the block using #source.
103
104
  # * result_identifier: Use if you'd like a different identifier/name in the results than the name of the index.
104
105
  # * after_indexing: As of this writing only used in the db source. Executes the given after_indexing as SQL after the indexing process.
105
- # * tokenizer: Call and pass either a tokenizer (responds to #tokenize) or the options for a tokenizer..
106
+ # * indexing: Call and pass either a tokenizer (responds to #tokenize) or the options for a tokenizer..
106
107
  # * key_format: Call and pass in a format method for the ids (default is #to_i).
107
108
  #
108
109
  # Example:
@@ -231,8 +232,7 @@ module Picky
231
232
  options = { partial: Partial::None.new }.merge options
232
233
 
233
234
  define_category category_name, options do |category|
234
- Indexing::Wrappers::Category::Location.install_on category, range, precision
235
- Indexed::Wrappers::Category::Location.install_on category, range, precision
235
+ Wrappers::Category::Location.wrap category, range, precision
236
236
  end
237
237
  end
238
238
  alias define_ranged_category ranged_category
@@ -27,7 +27,7 @@ module Picky
27
27
  index_in_parallel
28
28
  else
29
29
  with_data_snapshot do
30
- categories.each &:index
30
+ categories.index
31
31
  end
32
32
  end
33
33
  end
@@ -73,9 +73,10 @@ module Picky
73
73
  # Only use where the category does have a #each source defined.
74
74
  #
75
75
  def index_in_parallel
76
+ categories.empty
76
77
  indexer = Indexers::Parallel.new self
77
78
  indexer.index categories
78
- categories.each &:cache
79
+ categories.cache
79
80
  end
80
81
 
81
82
  # Returns the installed tokenizer or the default.
@@ -20,18 +20,10 @@ module Picky
20
20
  #
21
21
  def index categories
22
22
  start_indexing_message
23
- prepare categories
24
23
  process categories
25
24
  finish_indexing_message
26
25
  end
27
26
 
28
- # By default, an indexer
29
- # * prepares the index directories.
30
- #
31
- def prepare categories
32
- categories.each &:prepare_index_directory
33
- end
34
-
35
27
  end
36
28
 
37
29
  end
@@ -45,7 +45,7 @@ module Picky
45
45
  # Is it a good idea that not the tokenizer has control over when he gets the next text?
46
46
  #
47
47
  combined.each do |category, cache, _, tokenizer|
48
- tokens, _ = tokenizer.tokenize object.send(category.from).to_s # Note: Originals not needed.
48
+ tokens, _ = tokenizer.tokenize object.send(category.from) # Note: Originals not needed.
49
49
  tokens.each do |token_text|
50
50
  next unless token_text
51
51
  cache << id << comma << token_text << newline
data/lib/picky/loader.rb CHANGED
@@ -83,6 +83,7 @@ module Picky
83
83
  load_relative 'generators/partial/strategy'
84
84
  load_relative 'generators/partial/none'
85
85
  load_relative 'generators/partial/substring'
86
+ load_relative 'generators/partial/postfix'
86
87
  load_relative 'generators/partial/infix'
87
88
  load_relative 'generators/partial/default'
88
89
 
@@ -133,21 +134,23 @@ module Picky
133
134
  # Indexing and Indexed things.
134
135
  #
135
136
  load_relative 'bundle'
137
+ load_relative 'bundle_indexing'
138
+ load_relative 'bundle_indexed'
139
+ load_relative 'bundle_realtime'
136
140
 
137
- load_relative 'indexing/bundle'
138
- load_relative 'indexing/wrappers/category/location'
139
-
140
- load_relative 'indexed/bundle'
141
- load_relative 'indexed/bundle_realtime'
142
- load_relative 'indexed/wrappers/exact_first'
143
-
144
- # Bundle Wrapper
141
+ # Wrappers.
145
142
  #
146
- load_relative 'indexed/wrappers/bundle/wrapper'
147
- load_relative 'indexed/wrappers/bundle/calculation'
148
- load_relative 'indexed/wrappers/bundle/location'
143
+ load_relative 'wrappers/category/location'
144
+ load_relative 'wrappers/category/exact_first'
149
145
 
150
- load_relative 'indexed/wrappers/category/location'
146
+ load_relative 'wrappers/bundle/delegators'
147
+ load_relative 'wrappers/bundle/wrapper'
148
+ load_relative 'wrappers/bundle/calculation'
149
+ load_relative 'wrappers/bundle/location'
150
+ load_relative 'wrappers/bundle/exact_partial'
151
+
152
+ load_relative 'wrappers/sources/base'
153
+ load_relative 'wrappers/sources/location'
151
154
 
152
155
  # Tokens.
153
156
  #
@@ -245,9 +248,6 @@ module Picky
245
248
  load_relative 'sources/couch'
246
249
  load_relative 'sources/mongo'
247
250
 
248
- load_relative 'sources/wrappers/base'
249
- load_relative 'sources/wrappers/location'
250
-
251
251
  # Interfaces
252
252
  #
253
253
  load_relative 'interfaces/live_parameters'
@@ -31,7 +31,7 @@ module Picky
31
31
  # Returns nil if it is not allowed, the normalized qualifier if it is.
32
32
  #
33
33
  def map qualifier
34
- return nil if qualifier.blank?
34
+ return nil if qualifier.empty?
35
35
 
36
36
  @mapping[qualifier.to_sym]
37
37
  end
@@ -17,7 +17,9 @@ module Picky
17
17
 
18
18
  # Set the amount of requests before the Unicorn commits Harakiri.
19
19
  #
20
- cattr_accessor :after
20
+ class << self
21
+ attr_accessor :after
22
+ end
21
23
 
22
24
  def initialize app
23
25
  @app = app
@@ -33,11 +33,22 @@ module Picky
33
33
  @@traversal_id = :__picky_id
34
34
 
35
35
  def initialize select_statement, options = { file: 'app/db.yml' }
36
+ check_gem
37
+
36
38
  @select_statement = select_statement
37
39
  @database = create_database_adapter
38
40
  @options = options
39
41
  end
40
42
 
43
+ # Tries to require the active_record gem.
44
+ #
45
+ def check_gem # :nodoc:
46
+ require 'active_record'
47
+ rescue LoadError
48
+ warn_gem_missing 'active_record', 'the (ActiveRecord) DB source'
49
+ exit 1
50
+ end
51
+
41
52
  def to_s
42
53
  parameters = [select_statement.inspect]
43
54
  parameters << options unless options.empty?
@@ -34,8 +34,8 @@ module Picky
34
34
  @indexes << <<-ANALYSIS
35
35
  #{"#{category.index_name}".indented_to_s}\n
36
36
  #{"#{category.name}".indented_to_s(4)}\n
37
- #{"exact\n#{Analyzer.new.analyze(category.indexed_exact).indented_to_s}".indented_to_s(6)}\n
38
- #{"partial\n#{Analyzer.new.analyze(category.indexed_partial).indented_to_s}".indented_to_s(6)}
37
+ #{"exact\n#{Analyzer.new.analyze(category.exact).indented_to_s}".indented_to_s(6)}\n
38
+ #{"partial\n#{Analyzer.new.analyze(category.partial).indented_to_s}".indented_to_s(6)}
39
39
  ANALYSIS
40
40
  end
41
41
  end
@@ -172,7 +172,7 @@ Case sensitive? #{@case_sensitive ? "Yes." : "-"}
172
172
  # [[:token1, :token2], ["Original1", "Original2"]]
173
173
  #
174
174
  def tokenize text
175
- text = preprocess text # processing the text
175
+ text = preprocess text.to_s # processing the text
176
176
  return empty_tokens if text.blank?
177
177
  words = pretokenize text # splitting and preparations for tokenizing
178
178
  return empty_tokens if words.empty?
@@ -43,7 +43,7 @@ module Picky
43
43
 
44
44
  # TODO Move to the right place.
45
45
  #
46
- category.indexing_exact[:location_minimum] = minimum
46
+ category.exact[:location_minimum] = minimum
47
47
  end
48
48
 
49
49
  end
@@ -0,0 +1,45 @@
1
+ module Picky
2
+
3
+ module Wrappers
4
+
5
+ module Bundle
6
+
7
+ # A calculation rewrites the symbol into a float.
8
+ #
9
+ # Note: A calculation will try to find a float in the index,
10
+ # not a sym.
11
+ #
12
+ # TODO I really need to allow integers as keys.
13
+ # The code below is just not up to the needed quality.
14
+ # Use key_format :to_i?
15
+ #
16
+ class Calculation < Wrapper
17
+
18
+ # API.
19
+ #
20
+ # By default, a calculation does not
21
+ # recalculate anything.
22
+ #
23
+ def recalculate float
24
+ float
25
+ end
26
+
27
+ #
28
+ #
29
+ def ids float_as_sym
30
+ @bundle.ids recalculate(float_as_sym.to_s.to_f).to_s.to_sym
31
+ end
32
+
33
+ #
34
+ #
35
+ def weight float_as_sym
36
+ @bundle.weight recalculate(float_as_sym.to_s.to_f).to_s.to_sym
37
+ end
38
+
39
+ end
40
+
41
+ end
42
+
43
+ end
44
+
45
+ end