picky 3.5.4 → 3.6.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.
Files changed (57) hide show
  1. data/lib/picky/backends/backend.rb +1 -1
  2. data/lib/picky/backends/file/basic.rb +0 -36
  3. data/lib/picky/backends/file/json.rb +1 -1
  4. data/lib/picky/backends/file.rb +4 -4
  5. data/lib/picky/backends/helpers/file.rb +0 -26
  6. data/lib/picky/backends/memory/basic.rb +0 -35
  7. data/lib/picky/backends/memory.rb +4 -4
  8. data/lib/picky/backends/redis/basic.rb +0 -33
  9. data/lib/picky/backends/redis.rb +4 -4
  10. data/lib/picky/backends/sqlite/db.rb +84 -0
  11. data/lib/picky/backends/sqlite.rb +75 -0
  12. data/lib/picky/bundle.rb +15 -87
  13. data/lib/picky/bundle_realtime.rb +1 -1
  14. data/lib/picky/categories.rb +1 -0
  15. data/lib/picky/categories_indexed.rb +1 -1
  16. data/lib/picky/categories_indexing.rb +1 -3
  17. data/lib/picky/category.rb +16 -2
  18. data/lib/picky/category_indexed.rb +5 -3
  19. data/lib/picky/category_indexing.rb +0 -26
  20. data/lib/picky/category_realtime.rb +2 -0
  21. data/lib/picky/extensions/string.rb +20 -0
  22. data/lib/picky/extensions/symbol.rb +22 -0
  23. data/lib/picky/generators/similarity/double_metaphone.rb +1 -2
  24. data/lib/picky/generators/similarity/metaphone.rb +1 -2
  25. data/lib/picky/generators/similarity/phonetic.rb +0 -10
  26. data/lib/picky/generators/similarity/soundex.rb +1 -2
  27. data/lib/picky/index.rb +9 -2
  28. data/lib/picky/index_indexed.rb +4 -4
  29. data/lib/picky/index_indexing.rb +1 -5
  30. data/lib/picky/indexes_indexed.rb +7 -6
  31. data/lib/picky/indexes_indexing.rb +1 -7
  32. data/lib/picky/loader.rb +4 -1
  33. data/lib/picky/sources/couch.rb +1 -1
  34. data/lib/picky/sources/mongo.rb +1 -1
  35. data/lib/picky/wrappers/bundle/calculation.rb +1 -1
  36. data/lib/picky/wrappers/bundle/exact_partial.rb +3 -12
  37. data/lib/picky/wrappers/bundle/location.rb +1 -0
  38. data/lib/tasks/index.rake +0 -4
  39. data/spec/lib/backends/file/basic_spec.rb +5 -17
  40. data/spec/lib/backends/memory/basic_spec.rb +5 -17
  41. data/spec/lib/backends/redis/basic_spec.rb +5 -52
  42. data/spec/lib/backends/sqlite/db_spec.rb +80 -0
  43. data/spec/lib/backends/sqlite_spec.rb +131 -0
  44. data/spec/lib/category_indexed_spec.rb +2 -2
  45. data/spec/lib/category_indexing_spec.rb +0 -24
  46. data/spec/lib/extensions/string_spec.rb +16 -0
  47. data/spec/lib/extensions/symbol_spec.rb +16 -0
  48. data/spec/lib/index_indexed_spec.rb +16 -16
  49. data/spec/lib/indexes_indexed_spec.rb +13 -7
  50. data/spec/lib/indexes_indexing_spec.rb +3 -6
  51. data/spec/lib/indexing/bundle_spec.rb +6 -125
  52. data/spec/lib/sources/couch_spec.rb +8 -8
  53. data/spec/lib/sources/mongo_spec.rb +5 -5
  54. data/spec/specific/realtime_spec.rb +397 -173
  55. metadata +44 -29
  56. data/lib/picky/bundling.rb +0 -10
  57. data/lib/tasks/checks.rake +0 -13
@@ -6,13 +6,15 @@ module Picky
6
6
 
7
7
  # Loads the index from cache.
8
8
  #
9
- def load_from_cache
9
+ def load
10
10
  timed_exclaim %Q{"#{identifier}": Loading index from cache.}
