searchgasm 1.2.2 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. data/CHANGELOG.rdoc +8 -0
  2. data/Manifest +42 -3
  3. data/README.rdoc +101 -82
  4. data/TODO.rdoc +1 -3
  5. data/lib/searchgasm/active_record/connection_adapters/mysql_adapter.rb +143 -6
  6. data/lib/searchgasm/active_record/connection_adapters/postgresql_adapter.rb +148 -0
  7. data/lib/searchgasm/active_record/connection_adapters/sqlite_adapter.rb +54 -0
  8. data/lib/searchgasm/condition/base.rb +59 -86
  9. data/lib/searchgasm/condition/begins_with.rb +3 -8
  10. data/lib/searchgasm/condition/blank.rb +5 -5
  11. data/lib/searchgasm/condition/ends_with.rb +3 -8
  12. data/lib/searchgasm/condition/equals.rb +4 -3
  13. data/lib/searchgasm/condition/greater_than.rb +3 -14
  14. data/lib/searchgasm/condition/greater_than_or_equal_to.rb +3 -14
  15. data/lib/searchgasm/condition/keywords.rb +3 -8
  16. data/lib/searchgasm/condition/less_than.rb +3 -14
  17. data/lib/searchgasm/condition/less_than_or_equal_to.rb +3 -14
  18. data/lib/searchgasm/condition/like.rb +15 -0
  19. data/lib/searchgasm/condition/nil.rb +5 -5
  20. data/lib/searchgasm/condition/not_begin_with.rb +17 -0
  21. data/lib/searchgasm/condition/not_end_with.rb +17 -0
  22. data/lib/searchgasm/condition/{does_not_equal.rb → not_equal.rb} +5 -4
  23. data/lib/searchgasm/condition/not_have_keywords.rb +17 -0
  24. data/lib/searchgasm/condition/not_like.rb +17 -0
  25. data/lib/searchgasm/condition/tree.rb +4 -5
  26. data/lib/searchgasm/conditions/base.rb +218 -72
  27. data/lib/searchgasm/modifiers/absolute.rb +15 -0
  28. data/lib/searchgasm/modifiers/acos.rb +11 -0
  29. data/lib/searchgasm/modifiers/asin.rb +11 -0
  30. data/lib/searchgasm/modifiers/atan.rb +11 -0
  31. data/lib/searchgasm/modifiers/base.rb +27 -0
  32. data/lib/searchgasm/modifiers/ceil.rb +15 -0
  33. data/lib/searchgasm/modifiers/char_length.rb +15 -0
  34. data/lib/searchgasm/modifiers/cos.rb +15 -0
  35. data/lib/searchgasm/modifiers/cot.rb +15 -0
  36. data/lib/searchgasm/modifiers/day_of_month.rb +15 -0
  37. data/lib/searchgasm/modifiers/day_of_week.rb +15 -0
  38. data/lib/searchgasm/modifiers/day_of_year.rb +15 -0
  39. data/lib/searchgasm/modifiers/degrees.rb +11 -0
  40. data/lib/searchgasm/modifiers/exp.rb +15 -0
  41. data/lib/searchgasm/modifiers/floor.rb +15 -0
  42. data/lib/searchgasm/modifiers/hex.rb +11 -0
  43. data/lib/searchgasm/modifiers/hour.rb +11 -0
  44. data/lib/searchgasm/modifiers/log.rb +15 -0
  45. data/lib/searchgasm/modifiers/log10.rb +11 -0
  46. data/lib/searchgasm/modifiers/log2.rb +11 -0
  47. data/lib/searchgasm/modifiers/md5.rb +11 -0
  48. data/lib/searchgasm/modifiers/microseconds.rb +11 -0
  49. data/lib/searchgasm/modifiers/milliseconds.rb +11 -0
  50. data/lib/searchgasm/modifiers/minute.rb +15 -0
  51. data/lib/searchgasm/modifiers/month.rb +15 -0
  52. data/lib/searchgasm/modifiers/octal.rb +15 -0
  53. data/lib/searchgasm/modifiers/radians.rb +11 -0
  54. data/lib/searchgasm/modifiers/round.rb +11 -0
  55. data/lib/searchgasm/modifiers/second.rb +15 -0
  56. data/lib/searchgasm/modifiers/sign.rb +11 -0
  57. data/lib/searchgasm/modifiers/sin.rb +11 -0
  58. data/lib/searchgasm/modifiers/square_root.rb +15 -0
  59. data/lib/searchgasm/modifiers/tan.rb +15 -0
  60. data/lib/searchgasm/modifiers/week.rb +11 -0
  61. data/lib/searchgasm/modifiers/year.rb +11 -0
  62. data/lib/searchgasm/shared/utilities.rb +0 -10
  63. data/lib/searchgasm/version.rb +2 -2
  64. data/lib/searchgasm.rb +15 -19
  65. data/searchgasm.gemspec +86 -9
  66. data/test/libs/ordered_hash.rb +9 -0
  67. data/test/test_condition_base.rb +21 -47
  68. data/test/test_condition_types.rb +44 -44
  69. data/test/test_conditions_base.rb +34 -21
  70. data/test/test_helper.rb +1 -0
  71. data/test/test_search_conditions.rb +1 -1
  72. metadata +85 -8
  73. data/lib/searchgasm/condition/contains.rb +0 -20
  74. data/lib/searchgasm/condition/during_evening.rb +0 -32
