model_set 0.10.6

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 (95) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +39 -0
  3. data/VERSION.yml +5 -0
  4. data/lib/model_set/conditioned.rb +33 -0
  5. data/lib/model_set/conditions.rb +103 -0
  6. data/lib/model_set/query.rb +132 -0
  7. data/lib/model_set/raw_query.rb +41 -0
  8. data/lib/model_set/raw_sql_query.rb +19 -0
  9. data/lib/model_set/set_query.rb +34 -0
  10. data/lib/model_set/solr_query.rb +70 -0
  11. data/lib/model_set/sphinx_query.rb +206 -0
  12. data/lib/model_set/sql_base_query.rb +52 -0
  13. data/lib/model_set/sql_query.rb +109 -0
  14. data/lib/model_set.rb +743 -0
  15. data/lib/multi_set.rb +67 -0
  16. data/test/model_set_test.rb +329 -0
  17. data/test/multi_set_test.rb +65 -0
  18. data/test/test_helper.rb +23 -0
  19. data/vendor/sphinx_client/README.rdoc +41 -0
  20. data/vendor/sphinx_client/Rakefile +21 -0
  21. data/vendor/sphinx_client/init.rb +1 -0
  22. data/vendor/sphinx_client/install.rb +5 -0
  23. data/vendor/sphinx_client/lib/sphinx/client.rb +1093 -0
  24. data/vendor/sphinx_client/lib/sphinx/request.rb +50 -0
  25. data/vendor/sphinx_client/lib/sphinx/response.rb +69 -0
  26. data/vendor/sphinx_client/lib/sphinx.rb +6 -0
  27. data/vendor/sphinx_client/spec/client_response_spec.rb +112 -0
  28. data/vendor/sphinx_client/spec/client_spec.rb +469 -0
  29. data/vendor/sphinx_client/spec/fixtures/default_search.php +8 -0
  30. data/vendor/sphinx_client/spec/fixtures/default_search_index.php +8 -0
  31. data/vendor/sphinx_client/spec/fixtures/excerpt_custom.php +11 -0
  32. data/vendor/sphinx_client/spec/fixtures/excerpt_default.php +8 -0
  33. data/vendor/sphinx_client/spec/fixtures/excerpt_flags.php +11 -0
  34. data/vendor/sphinx_client/spec/fixtures/field_weights.php +9 -0
  35. data/vendor/sphinx_client/spec/fixtures/filter.php +9 -0
  36. data/vendor/sphinx_client/spec/fixtures/filter_exclude.php +9 -0
  37. data/vendor/sphinx_client/spec/fixtures/filter_float_range.php +9 -0
  38. data/vendor/sphinx_client/spec/fixtures/filter_float_range_exclude.php +9 -0
  39. data/vendor/sphinx_client/spec/fixtures/filter_range.php +9 -0
  40. data/vendor/sphinx_client/spec/fixtures/filter_range_exclude.php +9 -0
  41. data/vendor/sphinx_client/spec/fixtures/filter_range_int64.php +10 -0
  42. data/vendor/sphinx_client/spec/fixtures/filter_ranges.php +10 -0
  43. data/vendor/sphinx_client/spec/fixtures/filters.php +10 -0
  44. data/vendor/sphinx_client/spec/fixtures/filters_different.php +13 -0
  45. data/vendor/sphinx_client/spec/fixtures/geo_anchor.php +9 -0
  46. data/vendor/sphinx_client/spec/fixtures/group_by_attr.php +9 -0
  47. data/vendor/sphinx_client/spec/fixtures/group_by_attrpair.php +9 -0
  48. data/vendor/sphinx_client/spec/fixtures/group_by_day.php +9 -0
  49. data/vendor/sphinx_client/spec/fixtures/group_by_day_sort.php +9 -0
  50. data/vendor/sphinx_client/spec/fixtures/group_by_month.php +9 -0
  51. data/vendor/sphinx_client/spec/fixtures/group_by_week.php +9 -0
  52. data/vendor/sphinx_client/spec/fixtures/group_by_year.php +9 -0
  53. data/vendor/sphinx_client/spec/fixtures/group_distinct.php +10 -0
  54. data/vendor/sphinx_client/spec/fixtures/id_range.php +9 -0
  55. data/vendor/sphinx_client/spec/fixtures/id_range64.php +9 -0
  56. data/vendor/sphinx_client/spec/fixtures/index_weights.php +9 -0
  57. data/vendor/sphinx_client/spec/fixtures/keywords.php +8 -0
  58. data/vendor/sphinx_client/spec/fixtures/limits.php +9 -0
  59. data/vendor/sphinx_client/spec/fixtures/limits_cutoff.php +9 -0
  60. data/vendor/sphinx_client/spec/fixtures/limits_max.php +9 -0
  61. data/vendor/sphinx_client/spec/fixtures/limits_max_cutoff.php +9 -0
  62. data/vendor/sphinx_client/spec/fixtures/match_all.php +9 -0
  63. data/vendor/sphinx_client/spec/fixtures/match_any.php +9 -0
  64. data/vendor/sphinx_client/spec/fixtures/match_boolean.php +9 -0
  65. data/vendor/sphinx_client/spec/fixtures/match_extended.php +9 -0
  66. data/vendor/sphinx_client/spec/fixtures/match_extended2.php +9 -0
  67. data/vendor/sphinx_client/spec/fixtures/match_fullscan.php +9 -0
  68. data/vendor/sphinx_client/spec/fixtures/match_phrase.php +9 -0
  69. data/vendor/sphinx_client/spec/fixtures/max_query_time.php +9 -0
  70. data/vendor/sphinx_client/spec/fixtures/miltiple_queries.php +12 -0
  71. data/vendor/sphinx_client/spec/fixtures/ranking_bm25.php +9 -0
  72. data/vendor/sphinx_client/spec/fixtures/ranking_none.php +9 -0
  73. data/vendor/sphinx_client/spec/fixtures/ranking_proximity.php +9 -0
  74. data/vendor/sphinx_client/spec/fixtures/ranking_proximity_bm25.php +9 -0
  75. data/vendor/sphinx_client/spec/fixtures/ranking_wordcount.php +9 -0
  76. data/vendor/sphinx_client/spec/fixtures/retries.php +9 -0
  77. data/vendor/sphinx_client/spec/fixtures/retries_delay.php +9 -0
  78. data/vendor/sphinx_client/spec/fixtures/select.php +9 -0
  79. data/vendor/sphinx_client/spec/fixtures/set_override.php +11 -0
  80. data/vendor/sphinx_client/spec/fixtures/sort_attr_asc.php +9 -0
  81. data/vendor/sphinx_client/spec/fixtures/sort_attr_desc.php +9 -0
  82. data/vendor/sphinx_client/spec/fixtures/sort_expr.php +9 -0
  83. data/vendor/sphinx_client/spec/fixtures/sort_extended.php +9 -0
  84. data/vendor/sphinx_client/spec/fixtures/sort_relevance.php +9 -0
  85. data/vendor/sphinx_client/spec/fixtures/sort_time_segments.php +9 -0
  86. data/vendor/sphinx_client/spec/fixtures/sphinxapi.php +1269 -0
  87. data/vendor/sphinx_client/spec/fixtures/update_attributes.php +8 -0
  88. data/vendor/sphinx_client/spec/fixtures/update_attributes_mva.php +8 -0
  89. data/vendor/sphinx_client/spec/fixtures/weights.php +9 -0
  90. data/vendor/sphinx_client/spec/sphinx/sphinx-id64.conf +67 -0
  91. data/vendor/sphinx_client/spec/sphinx/sphinx.conf +67 -0
  92. data/vendor/sphinx_client/spec/sphinx/sphinx_test.sql +86 -0
  93. data/vendor/sphinx_client/sphinx.yml.tpl +3 -0
  94. data/vendor/sphinx_client/tasks/sphinx.rake +75 -0
  95. metadata +151 -0