11
- clear_realtime_mapping
11
+ clear_realtime_mapping # TODO What to do?
12
12
  exact.load
13
13
  partial.load
14
14
  end
15
- alias reload load_from_cache
15
+ # TODO Remove in 4.0.
16
+ #
17
+ alias reload load
16
18
 
17
19
  # Gets the weight for this token's text.
18
20
  #
@@ -107,14 +107,6 @@ module Picky
107
107
  @tokenizer || @index.tokenizer
108
108
  end
109
109
 
110
- # Checks the caches for existence.
111
- #
112
- def check
113
- timed_exclaim "Checking #{identifier}."
114
- exact.raise_unless_cache_exists
115
- partial.raise_unless_cache_exists
116
- end
117
-
118
110
  # Deletes the caches.
119
111
  #
120
112
  def clear
@@ -123,24 +115,6 @@ module Picky
123
115
  partial.delete
124
116
  end
125
117
 
126
- # Backup the caches.
127
- # (Revert with restore_caches)
128
- #
129
- def backup
130
- timed_exclaim "Backing up #{identifier}."
131
- exact.backup
132
- partial.backup
133
- end
134
-
135
- # Restore the caches.
136
- # (Revert with backup_caches)
137
- #
138
- def restore
139
- timed_exclaim "Restoring #{identifier}."
140
- exact.restore
141
- partial.restore
142
- end
143
-
144
118
  end
145
119
 
146
120
  end
@@ -6,6 +6,7 @@ module Picky
6
6
  # given id.
7
7
  #
8
8
  def remove id
9
+ id = id.send key_format
9
10
  exact.remove id
10
11
  partial.remove id
11
12
  end
@@ -38,6 +39,7 @@ module Picky
38
39
  def add_tokenized_token id, text, where = :unshift
39
40
  return unless text
40
41
  id = id.send key_format # TODO Speed this up!
42
+
41
43
  # text = text.to_sym if @symbols # TODO Symbols.
42
44
  exact.add id, text, where
43
45
  partial.add_partialized id, text, where
@@ -2,6 +2,26 @@
2
2
  #
3
3
  class String # :nodoc:all
4
4
 
5
+ # Returns a _single_ double metaphone code
6
+ # for this string.
7
+ #
8
+ def double_metaphone
9
+ codes = Text::Metaphone.double_metaphone self
10
+ codes.first unless codes.empty?
11
+ end
12
+
13
+ # Returns a metaphone code for this string.
14
+ #
15
+ def metaphone
16
+ Text::Metaphone.metaphone self
17
+ end
18
+
19
+ # Returns a soundex code for this string.
20
+ #
21
+ def soundex
22
+ Text::Soundex.soundex self
23
+ end
24
+
5
25
  # 'keys'.each_subtoken # => yields each of ['keys', 'key', 'ke', 'k']
6
26
  # 'keys'.each_subtoken(2) # => yields each of ['keys', 'key', 'ke']
7
27
  #
@@ -2,6 +2,28 @@
2
2
  #
3
3
  class Symbol # :nodoc:all
4
4
 
5
+ # Returns a _single_ double metaphone code
6
+ # for this symbol.
7
+ #
8
+ def double_metaphone
9
+ codes = Text::Metaphone.double_metaphone self
10
+ codes.first.intern unless codes.empty?
11
+ end
12
+
13
+ # Returns a metaphone code for this symbol.
14
+ #
15
+ def metaphone
16
+ code = Text::Metaphone.metaphone self.to_s
17
+ code.intern if code
18
+ end
19
+
20
+ # Returns a soundex code for this symbol.
21
+ #
22
+ def soundex
23
+ code = Text::Soundex.soundex self.to_s
24
+ code.intern if code
25
+ end
26
+
5
27
  # :keys.each_subtoken # => yields each of [:keys, :key, :ke, :k]
6
28
  # :keys.each_subtoken(2) # => yields each of [:keys, :key, :ke]
7
29
  #
@@ -19,8 +19,7 @@ module Picky
19
19
  # Returns a symbol.
20
20
  #
21
21
  def encoded str_or_sym