data/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,11 @@
1
+ == 1.3.0 released 2008-09-29
2
+
3
+ * Added modifiers into the mix: hour_of_created_at_less_than = 10, etc.
4
+ * Changed how the Searchgasm::Conditions::Base class works. Instead of predefining all methods for all conditions upon instantiation, they are defined as needed via method_missing. Similar to
5
+ ActiveRecord's dynamic finders: User.find_by_name_and_email(name, email). Once the are defined they never hit method_missing again, acts like a cache.
6
+ * Altered how values are handled for each condition, meaningless values are ignored completely.
7
+ * Added in more "not" conditions: not_like, not_begin_with, not_have_keywords, etc
8
+
1
9
  == 1.2.2 released 2008-09-29
2
10
 
3
11
  * Fixed bug when reverse engineering order to order_by, assumed ASC and DESC would always be present when they are not.
data/Manifest CHANGED
@@ -10,10 +10,7 @@ lib/searchgasm/condition/base.rb
10
10
  lib/searchgasm/condition/begins_with.rb
11
11
  lib/searchgasm/condition/blank.rb
12
12
  lib/searchgasm/condition/child_of.rb
13
- lib/searchgasm/condition/contains.rb
14
13
  lib/searchgasm/condition/descendant_of.rb
15
- lib/searchgasm/condition/does_not_equal.rb
16
- lib/searchgasm/condition/during_evening.rb
17
14
  lib/searchgasm/condition/ends_with.rb
18
15
  lib/searchgasm/condition/equals.rb
19
16
  lib/searchgasm/condition/greater_than.rb
@@ -22,7 +19,13 @@ lib/searchgasm/condition/inclusive_descendant_of.rb
22
19
  lib/searchgasm/condition/keywords.rb
23
20
  lib/searchgasm/condition/less_than.rb
24
21
  lib/searchgasm/condition/less_than_or_equal_to.rb
22
+ lib/searchgasm/condition/like.rb
25
23
  lib/searchgasm/condition/nil.rb
24
+ lib/searchgasm/condition/not_begin_with.rb
25
+ lib/searchgasm/condition/not_end_with.rb
26
+ lib/searchgasm/condition/not_equal.rb
27
+ lib/searchgasm/condition/not_have_keywords.rb
28
+ lib/searchgasm/condition/not_like.rb
26
29
  lib/searchgasm/condition/sibling_of.rb
27
30
  lib/searchgasm/condition/tree.rb
28
31
  lib/searchgasm/conditions/base.rb
@@ -37,6 +40,41 @@ lib/searchgasm/helpers/control_types/remote_select.rb
37
40
  lib/searchgasm/helpers/control_types/select.rb
38
41
  lib/searchgasm/helpers/form.rb
39
42
  lib/searchgasm/helpers/utilities.rb
