outoftime-sunspot 0.0.1

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.
Files changed (100) hide show
  1. data/History.txt +7 -0
  2. data/Manifest.txt +104 -0
  3. data/PostInstall.txt +7 -0
  4. data/README.rdoc +115 -0
  5. data/Rakefile +27 -0
  6. data/config/hoe.rb +74 -0
  7. data/config/requirements.rb +15 -0
  8. data/lib/light_config.rb +40 -0
  9. data/lib/sunspot/adapters.rb +54 -0
  10. data/lib/sunspot/conditions.rb +50 -0
  11. data/lib/sunspot/conditions_builder.rb +37 -0
  12. data/lib/sunspot/configuration.rb +17 -0
  13. data/lib/sunspot/field.rb +108 -0
  14. data/lib/sunspot/field_builder.rb +37 -0
  15. data/lib/sunspot/indexer.rb +65 -0
  16. data/lib/sunspot/query.rb +115 -0
  17. data/lib/sunspot/query_builder.rb +30 -0
  18. data/lib/sunspot/restriction.rb +72 -0
  19. data/lib/sunspot/scope_builder.rb +33 -0
  20. data/lib/sunspot/search.rb +83 -0
  21. data/lib/sunspot/session.rb +43 -0
  22. data/lib/sunspot/type.rb +62 -0
  23. data/lib/sunspot/util.rb +13 -0
  24. data/lib/sunspot/version.rb +10 -0
  25. data/lib/sunspot.rb +50 -0
  26. data/setup.rb +1585 -0
  27. data/solr/README.txt +36 -0
  28. data/solr/etc/jetty.xml +206 -0
  29. data/solr/etc/webdefault.xml +379 -0
  30. data/solr/exampledocs/books.csv +11 -0
  31. data/solr/exampledocs/hd.xml +46 -0
  32. data/solr/exampledocs/ipod_other.xml +50 -0
  33. data/solr/exampledocs/ipod_video.xml +35 -0
  34. data/solr/exampledocs/mem.xml +58 -0
  35. data/solr/exampledocs/monitor.xml +31 -0
  36. data/solr/exampledocs/monitor2.xml +30 -0
  37. data/solr/exampledocs/mp500.xml +39 -0
  38. data/solr/exampledocs/post.jar +0 -0
  39. data/solr/exampledocs/post.sh +28 -0
  40. data/solr/exampledocs/sd500.xml +33 -0
  41. data/solr/exampledocs/solr.xml +38 -0
  42. data/solr/exampledocs/spellchecker.xml +58 -0
  43. data/solr/exampledocs/utf8-example.xml +42 -0
  44. data/solr/exampledocs/vidcard.xml +52 -0
  45. data/solr/lib/jetty-6.1.3.jar +0 -0
  46. data/solr/lib/jetty-util-6.1.3.jar +0 -0
  47. data/solr/lib/jsp-2.1/ant-1.6.5.jar +0 -0
  48. data/solr/lib/jsp-2.1/core-3.1.1.jar +0 -0
  49. data/solr/lib/jsp-2.1/jsp-2.1.jar +0 -0
  50. data/solr/lib/jsp-2.1/jsp-api-2.1.jar +0 -0
  51. data/solr/lib/servlet-api-2.5-6.1.3.jar +0 -0
  52. data/solr/solr/README.txt +52 -0
  53. data/solr/solr/bin/abc +176 -0
  54. data/solr/solr/bin/abo +176 -0
  55. data/solr/solr/bin/backup +108 -0
  56. data/solr/solr/bin/backupcleaner +142 -0
  57. data/solr/solr/bin/commit +128 -0
  58. data/solr/solr/bin/optimize +129 -0
  59. data/solr/solr/bin/readercycle +129 -0
  60. data/solr/solr/bin/rsyncd-disable +77 -0
  61. data/solr/solr/bin/rsyncd-enable +76 -0
  62. data/solr/solr/bin/rsyncd-start +145 -0
  63. data/solr/solr/bin/rsyncd-stop +105 -0
  64. data/solr/solr/bin/scripts-util +83 -0
  65. data/solr/solr/bin/snapcleaner +148 -0
  66. data/solr/solr/bin/snapinstaller +168 -0
  67. data/solr/solr/bin/snappuller +248 -0
  68. data/solr/solr/bin/snappuller-disable +77 -0
  69. data/solr/solr/bin/snappuller-enable +77 -0
  70. data/solr/solr/bin/snapshooter +109 -0
  71. data/solr/solr/conf/admin-extra.html +31 -0
  72. data/solr/solr/conf/protwords.txt +21 -0
  73. data/solr/solr/conf/schema.xml +231 -0
  74. data/solr/solr/conf/scripts.conf +24 -0
  75. data/solr/solr/conf/solrconfig.xml +394 -0
  76. data/solr/solr/conf/stopwords.txt +57 -0
  77. data/solr/solr/conf/synonyms.txt +31 -0
  78. data/solr/start.jar +0 -0
  79. data/solr/webapps/solr.war +0 -0
  80. data/tasks/deployment.rake +34 -0
  81. data/tasks/environment.rake +7 -0
  82. data/tasks/rcov.rake +6 -0
  83. data/tasks/solr.rake +12 -0
  84. data/tasks/website.rake +17 -0
  85. data/test/api/test_build_search.rb +216 -0
  86. data/test/api/test_helper.rb +4 -0
  87. data/test/api/test_indexer.rb +110 -0
  88. data/test/api/test_retrieve_search.rb +114 -0
  89. data/test/api/test_session.rb +46 -0
  90. data/test/custom_expectation.rb +53 -0
  91. data/test/integration/test_field_types.rb +62 -0
  92. data/test/integration/test_helper.rb +1 -0
  93. data/test/integration/test_keyword_search.rb +32 -0
  94. data/test/integration/test_pagination.rb +32 -0
  95. data/test/mocks/base_class.rb +2 -0
  96. data/test/mocks/comment.rb +28 -0
  97. data/test/mocks/mock_adapter.rb +25 -0
  98. data/test/mocks/post.rb +41 -0
  99. data/test/test_helper.rb +31 -0
  100. metadata +191 -0
