conditioner 0.0.3 → 0.0.4

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.
data/Rakefile CHANGED
@@ -26,9 +26,10 @@ end
26
26
 
27
27
  PKG_FILES = FileList[ '[a-zA-Z]*', 'generators/**/*', 'lib/**/*', 'rails/**/*', 'tasks/**/*', 'test/**/*' ]
28
28
 
29
+ require 'lib/conditioner.rb'
29
30
  spec = Gem::Specification.new do |s|
30
31
  s.name = "conditioner"
31
- s.version = "0.0.3"
32
+ s.version = Conditioner::VERSION
32
33
  s.author = "niquola"
33
34
  s.email = "niquola@gmail.com"
34
35
  s.homepage = "http://github.com/niquola/conditioner"
@@ -2,10 +2,11 @@ $:.unshift(File.dirname(__FILE__)) unless
2
2
  $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
3
 
4
4
  module Conditioner
5
- VERSION = '0.0.3'
5
+ VERSION = '0.0.4'
6
6
  autoload :ActiveRecordMixin, 'conditioner/active_record_mixin'
7
7
  autoload :Condition, 'conditioner/condition'
8
8
  autoload :Configurator, 'conditioner/configurator'
9
+ autoload :FakeModel, 'conditioner/fake_model'
9
10
 
10
11
  class << self
11
12
  def enable
@@ -23,6 +24,16 @@ module Conditioner
23
24
  def configure
24
25
  yield config
25
26
  end
27
+
28
+ def create(table_name_or_model, options = {})
29
+ if table_name_or_model.is_a?(String)
30
+ model = FakeModel.new(table_name_or_model, options)
31
+ else
32
+ model = table_name_or_model
33
+ end
34
+
35
+ Condition.new(model, options)
36
+ end
26
37
  end
27
38
  end
28
39
 
@@ -1,10 +1,10 @@
1
1
  module Conditioner
2
2
  class Condition < String
3
- def initialize(model)
4
- @model=model
5
- @result=[]
6
- @column_names=@model.column_names
7
- @first_condition=true
3
+ def initialize(model, options = {})
4
+ @model = model
5
+ @column_names = @model.column_names
6
+ @result = []
7
+ @first_condition = true
8
8
  yield self if block_given?
9
9
  end
10
10
 
@@ -28,12 +28,12 @@ module Conditioner
28
28
  @condition_called_flag= true
29
29
  result= []
30
30
  unless @first_condition
31
- result<<' '<<unit
31
+ result << ' ' << unit
32
32
  else
33
- @first_condition=false
33
+ @first_condition = false
34
34
  end
35
- result<<@model.send(:sanitize_sql_for_conditions, *args)
36
- self<< result.join(" ")
35
+ result << @model.send(:sanitize_sql_for_conditions, *args)
36
+ self << result.join(" ")
37
37
  self
38
38
  end
39
39
 
@@ -59,3 +59,4 @@ module Conditioner
59
59
  end
60
60
  end
61
61
  end
62
+
@@ -16,17 +16,33 @@ module Conditioner
16
16
 
17
17
  def activate_default_rules!
18
18
  add_rule do |field, v, cnd|
