Permalink
Browse files

first commit

  • Loading branch information...
0 parents commit c661e068da672a9dd5cfb3ab404d6c44150fb898 @radar committed Oct 3, 2010
@@ -0,0 +1,3 @@
+pkg/*
+*.gem
+.bundle
@@ -0,0 +1,9 @@
+source :gemcutter
+
+group(:test) do
+ gem 'sqlite3-ruby'
+ gem 'rspec'
+end
+
+# Specify your gem's dependencies in searcher.gemspec
+gemspec
@@ -0,0 +1,46 @@
+PATH
+ remote: .
+ specs:
+ searcher (0.0.1)
+ activerecord (~> 3.0.0)
+
+GEM
+ remote: http://rubygems.org/
+ specs:
+ activemodel (3.0.0)
+ activesupport (= 3.0.0)
+ builder (~> 2.1.2)
+ i18n (~> 0.4.1)
+ activerecord (3.0.0)
+ activemodel (= 3.0.0)
+ activesupport (= 3.0.0)
+ arel (~> 1.0.0)
+ tzinfo (~> 0.3.23)
+ activesupport (3.0.0)
+ arel (1.0.1)
+ activesupport (~> 3.0.0)
+ builder (2.1.2)
+ diff-lcs (1.1.2)
+ i18n (0.4.1)
+ rspec (2.0.0.beta.22)
+ rspec-core (= 2.0.0.beta.22)
+ rspec-expectations (= 2.0.0.beta.22)
+ rspec-mocks (= 2.0.0.beta.22)
+ rspec-core (2.0.0.beta.22)
+ rspec-expectations (2.0.0.beta.22)
+ diff-lcs (>= 1.1.2)
+ rspec-mocks (2.0.0.beta.22)
+ rspec-core (= 2.0.0.beta.22)
+ rspec-expectations (= 2.0.0.beta.22)
+ sqlite3-ruby (1.3.1)
+ tzinfo (0.3.23)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ activerecord (~> 3.0.0)
+ bundler (>= 1.0.0)
+ rspec
+ searcher!
+ sqlite3-ruby
@@ -0,0 +1,2 @@
+require 'bundler'
+Bundler::GemHelper.install_tasks
@@ -0,0 +1,8 @@
+require 'active_record'
+require 'searcher/class_methods'
+
+module Searcher
+ # Your code goes here...
+end
+
+ActiveRecord::Base.extend(Searcher::ClassMethods)
@@ -0,0 +1,35 @@
+require 'searcher/config'
+
+module Searcher
+ module ClassMethods
+ def search_config(&block)
+ @config ||= Searcher::Config.new.instance_exec(&block)
+ end
+
+ def search(query)
+ klass = self
+ table = Table(klass.table_name)
+
+ result = query.split(" ").inject(klass) do |k, piece|
+ if piece.include?(":")
+ external, q = piece.split(":")
+ external = @config[:externals][external.to_sym]
+
+ # Find the type of association we're dealing with
+ association = reflect_on_association(external[:from])
+ p association.methods.sort - Object.methods
+ case association.macro
+ when :has_and_belongs_to_many
+ join_table = Table(association.table_name)
+ k.joins(join_table).on(table[klass.primary_key].eq(join_table[association.primary_key_name]))
+ end
+
+ else
+ k.where(table[@config[:default]].matches_any("%#{piece}%"))
+ end
+ end
+
+ result
+ end
+ end
+end
@@ -0,0 +1,18 @@
+module Searcher
+ class Config
+ def initialize
+ @config = {}
+ end
+
+ def default(field)
+ @config[:default] = field
+ @config
+ end
+
+ def external(field, options)
+ @config[:externals] ||= {}
+ @config[:externals][field.to_sym] = options
+ @config
+ end
+ end
+end
@@ -0,0 +1,3 @@
+module Searcher
+ VERSION = "0.0.1"
+end
@@ -0,0 +1,24 @@
+# -*- encoding: utf-8 -*-
+require File.expand_path("../lib/searcher/version", __FILE__)
+
+Gem::Specification.new do |s|
+ s.name = "searcher"
+ s.version = Searcher::VERSION
+ s.platform = Gem::Platform::RUBY
+ s.authors = []
+ s.email = []
+ s.homepage = "http://rubygems.org/gems/searcher"
+ s.summary = "TODO: Write a gem summary"
+ s.description = "TODO: Write a gem description"
+
+ s.required_rubygems_version = ">= 1.3.6"
+ s.rubyforge_project = "searcher"
+
+ s.add_development_dependency "bundler", ">= 1.0.0"
+
+ s.add_dependency "activerecord", "~> 3.0.0"
+
+ s.files = `git ls-files`.split("\n")
+ s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
+ s.require_path = 'lib'
+end
Binary file not shown.
@@ -0,0 +1,25 @@
+class Ticket < ActiveRecord::Base
+ has_and_belongs_to_many :tags
+ belongs_to :tag
+
+ search_config do
+ default :description
+ external :tag, :from => :tags, :field => "name"
+ end
+end
+
+class Tag < ActiveRecord::Base
+ has_and_belongs_to_many :tickets
+end
+
+class State < ActiveRecord::Base
+ has_many :tickets
+end
+
+
+## seed data:
+
+# Ticket with a description, no tag
+ticket = Ticket.create(:description => "Hello world! You are awesome.")
+ticket.tags << Tag.create(:name => "bug")
+
@@ -0,0 +1,21 @@
+ActiveRecord::Schema.define do
+ self.verbose = false
+
+ create_table :tickets, :force => true do |t|
+ t.string :description
+ t.timestamps
+ end
+
+ create_table :tags_tickets, :force => true, :id => false do |t|
+ t.integer :post_id, :tag_id
+ end
+
+ create_table :tags, :force => true do |t|
+ t.string :name
+ end
+
+ create_table :state, :force => true do |t|
+ t.string :name
+ end
+
+end
@@ -0,0 +1,21 @@
+require 'spec_helper'
+
+describe Searcher do
+ let(:search_results) { subject }
+ let(:first_result) { subject.first }
+
+ context "default field" do
+ subject { Ticket.search("Hello") }
+
+ it "first result" do
+ first_result.description.should eql("Hello world! You are awesome.")
+ end
+ end
+
+ context "label search" do
+ subject { Ticket.search("tag:bug") }
+ it "has_and_belongs_to_many" do
+ first_result.description.should eql("Hello world! You are awesome.")
+ end
+ end
+end
@@ -0,0 +1,16 @@
+require 'searcher'
+
+here = File.dirname(__FILE__)
+
+# Connect to the test database
+ActiveRecord::Base.establish_connection(:database => "searcher.sqlite3", :adapter => "sqlite3")
+
+# Load the schema into the test database
+load here + '/fixtures/schema.rb'
+
+# Load the models
+require here + '/fixtures/models'
+
+
+require 'logger'
+ActiveRecord::Base.logger = Logger.new("tmp/activerecord.log")
@@ -0,0 +1,51 @@
+# Logfile created on Sun Oct 03 13:36:03 +1100 2010 by logger.rb/22285
+D, [2010-10-03T13:38:15.026362 #9629] DEBUG -- : Ticket Load (0.2ms) SELECT "tickets".* FROM "tickets" WHERE (("tickets"."description" LIKE '%Hello%')) LIMIT 1
+D, [2010-10-03T13:38:30.373955 #9648] DEBUG -- : Ticket Load (0.2ms) SELECT "tickets".* FROM "tickets" WHERE (("tickets"."description" LIKE '%Hello%')) LIMIT 1
+D, [2010-10-03T13:47:45.075981 #9890] DEBUG -- : Ticket Load (0.2ms) SELECT "tickets".* FROM "tickets" WHERE (("tickets"."description" LIKE '%Hello%')) LIMIT 1
+D, [2010-10-03T13:50:40.166157 #10048] DEBUG -- : Ticket Load (0.2ms) SELECT "tickets".* FROM "tickets" WHERE (("tickets"."description" LIKE '%Hello%')) LIMIT 1
+D, [2010-10-03T13:51:21.792773 #10073] DEBUG -- : Ticket Load (0.2ms) SELECT "tickets".* FROM "tickets" WHERE (("tickets"."description" LIKE '%Hello%')) LIMIT 1
+D, [2010-10-03T13:51:44.496588 #10097] DEBUG -- : Ticket Load (0.2ms) SELECT "tickets".* FROM "tickets" WHERE (("tickets"."description" LIKE '%Hello%')) LIMIT 1
+D, [2010-10-03T13:51:44.500738 #10097] DEBUG -- : Ticket Load (0.1ms) SELECT "tickets".* FROM "tickets" WHERE (("tickets"."description" LIKE '%tag:bug%')) LIMIT 1
+D, [2010-10-03T13:54:57.827823 #10154] DEBUG -- : Ticket Load (0.2ms) SELECT "tickets".* FROM "tickets" WHERE (("tickets"."description" LIKE '%Hello%')) LIMIT 1
+D, [2010-10-03T13:55:49.980726 #10184] DEBUG -- : Ticket Load (0.9ms) SELECT "tickets".* FROM "tickets" WHERE (("tickets"."description" LIKE '%Hello%')) LIMIT 1
+D, [2010-10-03T13:56:02.832917 #10203] DEBUG -- : Ticket Load (0.2ms) SELECT "tickets".* FROM "tickets" WHERE (("tickets"."description" LIKE '%Hello%')) LIMIT 1
+D, [2010-10-03T13:56:22.551506 #10222] DEBUG -- : Ticket Load (0.2ms) SELECT "tickets".* FROM "tickets" WHERE (("tickets"."description" LIKE '%Hello%')) LIMIT 1
+D, [2010-10-03T13:56:39.036418 #10241] DEBUG -- : Ticket Load (0.2ms) SELECT "tickets".* FROM "tickets" WHERE (("tickets"."description" LIKE '%Hello%')) LIMIT 1
+D, [2010-10-03T13:57:08.263790 #10265] DEBUG -- : Ticket Load (0.2ms) SELECT "tickets".* FROM "tickets" WHERE (("tickets"."description" LIKE '%Hello%')) LIMIT 1
+D, [2010-10-03T13:57:08.267308 #10265] DEBUG -- : SQL (0.2ms) SELECT name
+ FROM sqlite_master
+ WHERE type = 'table' AND NOT name = 'sqlite_sequence'
+
+D, [2010-10-03T13:57:08.267674 #10265] DEBUG -- : SQL (0.1ms)  SELECT name
+ FROM sqlite_master
+ WHERE type = 'table' AND NOT name = 'sqlite_sequence'
+
+D, [2010-10-03T13:57:41.318240 #10294] DEBUG -- : Ticket Load (0.2ms) SELECT "tickets".* FROM "tickets" WHERE (("tickets"."description" LIKE '%Hello%')) LIMIT 1
+D, [2010-10-03T14:01:28.121270 #10333] DEBUG -- : Ticket Load (0.3ms) SELECT "tickets".* FROM "tickets" WHERE (("tickets"."description" LIKE '%Hello%')) LIMIT 1
+D, [2010-10-03T14:01:28.125293 #10333] DEBUG -- : SQL (0.2ms) SELECT name
+ FROM sqlite_master
+ WHERE type = 'table' AND NOT name = 'sqlite_sequence'
+
+D, [2010-10-03T14:01:28.125664 #10333] DEBUG -- : SQL (0.1ms)  SELECT name
+ FROM sqlite_master
+ WHERE type = 'table' AND NOT name = 'sqlite_sequence'
+
+D, [2010-10-03T14:01:44.778300 #10353] DEBUG -- : Ticket Load (0.2ms) SELECT "tickets".* FROM "tickets" WHERE (("tickets"."description" LIKE '%Hello%')) LIMIT 1
+D, [2010-10-03T14:02:03.670179 #10373] DEBUG -- : Ticket Load (0.2ms) SELECT "tickets".* FROM "tickets" WHERE (("tickets"."description" LIKE '%Hello%')) LIMIT 1
+D, [2010-10-03T14:02:37.447167 #10393] DEBUG -- : Ticket Load (0.2ms) SELECT "tickets".* FROM "tickets" WHERE (("tickets"."description" LIKE '%Hello%')) LIMIT 1
+D, [2010-10-03T14:02:58.220810 #10418] DEBUG -- : Ticket Load (0.2ms) SELECT "tickets".* FROM "tickets" WHERE (("tickets"."description" LIKE '%Hello%')) LIMIT 1
+D, [2010-10-03T14:03:33.734817 #10441] DEBUG -- : Ticket Load (0.2ms) SELECT "tickets".* FROM "tickets" WHERE (("tickets"."description" LIKE '%Hello%')) LIMIT 1
+D, [2010-10-03T14:04:18.534796 #10463] DEBUG -- : Ticket Load (0.2ms) SELECT "tickets".* FROM "tickets" WHERE (("tickets"."description" LIKE '%Hello%')) LIMIT 1
+D, [2010-10-03T14:06:14.718183 #10521] DEBUG -- : Ticket Load (0.2ms) SELECT "tickets".* FROM "tickets" WHERE (("tickets"."description" LIKE '%Hello%')) LIMIT 1
+D, [2010-10-03T14:06:14.723461 #10521] DEBUG -- : SQL (0.2ms) SELECT name
+ FROM sqlite_master
+ WHERE type = 'table' AND NOT name = 'sqlite_sequence'
+
+D, [2010-10-03T14:06:44.865381 #10553] DEBUG -- : Ticket Load (0.2ms) SELECT "tickets".* FROM "tickets" WHERE (("tickets"."description" LIKE '%Hello%')) LIMIT 1
+D, [2010-10-03T14:06:44.870723 #10553] DEBUG -- : SQL (0.2ms) SELECT name
+ FROM sqlite_master
+ WHERE type = 'table' AND NOT name = 'sqlite_sequence'
+
+D, [2010-10-03T14:06:57.779312 #10572] DEBUG -- : Ticket Load (0.2ms) SELECT "tickets".* FROM "tickets" WHERE (("tickets"."description" LIKE '%Hello%')) LIMIT 1
+D, [2010-10-03T14:06:57.785081 #10572] DEBUG -- : Ticket Load (0.1ms) SELECT "tickets".* FROM "tickets" tags
+D, [2010-10-03T14:07:55.279170 #10603] DEBUG -- : Ticket Load (0.2ms) SELECT "tickets".* FROM "tickets" WHERE (("tickets"."description" LIKE '%Hello%')) LIMIT 1

0 comments on commit c661e06

Please sign in to comment.