@@ -0,0 +1,52 @@
1
+ class ModelSet
2
+ class SQLBaseQuery < Query
3
+ # SQL methods common to SQLQuery and RawSQLQuery.
4
+ def ids
5
+ @ids ||= fetch_id_set(sql)
6
+ end
7
+
8
+ def size
9
+ @size ||= ids.size
10
+ end
11
+
12
+ private
13
+
14
+ def ids_clause(ids, field = id_field_with_prefix)
15
+ db.ids_clause(ids, field)
16
+ end
17
+
18
+ def fetch_id_set(sql)
19
+ db.select_values(sql).collect {|id| id.to_i}.to_ordered_set
20
+ end
21
+
22
+ def db
23
+ model_class.connection
24
+ end
25
+
26
+ def sanitize_condition(condition)
27
+ model_class.send(:sanitize_sql, condition)
28
+ end
29
+
30
+ def limit_clause
31
+ return unless limit
32
+ limit_clause = "LIMIT #{limit}"
33
+ limit_clause << " OFFSET #{offset}" if offset > 0
34
+ limit_clause
35
+ end
36
+ end
37
+ end
38
+
39
+ class ActiveRecord::ConnectionAdapters::AbstractAdapter
40
+ def ids_clause(ids, field)
41
+ # Make sure all ids are integers to prevent SQL injection attacks.
42
+ ids = ids.collect {|id| id.to_i}
43
+
44
+ if ids.empty?
45
+ "FALSE"
46
+ elsif kind_of?(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)
47
+ "#{field} = ANY ('{#{ids.join(',')}}'::bigint[])"
48
+ else
49
+ "#{field} IN (#{ids.join(',')})"
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,109 @@
1
+ class ModelSet
2
+ class SQLQuery < SQLBaseQuery
3
+ include Conditioned
4
+
5
+ def anchor!(query)
6
+ if query.respond_to?(:sql)
7
+ sql = "#{id_field_with_prefix} IN (#{query.sql})"
8
+ else
9
+ sql = ids_clause(query.ids)
10
+ end
11
+ @reorder = query.ids
12
+ add_conditions!(sql)
13
+ end
14
+
15
+ def ids
16
+ if @ids.nil?
17
+ @ids = fetch_id_set(sql)
18
+ @ids.reorder!(@reorder) if @reorder
19
+ end
20
+ @ids
21
+ end
22
+
23
+ def limit_enabled?
24
+ return false if @reorder
25
+ super
26
+ end
27
+
28
+ def aggregate(query, opts = {})
29
+ sql = "SELECT #{query} #{from_clause}"
30
+ sql << " LIMIT #{opts[:limit]}" if opts[:limit]
31
+ sql << " GROUP BY #{opts[:group_by]}" if opts[:group_by]
32
+ result = db.select_rows(sql).first
33
+ result.size == 1 ? result.first : result
34
+ end
35
+
36
+ def add_joins!(*joins)
37
+ @joins ||= []
38
+
39
+ joins.each do |join|
40
+ @joins << sanitize_condition(join)
41
+ end
42
+ @joins.uniq!
43
+
44
+ clear_cache!
45
+ end
46
+
47
+ def in!(ids, field = id_field_with_prefix)
48
+ add_conditions!( ids_clause(ids, field) )
49
+ end
50
+
51
+ def order_by!(*args)
52
+ opts = args.last.kind_of?(Hash) ? args.pop : {}
53
+
54
+ @sort_join = sanitize_condition(opts[:join])
55
+ @sort_order = args
56
+ @reorder = nil
57
+ clear_cache!
58
+ end
59
+
60
+ def reverse!
61
+ if @reorder
62
+ @reorder.reverse!
63
+ elsif @sort_order
64
+ @sort_order.collect! do |sub_order|
65
+ if sub_order =~ / DESC$/i
66
+ sub_order.slice(0..-6)
67
+ else
68
+ "#{sub_order} DESC"
69
+ end
70
+ end
71
+ else
72
+ @sort_order = ["#{id_field_with_prefix} DESC"]
73
+ end
74
+ clear_cache!
75
+ end
76
+
77
+ def sql
78
+ "#{select_clause} #{from_clause} #{order_clause} #{limit_clause}"
79
+ end
80
+
81
+ def count
82
+ @count ||= limit ? aggregate("COUNT(DISTINCT #{id_field_with_prefix})").to_i : size
83
+ end
84
+
85
+ private
86
+
87
+ def select_clause
88
+ "SELECT #{id_field_with_prefix}"
89
+ end
90
+
91
+ def from_clause
92
+ "FROM #{table_name} #{join_clause} WHERE #{conditions.to_s}"
93
+ end
94
+
95
+ def order_clause
96
+ return unless @sort_order
97
+ # Prevent SQL injection attacks.
98
+ "ORDER BY #{@sort_order.join(', ').gsub(/[^\w_, \.\(\)'\"]/, '')}"
99
+ end
100
+
101
+ def join_clause
102
+ return unless @joins or @sort_join
103
+ joins = []
104
+ joins << @joins if @joins
105
+ joins << @sort_join if @sort_join
106
+ joins.join(' ')
107
+ end
108
+ end
109
+ end