19
- if cnd.is_field?(field) && v =~ /(\*$|^\*)/
20
- cnd.and(["#{cnd.with_table_name(field)} ILIKE ?",v.gsub(/(\*$|^\*)/,'%')])
21
- elsif cnd.is_field?(field) && v =~ /(%$|^%)/
22
- cnd.and(["upper(#{cnd.with_table_name(field)}) like upper(?)",v])
23
- #FIXME: add logic for ranges
24
- elsif field=~ /^from_(\w*_(datetime|at))/ and cnd.is_field?($1)
25
- cnd.and(["#{cnd.with_table_name($1)} >= ?","#{v} 00:00:00.000"])
26
- elsif field=~ /^to_(\w*_(datetime|at))/ and cnd.is_field?($1)
27
- cnd.and(["#{cnd.with_table_name($1)} <= ?","#{v} 23:59:59.999"])
28
- elsif cnd.is_field?(field) && (field.include?('_datetime') || field.include?('_at'))
29
- cnd.and(["(#{cnd.with_table_name(field)} BETWEEN ? AND ?)","#{v} 00:00","#{v} 23:59:59.999"])
19
+ unless v.nil? || (v.respond_to?(:'empty?') && v.empty?)
20
+ if cnd.is_field?(field) && v =~ /(\*$|^\*)/
21
+ cnd.and(["#{cnd.with_table_name(field)} ILIKE ?",v.gsub(/(\*$|^\*)/,'%')])
22
+ elsif cnd.is_field?(field) && v =~ /(%$|^%)/
23
+ cnd.and(["upper(#{cnd.with_table_name(field)}) like upper(?)",v])
24
+ #FIXME: add logic for ranges
25
+ elsif field=~ /^from_(\w*_(datetime|at))/ and cnd.is_field?($1)
26
+ cnd.and(["#{cnd.with_table_name($1)} >= ?","#{v} 00:00:00.000"])
27
+ elsif field=~ /^to_(\w*_(datetime|at))/ and cnd.is_field?($1)
28
+ cnd.and(["#{cnd.with_table_name($1)} <= ?","#{v} 23:59:59.999"])
29
+ elsif cnd.is_field?(field) && (field.include?('_datetime') || field.include?('_at'))
30
+ cnd.and(["(#{cnd.with_table_name(field)} BETWEEN ? AND ?)","#{v} 00:00","#{v} 23:59:59.999"])
31
+ elsif field=~ /^(\w*)_(ltoe|gtoe|lt|gt)$/ and cnd.is_field?($1)
32
+ operator = { 'lt' => '<', 'gt' => '>', 'ltoe' => '<=', 'gtoe' => '>=' }[$2]
33
+ cnd.and(["#{cnd.with_table_name($1)} #{operator} ?", v])
34
+ elsif field=~ /^(\w*)_(begins_with|ends_with|contains)$/ and cnd.is_field?($1)
35
+ if $2 == 'begins_with'
36
+ like_expr = "#{v}%"
37
+ elsif $2 == 'ends_with'
38
+ like_expr = "%#{v}"
39
+ else
40
+ like_expr = "%#{v}%"
41
+ end
42
+ cnd.and(["#{cnd.with_table_name($1)} ILIKE ?", like_expr])
43
+ elsif field=~ /^(\w*)_in$/ and cnd.is_field?($1)
44
+ cnd.and(["#{cnd.with_table_name($1)} IN (?)", v])
45
+ end
30
46
  end
31
47
  end
32
48
  end
@@ -0,0 +1,27 @@
1
+ module Conditioner
2
+ class FakeModel
3
+
4
+ def initialize(table_name, options = {})
5
+ @table_name = table_name
6
+ @options = options
7
+ end
8
+
9
+ def sanitize_sql_for_conditions(*args)
10
+ args << ActiveRecord::Base.connection.quote_table_name(@table_name)
11
+ ActiveRecord::Base.send(:sanitize_sql_for_conditions, *args)
12
+ end
13
+
14
+ def column_names
15
+ if @options[:columns]
16
+ @options[:columns]
17
+ else
18
+ @column_names ||= ActiveRecord::Base.connection.columns(@table_name).map { |c| c.name }
19
+ end
20
+ end
21
+
22
+ def table_name
23
+ @table_name
24
+ end
25
+
26
+ end
27
+ end
@@ -7,8 +7,8 @@ Conditioner.configure do |cfg|
7
7
  #cfg.clear_rules!
8
8
 
9
9
  cfg.add_rule do |key, value, cnd|
10
- if /(.\w*)_gt/ =~ key.to_s && cnd.is_field?($1)
11
- cnd.and(["#{key.gsub(/_gt$/,'')} > ?",value])
10
+ if /(.\w*)_gt/ =~ key.to_s && cnd.is_field?($1)
11
+ cnd.and(["#{key.gsub(/_gt$/,'')} > ? ", value])
12
12
  end
13
13
  end
14
14
  end
@@ -25,25 +25,67 @@ class TestConditioner < Test::Unit::TestCase
25
25
 
26
26
  def test_extraction
27
27
  cnd=User.conditioner(:updated_at=>'2009-01-01', :email=>'nicola@mail.com',:unexisting=>'value')
28
- assert_match(/"users"."email"\s*=\s*E'nicola@mail.com'/, cnd)
29
- assert_match(/users.updated_at BETWEEN E'2009-01-01 00:00' AND E'2009-01-01 23:59:59.999'/, cnd)
28
+ assert_match(/"users"."email"\s*=\s*'nicola@mail.com'/, cnd)
29
+ assert_match(/users.updated_at BETWEEN '2009-01-01 00:00' AND '2009-01-01 23:59:59.999'/, cnd)
30
30
  assert_no_match(/unexisting/, cnd)
31
31
  end
32
32
 
33
33
  def test_extract_from_and_to_prefixed_date_fields
34
34
  cnd = User.conditioner :to_updated_at =>'2010-02-02', :from_updated_at=>'2009-01-01'