43
+ lib/searchgasm/modifiers/absolute.rb
44
+ lib/searchgasm/modifiers/acos.rb
45
+ lib/searchgasm/modifiers/asin.rb
46
+ lib/searchgasm/modifiers/atan.rb
47
+ lib/searchgasm/modifiers/base.rb
48
+ lib/searchgasm/modifiers/ceil.rb
49
+ lib/searchgasm/modifiers/char_length.rb
50
+ lib/searchgasm/modifiers/cos.rb
51
+ lib/searchgasm/modifiers/cot.rb
52
+ lib/searchgasm/modifiers/day_of_month.rb
53
+ lib/searchgasm/modifiers/day_of_week.rb
54
+ lib/searchgasm/modifiers/day_of_year.rb
55
+ lib/searchgasm/modifiers/degrees.rb
56
+ lib/searchgasm/modifiers/exp.rb
57
+ lib/searchgasm/modifiers/floor.rb
58
+ lib/searchgasm/modifiers/hex.rb
59
+ lib/searchgasm/modifiers/hour.rb
60
+ lib/searchgasm/modifiers/log.rb
61
+ lib/searchgasm/modifiers/log10.rb
62
+ lib/searchgasm/modifiers/log2.rb
63
+ lib/searchgasm/modifiers/md5.rb
64
+ lib/searchgasm/modifiers/microseconds.rb
65
+ lib/searchgasm/modifiers/milliseconds.rb
66
+ lib/searchgasm/modifiers/minute.rb
67
+ lib/searchgasm/modifiers/month.rb
68
+ lib/searchgasm/modifiers/octal.rb
69
+ lib/searchgasm/modifiers/radians.rb
70
+ lib/searchgasm/modifiers/round.rb
71
+ lib/searchgasm/modifiers/second.rb
72
+ lib/searchgasm/modifiers/sign.rb
73
+ lib/searchgasm/modifiers/sin.rb
74
+ lib/searchgasm/modifiers/square_root.rb
75
+ lib/searchgasm/modifiers/tan.rb
76
+ lib/searchgasm/modifiers/week.rb
77
+ lib/searchgasm/modifiers/year.rb
40
78
  lib/searchgasm/search/base.rb
41
79
  lib/searchgasm/search/conditions.rb
42
80
  lib/searchgasm/search/ordering.rb
@@ -56,6 +94,7 @@ test/fixtures/orders.yml
56
94
  test/fixtures/user_groups.yml
57
95
  test/fixtures/users.yml
58
96
  test/libs/acts_as_tree.rb
97
+ test/libs/ordered_hash.rb
59
98
  test/libs/rexml_fix.rb
60
99
  test/test_active_record_associations.rb
61
100
  test/test_active_record_base.rb
