Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

162 lines (141 sloc) 4.23 kb
module Picky
#
#
class Index
attr_reader :bundle_class
# Delegators for indexing.
#
delegate :cache,
:check,
:clear,
:backup,
:restore,
:to => :categories
# Calling index on an index will call index
# on every category.
#
# Decides whether to use a parallel indexer or whether to
# delegate to each category to index themselves.
#
def index
if source.respond_to?(:each)
check_source_empty
index_in_parallel
else
with_data_snapshot do
categories.index
end
end
end
# Define an index tokenizer on the index.
#
# Parameters are the exact same as for indexing.
#
def indexing options = {}
@tokenizer = if options.respond_to?(:tokenize)
options
else
options && Tokenizer.new(options)
end
end
alias define_indexing indexing
# Check if the given enumerable source is empty.
#
# Note: Checking as early as possible to tell the
# user as early as possible.
#
def check_source_empty
warn %Q{\n\033[1mWarning\033[m, source for index "#{name}" is empty: #{source} (responds true to empty?).\n} if source.respond_to?(:empty?) && source.empty?
end
# Note: Duplicated in category_indexing.rb.
#
# Take a data snapshot if the source offers it.
#
def with_data_snapshot
if source.respond_to? :with_snapshot
source.with_snapshot(self) do
yield
end
else
yield
end
end
# Indexes the categories in parallel.
#
# Only use where the category does have a #each source defined.
#
def index_in_parallel
categories.empty
indexer = Indexers::Parallel.new self
indexer.index categories
categories.cache
end
# Returns the installed tokenizer or the default.
#
def tokenizer
@tokenizer || Indexes.tokenizer
end
# Define a source on the index.
#
# Parameter is a source, either one of the standard sources or
# anything responding to #each and returning objects that
# respond to id and the category names (or the category from option).
#
def source some_source = nil, &block
some_source ||= block
some_source ? define_source(some_source) : (@source && extract_source || raise_no_source)
end
# Extract the actual source if it is wrapped in a time
# capsule, i.e. a block/lambda.
#
# TODO Extract into module.
#
def extract_source
@source = @source.respond_to?(:call) ? @source.call : @source
end
def define_source source
check_source source
@source = source
end
def raise_no_source
raise NoSourceSpecifiedException.new(<<-NO_SOURCE
No source given for index #{name}. An index needs a source.
Example:
Index.new(:with_source) do
source Sources::CSV.new(:title, file: 'data/books.csv')
category :title
category :author
end
NO_SOURCE
)
end
def check_source source # :nodoc:
raise ArgumentError.new(<<-SOURCE
The index "#{name}" should use a data source that responds to either the method #each, or the method #harvest, which yields(id, text), OR it can be a lambda/block, returning such a source.
Or it could use one of the built-in sources:
Sources::#{(Sources.constants - [:Base, :Wrappers, :NoCSVFileGiven, :NoCouchDBGiven]).join(',
Sources::')}
SOURCE
) unless source.respond_to?(:each) || source.respond_to?(:harvest) || source.respond_to?(:call)
end
# Define a key_format on the index.
#
# Parameter is a method name to use on the key (e.g. :to_i, :to_s, :strip).
#
def key_format format = nil
format ? define_key_format(format) : @key_format
end
def define_key_format key_format
@key_format = key_format
end
# Define what to do after indexing.
# (Only used in the Sources::DB)
#
def after_indexing after_indexing = nil
after_indexing ? define_after_indexing(after_indexing) : @after_indexing
end
def define_after_indexing after_indexing
@after_indexing = after_indexing
end
end
end
Jump to Line
Something went wrong with that request. Please try again.