mongo_tanker 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mongo_tanker.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 JD Hendrickson
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,29 @@
1
+ # MongoTanker
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'mongo_tanker'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install mongo_tanker
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,53 @@
1
+ require "mongo_tanker/version"
2
+ require "mongo_tanker/tank/index"
3
+ require "mongo_tanker/orm/mongoid"
4
+
5
+ ## Require workers
6
+ require "mongo_tanker/workers/sidekiq_workers/add_to_index_worker"
7
+ require "mongo_tanker/workers/sidekiq_workers/remove_from_index_worker"
8
+
9
+ module MongoTanker
10
+ ## Public Index Tank URL
11
+ mattr_accessor :public_url
12
+ @@public_url = ENV['INDEXTANK_PUBLIC_URL']
13
+
14
+ ## Private Index Tank URL
15
+ mattr_accessor :private_url
16
+ @@private_url = ENV['INDEXTANK_PRIVATE_URL']
17
+
18
+ ## Default index name (default: Rails.env)
19
+ mattr_accessor :default_index
20
+ @@default_index = Rails.env
21
+
22
+ ## Unique indexing key
23
+ ## This is used for development and/or shared environments that may be
24
+ ## writing to the same single index. This way, you can index the data
25
+ ## with a unique key that can be used to retrive that data as well
26
+ mattr_accessor :index_key
27
+ @@index_key = nil
28
+
29
+ ## Process in the background?
30
+ ## If you are running Sidekiq, setting this value to true will run workers
31
+ ## push updates to your indexes. If set to false, then standard callbacks
32
+ ## will be used on your models instead.
33
+ mattr_accessor :run_in_the_background
34
+ @@run_in_the_background = false
35
+
36
+ ## This is for later use
37
+ mattr_accessor :background_engine
38
+ @@background_engine = :sidekiq
39
+
40
+ ## Queue Name to use (default is nil - default of the engine)
41
+ mattr_accessor :queue_name
42
+ @@queue_name = nil
43
+
44
+ def self.queue_name=(value)
45
+ @@queue_name = value.to_s.downcase.parameterize.underscore.to_sym
46
+ end
47
+
48
+ # Default way to setup Devise. Run rails generate devise_install to create
49
+ # a fresh initializer with all configuration values.
50
+ def self.setup
51
+ yield self
52
+ end
53
+ end
@@ -0,0 +1,155 @@
1
+ ##
2
+ ##
3
+ module MongoTanker
4
+ module ORM
5
+ module Mongoid
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ after_save :mongo_tanker_add_to_index!
10
+ after_destroy :mongo_tanker_remove_from_index!
11
+ end
12
+
13
+ ## Class Methods ---------------------------------
14
+
15
+ module ClassMethods
16
+ ##
17
+ # searchify
18
+ # set searchify parameters for the model implementing this concern.
19
+ #
20
+ # Options
21
+ # ===============================
22
+ # :doc_id
23
+ # Name of a Rails route to use as the doc_id
24
+ #
25
+ # :use_route_as_doc_id (default: true)
26
+ # Set to false if the :doc_id value should be treated as string
27
+ #
28
+ # :index (default: MongoTanker.default_index)
29
+ # Name of the Searchify index this resource will be indexed against.
30
+ #
31
+ # :sync_mode (default: true)
32
+ # Automatically execute indexing push/removal
33
+ # Options:
34
+ # :all - auto push & remove from indexes
35
+ # :none - do nothing automatically
36
+ # :push - only perform index pushes automatically
37
+ # :remove - only remove from indexes automatically
38
+ #
39
+ def mongo_tanker( options={} )
40
+ @mongo_tanker = @mongo_tanker || {}
41
+
42
+ default_options = {
43
+ :doc_id_route => @mongo_tanker.fetch(:doc_id_route, nil),
44
+ :index_name => @mongo_tanker.fetch(:index_name, MongoTanker.default_index),
45
+ :sync_mode => @mongo_tanker.fetch(:sync_mode, :all)
46
+ }
47
+
48
+ @mongo_tanker = default_options.merge options
49
+ return @mongo_tanker
50
+ end
51
+
52
+ ## Map document
53
+ def mongo_tanker_document_defaults
54
+ fields = {
55
+ }
56
+
57
+ return fields
58
+ end
59
+ end
60
+
61
+ ## Instance Methods ---------------------------------
62
+
63
+ ## mongo_tanker_doc_id
64
+ # Build the mongo_tank doc id based on settings and rules
65
+ #
66
+ # TODO: This could probably be enhanced to allow for even more
67
+ # ways of building the doc id
68
+ def mongo_tanker_document_id
69
+ return @mongo_tanker_doc_id ||= (
70
+ doc_id_route = self.class.mongo_tanker[:doc_id_route]
71
+
72
+ if (doc_id_route)
73
+ @mongo_tanker_doc_id = Rails.application.routes.url_helpers.send(doc_id_route.to_sym, self.id.to_s)
74
+ else
75
+ @mongo_tanker_doc_id = self.id.to_s
76
+ end
77
+ )
78
+ end
79
+
80
+ ## to_mongo_tanker_document
81
+ # Returns the actual document structure for this particular MongoDB document
82
+ #
83
+ def to_mongo_tanker_document
84
+ document = {
85
+ :id => self.id.to_s,
86
+ :text => self.mongo_tanker_meta_data,
87
+ :match => "all",
88
+ :group => self.class.name.pluralize.underscore.parameterize,
89
+ :group_name => self.class.name.pluralize.underscore.humanize.titleize,
90
+ :bo_type => self.class.name
91
+ }
92
+
93
+ document[:index_key] = MongoTanker.index_key unless MongoTanker.index_key.nil?
94
+
95
+ document.merge!(mongo_tanker_document_map) if self.respond_to?(:mongo_tanker_document_map, true)
96
+
97
+ return document
98
+ end
99
+
100
+ ##
101
+ # mongo_tank_meta_data
102
+ # Returns a string with all of the meta data for this mongo document.
103
+ #
104
+ # By default, this will be empty. You must define a protected "mongo_tanker_meta_map" method
105
+ # which will return an array of the field values to be returned.
106
+ #
107
+ def mongo_tanker_meta_data
108
+ meta_data = [] | ((self.respond_to?(:mongo_tanker_meta_map, true)) ? mongo_tanker_meta_map : [])
109
+ return meta_data.flatten.join(" ")
110
+ end
111
+
112
+ private # -------------------------------------------
113
+
114
+ def mongo_tanker_add_to_index!
115
+ if MongoTanker.run_in_the_background
116
+ mongo_tanker_add_to_index_in_the_bg!
117
+ else
118
+ index_name = self.class.mongo_tanker[:index_name]
119
+ index = MongoTanker::Tank::Index.open(index_name)
120
+
121
+ index.document(self.mongo_tanker_document_id).add(self.to_mongo_tanker_document)
122
+ end
123
+ end
124
+
125
+ def mongo_tanker_remove_from_index!
126
+ if MongoTanker.run_in_the_background
127
+ mongo_tanker_remove_from_index_in_the_bg!
128
+ else
129
+ index_name = self.class.mongo_tanker[:index_name]
130
+ index = MongoTanker::Tank::Index.open(index_name)
131
+
132
+ index.document(self.mongo_tanker_document_id).delete
133
+ end
134
+ end
135
+
136
+ def mongo_tanker_add_to_index_in_the_bg!
137
+ case(MongoTanker.background_engine.to_s.downcase.to_sym)
138
+ when :sidekiq
139
+ Sidekiq::Client.enqueue(MongoTanker::Workers::SidekiqWorkers::AddToIndexWorker, self.class.name, self.id.to_s)
140
+ else
141
+ throw "Sidekiq is currently the only supported background processing engine."
142
+ end
143
+ end
144
+
145
+ def mongo_tanker_remove_from_index_in_the_bg!
146
+ case(MongoTanker.background_engine.to_s.downcase.to_sym)
147
+ when :sidekiq
148
+ Sidekiq::Client.enqueue(MongoTanker::Workers::SidekiqWorkers::RemoveFromIndexWorker, self.class.name, self.mongo_tanker_document_id)
149
+ else
150
+ throw "Sidekiq is currently the only supported background processing engine."
151
+ end
152
+ end
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,24 @@
1
+ require 'indextank'
2
+
3
+ ##
4
+ module MongoTanker
5
+ module Tank
6
+ class Index
7
+ def self.open(index_name, scope = 'private')
8
+ url = (scope == 'private') ? MongoTanker.private_url : MongoTanker.public_url
9
+ client = IndexTank::Client.new url
10
+ index = client.indexes index_name
11
+
12
+ unless index.exists?
13
+ index.add :public_search => true
14
+
15
+ while not index.running?
16
+ sleep 0.5
17
+ end
18
+ end
19
+
20
+ return index
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,3 @@
1
+ module MongoTanker
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,22 @@
1
+ require 'sidekiq'
2
+
3
+ module MongoTanker
4
+ module Workers
5
+ module SidekiqWorkers
6
+ class AddToIndexWorker
7
+ include Sidekiq::Worker
8
+
9
+ sidekiq_options :queue => :indexing
10
+
11
+ def perform(resource_name, resource_id)
12
+ klass = resource_name.to_s.constantize
13
+ resource = klass.find resource_id
14
+ index_name = klass.mongo_tanker[:index_name]
15
+ index = MongoTanker::Tank::Index.open(index_name)
16
+
17
+ index.document(resource.mongo_tanker_document_id).add(resource.to_mongo_tanker_document)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,21 @@
1
+ require 'sidekiq'
2
+
3
+ module MongoTanker
4
+ module Workers
5
+ module SidekiqWorkers
6
+ class RemoveFromIndexWorker
7
+ include Sidekiq::Worker
8
+
9
+ sidekiq_options :queue => :indexing
10
+
11
+ def perform(resource_name, doc_id)
12
+ klass = resource_name.to_s.constantize
13
+ index_name = klass.mongo_tanker[:index_name]
14
+ index = MongoTanker::Tank::Index.open(index_name)
15
+
16
+ index.document(doc_id).delete()
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'mongo_tanker/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "mongo_tanker"
8
+ gem.version = MongoTanker::VERSION
9
+ gem.authors = ["JD Hendrickson"]
10
+ gem.email = ["jd@digitalopera.com"]
11
+ gem.description = "Simple DSL for using an IndexTank search provider with Mongoid"
12
+ gem.summary = "Simple DSL for using an IndexTank search provider with Mongoid"
13
+ gem.homepage = "https://github.com/digitalopera/mongotanker"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_dependency "mongoid", "~> 3.0.0"
21
+ gem.add_dependency "indextank", "~> 1.0.12"
22
+ gem.add_dependency "activesupport", "~> 3.2.0"
23
+ end
metadata ADDED
@@ -0,0 +1,105 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mongo_tanker
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - JD Hendrickson
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-06-11 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: mongoid
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 3.0.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 3.0.0
30
+ - !ruby/object:Gem::Dependency
31
+ name: indextank
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 1.0.12
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 1.0.12
46
+ - !ruby/object:Gem::Dependency
47
+ name: activesupport
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 3.2.0
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 3.2.0
62
+ description: Simple DSL for using an IndexTank search provider with Mongoid
63
+ email:
64
+ - jd@digitalopera.com
65
+ executables: []
66
+ extensions: []
67
+ extra_rdoc_files: []
68
+ files:
69
+ - .gitignore
70
+ - Gemfile
71
+ - LICENSE.txt
72
+ - README.md
73
+ - Rakefile
74
+ - lib/mongo_tanker.rb
75
+ - lib/mongo_tanker/orm/mongoid.rb
76
+ - lib/mongo_tanker/tank/index.rb
77
+ - lib/mongo_tanker/version.rb
78
+ - lib/mongo_tanker/workers/sidekiq_workers/add_to_index_worker.rb
79
+ - lib/mongo_tanker/workers/sidekiq_workers/remove_from_index_worker.rb
80
+ - mongo_tanker.gemspec
81
+ homepage: https://github.com/digitalopera/mongotanker
82
+ licenses: []
83
+ post_install_message:
84
+ rdoc_options: []
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - ! '>='
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ requirements: []
100
+ rubyforge_project:
101
+ rubygems_version: 1.8.24
102
+ signing_key:
103
+ specification_version: 3
104
+ summary: Simple DSL for using an IndexTank search provider with Mongoid
105
+ test_files: []