searchlogic 1.5.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (125) hide show
  1. data/CHANGELOG.rdoc +228 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Manifest +123 -0
  4. data/README.rdoc +383 -0
  5. data/Rakefile +15 -0
  6. data/TODO.rdoc +6 -0
  7. data/examples/README.rdoc +4 -0
  8. data/init.rb +1 -0
  9. data/lib/searchlogic.rb +89 -0
  10. data/lib/searchlogic/active_record/associations.rb +52 -0
  11. data/lib/searchlogic/active_record/base.rb +218 -0
  12. data/lib/searchlogic/active_record/connection_adapters/mysql_adapter.rb +172 -0
  13. data/lib/searchlogic/active_record/connection_adapters/postgresql_adapter.rb +168 -0
  14. data/lib/searchlogic/active_record/connection_adapters/sqlite_adapter.rb +75 -0
  15. data/lib/searchlogic/condition/base.rb +159 -0
  16. data/lib/searchlogic/condition/begins_with.rb +17 -0
  17. data/lib/searchlogic/condition/blank.rb +21 -0
  18. data/lib/searchlogic/condition/child_of.rb +11 -0
  19. data/lib/searchlogic/condition/descendant_of.rb +24 -0
  20. data/lib/searchlogic/condition/ends_with.rb +17 -0
  21. data/lib/searchlogic/condition/equals.rb +27 -0
  22. data/lib/searchlogic/condition/greater_than.rb +15 -0
  23. data/lib/searchlogic/condition/greater_than_or_equal_to.rb +15 -0
  24. data/lib/searchlogic/condition/inclusive_descendant_of.rb +11 -0
  25. data/lib/searchlogic/condition/keywords.rb +47 -0
  26. data/lib/searchlogic/condition/less_than.rb +15 -0
  27. data/lib/searchlogic/condition/less_than_or_equal_to.rb +15 -0
  28. data/lib/searchlogic/condition/like.rb +15 -0
  29. data/lib/searchlogic/condition/nil.rb +21 -0
  30. data/lib/searchlogic/condition/not_begin_with.rb +20 -0
  31. data/lib/searchlogic/condition/not_blank.rb +19 -0
  32. data/lib/searchlogic/condition/not_end_with.rb +20 -0
  33. data/lib/searchlogic/condition/not_equal.rb +26 -0
  34. data/lib/searchlogic/condition/not_have_keywords.rb +20 -0
  35. data/lib/searchlogic/condition/not_like.rb +20 -0
  36. data/lib/searchlogic/condition/not_nil.rb +19 -0
  37. data/lib/searchlogic/condition/sibling_of.rb +14 -0
  38. data/lib/searchlogic/condition/tree.rb +17 -0
  39. data/lib/searchlogic/conditions/base.rb +484 -0
  40. data/lib/searchlogic/conditions/protection.rb +36 -0
  41. data/lib/searchlogic/config.rb +31 -0
  42. data/lib/searchlogic/config/helpers.rb +289 -0
  43. data/lib/searchlogic/config/search.rb +53 -0
  44. data/lib/searchlogic/core_ext/hash.rb +75 -0
  45. data/lib/searchlogic/helpers/control_types/link.rb +310 -0
  46. data/lib/searchlogic/helpers/control_types/links.rb +241 -0
  47. data/lib/searchlogic/helpers/control_types/remote_link.rb +87 -0
  48. data/lib/searchlogic/helpers/control_types/remote_links.rb +72 -0
  49. data/lib/searchlogic/helpers/control_types/remote_select.rb +36 -0
  50. data/lib/searchlogic/helpers/control_types/select.rb +82 -0
  51. data/lib/searchlogic/helpers/form.rb +208 -0
  52. data/lib/searchlogic/helpers/utilities.rb +197 -0
  53. data/lib/searchlogic/modifiers/absolute.rb +15 -0
  54. data/lib/searchlogic/modifiers/acos.rb +11 -0
  55. data/lib/searchlogic/modifiers/asin.rb +11 -0
  56. data/lib/searchlogic/modifiers/atan.rb +11 -0
  57. data/lib/searchlogic/modifiers/base.rb +27 -0
  58. data/lib/searchlogic/modifiers/ceil.rb +15 -0
  59. data/lib/searchlogic/modifiers/char_length.rb +15 -0
  60. data/lib/searchlogic/modifiers/cos.rb +15 -0
  61. data/lib/searchlogic/modifiers/cot.rb +15 -0
  62. data/lib/searchlogic/modifiers/day_of_month.rb +15 -0
  63. data/lib/searchlogic/modifiers/day_of_week.rb +15 -0
  64. data/lib/searchlogic/modifiers/day_of_year.rb +15 -0
  65. data/lib/searchlogic/modifiers/degrees.rb +11 -0
  66. data/lib/searchlogic/modifiers/exp.rb +15 -0
  67. data/lib/searchlogic/modifiers/floor.rb +15 -0
  68. data/lib/searchlogic/modifiers/hex.rb +11 -0
  69. data/lib/searchlogic/modifiers/hour.rb +11 -0
  70. data/lib/searchlogic/modifiers/log.rb +15 -0
  71. data/lib/searchlogic/modifiers/log10.rb +11 -0
  72. data/lib/searchlogic/modifiers/log2.rb +11 -0
  73. data/lib/searchlogic/modifiers/lower.rb +15 -0
  74. data/lib/searchlogic/modifiers/ltrim.rb +15 -0
  75. data/lib/searchlogic/modifiers/md5.rb +11 -0
  76. data/lib/searchlogic/modifiers/microseconds.rb +11 -0
  77. data/lib/searchlogic/modifiers/milliseconds.rb +11 -0
  78. data/lib/searchlogic/modifiers/minute.rb +15 -0
  79. data/lib/searchlogic/modifiers/month.rb +15 -0
  80. data/lib/searchlogic/modifiers/octal.rb +15 -0
  81. data/lib/searchlogic/modifiers/radians.rb +11 -0
  82. data/lib/searchlogic/modifiers/round.rb +11 -0
  83. data/lib/searchlogic/modifiers/rtrim.rb +15 -0
  84. data/lib/searchlogic/modifiers/second.rb +15 -0
  85. data/lib/searchlogic/modifiers/sign.rb +11 -0
  86. data/lib/searchlogic/modifiers/sin.rb +11 -0
  87. data/lib/searchlogic/modifiers/square_root.rb +15 -0
  88. data/lib/searchlogic/modifiers/tan.rb +15 -0
  89. data/lib/searchlogic/modifiers/trim.rb +15 -0
  90. data/lib/searchlogic/modifiers/upper.rb +15 -0
  91. data/lib/searchlogic/modifiers/week.rb +11 -0
  92. data/lib/searchlogic/modifiers/year.rb +11 -0
  93. data/lib/searchlogic/search/base.rb +148 -0
  94. data/lib/searchlogic/search/conditions.rb +53 -0
  95. data/lib/searchlogic/search/ordering.rb +244 -0
  96. data/lib/searchlogic/search/pagination.rb +121 -0
  97. data/lib/searchlogic/search/protection.rb +89 -0
  98. data/lib/searchlogic/search/searching.rb +31 -0
  99. data/lib/searchlogic/shared/utilities.rb +50 -0
  100. data/lib/searchlogic/shared/virtual_classes.rb +39 -0
  101. data/lib/searchlogic/version.rb +79 -0
  102. data/searchlogic.gemspec +39 -0
  103. data/test/fixtures/accounts.yml +15 -0
  104. data/test/fixtures/cats.yml +3 -0
  105. data/test/fixtures/dogs.yml +3 -0
  106. data/test/fixtures/orders.yml +14 -0
  107. data/test/fixtures/user_groups.yml +13 -0
  108. data/test/fixtures/users.yml +36 -0
  109. data/test/test_active_record_associations.rb +81 -0
  110. data/test/test_active_record_base.rb +93 -0
  111. data/test/test_condition_base.rb +52 -0
  112. data/test/test_condition_types.rb +143 -0
  113. data/test/test_conditions_base.rb +242 -0
  114. data/test/test_conditions_protection.rb +16 -0
  115. data/test/test_config.rb +23 -0
  116. data/test/test_helper.rb +134 -0
  117. data/test/test_search_base.rb +227 -0
  118. data/test/test_search_conditions.rb +19 -0
  119. data/test/test_search_ordering.rb +165 -0
  120. data/test/test_search_pagination.rb +72 -0
  121. data/test/test_search_protection.rb +24 -0
  122. data/test_libs/acts_as_tree.rb +98 -0
  123. data/test_libs/ordered_hash.rb +9 -0
  124. data/test_libs/rexml_fix.rb +14 -0
  125. metadata +317 -0
