thinkingtank 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,14 @@
1
+ require 'rails'
2
+ require 'thinkingtank/init'
3
+
4
+ if defined?(Rails::Railtie)
5
+ # Rails 3
6
+ # The Railtie will load the Activerecord extensions at the appropriate
7
+ # point in the boot process
8
+ require 'thinkingtank/railtie'
9
+ else
10
+ # Rails 2
11
+ # Load the extensions now, since we don't have fine-grained control like
12
+ # in a Railtie
13
+ require 'thinkingtank/activerecord_extensions'
14
+ end
@@ -0,0 +1,60 @@
1
+ require 'thinkingtank/init'
2
+
3
+ class << ActiveRecord::Base
4
+ @indexable = false
5
+ def search(*args)
6
+ return indextank_search(true, *args)
7
+ end
8
+ def search_raw(*args)
9
+ return indextank_search(false, *args)
10
+ end
11
+
12
+ def define_index(name = nil, &block)
13
+ include ThinkingTank::IndexMethods
14
+ @thinkingtank_builder = ThinkingTank::Builder.new self, &block
15
+ @indexable = true
16
+ after_save :update_index
17
+ end
18
+
19
+ def is_indexable?
20
+ return @indexable
21
+ end
22
+
23
+ def thinkingtank_builder
24
+ return @thinkingtank_builder
25
+ end
26
+
27
+ private
28
+
29
+ def indextank_search(models, *args)
30
+ options = args.extract_options!
31
+ query = args.join(' ')
32
+
33
+ # transform fields in query
34
+
35
+ if options.has_key? :conditions
36
+ options[:conditions].each do |field,value|
37
+ query += " #{field}:(#{value})"
38
+ end
39
+ end
40
+
41
+ options.slice!(:snippet, :fetch, :function)
42
+
43
+ it = ThinkingTank::Configuration.instance.client
44
+ models = []
45
+ res = it.search("__any:(#{query.to_s}) __type:#{self.name}", options)
46
+ if models
47
+ res['results'].each do |doc|
48
+ type, docid = doc['docid'].split(" ", 2)
49
+ models << self.find(id=docid)
50
+ end
51
+ return models
52
+ else
53
+ res['results'].each do |doc|
54
+ type, docid = doc['docid'].split(" ", 2)
55
+ doc['model'] = self.find(id=docid)
56
+ end
57
+ return res
58
+ end
59
+ end
60
+ end
@@ -246,7 +246,7 @@ module IndexTank
246
246
 
247
247
  class HerokuClient < ApiClient
248
248
  def initialize()
249
- super(ENV['HEROKUTANK_API_URL'])
249
+ super(ENV['INDEXTANK_API_URL'])
250
250
  end
251
251
  end
252
252
 
@@ -1,4 +1,10 @@
1
- require 'indextank_client'
1
+ # Require these to allow requiring thinkingtank outside a Rails app, e.g.
2
+ # for testing.
3
+ require 'erb'
4
+ require 'yaml'
5
+ require 'singleton'
6
+
7
+ require 'thinkingtank/indextank_client'
2
8
 
3
9
  module ThinkingTank
4
10
  class Builder
@@ -23,6 +29,7 @@ module ThinkingTank
23
29
  include Singleton
24
30
  attr_accessor :app_root, :client
25
31
  def initialize
32
+ self.app_root = Rails.root if defined?(Rails.root)
26
33
  self.app_root = RAILS_ROOT if defined?(RAILS_ROOT)
27
34
  self.app_root = Merb.root if defined?(Merb)
28
35
  self.app_root ||= Dir.pwd
@@ -31,12 +38,15 @@ module ThinkingTank
31
38
  return unless File.exists?(path)
32
39
 
33
40
  conf = YAML::load(ERB.new(IO.read(path)).result)[environment]
34
- api_url = ENV['HEROKUTANK_API_URL'] || conf['api_url']
35
- self.client = IndexTank::ApiClient.new(api_url).get_index(conf['index_name'])
41
+ api_url = ENV['INDEXTANK_API_URL'] || conf['api_url']
42
+ index_name = conf['index_name'] || 'default_index'
43
+ self.client = IndexTank::ApiClient.new(api_url).get_index(index_name)
36
44
  end
37
45
  def environment
38
46
  if defined?(Merb)
39
47
  Merb.environment
48
+ elsif defined?(Rails.env)
49
+ Rails.env
40
50
  elsif defined?(RAILS_ENV)
41
51
  RAILS_ENV
42
52
  else
@@ -61,65 +71,3 @@ module ThinkingTank
61
71
  end
62
72
 
63
73
  end