35
- assert_match(/updated_at <= E'2010-02-02 23:59:59.999'/, cnd)
36
- assert_match(/updated_at >= E'2009-01-01 00:00:00.000'/, cnd)
35
+ assert_match(/updated_at <= '2010-02-02 23:59:59.999'/, cnd)
36
+ assert_match(/updated_at >= '2009-01-01 00:00:00.000'/, cnd)
37
+ end
38
+
39
+ def test_extract_lt_and_gt_postfixed_fields
40
+ cnd = User.conditioner :id_lt => '5', :id_gt => 2
41
+ assert_match(/id < '5'/, cnd)
42
+ assert_match(/id > 2/, cnd)
43
+ end
44
+
45
+ def test_extract_ltoe_and_gtoe_postfixed_fields
46
+ cnd = User.conditioner :id_ltoe => '5', :id_gtoe => 2
47
+ assert_match(/id <= '5'/, cnd)
48
+ assert_match(/id >= 2/, cnd)
49
+ end
50
+
51
+ def test_begins_ends_contains_rules
52
+ cnd = User.conditioner :email_begins_with => "a", :email_ends_with => "b", :email_contains => "c"
53
+ assert_match(/email ILIKE 'a%'/, cnd)
54
+ assert_match(/email ILIKE '%b'/, cnd)
55
+ assert_match(/email ILIKE '%c%'/, cnd)
56
+ cnd = User.conditioner :email_begins_with => ""
57
+ assert_no_match(/email ILIKE/, cnd,'must not empty values')
58
+ end
59
+
60
+ def test_in_postfixed_field
61
+ cnd = User.conditioner :email_in => ['a', 'b', 'c']
62
+ assert_match(/email IN \('a','b','c'\)/, cnd)
37
63
  end
38
64
 
39
65
  def test_ilike
40
- cnd = User.conditioner :name=>'*nicola*'
41
- assert_match(/name ILIKE E'%nicola%'/, cnd)
42
- assert_no_match(/\*nicola\*/, cnd,'Rule must work only once!')
66
+ cnd = User.conditioner :name=> '*nicola*'
67
+ assert_match(/name ILIKE '%nicola%'/, cnd)
68
+ assert_no_match(/\*nicola\*/, cnd, 'Rule must work only once!')
43
69
  end
44
70
 
45
71
  def test_configurator
46
72
  cnd = User.conditioner :created_at_gt => '2010-01-01'
47
- assert_match(/created_at > E'2010-01-01'/, cnd)
73
+ assert_match(/created_at > '2010-01-01'/, cnd)
48
74
  end
75
+
76
+ def test_conditioner_without_model
77
+ cnd = Conditioner.create('users', :columns => ['id', 'email']).extract(:email => "nicola", :foo => "bar")
78
+ assert_equal(%Q["users"."email" = 'nicola'], cnd)
79
+ end
80
+
81
+ def test_conditioner_without_model_with_advanced_rules
82
+ cnd = Conditioner.create('users', :columns => ['id', 'email']).extract(:email => "*nicola*")
83
+ assert_match(/email ILIKE '%nicola%'/, cnd)
84
+ end
85
+
86
+ def test_conditioner_without_model_and_without_hardcoded_columns
87
+ cnd = Conditioner.create('users').extract(:email => "nicola", :foo => "bar")
88
+ assert_equal(%Q["users"."email" = 'nicola'], cnd)
89
+ end
90
+
49
91
  end
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: conditioner
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 23
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
8
  - 0
8
- - 3
9
- version: 0.0.3
9
+ - 4
10
+ version: 0.0.4
10
11
  platform: ruby
11
12
  authors:
12
13
  - niquola
@@ -14,7 +15,7 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-04-15 00:00:00 +04:00
18
+ date: 2010-06-18 00:00:00 +04:00
18
19
  default_executable:
19
20
  dependencies: []
20
21
 
@@ -36,6 +37,7 @@ files:
36
37
  - lib/conditioner.rb
37
38
  - lib/conditioner/condition.rb
38
39
  - lib/conditioner/active_record_mixin.rb
40
+ - lib/conditioner/fake_model.rb
39
41
  - lib/conditioner/configurator.rb
40
42
  - test/conditioner_test.rb
41
43
  - test/test_helper.rb
@@ -49,23 +51,27 @@ rdoc_options: []
49
51
  require_paths:
50
52
  - lib
51
53
  required_ruby_version: !ruby/object:Gem::Requirement
54
+ none: false
52
55
  requirements:
53
56
  - - ">="
54
57
  - !ruby/object:Gem::Version
58
+ hash: 3
55
59
  segments:
56
60
  - 0
57
61
  version: "0"
58
62
  required_rubygems_version: !ruby/object:Gem::Requirement
63
+ none: false
59
64
  requirements:
60
65
  - - ">="
61
66
  - !ruby/object:Gem::Version
67
+ hash: 3
62
68
  segments:
63
69
  - 0
64
70
  version: "0"
65
71
  requirements: []
66
72
 
67
73
  rubyforge_project:
68
- rubygems_version: 1.3.6
74
+ rubygems_version: 1.3.7
69
75
  signing_key:
70
76
  specification_version: 3
71
77
  summary: Simple conditions builder for active_record