thinkingtank 0.0.4 → 0.0.5

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.
@@ -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')