64
-
65
- class << ActiveRecord::Base
66
- @indexable = false
67
- def search(*args)
68
- return indextank_search(true, *args)
69
- end
70
- def search_raw(*args)
71
- return indextank_search(false, *args)
72
- end
73
-
74
- def define_index(name = nil, &block)
75
- include ThinkingTank::IndexMethods
76
- @thinkingtank_builder = ThinkingTank::Builder.new self, &block
77
- @indexable = true
78
- after_save :update_index
79
- end
80
-
81
- def is_indexable?
82
- return @indexable
83
- end
84
-
85
- def thinkingtank_builder
86
- return @thinkingtank_builder
87
- end
88
-
89
- private
90
-
91
- def indextank_search(models, *args)
92
- options = args.extract_options!
93
- query = args.join(' ')
94
-
95
- # transform fields in query
96
-
97
- if options.has_key? :conditions
98
- options[:conditions].each do |field,value|
99
- query += " #{field}:(#{value})"
100
- end
101
- end
102
-
103
- options.slice!(:snippet, :fetch, :function)
104
-
105
- it = ThinkingTank::Configuration.instance.client
106
- models = []
107
- res = it.search("__any:(#{query.to_s}) __type:#{self.name}", options)
108
- if models
109
- res['results'].each do |doc|
110
- type, docid = doc['docid'].split(" ", 2)
111
- models << self.find(id=docid)
112
- end
113
- return models
114
- else
115
- res['results'].each do |doc|
116
- type, docid = doc['docid'].split(" ", 2)
117
- doc['model'] = self.find(id=docid)
118
- end
119
- return res
120
- end
121
- end
122
-
123
- end
124
-
125
-
@@ -0,0 +1,9 @@
1
+ class ThinkingTankRailtie < ::Rails::Railtie
2
+ rake_tasks do
3
+ require 'thinkingtank/tasks'
4
+ end
5
+
6
+ config.before_initialize do
7
+ require 'thinkingtank/activerecord_extensions'
8
+ end
9
+ end
@@ -1,6 +1,5 @@
1
- require 'erb'
2
- require 'active_record'
3
- require 'indextank_client'
1
+ # Load init for Rails 2, since it directly loads this file
2
+ require 'thinkingtank/init'
4
3
 
5
4
  def load_models
6
5
  app_root = ThinkingTank::Configuration.instance.app_root
@@ -30,19 +29,44 @@ end
30
29
 
31
30
  def reindex_models
32
31
  it = ThinkingTank::Configuration.instance.client
33
- if it.exists?
32
+ if it.nil?
33
+ puts "!!! Couldn't create a client. Does config/indextank.yml have the correct info?"
34
+ return false
35
+ end
36
+
37
+ if it.exists? and it.code
38
+ # Check for code because it.exists? may return true for a
39
+ # nonexistent index
34
40
  puts "Deleting existing index"
35
41
  it.delete_index()
36
42
  end
37
43
  puts "Creating a new empty index"
38
44
  it.create_index()
39
- puts "Waiting for the index to be ready"
45
+ puts "Waiting for the index to be ready (this might take a while)"
40
46
  while not it.running?
47
+ print "."
48
+ STDOUT.flush
41
49
  sleep 0.5
42
50
  end
51
+ print "\n"
52
+ STDOUT.flush
53
+
54
+
55
+ subclasses = nil
56
+ if ActiveRecord::Base.respond_to?(:descendants)
57
+ # Rails 3.0.0 and higher
58
+ subclasses = ActiveRecord::Base.descendants
59
+ elsif Object.respond_to?(:subclasses_of)
60
+ subclasses = Object.subclasses_of(ActiveRecord::Base)
61
+ end
43
62
 
44
- Object.subclasses_of(ActiveRecord::Base).each do |klass|
45
- reindex klass if klass.is_indexable?
63
+ if subclasses.nil?
64
+ STDERR.puts "Couldn't detect models to index."
65
+ return false
66
+ else
67
+ subclasses.each do |klass|
68
+ reindex klass if klass.is_indexable?
69
+ end
46
70
  end
47
71
  end
48
72
 
@@ -54,6 +78,8 @@ def reindex(klass)
54
78
  end
55
79
 
56
80
  namespace :indextank do
81
+ # MUST have a description for it to show up in rake -T!
82
+ desc "Reindex all models. This deletes and recreates the index."
57
83
  task :reindex => :environment do
58
84
  load_models
59
85
  reindex_models
@@ -61,5 +87,6 @@ namespace :indextank do
61
87
  end
62
88
 
63
89
  namespace :it do
90
+ desc "An alias for indextank:reindex"
64
91
  task :reindex => "indextank:reindex"
65
92
  end
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: thinkingtank
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 21
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
8
  - 0
8
- - 4
9
- version: 0.0.4
9
+ - 5
10
+ version: 0.0.5
10
11
  platform: ruby