data/README.rdoc CHANGED
@@ -33,7 +33,9 @@ Now try out some of the examples below:
33
33
  User.all(
34
34
  :conditions => {
35
35
  :first_name_contains => "Ben", # first_name like '%Ben%'
36
- :email_ends_with => "binarylogic.com" # email like '%binarylogic.com'
36
+ :email_ends_with => "binarylogic.com", # email like '%binarylogic.com'
37
+ :created_after => Time.now, # created_at > Time.now
38
+ :created_at_hour_gt => 5 # HOUR(created_at) > 5 (depends on DB type)
37
39
  },
38
40
  :per_page => 20, # limit 20
39
41
  :page => 3, # offset 40, which starts us on page 3
@@ -46,6 +48,8 @@ same as above, but object based
46
48
  search = User.new_search
47
49
  search.conditions.first_name_contains = "Ben"
48
50
  search.conditions.email_ends_with = "binarylogic.com"
51
+ search.conditions.created_after = Time.now
52
+ search.conditiona.created_at_hour_gt = 5
49
53
  search.per_page = 20
50
54
  search.page = 3
51
55
  search.order_as = "ASC"
@@ -196,27 +200,6 @@ As you saw above, the nice thing about Searchgasm is it's integration with forms
196
200
 
197
201
  search = @current_user.orders.build_search(:conditions => {:total_lte => 500})
198
202
 
199
- == Searching trees
200
-
201
- For tree data structures you get a few nifty methods. Let's assume Users is a tree data structure.
202
-
203
- # Child of
204
- User.all(:conditions => {:child_of => User.roots.first})
205
- User.all(:conditions => {:child_of => User.roots.first.id})
206
-
207
- # Sibling of
208
- User.all(:conditions => {:sibling_of => User.roots.first})
209
- User.all(:conditions => {:sibling_of => User.roots.first.id})
210
-
211
- # Descendant of (includes all recursive children: children, grand children, great grand children, etc)
212
- User.all(:conditions => {:descendant_of => User.roots.first})
213
- User.all(:conditions => {:descendant_of => User.roots.first.id})
214
-
215
- # Inclusive descendant_of. Same as above but includes the root
216
- User.all(:conditions => {:inclusive_descendant_of => User.roots.first})
217
- User.all(:conditions => {:inclusive_descendant_of => User.roots.first.id})
218
-
219
-
220
203
  == Scope support
221
204
 
222
205
  Not only can you use searchgasm when searching, but you can use it when using scopes.
@@ -256,82 +239,114 @@ Lesson learned: use new\_search when passing in params as *ANY* of the options.
256
239
 
257
240
  == Available Conditions
258
241
 
259
- Depending on the type, each column comes preloaded with a bunch of nifty conditions:
242
+ The conditions are pretty self explanitory, but if you need more information checkout the docs or the source. The code is very simple and self explanatory.
260
243
 
261
- all columns
262
- => :equals, :does_not_equal
244
+ === Column conditions
263
245
 
264
- :string, :text
265
- => :begins_with, :contains, :keywords, :ends_with
246
+ Each column can be used with any of the following conditions
266
247
 
267
- :integer, :float, :decimal,:datetime, :timestamp, :time, :date
268
- => :greater_than, :greater_than_or_equal_to, :less_than, :less_than_or_equal_to
248
+ Name Aliases Description
249
+ :begins_with :starts_with, :sw, :bw, :start col LIKE 'value%'
250
+ :ends_with :ew, :ends, :end col LIKE '%value'
251
+ :equals :is, "" Lets ActiveRecord handle this
252
+ :greater_than :gt, :after col > value
253
+ :greater_than_or_equal_to :at_least, :least, :gte col >= value
254
+ :less_than :lt, :before col < value
255
+ :less_than_or_equal_to :at_most, :most, :lte col <= value
256
+ :keywords :kwords, :kw Splits into each word and omits meaningless words, a true keyword search
257
+ :like :contains, :has col LIKE '%value%'
258
+
259
+ :not_begin_with :not_bw, :not_sw, :not_start_with, :not_start, :beginning_is_not, :beginning_not
260
+ :not_end_with :not_ew, :not_end, :end_is_not, :end_not
261
+ :not_equal :does_not_equal, :is_not, :not
262
+ :not_have_keywords :not_have_keywords, :not_keywords, :not_have_kw, :not_kw, :not_have_kwwords, :not_kwwords
263
+ :not_like :not_contain, :not_have
269
264
 
270
- tree data structures (see above "searching trees")
271
- => :child_of, :sibling_of, :descendant_of, :inclusive_descendant_of
265
+ === Class level conditions
272
266
 
273
- Some of these conditions come with aliases, so you have your choice how to call the conditions. For example you can use "greater\_than" or "gt":
267
+ Each model comes preloaded with class level conditions as well. The difference is that these are not applied to each column, but instead to the model as a whole. Example: search.conditions.child_of = 2
274
268
 
275
- :equals => :is
276
- :does_not_equal => :is_not, :not
277
- :is_nil => :nil, :is_null, :null
278
- :is_blank => :blank
279
- :begins_with => :starts_with, :sw, :bw, :start
280
- :contains => :like, :has
281
- :ends_with => :ew, :ends, :end
282
- :greater_than => :gt, :after
283
- :greater_than_or_equal_to => :at_least, :gte
284
- :keywords => :kwords, :kw
285
- :less_than => :lt, :before
286
- :less_than_or_equal_to => :at_most, :lte
269
+ Name Description
270
+ :child_of Returns all children of value
271
+ :descendant_of Returns all descendants (children, grandchildren, grandgrandchildren, etc)
272
+ :inclusive_descendant_of Same as above but also includes the root
273
+ :sibling_of Returns all records that have the same parent
287
274
 
288
- For more information on each condition see Searchgasm::Condition. Each condition has it's own class and the source is pretty simple and self explanatory.
275
+ == Modifiers
289
276
 
290
- === Enhanced searching and blacklisted words
277
+ === What are modifiers?
291
278
 
292
- You will notice above there is "contains" and "keywords". The difference is that "keywords" is an enhanced search. It acts like a real keyword search. It finds those keywords, in any order, and blacklists meaningless words such as "and", "the", etc. "contains" finds the EXACT string in the column you are searching, spaces and all.
279
+ ActiveRecord does a great job when it comes to keeping your code database agnostic. But I feel like it neglected searching when it came to that goal. What if you want to find all records that were created after 7am? Depending on your database you would have to do something like the following:
293
280
 
294
- === Roll your own conditions
281
+ MySQL: HOUR(created_at)
282
+ PostgreSQL: date_part('hour', created_at)
283
+ SQLite: strftime('%H', created_at)
295
284
 
296
- I didn't include this function because its MySQL specific, and it's probably rarely used, but MySQL supports a "SOUNDS LIKE" function.
285
+ All of a sudden your app is not database agnostic. Searchgasm to the rescue! Searchgasm creates what I like to call "modifiers" to handle this nonsense for you. A modifier modifies a column. For example, the hour modifier modifies a datetime column to return the hour.
297
286
 
298
- I want to use it, so let's add it:
287
+ The last thing to keep in mind is that <b>not all modifiers are available for every database</b>. MySQL and PostgreSQL support all of these, but SQLite does not. SQLite is nice, in the sense that its really is "lite". The only modifiers it supports are the datetime modifiers. If you want support for the other modifiers you have to write the SQLite function yourself and register the modifier in searchgasm.
299
288
 
300
- # config/initializers/searchgasm.rb
301
- # Actual function for MySQL databases only
302
- class SoundsLike < Searchgasm::Condition::Base
303
- class << self
304
- # I pass you the column, you tell me what you want the method to be called.
305
- # If you don't want to add this condition for that column, return nil
306
- # It defaults to "#{column.name}_sounds_like" (using the class name). So if thats what you want you don't even need to do this.
307
- def name_for_column(column)
308
- super
309
- end
310
-
311
- # Only do this if you want aliases for your condition
312
- def aliases_for_column(column)
313
- ["#{column.name}_sounds", "#{column.name}_similar_to"]
314
- end
315
- end
316
-
317
- # You can return an array or a string. NOT a hash, because all of these conditions
318
- # need to eventually get merged together. The array or string can be anything you would put in
319
- # the :conditions option for ActiveRecord::Base.find(). Also, for a list of methods / variables you can use check out
320
- # Searchgasm::Condition::Base.
321
- def to_conditions(value)
322
- ["#{quoted_table_name}.#{quoted_column_name} SOUNDS LIKE ?", value]
323
- end
324
- end
289
+ Here are all of the available modifiers:
290
+
291
+ === Available modifiers
292
+
293
+ Name Aliases Description
294
+ :microsecond :microseconds, :microsecs, :microsec Extracts the microseconds
295
+ :millisecond :milliseconds, :millisecs, :millisec Extracts the milliseconds
296
+ :second :sec Extracts the seconds
297
+ :minute :min Extracts the minute
298
+ :hour Extracts the hour
299
+ :day_of_week :dow Extracts the day of week (1-7)
300
+ :day_of_month :dom Extracts the day of month (1-31)
301
+ :day_of_year :doy Extracts the day of year (1-366)
302
+ :week Extracts the week (1-53), 53rd week can be a "run-over" week to the next year
303
+ :month :mon Extracts the month (1-12)
304
+ :year Extracts the year
305
+
306
+ :md5 Converts to a MD5
307
+ :char_length :length The length of the string (integer)
325
308
 
326
- Searchgasm::Conditions::Base.register_condition(SoundsLike)
309
+ :absolute :abs The absolute value (-1 => 1)
310
+ :acos The arc cosine
311
+ :asin The arc sine
312
+ :atan The arc tangent
313
+ :ceil :round_up Rounds up to the nearest int
314
+ :cos :cosine The cosine
315
+ :cot :cotangent The cotangent
316
+ :degrees Converts radians to degrees
317
+ :exp :exponential Returns the value of e (the base of natural logarithms) raised to the power of X
318
+ :floor :round_down Rounds down to the nearest int
319
+ :hex Converts the number to a hex
320
+ :log :ln The natural logarithm
321
+ :log10 Returns the base-10 logarithm
322
+ :log2 Returns the base-2 logarithm
323
+ :octal :oct Return an octal representation of a decimal number
324
+ :radians Converts to radians
325
+ :round Rounds the number
326
+ :sign The sign of the number
327
+ :sin The sine of the number
328
+ :square_root :sqrt, :sq_rt The square root of the number
329
+ :tan :tangent The tangent of the number
330
+
331
+ === How to use modifiers
332
+
333
+ Here's what the above table means. Let's take the created_at column. The created_at column is a datetime column, laet's apply modifiers that make sense for a datetime column.
334
+
335
+ search.conditions.second_of_created_at = 2
336
+ search.conditions.sec_of_created_at_greater_than = 3
337
+ search.conditions.year_of_created_at_most = 5
338
+ search.conditions.year_of_created_at_lt = 2000
339
+ # ... any of the modifiers that apply to datetime columns
340
+
341
+ Here's the cool part. Chaining modifiers:
327
342
 
328
- Now test it out:
343
+ search.conditions.ceil_of_cos_of_sec_of_created_at_greater_than = 3
344
+
345
+ As long as the modifier chain makes sense the possibilities are endless.
329
346
 
330
- search = User.new_search
331
- search.conditions.first_name_sounds_like = "Ben"
332
- search.all # will return any user that has a first name that sounds like "Ben"
347
+ == Roll your own conditions & modifiers
333
348
 
334
- Pretty nifty, huh? You can create any condition ultimately creating any SQL you want. The sky is the limit. For more information see Searchgasm::Condition::Base
349
+ For more information on this please see Searchgasm::Conditions::Base
335
350
 
336
351
  == Under the hood
337
352
 
@@ -339,7 +354,11 @@ I'm a big fan of understanding what I'm using, so here's a quick explanation: Th
339
354
 
340
355
  ActiveRecord should never know about Searchgasm
341
356
 
342
- What that rule means is that any options you pass when searching get "sanitized" down into options ActiveRecord can understand. Searchgasm serves as a transparent filter between you and ActiveRecord. It doesn't dig into the ActiveRecord internals, it only uses what is publicly available. It jumps in and helps out <em>only</em> when needed, otherwise it sits back and stays completely out of the way. Between that and the extensive tests, this is a solid and fast plugin.
357
+ What that rule means is that any options you pass when searching get "sanitized" down into options ActiveRecord can understand. Searchgasm serves as a transparent filter between you and ActiveRecord. It doesn't dig into the ActiveRecord internals, it only uses what is publicly available. It jumps in and helps out <em>only</em> when needed, otherwise it sits back and stays completely out of the way.
358
+
359
+ Lastly, Searchgasm is lazy. It only creates objects, methods, and classes when needed. Once it creates them it caches them. For example, all of the nifty conditions are created via meta programming. The first time you execute something like User.new_search all of that method creation gets cached into Searchgasm::Cache::UserSearch. The next time you execute User.new_search it will be over 50 times faster because it uses the cached class.
360
+
361
+ Between that and the extensive tests, this is a solid and fast plugin.
343
362
 
344
363
  == Credits
345
364
 
data/TODO.rdoc CHANGED
@@ -1,5 +1,3 @@
1
1
  = To Do
2
2
 
3
- 1. Add month condition for date and datetime columns. So you can specify a specific month, by name, number, etc.
4
- 2. Add day condition for time and datetime columns. So you can specify that the time is during the day or the night.
5
- 3. Add weekend condition for date and datetime columns. So you can specify if the date is on a friday, saturday, or sunday
3
+ 1. Perform "more efficient" checks: year_of_created_at = 2008 and month_of_created_at = 8. Should result in a "BETWEEN" statement utilizing the column indexes. Thanks Georg for letting me know about this.
@@ -1,15 +1,152 @@
1
1
  module Searchgasm
2
2
  module ActiveRecord
3
- module ConnectionAdapters
3
+ module ConnectionAdapters # :nodoc: all
4
4
  module MysqlAdapter
5
- def hour_sql
6
- "HOUR(?)"
5
+ # Date / time functions
6
+ def microseconds_sql(column_name)
7
+ "MICROSECOND(#{column_name})"
7
8
  end
8
9
 
9
- def month_sql
10
- "MONTH(?)"
10
+ def milliseconds_sql(column_name)
11
+ "(MICROSECOND(#{column_name}) / 1000)"
12
+ end
13
+
14
+ def second_sql(column_name)
15
+ "SECOND(#{column_name})"
16
+ end
17
+
18
+ def minute_sql(column_name)
19
+ "MINUTE(#{column_name})"
20
+ end
21
+
22
+ def hour_sql(column_name)
23
+ "HOUR(#{column_name})"
24
+ end
25
+
26
+ def day_of_week_sql(column_name)
27
+ "DAYOFWEEK(#{column_name})"
28
+ end
29
+
30
+ def day_of_month_sql(column_name)
31
+ "DAYOFMONTH(#{column_name})"
32
+ end
33
+
34
+ def day_of_year_sql(column_name)
35
+ "DAYOFYEAR(#{column_name})"
36
+ end
37
+
38
+ def week_sql(column_name)
39
+ "WEEK(#{column_name}, 2)"
40
+ end
41
+
42
+ def month_sql(column_name)
43
+ "MONTH(#{column_name})"
44
+ end
45
+
46
+ def year_sql(column_name)
47
+ "MONTH(#{column_name})"
48
+ end
49
+
50
+ # String functions
51
+ def char_length_sql(column_name)
52
+ "CHAR_LENGTH(#{column_name})"
53
+ end
54
+
55
+ def md5_sql(column_name)
56
+ "MD5(#{column_name})"
57
+ end
58
+
59
+ # Number functions
60
+ def absolute_sql(column_name)
61
+ "ABS(#{column_name})"
62
+ end
63
+
64
+ def acos_sql(column_name)
65
+ "ACOS(#{column_name})"
66
+ end
67
+
68
+ def asin_sql(column_name)
69
+ "ASIN(#{column_name})"
70
+ end
71
+
72
+ def atan_sql(column_name)
73
+ "ATAN(#{column_name})"
74
+ end
75
+
76
+ def ceil_sql(column_name)
77
+ "CEIL(#{column_name})"
78
+ end
79
+
80
+ def cos_sql(column_name)
81
+ "COS(#{column_name})"
82
+ end
83
+
84
+ def cot_sql(column_name)
85
+ "COT(#{column_name})"
86
+ end
87
+
88
+ def degrees_sql(column_name)
89
+ "DEGREES(#{column_name})"
90
+ end
91
+
92
+ def exp_sql(column_name)
93
+ "EXP(#{column_name})"
94
+ end
95
+
96
+ def floor_sql(column_name)
97
+ "FLOOR(#{column_name})"
98
+ end
99
+
100
+ def hex_sql(column_name)
101
+ "HEX(#{column_name})"
102
+ end
103
+
104
+ def ln_sql(column_name)
105
+ "LN(#{column_name})"
106
+ end
107
+
108
+ def log_sql(column_name)
109
+ "LOG(#{column_name})"
110
+ end
111
+
112
+ def log2_sql(column_name)
113
+ "LOG2(#{column_name})"
114
+ end
115
+
116
+ def log10_sql(column_name)
117
+ "LOG10(#{column_name})"
118
+ end
119
+
120
+ def octal_sql(column_name)
121
+ "OCT(#{column_name})"
122
+ end
123
+
124
+ def radians_sql(column_name)
125
+ "RADIANS(#{column_name})"
126
+ end
127
+
128
+ def round_sql(column_name)
129
+ "ROUND(#{column_name})"
130
+ end
131
+
132
+ def sign_sql(column_name)
133
+ "SIGN(#{column_name})"
134
+ end
135
+
136
+ def sin_sql(column_name)
137
+ "SIN(#{column_name})"
138
+ end
139
+
140
+ def square_root_sql(column_name)
141
+ "SQRT(#{column_name})"
142
+ end
143
+
144
+ def tan_sql(column_name)
145
+ "TAN(#{column_name})"
11
146
  end
12
147
  end
13
148
  end
14
149
  end
15
- end
150
+ end
151
+
152
+ ::ActiveRecord::ConnectionAdapters::MysqlAdapter.send(:include, Searchgasm::ActiveRecord::ConnectionAdapters::MysqlAdapter)
@@ -0,0 +1,148 @@
1
+ module Searchgasm
2
+ module ActiveRecord
3
+ module ConnectionAdapters
4
+ module PostgreSQLAdapter
5
+ # Datetime functions
6
+ def microseconds_sql(column_name)
7
+ "date_part('microseconds', #{column_name})"
8
+ end
9
+
10
+ def milliseconds_sql(column_name)
11
+ "date_part('milliseconds', #{column_name})"
12
+ end
13
+
14
+ def second_sql(column_name)
15
+ "date_part('second', #{column_name})"
16
+ end
17
+
18
+ def minute_sql(column_name)
19
+ "date_part('minute', #{column_name})"
20
+ end
21
+
22
+ def hour_sql(column_name)
23
+ "date_part('hour', #{column_name})"
24
+ end
25
+
26
+ def day_of_week_sql(column_name)
27
+ "(date_part('dow', #{column_name}) + 1)"
28
+ end
29
+
30
+ def day_of_month_sql(column_name)
31
+ "date_part('day', #{column_name})"
32
+ end
33
+
34
+ def day_of_year_sql(column_name)
35
+ "date_part('doy', #{column_name})"
36
+ end
37
+
38
+ def week_sql(column_name)
39
+ "date_part('week', #{column_name})"
40
+ end
41
+
42
+ def month_sql(column_name)
43
+ "date_part('month', #{column_name})"
44
+ end
45
+
46
+ def year_sql(column_name)
47
+ "date_part('year', #{column_name})"
48
+ end
49
+
50
+ # String functions
51
+ def char_length_sql(column_name)
52
+ "length(#{column_name})"
53
+ end
54
+
55
+ def md5_sql(column_name)
56
+ "md5(#{column_name})"
57
+ end
58
+
59
+ # Number functions
60
+ def absolute_sql(column_name)
61
+ "abs(#{column_name})"
62
+ end
63
+
64
+ def acos_sql(column_name)
65
+ "acos(#{column_name})"
66
+ end
67
+
68
+ def asin_sql(column_name)
69
+ "asin(#{column_name})"
70
+ end
71
+
72
+ def atan_sql(column_name)
73
+ "atan(#{column_name})"
74
+ end
75
+
76
+ def ceil_sql(column_name)
77
+ "ceil(#{column_name})"
78
+ end
79
+
80
+ def cos_sql(column_name)
81
+ "cos(#{column_name})"
82
+ end
83
+
84
+ def cot_sql(column_name)
85
+ "cot(#{column_name})"
86
+ end
87
+
88
+ def degrees_sql(column_name)
89
+ "degrees(#{column_name})"
90
+ end
91
+
92
+ def exp_sql(column_name)
93
+ "exp(#{column_name})"
94
+ end
95
+
96
+ def floor_sql(column_name)
97
+ "floor(#{column_name})"
98
+ end
99
+
100
+ def hex_sql(column_name)
101
+ "to_hex(#{column_name})"
102
+ end
103
+
104
+ def ln_sql(column_name)
105
+ "ln(#{column_name})"
106
+ end
107
+
108
+ def log_sql(column_name)
109
+ "log(#{column_name})"
110
+ end
111
+
112
+ def log2_sql(column_name)
113
+ "log(2.0, #{column_name})"
114
+ end
115
+
116
+ def log10_sql(column_name)
117
+ "log(10.0, #{column_name})"
118
+ end
119
+
120
+ def radians_sql(column_name)
121
+ "radians(#{column_name})"
122
+ end
123
+
124
+ def round_sql(column_name)
125
+ "round(#{column_name})"
126
+ end
127
+
128
+ def sign_sql(column_name)
129
+ "sign(#{column_name})"
130
+ end
131
+
132
+ def sin_sql(column_name)
133
+ "sin(#{column_name})"
134
+ end
135
+
136
+ def square_root_sql(column_name)
137
+ "sqrt(#{column_name})"
138
+ end
139
+
140
+ def tan_sql(column_name)
141
+ "tan(#{column_name})"
142
+ end
143
+ end
144
+ end
145
+ end
146
+ end
147
+
148
+ ::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.send(:include, Searchgasm::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)