22
- codes = Text::Metaphone.double_metaphone str_or_sym.to_s
23
- codes.first.intern unless codes.empty?
22
+ str_or_sym.double_metaphone
24
23
  end
25
24
 
26
25
  end
@@ -19,8 +19,7 @@ module Picky
19
19
  # Returns a symbol.
20
20
  #
21
21
  def encoded str_or_sym
22
- code = Text::Metaphone.metaphone str_or_sym.to_s
23
- code.intern if code
22
+ str_or_sym.metaphone
24
23
  end
25
24
 
26
25
  end
@@ -23,16 +23,6 @@ module Picky
23
23
  @amount = amount
24
24
  end
25
25
 
26
- # # Generates an index for the given index (in exact index style).
27
- # #
28
- # # In the following form:
29
- # # [:meier, :mueller, :peter, :pater] => { MR: [:meier], MLR: [:mueller], PTR: [:peter, :pater] }
30
- # #
31
- # def generate_from inverted
32
- # hash = hashify inverted.keys
33
- # sort hash
34
- # end
35
-
36
26
  protected
37
27
 
38
28
  # Sorts the index values in place.
@@ -19,8 +19,7 @@ module Picky
19
19
  # Returns a symbol.
20
20
  #
21
21
  def encoded str_or_sym
22
- code = Text::Soundex.soundex str_or_sym.to_s
23
- code.intern if code
22
+ str_or_sym.soundex
24
23
  end
25
24
 
26
25
  end
data/lib/picky/index.rb CHANGED
@@ -132,11 +132,18 @@ module Picky
132
132
  #
133
133
  def backend backend = nil
134
134
  if backend
135
- @backend = backend
135
+ @backend = reset_backend backend
136
136
  else
137
- @backend || Backends::Memory.new
137
+ @backend ||= Backends::Memory.new
138
138
  end
139
139
  end
140
+ # TODO Rewrite such that reset_backend just sets the
141
+ # lazily evaluated backend to nil.
142
+ #
143
+ def reset_backend backend
144
+ categories.reset_backend backend
145
+ backend
146
+ end
140
147
 
141
148
  # TODO Symbols.
142
149
  #
@@ -4,15 +4,15 @@ module Picky
4
4
  #
5
5
  class Index
6
6
 
7
- attr_reader :combinator
8
-
9
- delegate :load_from_cache,
7
+ delegate :load,
10
8
  :analyze,
11
9
  :reindex,
12
10
  :possible_combinations,
13
11
  :to => :categories
14
12
 
15
- alias reload load_from_cache
13
+ # TODO Remove in 4.0.
14
+ #
15
+ alias reload load
16
16
 
17
17
  # Define how the results of this index are identified.
18
18
  # (Shown in the client, for example)
@@ -4,15 +4,11 @@ module Picky
4
4
  #
5
5
  class Index
6
6
 
7
- attr_reader :bundle_class
8
-
9
7
  # Delegators for indexing.
10
8
  #
11
9
  delegate :cache,
12
- :check,
13
10
  :clear,
14
- :backup,
15
- :restore,
11
+ :prepare,
16
12
  :to => :categories
17
13
 
18
14
  # Calling index on an index will call index
@@ -4,17 +4,18 @@ module Picky
4
4
  #
5
5
  class Indexes
6
6
 
7
- instance_delegate :load_from_cache,
8
- :reload,
7
+ instance_delegate :load,
9
8
  :analyze
10
9
 
11
- each_delegate :load_from_cache,
10
+ each_delegate :load,
11
+ :reload,
12
12
  :to => :indexes
13
13
 
14
- # Reloads all indexes, one after another,
15
- # in the order they were added.
14
+ # TODO Remove in 4.0.
16
15
  #
17
- alias reload load_from_cache
16
+ def self.reload
17
+ self.instance.reload
18
+ end
18
19
 
19
20
  end
20
21
 
@@ -5,17 +5,11 @@ module Picky
5
5
  class Indexes
6
6
 
7
7
  instance_delegate :index,
8
- :check,
9
8
  :clear,
10
- :backup,
11
- :restore,
12
9
  :index_for_tests,