11
12
  authors:
12
13
  - Flaptor
@@ -14,7 +15,7 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-07-27 00:00:00 -07:00
18
+ date: 2010-12-23 00:00:00 -02:00
18
19
  default_executable:
19
20
  dependencies: []
20
21
 
@@ -29,12 +30,12 @@ extensions: []
29
30
  extra_rdoc_files: []
30
31
 
31
32
  files:
32
- - rails/init.rb
33
- - lib/indextank_client.rb
33
+ - lib/thinkingtank/indextank_client.rb
34
34
  - lib/thinkingtank/init.rb
35
- - README
36
- - tasks/rails.rake
35
+ - lib/thinkingtank/railtie.rb
37
36
  - lib/thinkingtank/tasks.rb
37
+ - lib/thinkingtank/activerecord_extensions.rb
38
+ - lib/thinkingtank.rb
38
39
  has_rdoc: true
39
40
  homepage: http://indextank.com/
40
41
  licenses: []
@@ -45,23 +46,27 @@ rdoc_options: []
45
46
  require_paths:
46
47
  - lib
47
48
  required_ruby_version: !ruby/object:Gem::Requirement
49
+ none: false
48
50
  requirements:
49
51
  - - ">="
50
52
  - !ruby/object:Gem::Version
53
+ hash: 3
51
54
  segments:
52
55
  - 0
53
56
  version: "0"
54
57
  required_rubygems_version: !ruby/object:Gem::Requirement
58
+ none: false
55
59
  requirements:
56
60
  - - ">="
57
61
  - !ruby/object:Gem::Version
62
+ hash: 3
58
63
  segments:
59
64
  - 0
60
65
  version: "0"
61
66
  requirements: []
62
67
 
63
68
  rubyforge_project:
64
- rubygems_version: 1.3.6
69
+ rubygems_version: 1.3.7
65
70
  signing_key:
66
71
  specification_version: 3
67
72
  summary: Thinking-Sphinx-like Indextank plugin.
data/README DELETED
@@ -1,67 +0,0 @@
1
- ThinkingTank
2
- =============
3
-
4
- ActiveRecord extension that allows to define models that should be indexed
5
- in an existing IndexTank index. It supports a very similar syntax to
6
- ThinkingSphinx allowing to easily port an existing project.
7
-
8
- Every indexable model should include a define_index block in its class
9
- definition, see the example for more details. This block supports the indexes
10
- method and receives a field name.
11
-
12
- Model classes now have a search method that receives one or more string
13
- arguments with query strings (according to the query specifications) and
14
- supports the :conditions argument as a hash from field name to query string.
15
-
16
- In order for this extension to work you need to define a config/indextank.yml
17
- in your application with the api_key and index_code (or index_name) settings
18
- for each environment (similar to config/database.yml).
19
-
20
- Indexed fields in ActiveRecord are prepended an underscore when sent to
21
- IndexTank so if you plan to write query strings that use your field names you
22
- will have to prepend the underscore to the field names.
23
-
24
- In order for the ThinkingTank rake tasks to be available you need to add:
25
-
26
- require 'thinkingtank/tasks'
27
-
28
- to your Rakefile. You can use the following task to reindex your entire database:
29
-
30
- rake indextank:reindex
31
-
32
-
33
- Example
34
- =======
35
-
36
- Sample config/indextank.yml file:
37
-
38
- development:
39
- api_key: '<YOUR API KEY>'
40
- index_code: '<INDEX CODE>'
41
- # instead of index_code you can also use an index_name
42
- test:
43
- api_key: '<YOUR API KEY>'
44
- index_code: '<INDEX CODE>'
45
- # instead of index_code you can also use an index_name
46
- production:
47
- api_key: '<YOUR API KEY>'
48
- index_code: '<INDEX CODE>'
49
- # instead of index_code you can also use an index_name
50
-
51
- Sample model:
52
- class Person < ActiveRecord::Base
53
- define_index do
54
- indexes :name
55
- indexes gender
56
- indexes age
57
- end
58
- end
59
-
60
- Sample query code:
61
- Person.search("john")
62
- Person.search("john OR stacey")
63
- Person.search("stacey", :conditions => { :age => 25 } )
64
- Person.search("james", :conditions => { :age => 25 , :gender => "female" } )
65
-
66
-
67
- Copyright(c) 2010 Flaptor Inc.
data/rails/init.rb DELETED
@@ -1,4 +0,0 @@
1
- # Include hook code here
2
- require 'active_record'
3
- require File.dirname(__FILE__) + '/../lib/thinkingtank/init'
4
-
data/tasks/rails.rake DELETED
@@ -1 +0,0 @@
1
- require File.join(File.dirname(__FILE__), '/tasks')