@@ -0,0 +1,31 @@
1
+ module Searchlogic
2
+ module Search
3
+ # = Searchlogic Searching
4
+ #
5
+ # Implements searching functionality for searchlogic. Searchlogic::Search::Base and Searchlogic::Conditions::Base can both search and include
6
+ # this module.
7
+ module Searching
8
+ # Use these methods just like you would in ActiveRecord
9
+ SEARCH_METHODS = [:all, :find, :first]
10
+ CALCULATION_METHODS = [:average, :calculate, :count, :maximum, :minimum, :sum]
11
+
12
+ (SEARCH_METHODS + CALCULATION_METHODS).each do |method|
13
+ class_eval <<-"end_eval", __FILE__, __LINE__
14
+ def #{method}(*args)
15
+ find_options = {}
16
+ options = args.extract_options! # can't pass options, your options are in the search
17
+ klass.send(:with_scope, :find => acting_as_filter? ? {} : scope) do
18
+ options = sanitize(#{SEARCH_METHODS.include?(method)})
19
+ if #{CALCULATION_METHODS.include?(method)}
20
+ options[:distinct] = true if #{method == :count} && !joins.blank? && Config.search.remove_duplicates?
21
+ args[0] = klass.primary_key if [nil, :all].include?(args[0])
22
+ end
23
+ args << options
24
+ klass.#{method}(*args)
25
+ end
26
+ end
27
+ end_eval
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,50 @@
1
+ module Searchlogic
2
+ module Shared
3
+ module Utilities # :nodoc:
4
+ private
5
+ def merge_conditions(*conditions)
6
+ options = conditions.extract_options!
7
+ conditions.delete_if { |condition| condition.blank? }
8
+ return if conditions.blank?
9
+ return conditions.first if conditions.size == 1
10
+
11
+ conditions_strs = []
12
+ conditions_subs = []
13
+
14
+ conditions.each do |condition|
15
+ next if condition.blank?
16
+ arr_condition = condition.is_a?(Array) ? condition : [condition]
17
+ conditions_strs << arr_condition.first
18
+ conditions_subs += arr_condition[1..-1]
19
+ end
20
+
21
+ return if conditions_strs.blank?
22
+
23
+ join = options[:any] ? "OR" : "AND"
24
+ conditions_str = "(#{conditions_strs.join(") #{join} (")})"
25
+
26
+ return conditions_str if conditions_subs.blank?
27
+
28
+ [conditions_str, *conditions_subs]
29
+ end
30
+
31
+ def merge_joins(*joins)
32
+ joins.delete_if { |join| join.blank? }
33
+ return if joins.blank?
34
+ return joins.first if joins.size == 1
35
+
36
+ new_joins = []
37
+ joins.each do |join|
38
+ case join
39
+ when Array
40
+ new_joins += join
41
+ else
42
+ new_joins << join
43
+ end
44
+ end
45
+
46
+ new_joins.compact.uniq
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,39 @@
1
+ module Searchlogic
2
+ module Shared
3
+ # = Searchlogic Virtual Classes
4
+ #
5
+ # Creates virtual classes for each model, to implementing a type of caching. So that object instantiation for searchlogic searches is cached. This is lazy, meaning
6
+ # it will only cache when it needs. So the first instantion will be much slow than the following ones. This is cached in the RAM, so if the process is restarted the caching is cleared.
7
+ module VirtualClasses
8
+ def self.included(klass)
9
+ klass.extend ClassMethods
10
+ end
11
+
12
+ module ClassMethods
13
+ # Creates virtual classes for the class passed to it. This is a neccesity for keeping dynamically created method
14
+ # names specific to models. It provides caching and helps a lot with performance.
15
+ def create_virtual_class(model_class)
16
+ class_search_name = "::Searchlogic::Cache::#{model_class.name}" + name.split(/::/)[1]
17
+
18
+ begin
19
+ eval(class_search_name)
20
+ rescue NameError
21
+ eval <<-end_eval
22
+ class #{class_search_name} < ::#{name}
23
+ def self.klass
24
+ #{model_class.name}
25
+ end
26
+
27
+ def klass
28
+ #{model_class.name}
29
+ end
30
+ end
31
+
32
+ #{class_search_name}
33
+ end_eval
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,79 @@
1
+ # (The MIT License)
2
+ #
3
+ # Copyright (c) 2008 Jamis Buck <jamis@37signals.com>,
4
+ # with modifications by Bruce Williams <bruce@fiveruns.com>
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining
7
+ # a copy of this software and associated documentation files (the
8
+ # 'Software'), to deal in the Software without restriction, including
9
+ # without limitation the rights to use, copy, modify, merge, publish,
10
+ # distribute, sublicense, and/or sell copies of the Software, and to
11
+ # permit persons to whom the Software is furnished to do so, subject to
12
+ # the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be
15
+ # included in all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
18
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
+ module Searchlogic
25
+ # = Version
26
+ #
27
+ # A class for describing the current version of a library. The version
28
+ # consists of three parts: the +major+ number, the +minor+ number, and the
29
+ # +tiny+ (or +patch+) number.
30
+ class Version
31
+
32
+ include Comparable
33
+
34
+ # A convenience method for instantiating a new Version instance with the
35
+ # given +major+, +minor+, and +tiny+ components.
36
+ def self.[](major, minor, tiny)
37
+ new(major, minor, tiny)
38
+ end
39
+
40
+ attr_reader :major, :minor, :tiny
41
+
42
+ # Create a new Version object with the given components.
43
+ def initialize(major, minor, tiny)
44
+ @major, @minor, @tiny = major, minor, tiny
45
+ end
46
+
47
+ # Compare this version to the given +version+ object.
48
+ def <=>(version)
49
+ to_i <=> version.to_i
50
+ end
51
+
52
+ # Converts this version object to a string, where each of the three
53
+ # version components are joined by the '.' character. E.g., 2.0.0.
54
+ def to_s
55
+ @to_s ||= [@major, @minor, @tiny].join(".")
56
+ end
57
+
58
+ # Converts this version to a canonical integer that may be compared
59
+ # against other version objects.
60
+ def to_i
61
+ @to_i ||= @major * 1_000_000 + @minor * 1_000 + @tiny
62
+ end
63
+
64
+ def to_a
65
+ [@major, @minor, @tiny]
66
+ end
67
+
68
+ MAJOR = 1
69
+ MINOR = 5
70
+ TINY = 3
71
+
72
+ # The current version as a Version instance
73
+ CURRENT = new(MAJOR, MINOR, TINY)
74
+ # The current version as a String
75
+ STRING = CURRENT.to_s
76
+
77
+ end
78
+
79
+ end
@@ -0,0 +1,39 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = %q{searchlogic}
3
+ s.version = "1.5.3"
4
+
5
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
6
+ s.authors = ["Ben Johnson of Binary Logic"]
7
+ s.date = %q{2008-11-03}
8
+ s.description = %q{Object based ActiveRecord searching, ordering, pagination, and more!}
9
+ s.email = %q{bjohnson@binarylogic.com}
10
+ s.extra_rdoc_files = ["CHANGELOG.rdoc", "lib/searchlogic/active_record/associations.rb", "lib/searchlogic/active_record/base.rb", "lib/searchlogic/active_record/connection_adapters/mysql_adapter.rb", "lib/searchlogic/active_record/connection_adapters/postgresql_adapter.rb", "lib/searchlogic/active_record/connection_adapters/sqlite_adapter.rb", "lib/searchlogic/condition/base.rb", "lib/searchlogic/condition/begins_with.rb", "lib/searchlogic/condition/blank.rb", "lib/searchlogic/condition/child_of.rb", "lib/searchlogic/condition/descendant_of.rb", "lib/searchlogic/condition/ends_with.rb", "lib/searchlogic/condition/equals.rb", "lib/searchlogic/condition/greater_than.rb", "lib/searchlogic/condition/greater_than_or_equal_to.rb", "lib/searchlogic/condition/inclusive_descendant_of.rb", "lib/searchlogic/condition/keywords.rb", "lib/searchlogic/condition/less_than.rb", "lib/searchlogic/condition/less_than_or_equal_to.rb", "lib/searchlogic/condition/like.rb", "lib/searchlogic/condition/nil.rb", "lib/searchlogic/condition/not_begin_with.rb", "lib/searchlogic/condition/not_blank.rb", "lib/searchlogic/condition/not_end_with.rb", "lib/searchlogic/condition/not_equal.rb", "lib/searchlogic/condition/not_have_keywords.rb", "lib/searchlogic/condition/not_like.rb", "lib/searchlogic/condition/not_nil.rb", "lib/searchlogic/condition/sibling_of.rb", "lib/searchlogic/condition/tree.rb", "lib/searchlogic/conditions/base.rb", "lib/searchlogic/conditions/protection.rb", "lib/searchlogic/config/helpers.rb", "lib/searchlogic/config/search.rb", "lib/searchlogic/config.rb", "lib/searchlogic/core_ext/hash.rb", "lib/searchlogic/helpers/control_types/link.rb", "lib/searchlogic/helpers/control_types/links.rb", "lib/searchlogic/helpers/control_types/remote_link.rb", "lib/searchlogic/helpers/control_types/remote_links.rb", "lib/searchlogic/helpers/control_types/remote_select.rb", "lib/searchlogic/helpers/control_types/select.rb", "lib/searchlogic/helpers/form.rb", "lib/searchlogic/helpers/utilities.rb", "lib/searchlogic/modifiers/absolute.rb", "lib/searchlogic/modifiers/acos.rb", "lib/searchlogic/modifiers/asin.rb", "lib/searchlogic/modifiers/atan.rb", "lib/searchlogic/modifiers/base.rb", "lib/searchlogic/modifiers/ceil.rb", "lib/searchlogic/modifiers/char_length.rb", "lib/searchlogic/modifiers/cos.rb", "lib/searchlogic/modifiers/cot.rb", "lib/searchlogic/modifiers/day_of_month.rb", "lib/searchlogic/modifiers/day_of_week.rb", "lib/searchlogic/modifiers/day_of_year.rb", "lib/searchlogic/modifiers/degrees.rb", "lib/searchlogic/modifiers/exp.rb", "lib/searchlogic/modifiers/floor.rb", "lib/searchlogic/modifiers/hex.rb", "lib/searchlogic/modifiers/hour.rb", "lib/searchlogic/modifiers/log.rb", "lib/searchlogic/modifiers/log10.rb", "lib/searchlogic/modifiers/log2.rb", "lib/searchlogic/modifiers/lower.rb", "lib/searchlogic/modifiers/ltrim.rb", "lib/searchlogic/modifiers/md5.rb", "lib/searchlogic/modifiers/microseconds.rb", "lib/searchlogic/modifiers/milliseconds.rb", "lib/searchlogic/modifiers/minute.rb", "lib/searchlogic/modifiers/month.rb", "lib/searchlogic/modifiers/octal.rb", "lib/searchlogic/modifiers/radians.rb", "lib/searchlogic/modifiers/round.rb", "lib/searchlogic/modifiers/rtrim.rb", "lib/searchlogic/modifiers/second.rb", "lib/searchlogic/modifiers/sign.rb", "lib/searchlogic/modifiers/sin.rb", "lib/searchlogic/modifiers/square_root.rb", "lib/searchlogic/modifiers/tan.rb", "lib/searchlogic/modifiers/trim.rb", "lib/searchlogic/modifiers/upper.rb", "lib/searchlogic/modifiers/week.rb", "lib/searchlogic/modifiers/year.rb", "lib/searchlogic/search/base.rb", "lib/searchlogic/search/conditions.rb", "lib/searchlogic/search/ordering.rb", "lib/searchlogic/search/pagination.rb", "lib/searchlogic/search/protection.rb", "lib/searchlogic/search/searching.rb", "lib/searchlogic/shared/utilities.rb", "lib/searchlogic/shared/virtual_classes.rb", "lib/searchlogic/version.rb", "lib/searchlogic.rb", "README.rdoc", "TODO.rdoc"]
11
+ s.files = ["CHANGELOG.rdoc", "examples/README.rdoc", "init.rb", "lib/searchlogic/active_record/associations.rb", "lib/searchlogic/active_record/base.rb", "lib/searchlogic/active_record/connection_adapters/mysql_adapter.rb", "lib/searchlogic/active_record/connection_adapters/postgresql_adapter.rb", "lib/searchlogic/active_record/connection_adapters/sqlite_adapter.rb", "lib/searchlogic/condition/base.rb", "lib/searchlogic/condition/begins_with.rb", "lib/searchlogic/condition/blank.rb", "lib/searchlogic/condition/child_of.rb", "lib/searchlogic/condition/descendant_of.rb", "lib/searchlogic/condition/ends_with.rb", "lib/searchlogic/condition/equals.rb", "lib/searchlogic/condition/greater_than.rb", "lib/searchlogic/condition/greater_than_or_equal_to.rb", "lib/searchlogic/condition/inclusive_descendant_of.rb", "lib/searchlogic/condition/keywords.rb", "lib/searchlogic/condition/less_than.rb", "lib/searchlogic/condition/less_than_or_equal_to.rb", "lib/searchlogic/condition/like.rb", "lib/searchlogic/condition/nil.rb", "lib/searchlogic/condition/not_begin_with.rb", "lib/searchlogic/condition/not_blank.rb", "lib/searchlogic/condition/not_end_with.rb", "lib/searchlogic/condition/not_equal.rb", "lib/searchlogic/condition/not_have_keywords.rb", "lib/searchlogic/condition/not_like.rb", "lib/searchlogic/condition/not_nil.rb", "lib/searchlogic/condition/sibling_of.rb", "lib/searchlogic/condition/tree.rb", "lib/searchlogic/conditions/base.rb", "lib/searchlogic/conditions/protection.rb", "lib/searchlogic/config/helpers.rb", "lib/searchlogic/config/search.rb", "lib/searchlogic/config.rb", "lib/searchlogic/core_ext/hash.rb", "lib/searchlogic/helpers/control_types/link.rb", "lib/searchlogic/helpers/control_types/links.rb", "lib/searchlogic/helpers/control_types/remote_link.rb", "lib/searchlogic/helpers/control_types/remote_links.rb", "lib/searchlogic/helpers/control_types/remote_select.rb", "lib/searchlogic/helpers/control_types/select.rb", "lib/searchlogic/helpers/form.rb", "lib/searchlogic/helpers/utilities.rb", "lib/searchlogic/modifiers/absolute.rb", "lib/searchlogic/modifiers/acos.rb", "lib/searchlogic/modifiers/asin.rb", "lib/searchlogic/modifiers/atan.rb", "lib/searchlogic/modifiers/base.rb", "lib/searchlogic/modifiers/ceil.rb", "lib/searchlogic/modifiers/char_length.rb", "lib/searchlogic/modifiers/cos.rb", "lib/searchlogic/modifiers/cot.rb", "lib/searchlogic/modifiers/day_of_month.rb", "lib/searchlogic/modifiers/day_of_week.rb", "lib/searchlogic/modifiers/day_of_year.rb", "lib/searchlogic/modifiers/degrees.rb", "lib/searchlogic/modifiers/exp.rb", "lib/searchlogic/modifiers/floor.rb", "lib/searchlogic/modifiers/hex.rb", "lib/searchlogic/modifiers/hour.rb", "lib/searchlogic/modifiers/log.rb", "lib/searchlogic/modifiers/log10.rb", "lib/searchlogic/modifiers/log2.rb", "lib/searchlogic/modifiers/lower.rb", "lib/searchlogic/modifiers/ltrim.rb", "lib/searchlogic/modifiers/md5.rb", "lib/searchlogic/modifiers/microseconds.rb", "lib/searchlogic/modifiers/milliseconds.rb", "lib/searchlogic/modifiers/minute.rb", "lib/searchlogic/modifiers/month.rb", "lib/searchlogic/modifiers/octal.rb", "lib/searchlogic/modifiers/radians.rb", "lib/searchlogic/modifiers/round.rb", "lib/searchlogic/modifiers/rtrim.rb", "lib/searchlogic/modifiers/second.rb", "lib/searchlogic/modifiers/sign.rb", "lib/searchlogic/modifiers/sin.rb", "lib/searchlogic/modifiers/square_root.rb", "lib/searchlogic/modifiers/tan.rb", "lib/searchlogic/modifiers/trim.rb", "lib/searchlogic/modifiers/upper.rb", "lib/searchlogic/modifiers/week.rb", "lib/searchlogic/modifiers/year.rb", "lib/searchlogic/search/base.rb", "lib/searchlogic/search/conditions.rb", "lib/searchlogic/search/ordering.rb", "lib/searchlogic/search/pagination.rb", "lib/searchlogic/search/protection.rb", "lib/searchlogic/search/searching.rb", "lib/searchlogic/shared/utilities.rb", "lib/searchlogic/shared/virtual_classes.rb", "lib/searchlogic/version.rb", "lib/searchlogic.rb", "Manifest", "MIT-LICENSE", "Rakefile", "README.rdoc", "test/fixtures/accounts.yml", "test/fixtures/cats.yml", "test/fixtures/dogs.yml", "test/fixtures/orders.yml", "test/fixtures/user_groups.yml", "test/fixtures/users.yml", "test/test_active_record_associations.rb", "test/test_active_record_base.rb", "test/test_condition_base.rb", "test/test_condition_types.rb", "test/test_conditions_base.rb", "test/test_conditions_protection.rb", "test/test_config.rb", "test/test_helper.rb", "test/test_search_base.rb", "test/test_search_conditions.rb", "test/test_search_ordering.rb", "test/test_search_pagination.rb", "test/test_search_protection.rb", "test_libs/acts_as_tree.rb", "test_libs/ordered_hash.rb", "test_libs/rexml_fix.rb", "TODO.rdoc", "searchlogic.gemspec"]
12
+ s.has_rdoc = true
13
+ s.homepage = %q{http://github.com/binarylogic/searchlogic}
14
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Searchlogic", "--main", "README.rdoc"]
15
+ s.require_paths = ["lib"]
16
+ s.rubyforge_project = %q{searchlogic}
17
+ s.rubygems_version = %q{1.2.0}
18
+ s.summary = %q{Object based ActiveRecord searching, ordering, pagination, and more!}
19
+ s.test_files = ["test/test_active_record_associations.rb", "test/test_active_record_base.rb", "test/test_condition_base.rb", "test/test_condition_types.rb", "test/test_conditions_base.rb", "test/test_conditions_protection.rb", "test/test_config.rb", "test/test_helper.rb", "test/test_search_base.rb", "test/test_search_conditions.rb", "test/test_search_ordering.rb", "test/test_search_pagination.rb", "test/test_search_protection.rb"]
20
+
21
+ if s.respond_to? :specification_version then
22
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
23
+ s.specification_version = 2
24
+
25
+ if current_version >= 3 then
26
+ s.add_runtime_dependency(%q<activerecord>, [">= 0"])
27
+ s.add_runtime_dependency(%q<activesupport>, [">= 0"])
28
+ s.add_development_dependency(%q<echoe>, [">= 0"])
29
+ else
30
+ s.add_dependency(%q<activerecord>, [">= 0"])
31
+ s.add_dependency(%q<activesupport>, [">= 0"])
32
+ s.add_dependency(%q<echoe>, [">= 0"])
33
+ end
34
+ else
35
+ s.add_dependency(%q<activerecord>, [">= 0"])
36
+ s.add_dependency(%q<activesupport>, [">= 0"])
37
+ s.add_dependency(%q<echoe>, [">= 0"])
38
+ end
39
+ end
@@ -0,0 +1,15 @@
1
+ binary_logic:
2
+ id: 1
3
+ name: "Binary Logic"
4
+ active: true
5
+
6
+ neco:
7
+ id: 2
8
+ name: "NECO"
9
+ active: false
10
+
11
+ binary_fun:
12
+ id: 3
13
+ name: "Binary Fun"
14
+ active: true
15
+
@@ -0,0 +1,3 @@
1
+ pepper:
2
+ id: 1
3
+ description: pepper meows
@@ -0,0 +1,3 @@
1
+ harry:
2
+ id: 2
3
+ description: harry is hairy
@@ -0,0 +1,14 @@
1
+ bens_order:
2
+ id: 1
3
+ user_id: 1
4
+ total: 500.23
5
+ description: A bunch of apple products, etc.
6
+ receipt: some binary text
7
+
8
+ drews_order:
9
+ id: 2
10
+ user_id: 2
11
+ total: 2.12
12
+ description: Some more apple projects, ipod, etc
13
+ receipt: some more binary text
14
+
@@ -0,0 +1,13 @@
1
+ neco:
2
+ id: 1
3
+ name: NECO
4
+ user_ids:
5
+ - 1
6
+ - 2
7
+
8
+ johnsons:
9
+ id: 2
10
+ name: Johnsons
11
+ user_ids:
12
+ - 1
13
+ - 3
@@ -0,0 +1,36 @@
1
+ ben:
2
+ id: 1
3
+ account_id: 1
4
+ parent_id: null
5
+ first_name: Ben
6
+ last_name: Johnson
7
+ active: true
8
+ bio: Totally awesome!
9
+
10
+ drew:
11
+ id: 2
12
+ account_id: 2
13
+ parent_id: 1
14
+ first_name: Drew
15
+ last_name: Mills
16
+ active: false
17
+ bio: Totally not awesome!
18
+
19
+ jennifer:
20
+ id: 3
21
+ account_id: 1
22
+ parent_id: 2
23
+ first_name: Jennifer
24
+ last_name: Hopkins
25
+ active: false
26
+ bio: Totally not awesome at all!
27
+
28
+ tren:
29
+ id: 4
30
+ account_id:
31
+ parent_id:
32
+ first_name: Tren
33
+ last_name: Garfield
34
+ active: false
35
+ bio: Rocks a little too hard
36
+
@@ -0,0 +1,81 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class TestActiveRecordAssociations < Test::Unit::TestCase
4
+ def test_has_many
5
+ search = Account.find(1).users.new_search
6
+ assert_kind_of Searchlogic::Search::Base, search
7
+ assert_equal User, search.klass
8
+ assert_equal({:conditions => "\"users\".account_id = 1"}, search.scope)
9
+
10
+ assert_equal User.find(1, 3), search.all
11
+ assert_equal User.find(1), search.first
12
+ assert_equal 2, search.average("id")
13
+ assert_equal 2, search.count
14
+
15
+ search.conditions.first_name_contains = "Ben"
16
+
17
+ assert_equal [User.find(1)], search.all
18
+ assert_equal User.find(1), search.first
19
+ assert_equal 1, search.average("id")
20
+ assert_equal 1, search.count
21
+
22
+ assert_equal 2, Account.find(1).users.count
23
+ assert_equal 1, Account.find(1).users.all(:conditions => {:first_name_contains => "Ben"}).size
24
+ assert_equal 0, Account.find(1).users.all(:conditions => {:first_name_contains => "No one"}).size
25
+ assert_equal 1, Account.find(1).users.sum("id", :conditions => {:first_name_contains => "Ben"})
26
+ assert_equal 0, Account.find(1).users.sum("id", :conditions => {:first_name_contains => "No one"})
27
+ assert_equal 1, Account.find(1).users.average("id", :conditions => {:first_name_contains => "Ben"})
28
+ end
29
+
30
+ def test_has_many_through
31
+ search = Account.find(1).orders.new_search
32
+ assert_kind_of Searchlogic::Search::Base, search
33
+ assert_equal Order, search.klass
34
+ assert_equal({:joins => "INNER JOIN users ON orders.user_id = users.id ", :conditions => "(\"users\".account_id = 1)"}, search.scope)
35
+
36
+ assert_equal [Order.find(1)], search.all
37
+ assert_equal Order.find(1), search.first
38
+ assert_equal 1, search.average("id")
39
+ assert_equal 1, search.count
40
+
41
+ search.conditions.total_gt = 100
42
+
43
+ assert_equal [Order.find(1)], search.all
44
+ assert_equal Order.find(1), search.first
45
+ assert_equal 1, search.average("id")
46
+ assert_equal 1, search.count
47
+
48
+ assert_equal 1, Account.find(1).orders.count
49
+ assert_equal 1, Account.find(1).orders.all(:conditions => {:total_gt => 100}).size
50
+ assert_equal 0, Account.find(1).orders.all(:conditions => {:total_gt => 1000}).size
51
+ assert_equal 1, Account.find(1).orders.sum("id", :conditions => {:total_gt => 100})
52
+ assert_equal 0, Account.find(1).orders.sum("id", :conditions => {:total_gt => 1000})
53
+ assert_equal 1, Account.find(1).orders.average("id", :conditions => {:total_gt => 100})
54
+ end
55
+
56
+ def test_habtm
57
+ search = UserGroup.find(1).users.new_search
58
+ assert_kind_of Searchlogic::Search::Base, search
59
+ assert_equal User, search.klass
60
+ assert_equal({:conditions => "\"user_groups_users\".user_group_id = 1 ", :joins => "INNER JOIN \"user_groups_users\" ON \"users\".id = \"user_groups_users\".user_id"}, search.scope)
61
+
62
+ assert_equal User.find(1, 2), search.all
63
+ assert_equal User.find(1), search.first
64
+ assert_equal (1.5).to_s, search.average("id").to_s
65
+ assert_equal 2, search.count
66
+
67
+ search.conditions.first_name_contains = "Ben"
68
+
69
+ assert_equal [User.find(1)], search.all
70
+ assert_equal User.find(1), search.first
71
+ assert_equal 1, search.average("id")
72
+ assert_equal 1, search.count
73
+
74
+ assert_equal 2, UserGroup.find(1).users.count
75
+ assert_equal 1, UserGroup.find(1).users.all(:conditions => {:first_name_contains => "Ben"}).size
76
+ assert_equal 0, UserGroup.find(1).users.all(:conditions => {:first_name_contains => "No one"}).size
77
+ assert_equal 1, UserGroup.find(1).users.sum("id", :conditions => {:first_name_contains => "Ben"})
78
+ assert_equal 0, UserGroup.find(1).users.sum("id", :conditions => {:first_name_contains => "No one"})
79
+ assert_equal 1, UserGroup.find(1).users.average("id", :conditions => {:first_name_contains => "Ben"})
80
+ end
81
+ end
@@ -0,0 +1,93 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class TestActiveRecordBase < Test::Unit::TestCase
4
+ def test_standard_find
5
+ assert_equal [1,2,3], Account.all.map(&:id)
6
+ assert_equal 1, Account.first.id
7
+ assert_equal [1,2,3], Account.find(:all).map(&:id)
8
+ assert_equal [1], Account.find(:all, :conditions => {:name => "Binary Logic"}).map(&:id)
9
+ assert_equal [1], Account.find(:all, :conditions => ["name = ?", "Binary Logic"]).map(&:id)
10
+ assert_equal [1], Account.find(:all, :conditions => "name = 'Binary Logic'").map(&:id)
11
+ assert_equal 1, Account.find(:first).id
12
+ assert_equal [1,2,3], Account.find(:all, nil).map(&:id)
13
+ assert_equal [1,2,3], Account.find(:all, {}).map(&:id)
14
+ assert_equal [1,2,3], Account.find(:all, :select => "id, name").map(&:id)
15
+ end
16
+
17
+ def test_standard_calculations
18
+ assert_equal 3, Account.count({})
19
+ assert_equal 3, Account.count(nil)
20
+ assert_equal 3, Account.count(:limit => 1)
21
+ assert_equal 0, Account.count(:limit => 10, :offset => 10)
22
+ assert_equal 6, Account.sum("id")
23
+ assert_equal 6, Account.sum("id", {})
24
+ assert_equal 2, Account.average("id")
25
+ assert_equal 3, Account.maximum("id")
26
+ assert_equal 1, Account.minimum("id")
27
+ end
28
+
29
+ def test_valid_ar_options
30
+ assert_equal [ :conditions, :include, :joins, :limit, :offset, :order, :select, :readonly, :group, :from, :lock ], ActiveRecord::Base.valid_find_options
31
+ assert_equal [:conditions, :joins, :order, :select, :group, :having, :distinct, :limit, :offset, :include, :from], ActiveRecord::Base.valid_calculations_options
32
+ end
33
+
34
+ def test_build_search
35
+ search = Account.new_search(:conditions => {:name_keywords => "awesome"}, :page => 2, :per_page => 15)
36
+ assert_kind_of Searchlogic::Search::Base, search
37
+ assert_equal({}, search.scope)
38
+ assert_equal Account, search.klass
39
+ assert_equal "awesome", search.conditions.name_keywords
40
+ assert_equal 2, search.page
41
+ assert_equal 15, search.per_page
42
+ end
43
+
44
+ def test_searchlogic_searching
45
+ assert_equal Account.find(1, 3), Account.all(:conditions => {:name_contains => "Binary"})
46
+ assert_equal [Account.find(1)], Account.all(:conditions => {:name_contains => "Binary", :users => {:first_name_starts_with => "Ben"}})
47
+ assert_equal [], Account.all(:conditions => {:name_contains => "Binary", :users => {:first_name_starts_with => "Ben", :last_name => "Mills"}})
48
+ assert_equal Account.find(1, 2), Account.all(:conditions => {:users => {:id_gt => 0}}, :include => :users)
49
+
50
+ read_only_accounts = Account.all(:conditions => {:name_contains => "Binary"}, :readonly => true)
51
+ assert read_only_accounts.first.readonly?
52
+
53
+ assert_equal Account.find(1, 3), Account.all(:conditions => {:name_contains => "Binary"}, :page => 2)
54
+ assert_equal [], Account.all(:conditions => {:name_contains => "Binary"}, :page => 2, :per_page => 20)
55
+
56
+ assert_equal [Account.find(1)], Account.scope1.all(:conditions => {:users => {:first_name_starts_with => "Ben"}})
57
+ end
58
+
59
+ def test_searchlogic_counting
60
+ assert_equal 2, Account.count(:conditions => {:name_contains => "Binary"})
61
+ assert_equal 1, Account.count(:conditions => {:name_contains => "Binary", :users => {:first_name_contains => "Ben"}})
62
+ assert_equal 1, Account.count(:conditions => {:name_contains => "Binary", :users => {:first_name_contains => "Ben"}}, :limit => 10, :offset => 10, :order_by => "id", :group => "id")
63
+ end
64
+
65
+ def test_scoping
66
+ assert_equal({:conditions => {:name => "Binary"}, :limit => 10, :readonly => true}, Account.send(:with_scope, :find => {:conditions => {:name => "Binary"}, :limit => 10, :readonly => true}) { Account.send(:scope, :find) })
67
+ assert_equal({:conditions => ["\"accounts\".\"name\" LIKE ?", "%Binary%"], :limit => 10, :offset => 20}, Account.send(:with_scope, :find => {:conditions => {:name_contains => "Binary"}, :per_page => 10, :page => 3}) { Account.send(:scope, :find) })
68
+ end
69
+
70
+ def test_accessible_conditions
71
+ Account.conditions_accessible :name_contains
72
+ assert_equal Set.new(["name_contains"]), Account.accessible_conditions
73
+ Account.conditions_accessible :id_gt
74
+ assert_equal Set.new(["id_gt", "name_contains"]), Account.accessible_conditions
75
+ Account.conditions_accessible :id_gt, :name_contains
76
+ assert_equal Set.new(["id_gt", "name_contains"]), Account.accessible_conditions
77
+ Account.send(:write_inheritable_attribute, :conditions_accessible, nil)
78
+ end
79
+
80
+ def test_protected_conditions
81
+ Account.conditions_protected :name_contains
82
+ assert_equal Set.new(["name_contains"]), Account.protected_conditions
83
+ Account.conditions_protected :id_gt
84
+ assert_equal Set.new(["id_gt", "name_contains"]), Account.protected_conditions
85
+ Account.conditions_protected :id_gt, :name_contains
86
+ assert_equal Set.new(["id_gt", "name_contains"]), Account.protected_conditions
87
+ Account.send(:write_inheritable_attribute, :conditions_protected, nil)
88
+ end
89
+
90
+ def test_includes
91
+ assert_nothing_raised { Account.all(:conditions => {:users => {:first_name_like => "Ben"}}, :include => :users) }
92
+ end
93
+ end