13
10
  :tokenizer
14
11
 
15
- each_delegate :check,
16
- :clear,
17
- :backup,
18
- :restore,
12
+ each_delegate :clear,
19
13
  :to => :indexes
20
14
 
21
15
  # Runs the indexers in parallel (prepare + cache).
data/lib/picky/loader.rb CHANGED
@@ -128,6 +128,9 @@ module Picky
128
128
  load_relative 'backends/file/basic'
129
129
  load_relative 'backends/file/json'
130
130
 
131
+ load_relative 'backends/sqlite'
132
+ load_relative 'backends/sqlite/db'
133
+
131
134
  # Indexing and Indexed things.
132
135
  #
133
136
  load_relative 'bundle'
@@ -264,4 +267,4 @@ module Picky
264
267
 
265
268
  end
266
269
 
267
- end
270
+ end
@@ -32,7 +32,7 @@ module Picky
32
32
  @db = RestClient::Resource.new options.delete(:url), options
33
33
 
34
34
  key_format = options.delete :key_format
35
- @key_format = key_format && key_format.intern || :to_sym
35
+ @key_format = key_format && key_format.intern || :to_s
36
36
  end
37
37
 
38
38
  def to_s
@@ -37,7 +37,7 @@ module Picky
37
37
 
38
38
  @db = RestClient::Resource.new options.delete(:url), options
39
39
  @database = options.delete(:db)
40
- @key_format = options[:key_format] && options[:key_format].intern || :to_sym
40
+ @key_format = options[:key_format] && options[:key_format].intern || :to_s
41
41
  end
42
42
 
43
43
  # Tries to require the rest_client gem.
@@ -24,7 +24,7 @@ module Picky
24
24
  float
25
25
  end
26
26
 
27
- # TODO Symbols.
27
+ # TODO Symbols. Use a block here?
28
28
  #
29
29
  def ids float_str
30
30
  @bundle.ids calculate(float_str.to_f).to_s
@@ -10,22 +10,13 @@ module Picky
10
10
  # bundle such that a partial index will not
11
11
  # be dumped or generated.
12
12
  #
13
- class ExactPartial
14
-
15
- attr_reader :bundle
16
-
17
- include Delegator
18
- include IndexedDelegator
19
-
20
- def initialize bundle
21
- @bundle = bundle
22
- end
13
+ class ExactPartial < Wrapper
23
14
 
15
+ # Ignore these.
16
+ #
24
17
  def clear; end
25
18
  def dump; end
26
19
  def empty; end
27
- def generate_caches_from_memory; end
28
- def generate_partial_from arg; end
29
20
  def index; end
30
21
  def load; end
31
22
 
@@ -52,6 +52,7 @@ module Picky
52
52
  bundle.load
53
53
 
54
54
  # TODO Symbols (of the location_anchor!!!).
55
+ # It should always be a Symbol.
55
56
  #
56
57
  @calculation.anchor = bundle['location_anchor'] && bundle['location_anchor'].to_f || raise("Configuration 'location_anchor' for #{bundle.identifier} missing. Did you run rake index already?")
57
58
  end
data/lib/tasks/index.rake CHANGED
@@ -12,13 +12,9 @@ end
12
12
 
13
13
  namespace :index do
14
14
 
15
- # Advanced usage.
16
- #
17
- # desc "Takes a snapshot, indexes, and caches in random order."
18
15
  task :randomly => :application do
19
16
  Picky::Indexes.index true
20
17
  end
21
- # desc "Takes a snapshot, indexes, and caches in order given."
22
18
  task :ordered => :application do
23
19
  Picky::Indexes.index false
24
20
  end
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Picky::Backends::File::Basic do
4
-
4
+
5
5
  context 'without options' do
6
6
  let(:basic) { described_class.new 'some/cache/path/to/file' }
7
7
 
@@ -10,32 +10,20 @@ describe Picky::Backends::File::Basic do
10
10
  basic.empty.should == {}
11
11
  end
12
12
  end
13
-
13
+
14
14
  describe 'initial' do
15
15
  it 'returns the container that is used for indexing' do
16
16
  basic.initial.should == nil
17
17
  end
