conditioner 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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