data/History.txt ADDED
@@ -0,0 +1,7 @@
1
+ == 0.0.1 2008-12-11
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
5
+ * Define indexing for any class using DSL
6
+ * Search indexed classes using DSL
7
+
data/Manifest.txt ADDED
@@ -0,0 +1,104 @@
1
+ History.txt
2
+ Manifest.txt
3
+ PostInstall.txt
4
+ README.rdoc
5
+ Rakefile
6
+ config/hoe.rb
7
+ config/requirements.rb
8
+ lib/light_config.rb
9
+ lib/sunspot.rb
10
+ lib/sunspot/adapters.rb
11
+ lib/sunspot/conditions.rb
12
+ lib/sunspot/conditions_builder.rb
13
+ lib/sunspot/configuration.rb
14
+ lib/sunspot/field.rb
15
+ lib/sunspot/field_builder.rb
16
+ lib/sunspot/indexer.rb
17
+ lib/sunspot/query.rb
18
+ lib/sunspot/query_builder.rb
19
+ lib/sunspot/restriction.rb
20
+ lib/sunspot/scope_builder.rb
21
+ lib/sunspot/search.rb
22
+ lib/sunspot/session.rb
23
+ lib/sunspot/type.rb
24
+ lib/sunspot/util.rb
25
+ lib/sunspot/version.rb
26
+ log/test_solr.log
27
+ setup.rb
28
+ solr/README.txt
29
+ solr/etc/jetty.xml
30
+ solr/etc/webdefault.xml
31
+ solr/exampledocs/books.csv
32
+ solr/exampledocs/hd.xml
33
+ solr/exampledocs/ipod_other.xml
34
+ solr/exampledocs/ipod_video.xml
35
+ solr/exampledocs/mem.xml
36
+ solr/exampledocs/monitor.xml
37
+ solr/exampledocs/monitor2.xml
38
+ solr/exampledocs/mp500.xml
39
+ solr/exampledocs/post.jar
40
+ solr/exampledocs/post.sh
41
+ solr/exampledocs/sd500.xml
42
+ solr/exampledocs/solr.xml
43
+ solr/exampledocs/spellchecker.xml
44
+ solr/exampledocs/utf8-example.xml
45
+ solr/exampledocs/vidcard.xml
46
+ solr/lib/jetty-6.1.3.jar
47
+ solr/lib/jetty-util-6.1.3.jar
48
+ solr/lib/jsp-2.1/ant-1.6.5.jar
49
+ solr/lib/jsp-2.1/core-3.1.1.jar
50
+ solr/lib/jsp-2.1/jsp-2.1.jar
51
+ solr/lib/jsp-2.1/jsp-api-2.1.jar
52
+ solr/lib/servlet-api-2.5-6.1.3.jar
53
+ solr/logs
54
+ solr/solr/README.txt
55
+ solr/solr/bin/abc
56
+ solr/solr/bin/abo
57
+ solr/solr/bin/backup
58
+ solr/solr/bin/backupcleaner
59
+ solr/solr/bin/commit
60
+ solr/solr/bin/optimize
61
+ solr/solr/bin/readercycle
62
+ solr/solr/bin/rsyncd-disable
63
+ solr/solr/bin/rsyncd-enable
64
+ solr/solr/bin/rsyncd-start
65
+ solr/solr/bin/rsyncd-stop
66
+ solr/solr/bin/scripts-util
67
+ solr/solr/bin/snapcleaner
68
+ solr/solr/bin/snapinstaller
69
+ solr/solr/bin/snappuller
70
+ solr/solr/bin/snappuller-disable
71
+ solr/solr/bin/snappuller-enable
72
+ solr/solr/bin/snapshooter
73
+ solr/solr/conf/admin-extra.html
74
+ solr/solr/conf/protwords.txt
75
+ solr/solr/conf/schema.xml
76
+ solr/solr/conf/scripts.conf
77
+ solr/solr/conf/solrconfig.xml
78
+ solr/solr/conf/stopwords.txt
79
+ solr/solr/conf/synonyms.txt
80
+ solr/solr/conf/xslt
81
+ solr/solr/conf/xslt
82
+ solr/solr/data/spell
83
+ solr/start.jar
84
+ solr/webapps/solr.war
85
+ tasks/deployment.rake
86
+ tasks/environment.rake
87
+ tasks/rcov.rake
88
+ tasks/solr.rake
89
+ tasks/website.rake
90
+ test/api/test_build_search.rb
91
+ test/api/test_helper.rb
92
+ test/api/test_indexer.rb
93
+ test/api/test_retrieve_search.rb
94
+ test/api/test_session.rb
95
+ test/custom_expectation.rb
96
+ test/integration/test_field_types.rb
97
+ test/integration/test_helper.rb
98
+ test/integration/test_keyword_search.rb
99
+ test/integration/test_pagination.rb
100
+ test/mocks/base_class.rb
101
+ test/mocks/comment.rb
102
+ test/mocks/mock_adapter.rb
103
+ test/mocks/post.rb
104
+ test/test_helper.rb
data/PostInstall.txt ADDED
@@ -0,0 +1,7 @@
1
+
2
+ For more information on sunspot, see http://sunspot.rubyforge.org
3
+
4
+ NOTE: Change this information in PostInstall.txt
5
+ You can also delete it if you don't want it.
6
+
7
+
data/README.rdoc ADDED
@@ -0,0 +1,115 @@
1
+ = sunspot
2
+
3
+ http://github.com/outoftime/sunspot
4
+
5
+ Sunspot is a Ruby library for expressive, powerful interaction with the Solr search engine.
6
+ Sunspot is built on top of the solr-ruby gem, which provides a low-level interface for Solr
7
+ interaction; Sunspot provides a simple, intuitive, expressive DSL backed by powerful
8
+ features for indexing objects and searching against them.
9
+
10
+ Sunspot is designed to be easily plugged in to any ORM, or even non-database-backed
11
+ objects such as the filesystem.
12
+
13
+ Sunspot is currently under active development and is not feature-complete.
14
+
15
+ === Sunspot already has these features:
16
+
17
+ * Define indexing strategy for each searchable class using intuitive block-based API
18
+ * Clean separation between keyword-searchable fields and fields for scoping/ordering
19
+ * Define fields based on existing attributes or "virtual fields" for custom indexing
20
+ * Indexes each object's entire superclass hierarchy, for easy searching for all objects inheriting from a parent class
21
+ * Intuitive DSL for scoping searches, with all the usual boolean operators available
22
+ * Ability to pass dynamic conditions in as a hash, and define which operator to use for each condition
23
+ * Full compatibility with will_paginate
24
+ * Ordering
25
+
26
+ === Sunspot will have these features:
27
+
28
+ * Adapters for DataMapper, ActiveRecord, and File objects
29
+ * Extensible adapter architecture for easy integration of other ORMs or non-model classes
30
+ * High-power integration with ORM features for maximum efficiency (e.g., specify AR :include argument for eager loading associations when hydrating search results)
31
+ * Intuitive interface for requesting facets on indexed fields
32
+ * Define association facets, which return model objects as row values
33
+ * Access search parameters as hash or object attributes, for easy integration with form helpers or query string builders
34
+ * Plugins for drop-in integration with Merb and Rails
35
+
36
+ == Using Sunspot
37
+
38
+ === Define an index:
39
+
40
+ class Post
41
+ #...
42
+ end
43
+
44
+ Sunspot.setup(Post) do
45
+ text :title, :body
46
+ string :author_name
47
+ integer :blog_id
48
+ integer :category_ids
49
+ float :average_rating
50
+ time :published_at
51
+ string :sort_title do
52
+ title.downcase.sub(/^(an?|the)\W+/, ''/) if title = self.title
53
+ end
54
+ end
55
+
56
+ === Search for objects:
57
+
58
+ search = Sunspot.search Post, :conditions => { :average_rating => 3.0 } do
59
+ keywords 'great pizza'
60
+ with.author_name 'Mark Twain'
61
+ with.blog_id.any_of [2, 14]
62
+ with.category_ids.all_of [4, 10]
63
+ with.published_at.less_than Time.now
64
+
65
+ conditions.interpret :average_rating, :greater_than
66
+ conditions.default :average_rating, 4.0
67
+
68
+ paginate :page => 3, :per_page => 15
69
+ order_by :average_rating, :desc
70
+ end
71
+
72
+ === Get data and parameters from search:
73
+
74
+ search.results
75
+ search.total
76
+ search.page
77
+ search.per_page
78
+ search.keywords
79
+ search.conditions.average_rating
80
+ search.attributes[:conditions]
81
+
82
+ == REQUIREMENTS:
83
+
84
+ 1. extlib
85
+ 2. solr-ruby
86
+ 3. Java
87
+
88
+ == INSTALL:
89
+
90
+ * FIX (sudo gem install, anything else)
91
+
92
+ == LICENSE:
93
+
94
+ (The MIT License)
95
+
96
+ Copyright (c) 2008 Mat Brown
97
+
98
+ Permission is hereby granted, free of charge, to any person obtaining
99
+ a copy of this software and associated documentation files (the
100
+ 'Software'), to deal in the Software without restriction, including
101
+ without limitation the rights to use, copy, modify, merge, publish,
102
+ distribute, sublicense, and/or sell copies of the Software, and to
103
+ permit persons to whom the Software is furnished to do so, subject to
104
+ the following conditions:
105
+
106
+ The above copyright notice and this permission notice shall be
107
+ included in all copies or substantial portions of the Software.
108
+
109
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
110
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
111
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
112
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
113
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
114
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
115
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,27 @@
1
+ %w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
2
+ require File.dirname(__FILE__) + '/lib/sunspot'
3
+
4
+ ENV['RUBYOPT'] = '-W1'
5
+
6
+ # Generate all the Rake tasks
7
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
8
+ $hoe = Hoe.new('sunspot', Sunspot::VERSION) do |p|
9
+ p.developer('Mat Brown', 'mat@patch.com')
10
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
11
+ p.post_install_message = 'PostInstall.txt' # TODO remove if post-install message not required
12
+ p.rubyforge_name = p.name # TODO this is default value
13
+ # p.extra_deps = [
14
+ # ['activesupport','>= 2.0.2'],
15
+ # ]
16
+ p.extra_dev_deps = [
17
+ ['newgem', ">= #{::Newgem::VERSION}"]
18
+ ]
19
+
20
+ p.clean_globs |= %w[**/.DS_Store tmp *.log]
21
+ path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
22
+ p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
23
+ p.rsync_args = '-av --delete --ignore-errors'
24
+ end
25
+
26
+ require 'newgem/tasks' # load /tasks/*.rake
27
+ Dir['tasks/**/*.rake'].each { |t| load t }
data/config/hoe.rb ADDED
@@ -0,0 +1,74 @@
1
+ require 'sunspot/version'
2
+
3
+ AUTHOR = 'Mat Brown' # can also be an array of Authors
4
+ EMAIL = "mat@patch.com"
5
+ DESCRIPTION = "Awesome Solr interaction for Ruby"
6
+ GEM_NAME = 'sunspot' # what ppl will type to install your gem
7
+ RUBYFORGE_PROJECT = 'sunspot' # The unix name for your project
8
+ HOMEPATH = "http://github.com/outoftime/sunspot"
9
+ DOWNLOAD_PATH = "http://github.com/outoftime/sunspot"
10
+ EXTRA_DEPENDENCIES = [
11
+ ['solr-ruby', '= 0.0.6',
12
+ 'extlib', '>= 0.9.7']
13
+ ] # An array of rubygem dependencies [name, version]
14
+
15
+ @config_file = "~/.rubyforge/user-config.yml"
16
+ @config = nil
17
+ RUBYFORGE_USERNAME = "unknown"
18
+ def rubyforge_username
19
+ unless @config
20
+ begin
21
+ @config = YAML.load(File.read(File.expand_path(@config_file)))
22
+ rescue
23
+ puts <<-EOS
24
+ ERROR: No rubyforge config file found: #{@config_file}
25
+ Run 'rubyforge setup' to prepare your env for access to Rubyforge
26
+ - See http://newgem.rubyforge.org/rubyforge.html for more details
27
+ EOS
28
+ exit
29
+ end
30
+ end
31
+ RUBYFORGE_USERNAME.replace @config["username"]
32
+ end
33
+
34
+
35
+ REV = nil
36
+ # UNCOMMENT IF REQUIRED:
37
+ # REV = YAML.load(`svn info`)['Revision']
38
+ VERS = Sunspot::VERSION::STRING + (REV ? ".#{REV}" : "")
39
+ RDOC_OPTS = ['--quiet', '--title', 'sunspot documentation',
40
+ "--opname", "index.html",
41
+ "--line-numbers",
42
+ "--main", "README.rdoc",
43
+ "--inline-source"]
44
+
45
+ class Hoe
46
+ def extra_deps
47
+ @extra_deps.reject! { |x| Array(x).first == 'hoe' }
48
+ @extra_deps
49
+ end
50
+ end
51
+
52
+ # Generate all the Rake tasks
53
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
54
+ $hoe = Hoe.new(GEM_NAME, VERS) do |p|
55
+ p.developer(AUTHOR, EMAIL)
56
+ p.description = DESCRIPTION
57
+ p.summary = DESCRIPTION
58
+ p.url = HOMEPATH
59
+ p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
60
+ p.test_globs = ["spec/**/*_spec.rb"]
61
+ p.clean_globs |= ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store'] #An array of file patterns to delete on clean.
62
+
63
+ # == Optional
64
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
65
+ #p.extra_deps = EXTRA_DEPENDENCIES
66
+
67
+ #p.spec_extras = {} # A hash of extra values to set in the gemspec.
68
+ end
69
+
70
+ CHANGES = $hoe.paragraphs_of('History.txt', 0..1).join("\\n\\n")
71
+ PATH = (RUBYFORGE_PROJECT == GEM_NAME) ? RUBYFORGE_PROJECT : "#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
72
+ $hoe.remote_rdoc_dir = File.join(PATH.gsub(/^#{RUBYFORGE_PROJECT}\/?/,''), 'rdoc')
73
+ $hoe.rsync_args = '-av --delete --ignore-errors'
74
+ $hoe.spec.post_install_message = File.open(File.dirname(__FILE__) + "/../PostInstall.txt").read rescue ""
@@ -0,0 +1,15 @@
1
+ require 'fileutils'
2
+ include FileUtils
3
+
4
+ require 'rubygems'
5
+ %w[rake hoe newgem rubigen].each do |req_gem|
6
+ begin
7
+ require req_gem
8
+ rescue LoadError
9
+ puts "This Rakefile requires the '#{req_gem}' RubyGem."
10
+ puts "Installation: gem install #{req_gem} -y"
11
+ exit
12
+ end
13
+ end
14
+
15
+ $:.unshift(File.join(File.dirname(__FILE__), %w[.. lib]))
@@ -0,0 +1,40 @@
1
+ module LightConfig
2
+ class Configuration
3
+ def initialize(&block)
4
+ @properties = {}
5
+ ::LightConfig::Builder.new(self).instance_eval(&block)
6
+ singleton = (class <<self; self; end)
7
+ @properties.keys.each do |property|
8
+ singleton.module_eval do
9
+ define_method property do
10
+ @properties[property]
11
+ end
12
+
13
+ define_method "#{property}=" do |value|
14
+ @properties[property] = value
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ class Builder
22
+ def initialize(configuration)
23
+ @configuration = configuration
24
+ end
25
+
26
+ def method_missing(method, *args, &block)
27
+ raise ArgumentError("wrong number of arguments(#{args.length} for 1)") unless args.length < 2
28
+ value = if block then ::LightConfig::Configuration.new(&block)
29
+ else args.first
30
+ end
31
+ @configuration.instance_variable_get(:@properties)[method] = value
32
+ end
33
+ end
34
+ end
35
+
36
+ class <<LightConfig
37
+ def build(&block)
38
+ LightConfig::Configuration.new(&block)
39
+ end
40
+ end
@@ -0,0 +1,54 @@
1
+ module Sunspot
2
+ module Adapters
3
+ module InstanceAdapter
4
+ def initialize(instance)
5
+ @instance = instance
6
+ end
7
+
8
+ def index_id
9
+ "#{instance.class.name} #{id}"
10
+ end
11
+
12
+ protected
13
+ attr_accessor :instance
14
+ end
15
+
16
+ module ClassAdapter
17
+ def initialize(clazz)
18
+ @clazz = clazz
19
+ end
20
+
21
+ protected
22
+ attr_reader :clazz
23
+ end
24
+ end
25
+
26
+ class <<Adapters
27
+ def register(adapter, *classes)
28
+ for clazz in classes
29
+ adapters[clazz.name] = adapter
30
+ end
31
+ end
32
+
33
+ def adapt_class(clazz)
34
+ self.for(clazz).const_get('ClassAdapter').new(clazz)
35
+ end
36
+
37
+ def adapt_instance(instance)
38
+ self.for(instance.class).const_get('InstanceAdapter').new(instance)
39
+ end
40
+
41
+ def for(clazz)
42
+ while clazz != Object
43
+ return adapters[clazz.name] if adapters[clazz.name]
44
+ clazz = clazz.superclass
45
+ end
46
+ end
47
+
48
+ private
49
+
50
+ def adapters
51
+ @adapters ||= {}
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,50 @@
1
+ module Sunspot
2
+ class Conditions
3
+ def initialize(query, conditions_hash)
4
+ @query = query
5
+ @conditions_hash = conditions_hash.inject({}) do |hash, pair|
6
+ field_name, value = pair
7
+ hash[field_name.to_s] = value
8
+ hash
9
+ end
10
+ end
11
+
12
+ def interpret(field_name, condition_type)
13
+ operators_hash[field_name.to_s] = Sunspot::Restriction.const_get condition_type.to_s.camel_case
14
+ end
15
+
16
+ def default(field_name, value)
17
+ conditions_hash[field_name.to_s] ||= value
18
+ end
19
+
20
+ def restrictions
21
+ conditions_hash.map { |field_name, value| condition_for(field_name, value) }.compact
22
+ end
23
+
24
+ protected
25
+ attr_reader :conditions_hash
26
+
27
+ def condition_for(field_name, value)
28
+ operator = operator_for(field_name) || default_operator_for(value)
29
+ begin
30
+ @query.build_condition field_name, operator, value
31
+ rescue ArgumentError
32
+ nil # fail silently if field isn't configured
33
+ end
34
+ end
35
+
36
+ def default_operator_for(value)
37
+ if value.is_a?(Array) then Sunspot::Restriction::AnyOf
38
+ else Sunspot::Restriction::EqualTo
39
+ end
40
+ end
41
+
42
+ def operator_for(field_name)
43
+ operators_hash[field_name.to_s]
44
+ end
45
+
46
+ def operators_hash
47
+ @operators_hash ||= {}
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,37 @@
1
+ module Sunspot
2
+ class Conditions
3
+ def initialize(query, conditions_hash)
4
+ @query, @conditions_hash = query, conditions_hash
5
+ end
6
+
7
+ def interpret(field_name, condition_type)
8
+ operators_hash[field_name.to_s] = Sunspot::Restriction.const_get condition_type.to_s.camel_case
9
+ end
10
+
11
+ def conditions
12
+ conditions_hash.map { |field_name, value| condition_for(field_name, value) }
13
+ end
14
+
15
+ protected
16
+ attr_reader :conditions_hash
17
+
18
+ def condition_for(field_name, value)
19
+ operator = operator_for(field_name) || default_operator_for(value)
20
+ @query.build_condition field_name, operator, value
21
+ end
22
+
23
+ def default_operator_for(value)
24
+ if value.is_a?(Array) then Sunspot::Restriction::AnyOf
25
+ else Sunspot::Restriction::EqualTo
26
+ end
27
+ end
28
+
29
+ def operator_for(field_name)
30
+ operators_hash[field_name.to_s]
31
+ end
32
+
33
+ def operators_hash
34
+ @operators_hash ||= {}
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,17 @@
1
+ module Sunspot
2
+ module Configuration
3
+ end
4
+
5
+ class <<Configuration
6
+ def build
7
+ LightConfig.build do
8
+ solr do
9
+ url 'http://localhost:8983/solr'
10
+ end
11
+ pagination do
12
+ default_per_page 30
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,108 @@
1
+ module Sunspot
2
+ module Field
3
+ class Base
4
+ attr_accessor :name, :type
5
+
6
+ def initialize(name, type, options = {})
7
+ @name, @type = name, type
8
+ @multiple = options.delete(:multiple)
9
+ raise ArgumentError, "Unknown field option #{options.keys.first.inspect} provided for field #{name.inspect}" unless options.empty?
10
+ end
11
+
12
+ def pair_for(model)
13
+ if value = value_for(model)
14
+ { indexed_name.to_sym => to_indexed(value) }
15
+ else
16
+ {}
17
+ end
18
+ end
19
+
20
+ def ==(other)
21
+ other.respond_to?(:name) &&
22
+ other.respond_to?(:type) &&
23
+ self.name == other.name &&
24
+ self.type == other.type
25
+ end
26
+
27
+ def hash
28
+ name.hash + 31 * type.hash
29
+ end
30
+
31
+ def indexed_name
32
+ "#{type.indexed_name(name)}#{'m' if multiple?}"
33
+ end
34
+
35
+ def to_indexed(value)
36
+ if value.kind_of? Array
37
+ if multiple?
38
+ value.map { |val| to_indexed(val) }
39
+ else
40
+ raise ArgumentError, "#{name} is not a multiple-value field, so it cannot index values #{value.inspect}"
41
+ end
42
+ else
43
+ type.to_indexed(value)
44
+ end
45
+ end
46
+
47
+ def multiple?
48
+ !!@multiple
49
+ end
50
+ end
51
+
52
+ class AttributeField < ::Sunspot::Field::Base
53
+ protected
54
+
55
+ def value_for(model)
56
+ model.send(name)
57
+ end
58
+ end
59
+
60
+ class VirtualField < ::Sunspot::Field::Base
61
+ def initialize(name, type, options = {}, &block)
62
+ super(name, type, options)
63
+ @block = block
64
+ end
65
+
66
+ protected
67
+ attr_accessor :block
68
+
69
+ def value_for(model)
70
+ model.instance_eval(&block)
71
+ end
72
+ end
73
+ end
74
+
75
+ class <<Field
76
+ def register(clazz, fields)
77
+ fields = [fields] unless fields.kind_of? Enumerable
78
+ self.for(clazz).concat fields
79
+ end
80
+
81
+ def register_text(clazz, fields)
82
+ fields = [fields] unless fields.kind_of? Enumerable
83
+ self.text_for(clazz).concat fields
84
+ end
85
+
86
+ def text_for(clazz)
87
+ keyword_fields_hash[clazz.object_id] ||= []
88
+ end
89
+
90
+ def for(clazz)
91
+ fields_hash[clazz.object_id] ||= []
92
+ end
93
+
94
+ def unregister_all!
95
+ fields_hash.clear
96
+ end
97
+
98
+ private
99
+
100
+ def fields_hash
101
+ @fields_hash ||= {}
102
+ end
103
+
104
+ def keyword_fields_hash
105
+ @keyword_fields_hash ||= {}
106
+ end
107
+ end
108
+ end