18
18
  end
19
19
 
20
- describe 'backup_file_path_of' do
21
- it 'returns a backup path relative to the path' do
22
- basic.backup_file_path_of('some/path/to/some.memory.index').should == 'some/path/to/backup/some.memory.index'
23
- end
24
- end
25
-
26
- describe 'backup_directory' do
27
- it "returns the cache path's backup path" do
28
- basic.backup_directory('some/cache/path/to/file').should == 'some/cache/path/to/backup'
29
- end
30
- end
31
-
32
20
  describe 'to_s' do
33
21
  it 'returns the cache path with the default file extension' do
34
22
  basic.to_s.should == 'Picky::Backends::File::Basic(some/cache/path/to/file.file.index,some/cache/path/to/file.file_mapping.index.memory.json)'
35
23
  end
36
24
  end
37
25
  end
38
-
26
+
39
27
  context 'with options' do
40
28
  let(:basic) do
41
29
  described_class.new 'some/cache/path/to/file',
@@ -48,12 +36,12 @@ describe Picky::Backends::File::Basic do
48
36
  basic.empty.should == []
49
37
  end
50
38
  end
51
-
39
+
52
40
  describe 'initial' do
53
41
  it 'returns the container that is used for indexing' do
54
42
  basic.initial.should == []
55
43
  end
56
44
  end
57
45
  end
58
-
46
+
59
47
  end
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Picky::Backends::Memory::Basic do
4
-
4
+
5
5
  context 'without options' do
6
6
  let(:basic) { described_class.new 'some/cache/path/to/file' }
7
7
 
@@ -10,32 +10,20 @@ describe Picky::Backends::Memory::Basic do
10
10
  basic.empty.should == {}
11
11
  end
12
12
  end
13
-
13
+
14
14
  describe 'initial' do
15
15
  it 'returns the container that is used for indexing' do
16
16
  basic.initial.should == {}
17
17
  end
18
18
  end
19
19
 
20
- describe 'backup_file_path_of' do
21
- it 'returns a backup path relative to the path' do
22
- basic.backup_file_path_of('some/path/to/some.memory.index').should == 'some/path/to/backup/some.memory.index'
23
- end
24
- end
25
-
26
- describe 'backup_directory' do
27
- it "returns the cache path's backup path" do
28
- basic.backup_directory('some/cache/path/to/file').should == 'some/cache/path/to/backup'
29
- end
30
- end
31
-
32
20
  describe 'to_s' do
33
21
  it 'returns the cache path with the default file extension' do
34
22
  basic.to_s.should == 'Picky::Backends::Memory::Basic(some/cache/path/to/file.memory.index)'
35
23
  end
36
24
  end
37
25
  end
38
-
26
+
39
27
  context 'with options' do
40
28
  let(:basic) do
41
29
  described_class.new 'some/cache/path/to/file',
@@ -48,12 +36,12 @@ describe Picky::Backends::Memory::Basic do
48
36
  basic.empty.should == []
49
37
  end
50
38
  end
51
-
39
+
52
40
  describe 'initial' do
53
41
  it 'returns the container that is used for indexing' do
54
42
  basic.initial.should == []
55
43
  end
56
44
  end
57
45
  end
58
-
46
+
59
47
  end
@@ -1,19 +1,18 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Picky::Backends::Redis::Basic do
4
-
4
+
5
5
  let(:client) { stub :client }
6
-
6
+
7
7
  context 'without options' do
8
8
  let(:index) { described_class.new client, :some_namespace }
9
9
 
10
- describe 'load, retrieve, backup, delete' do
10
+ describe 'load, retrieve, delete' do
11
11
  it 'is nothing they do (at least on the backend)' do
12
12
  index.should_receive(:client).never
13
13
 
14
14
  index.load
15
15
  index.retrieve
16
- index.backup
17
16
  index.delete
18
17
  end
19
18
  end
@@ -30,59 +29,13 @@ describe Picky::Backends::Redis::Basic do
30
29
  end
31
30
  end
32
31
 
