require 'active_support' # @private module Mebla extend ActiveSupport::Autoload # Dependencies autoload :Mongoid, 'mongoid' autoload :Slingshot, 'slingshot' # Main modules autoload :Configuration autoload :Context autoload :LogSubscriber autoload :ResultSet # Errors autoload :Errors # Mongoid extensions autoload :Mebla, 'mebla/mongoid/mebla' @@mebla_mutex = Mutex.new @@context = nil # Returns Mebla's context for minipulating the index # @return [nil] def self.context if @@context.nil? @@mebla_mutex.synchronize do if @@context.nil? @@context = Mebla::Context.new end end end @@context end # Resets the context (reloads Mebla) # @return [nil] def self.reset_context! @@mebla_mutex.synchronize do @@context = nil end end # Check if mongoid is loaded # @return [Boolean] def self.mongoid? !defined?(Mongoid).nil? end # Check if slingshot is loaded # @return [Boolean] def self.slingshot? !defined?(Slingshot).nil? end # Check if elasticsearch is running # @return [Boolean] def self.elasticsearch? result = Slingshot::Configuration.client.get "#{Slingshot::Configuration.url}/_status" return (result =~ /error/) ? false: true rescue RestClient::Exception false end # Configure Mebla # # Example:: # # Mebla.configure do |config| # index = "mebla_index" # host = "localhost" # port = 9200 # end def self.configure(&block) yield Mebla::Configuration.instance end # Writes out a message to the log file according to the level given # @note If no level is given a message of type Logger::UNKOWN will be written to the log file # @param [String] message # @param [Symbol] level can be :debug, :warn or :info # @return [nil] def self.log(message, level = :none) case level when :debug hook = "mebla_debug.mebla" when :warn hook = "mebla_warn.mebla" when :info hook = "mebla_info.mebla" else hook = "mebla_unkown.mebla" end ::ActiveSupport::Notifications. instrument(hook, :message => message) end # Search the index using Slingshot search DSL # @param type_names a string, symbol or array representing the models to be searcheds # @return [ResultSet] # # Search for all documents with a field title with a value 'Testing Search':: # # Mebla.search do # query do # string "title: Testing Search" # end # end # # @note For more information about Slingshot search DSL, check http://karmi.github.com/slingshot def self.search(type_names = [], &block) # Convert type names from string or symbol to array type_names = case true when type_names.is_a?(Symbol), type_names.is_a?(String) [type_names] when type_names.is_a?(Array) type_names.collect{|name| name.to_s} else [] end # Create slingshot search object search_obj = Slingshot::Search::Search.new(::Mebla.context.slingshot_index_name, {}, &block) # Add a type filter to return only certain types search_obj = search_obj.filter(:terms, :_type => type_names) unless type_names.empty? # Log search query log("Searching:\n#{search_obj.to_json.to_s}", :debug) # Perform the search and parse the response results = Mebla::ResultSet.new(search_obj.perform.response) # Log results statistics log("Searched for:\n#{search_obj.to_json.to_s}\ngot #{results.total} in #{results.time}", :debug) # Return the results return results end end