33
- describe 'cache_small?' do
34
- context 'size 0' do
35
- before(:each) do
36
- index.stub! :size => 0
37
- end
38
- it 'is small' do
39
- index.cache_small?.should == true
40
- end
41
- end
42
- context 'size 1' do
43
- before(:each) do
44
- index.stub! :size => 1
45
- end
46
- it 'is not small' do
47
- index.cache_small?.should == false
48
- end
49
- end
50
- end
51
-
52
- describe 'cache_ok?' do
53
- context 'size 0' do
54
- before(:each) do
55
- index.stub! :size => 0
56
- end
57
- it 'is not ok' do
58
- index.cache_ok?.should == false
59
- end
60
- end
61
- context 'size 1' do
62
- before(:each) do
63
- index.stub! :size => 1
64
- end
65
- it 'is ok' do
66
- index.cache_ok?.should == true
67
- end
68
- end
69
- end
70
-
71
- describe "size" do
72
- it 'delegates to the backend' do
73
- client.should_receive(:dbsize).once.with
74
-
75
- index.size
76
- end
77
- end
78
-
79
32
  describe 'to_s' do
80
33
  it 'returns the cache path with the default file extension' do
81
34
  index.to_s.should == 'Picky::Backends::Redis::Basic(some_namespace:*)'
82
35
  end
83
36
  end
84
37
  end
85
-
38
+
86
39
  context 'with options' do
87
40
  let(:index) do
88
41
  described_class.new client,
@@ -103,5 +56,5 @@ describe Picky::Backends::Redis::Basic do
103
56
  end
104
57
  end
105
58
  end
106
-
59
+
107
60
  end
@@ -0,0 +1,80 @@
1
+ require 'spec_helper'
2
+
3
+ require 'sqlite3'
4
+
5
+ describe Picky::Backends::Sqlite::DB do
6
+
7
+ context 'hash-based indexes' do
8
+ let(:db) { described_class.new 'some/cache/path/to/file' }
9
+
10
+ describe 'dump' do
11
+ it 'delegates to the given hash' do
12
+ hash = stub :hash
13
+
14
+ db.should_receive(:dump_sqlite).once.with hash
15
+
16
+ db.dump hash
17
+ end
18
+ end
19
+
20
+ describe 'dump_sqlite' do
21
+ let(:client) { stub :client }
22
+ before(:each) do
23
+ db.stub! :db => client
24
+ end
25
+ it 'initializes the client' do
26
+ client.stub! :execute
27
+
28
+ db.should_receive(:lazily_initialize_client).once.with
29
+
30
+ db.dump_sqlite Hash.new
31
+ end
32
+ it 'executes something' do
33
+ db.stub! :lazily_initialize_client
34
+
35
+ client.should_receive(:execute).at_least(1).times
36
+
37
+ db.dump_sqlite Hash.new
38
+ end
39
+ it 'inserts keys and values' do
40
+ db.stub! :lazily_initialize_client
41
+ client.stub! :execute # We only want to test the insert statements.
42
+
43
+ client.should_receive(:execute).once.with 'insert into key_value values (?,?)', 'a', '[1,2,3]'
44
+ client.should_receive(:execute).once.with 'insert into key_value values (?,?)', 'b', '[4,5,6]'
45
+
46
+ db.dump_sqlite :a => [1,2,3], :b => [4,5,6]
47
+ end
48
+ end
49
+
50
+ describe 'load' do
51
+ it 'returns a copy of itself' do
52
+ db.load.should == db
53
+ end
54
+ it 'initializes the client' do
55
+ db.should_receive(:lazily_initialize_client).once.with
56
+
57
+ db.load
58
+ end
59
+ end
60
+
61
+ describe 'empty' do
62
+ it 'returns the container that is used for indexing' do
63
+ db.empty.should == {}
64
+ end
65
+ end
66
+
67
+ describe 'initial' do
68
+ it 'is correct' do
69
+ db.initial.should == {}
70
+ end
71
+ end
72
+
73
+ describe 'to_s' do
74
+ it 'returns the cache path with the default file extension' do
75
+ db.to_s.should == 'Picky::Backends::Sqlite::DB(some/cache/path/to/file.sqlite3)'
76
+ end
77
+ end
78
+ end
79
+
80
+ end