querybuilder 0.5.9 → 0.7.0

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 (46) hide show
  1. data/History.txt +29 -25
  2. data/Manifest.txt +20 -9
  3. data/README.rdoc +73 -10
  4. data/Rakefile +62 -30
  5. data/lib/extconf.rb +3 -0
  6. data/lib/query_builder.rb +39 -898
  7. data/lib/query_builder/error.rb +7 -0
  8. data/lib/query_builder/info.rb +3 -0
  9. data/lib/query_builder/parser.rb +80 -0
  10. data/lib/query_builder/processor.rb +714 -0
  11. data/lib/query_builder/query.rb +273 -0
  12. data/lib/querybuilder_ext.c +1870 -0
  13. data/lib/querybuilder_ext.rl +418 -0
  14. data/lib/querybuilder_rb.rb +1686 -0
  15. data/lib/querybuilder_rb.rl +214 -0
  16. data/lib/querybuilder_syntax.rl +47 -0
  17. data/old_QueryBuilder.rb +946 -0
  18. data/querybuilder.gemspec +42 -15
  19. data/tasks/build.rake +20 -0
  20. data/test/dummy_test.rb +21 -0
  21. data/test/mock/custom_queries/test.yml +5 -4
  22. data/test/mock/dummy.rb +9 -0
  23. data/test/mock/dummy_processor.rb +160 -0
  24. data/test/mock/queries/bar.yml +1 -1
  25. data/test/mock/queries/foo.yml +2 -2
  26. data/test/mock/user_processor.rb +34 -0
  27. data/test/query_test.rb +38 -0
  28. data/test/querybuilder/basic.yml +91 -0
  29. data/test/{query_builder → querybuilder}/custom.yml +11 -11
  30. data/test/querybuilder/errors.yml +32 -0
  31. data/test/querybuilder/filters.yml +115 -0
  32. data/test/querybuilder/group.yml +7 -0
  33. data/test/querybuilder/joins.yml +37 -0
  34. data/test/querybuilder/mixed.yml +18 -0
  35. data/test/querybuilder/rubyless.yml +15 -0
  36. data/test/querybuilder_test.rb +111 -0
  37. data/test/test_helper.rb +8 -3
  38. metadata +66 -19
  39. data/test/mock/dummy_query.rb +0 -114
  40. data/test/mock/user_query.rb +0 -55
  41. data/test/query_builder/basic.yml +0 -60
  42. data/test/query_builder/errors.yml +0 -50
  43. data/test/query_builder/filters.yml +0 -43
  44. data/test/query_builder/joins.yml +0 -25
  45. data/test/query_builder/mixed.yml +0 -12
  46. data/test/query_builder_test.rb +0 -36
@@ -4,50 +4,50 @@ it_should_be_available:
4
4
  context:
5
5
  custom_query_group: test
6
6
  src: "abc"
7
- res: "\"SELECT a,34 AS number,c FROM test WHERE 3 AND 2 AND 1 ORDER BY a ASC\""
7
+ res: "%Q{SELECT a,34 AS number,c FROM test WHERE 3 AND 2 AND 1 ORDER BY a ASC}"
8
8
 
9
9
  it_should_be_customizable:
10
10
  context:
11
11
  custom_query_group: test
12
12
  src: "foo where name < 50"
13
- res: "\"SELECT foo FROM foot WHERE objects.name < 50 ORDER BY f DESC\""
13
+ res: "%Q{SELECT foo FROM objects WHERE objects.name < 50 ORDER BY f DESC}"
14
14
 
15
15
  it_should_be_customizable_with_select_attributes:
16
16
  context:
17
17
  custom_query_group: test
18
18
  src: "abc where number < 50"
19
- res: "\"SELECT a,34 AS number,c FROM test WHERE (34) < 50 AND 3 AND 2 AND 1 ORDER BY a ASC\""
19
+ res: "%Q{SELECT a,34 AS number,c FROM test WHERE (34) < 50 AND 3 AND 2 AND 1 ORDER BY a ASC}"
20
20
 
21
21
  it_should_not_find_queries_not_in_group:
22
22
  context:
23
23
  custom_query_group: test
24
24
  src: "bar"
25
- res: "unknown relation 'bar'"
25
+ res: "Unknown relation 'bar'."
26
26
 
27
27
  # test2 context (queries = [foo,bar])
28
28
  it_should_not_find_queries_not_in_file_named_group:
29
29
  context:
30
30
  custom_query_group: test2
31
31
  src: "abc"
32
- res: "unknown relation 'abc'"
32
+ res: "Unknown relation 'abc'."
33
33
 
34
34
  it_should_find_queries_in_group_list:
35
35
  context:
36
36
  custom_query_group: test2
37
37
  src: "bar"
38
- res: "\"SELECT bar FROM bart\""
38
+ res: "%Q{SELECT bar FROM bart}"
39
39
 
40
- it_should_use_the_first_table_as_main:
40
+ it_should_not_use_the_first_table_as_main:
41
41
  context:
42
42
  custom_query_group: test
43
- src: "two_table where x = '4' and name like 'B%'"
44
- res: "[\"SELECT x,IF(table_one.y,table_one.y,table_two.z) AS y,table_two.name FROM table_one,table_two WHERE (x) = ? AND (table_two.name) LIKE ?\", \"4\", \"B%\"]"
43
+ src: "two_table where x = '4' and name like 'b%'"
44
+ res: "%Q{SELECT x AS x,IF(table_one.y,table_one.y,table_two.z) AS y,table_two.name FROM table_one,table_two WHERE (x) = '4' AND table_one.name LIKE 'b%'}"
45
45
 
46
46
  it_should_use_main_table_as_main:
47
47
  context:
48
48
  custom_query_group: test
49
49
  src: "two_table_main where name = '4'"
50
- res: "[\"SELECT x FROM table_one,foo,table_two WHERE foo.name = ?\", \"4\"]"
50
+ res: "%Q{SELECT x FROM foo,table_one,table_two WHERE foo.name = '4'}"
51
51
 
52
52
  it_should_limit_the_entries:
53
53
  context:
@@ -59,4 +59,4 @@ it_should_paginate_the_entries:
59
59
  context:
60
60
  custom_query_group: test
61
61
  src: "abc limit 4 paginate foo"
62
- res: "[\"SELECT a,34 AS number,c FROM test WHERE 3 AND 2 AND 1 ORDER BY a ASC LIMIT 4 OFFSET ?\", ((foo.to_i > 0 ? foo.to_i : 1)-1)*4]"
62
+ res: "[%Q{SELECT a,34 AS number,c FROM test WHERE 3 AND 2 AND 1 ORDER BY a ASC LIMIT 4 OFFSET ?}, ((foo.to_i > 0 ? foo.to_i : 1)-1)*4]"
@@ -0,0 +1,32 @@
1
+ bad_relation:
2
+ src: "bolobolo"
3
+ res: "Unknown relation 'bolobolo'."
4
+
5
+ bad_relation_in_alternate_query:
6
+ src: "(bolobolo) or (letters in project)"
7
+ res: "Unknown relation 'bolobolo'."
8
+
9
+ order:
10
+ src: "objects in project order by bad asc"
11
+ res: "Unknown field 'bad'."
12
+
13
+ offset_without_limit:
14
+ src: "objects in project offset 3"
15
+ res: "Invalid offset (used without limit)."
16
+
17
+ legacy_many_clauses:
18
+ src: letters or foo
19
+ res: "Unknown relation 'foo'."
20
+
21
+ bad_equation:
22
+ src: "objects where event_at > 2006.04.01"
23
+ res: 'Syntax error near ".04.01".'
24
+
25
+ bad_plus_plus:
26
+ src: "objects where 1 + 3 + + 5 > event_at"
27
+ res: 'Syntax error near " + + 5 > event_at".'
28
+
29
+ or_clause_with_filter:
30
+ src: "recipients where name = 'foo' or objects"
31
+ sxp: '[:query, [:filter, [:relation, "recipients"], [:or, [:"=", [:field, "name"], [:string, "foo"]], [:field, "objects"]]]]'
32
+ res: "Unknown field 'objects'."
@@ -0,0 +1,115 @@
1
+ simple:
2
+ src: "objects where name = 'foo' in site"
3
+ sxp: '[:query, [:scope, [:filter, [:relation, "objects"], [:"=", [:field, "name"], [:string, "foo"]]], "site"]]'
4
+ res: "%Q{SELECT objects.* FROM objects WHERE objects.name = 'foo'}"
5
+
6
+ recipients_where_kpath:
7
+ src: "recipients where kpath like 'NRCC%'"
8
+ res: "[%Q{SELECT objects.* FROM links,objects WHERE objects.kpath LIKE 'NRCC%' AND objects.id = links.target_id AND links.relation_id = 4 AND links.source_id = ?}, id]"
9
+
10
+ hand_made_class_filter:
11
+ src: "recipients where kpath like 'NRCC%'"
12
+ res: "[%Q{SELECT objects.* FROM links,objects WHERE objects.kpath LIKE 'NRCC%' AND objects.id = links.target_id AND links.relation_id = 4 AND links.source_id = ?}, id]"
13
+
14
+ better_class_filter:
15
+ src: "recipients where class = 'Client'"
16
+ res: "[%Q{SELECT objects.* FROM links,objects WHERE objects.kpath LIKE ? AND objects.id = links.target_id AND links.relation_id = 4 AND links.source_id = ?}, \"NRCC%\", id]"
17
+
18
+ like_filter_with_scope:
19
+ src: "letters where name like 'a%' in site"
20
+ sxp: '[:query, [:scope, [:filter, [:relation, "letters"], [:like, [:field, "name"], [:string, "a%"]]], "site"]]'
21
+ res: "%Q{SELECT objects.* FROM objects WHERE objects.name LIKE 'a%' AND objects.kpath LIKE 'NNL%'}"
22
+
23
+ not_like_with_scope:
24
+ src: "letters where name not like 'a%' in site"
25
+ sxp: '[:query, [:scope, [:filter, [:relation, "letters"], [:not, [:like, [:field, "name"], [:string, "a%"]]]], "site"]]'
26
+ res: "%Q{SELECT objects.* FROM objects WHERE objects.name NOT LIKE 'a%' AND objects.kpath LIKE 'NNL%'}"
27
+
28
+ letters_group_by_name:
29
+ sxp: '[:query, [:group, [:relation, "letters"], [:field, "name"]]]'
30
+ res: "[%Q{SELECT objects.* FROM objects WHERE objects.kpath LIKE 'NNL%' AND objects.parent_id = ? GROUP BY objects.name}, id]"
31
+
32
+ recipients_group_by_name:
33
+ sxp: '[:query, [:group, [:relation, "recipients"], [:field, "name"]]]'
34
+ res: "[%Q{SELECT objects.* FROM links,objects WHERE objects.id = links.target_id AND links.relation_id = 4 AND links.source_id = ? GROUP BY objects.name}, id]"
35
+
36
+ custom_query_having:
37
+ context:
38
+ custom_query_group: test
39
+ src: "abc where number > 12"
40
+ res: "%Q{SELECT a,34 AS number,c FROM test WHERE (34) > 12 AND 3 AND 2 AND 1 ORDER BY a ASC}"
41
+
42
+ equation_in_filter:
43
+ src: "objects where event_at > REF_DATE + custom_a months"
44
+ sxp: '[:query, [:filter, [:relation, "objects"], [:>, [:field, "event_at"], [:+, [:field, "REF_DATE"], [:interval, [:field, "custom_a"], "month"]]]]]'
45
+ res: "[%Q{SELECT objects.* FROM objects WHERE objects.event_at > now() + INTERVAL objects.custom_a MONTH AND objects.parent_id = ?}, id]"
46
+
47
+ equation_in_filter_using_gt:
48
+ src: "objects where event_at gt REF_DATE + custom_a months"
49
+ sxp: '[:query, [:filter, [:relation, "objects"], [:gt, [:field, "event_at"], [:+, [:field, "REF_DATE"], [:interval, [:field, "custom_a"], "month"]]]]]'
50
+ res: "[%Q{SELECT objects.* FROM objects WHERE objects.event_at > now() + INTERVAL objects.custom_a MONTH AND objects.parent_id = ?}, id]"
51
+
52
+ equation_in_filter_using_ge:
53
+ src: "objects where event_at ge REF_DATE + custom_a months"
54
+ sxp: '[:query, [:filter, [:relation, "objects"], [:ge, [:field, "event_at"], [:+, [:field, "REF_DATE"], [:interval, [:field, "custom_a"], "month"]]]]]'
55
+ res: "[%Q{SELECT objects.* FROM objects WHERE objects.event_at >= now() + INTERVAL objects.custom_a MONTH AND objects.parent_id = ?}, id]"
56
+
57
+ equation_in_filter_using_eq:
58
+ src: "objects where event_at eq REF_DATE + custom_a months"
59
+ sxp: '[:query, [:filter, [:relation, "objects"], [:eq, [:field, "event_at"], [:+, [:field, "REF_DATE"], [:interval, [:field, "custom_a"], "month"]]]]]'
60
+ res: "[%Q{SELECT objects.* FROM objects WHERE objects.event_at = now() + INTERVAL objects.custom_a MONTH AND objects.parent_id = ?}, id]"
61
+
62
+ equation_in_filter_using_le:
63
+ src: "objects where event_at le REF_DATE + custom_a months"
64
+ sxp: '[:query, [:filter, [:relation, "objects"], [:le, [:field, "event_at"], [:+, [:field, "REF_DATE"], [:interval, [:field, "custom_a"], "month"]]]]]'
65
+ res: "[%Q{SELECT objects.* FROM objects WHERE objects.event_at <= now() + INTERVAL objects.custom_a MONTH AND objects.parent_id = ?}, id]"
66
+
67
+ equation_in_filter_using_lt:
68
+ src: "objects where event_at lt REF_DATE + custom_a months"
69
+ sxp: '[:query, [:filter, [:relation, "objects"], [:lt, [:field, "event_at"], [:+, [:field, "REF_DATE"], [:interval, [:field, "custom_a"], "month"]]]]]'
70
+ res: "[%Q{SELECT objects.* FROM objects WHERE objects.event_at < now() + INTERVAL objects.custom_a MONTH AND objects.parent_id = ?}, id]"
71
+
72
+ equation_in_filter_using_ne:
73
+ src: "objects where event_at ne REF_DATE + custom_a months"
74
+ sxp: '[:query, [:filter, [:relation, "objects"], [:ne, [:field, "event_at"], [:+, [:field, "REF_DATE"], [:interval, [:field, "custom_a"], "month"]]]]]'
75
+ res: "[%Q{SELECT objects.* FROM objects WHERE objects.event_at <> now() + INTERVAL objects.custom_a MONTH AND objects.parent_id = ?}, id]"
76
+
77
+
78
+ equation_with_date_interval:
79
+ src: "objects where event_at > '2006-04-01' + 6 week"
80
+ sxp: '[:query, [:filter, [:relation, "objects"], [:>, [:field, "event_at"], [:+, [:string, "2006-04-01"], [:interval, [:integer, "6"], "week"]]]]]'
81
+ res: "[%Q{SELECT objects.* FROM objects WHERE objects.event_at > '2006-04-01' + INTERVAL 6 WEEK AND objects.parent_id = ?}, id]"
82
+
83
+ equation_and_or_par:
84
+ src: "objects where event_at > '2006-04-01' or name like 'foo%'"
85
+ sxp: '[:query, [:filter, [:relation, "objects"], [:or, [:>, [:field, "event_at"], [:string, "2006-04-01"]], [:like, [:field, "name"], [:string, "foo%"]]]]]'
86
+ res: "[%Q{SELECT objects.* FROM objects WHERE (objects.event_at > '2006-04-01' OR objects.name LIKE 'foo%') AND objects.parent_id = ?}, id]"
87
+
88
+ equation_par:
89
+ src: "objects where (1 > 2 or 2 > 3) and 4 = 5 "
90
+ sxp: '[:query, [:filter, [:relation, "objects"], [:and, [:par, [:or, [:>, [:integer, "1"], [:integer, "2"]], [:>, [:integer, "2"], [:integer, "3"]]]], [:"=", [:integer, "4"], [:integer, "5"]]]]]'
91
+ # res: "[%Q{SELECT objects.* FROM objects WHERE objects.parent_id = ? AND (1 > 2 OR 2 > 3) AND 4 = 5}, id]"
92
+
93
+ is_not_null:
94
+ src: "objects where name is not null"
95
+ sxp: '[:query, [:filter, [:relation, "objects"], [:is, [:field, "name"], [:raw, "not null"]]]]'
96
+ res: "[%Q{SELECT objects.* FROM objects WHERE objects.name IS NOT NULL AND objects.parent_id = ?}, id]"
97
+
98
+ is_null:
99
+ src: "objects where name is null"
100
+ sxp: '[:query, [:filter, [:relation, "objects"], [:is, [:field, "name"], [:raw, "null"]]]]'
101
+ res: "[%Q{SELECT objects.* FROM objects WHERE objects.name IS NULL AND objects.parent_id = ?}, id]"
102
+
103
+ match:
104
+ src: "objects where fulltext match 'one'"
105
+ sxp: '[:query, [:filter, [:relation, "objects"], [:match, [:field, "fulltext"], [:string, "one"]]]]'
106
+
107
+ functions:
108
+ src: "objects where event_at.year = REF_DATE.year"
109
+ sxp: '[:query, [:filter, [:relation, "objects"], [:"=", [:function, [:field, "event_at"], [:method, "year"]], [:function, [:field, "REF_DATE"], [:method, "year"]]]]]'
110
+ res: "[%Q{SELECT objects.* FROM objects WHERE strftime('%Y',objects.event_at) = strftime('%Y',now()) AND objects.parent_id = ?}, id]"
111
+
112
+ filter_empty_literal:
113
+ src: "objects where \"\" = ''"
114
+ sxp: '[:query, [:filter, [:relation, "objects"], [:"=", [:dstring, ""], [:string, ""]]]]'
115
+ sql: "SELECT objects.* FROM objects WHERE '' = '' AND objects.parent_id = 123"
@@ -0,0 +1,7 @@
1
+ group_by_function:
2
+ src: "objects in site group by event_at.year"
3
+ res: "%Q{SELECT objects.* FROM objects GROUP BY strftime('%Y',objects.event_at)}"
4
+
5
+ group_and_order:
6
+ src: "objects in site group by event_at.year order by event_at asc"
7
+ res: "%Q{SELECT objects.* FROM objects GROUP BY strftime('%Y',objects.event_at) ORDER BY objects.event_at ASC}"
@@ -0,0 +1,37 @@
1
+
2
+ icons_from_recipients:
3
+ sxp: '[:query, [:from, [:relation, "icons"], [:relation, "recipients"]]]'
4
+ res: "[%Q{SELECT objects.* FROM links,links AS li1,objects,objects AS ob1 WHERE objects.id = li1.source_id AND li1.relation_id = 5 AND li1.target_id = ob1.id AND ob1.id = links.target_id AND links.relation_id = 4 AND links.source_id = ? GROUP BY objects.id}, id]"
5
+
6
+ icons_from_recipients_from_letters:
7
+ sxp: '[:query, [:from, [:from, [:relation, "icons"], [:relation, "recipients"]], [:relation, "letters"]]]'
8
+
9
+ letters_from_recipients:
10
+ res: "[%Q{SELECT objects.* FROM links,objects,objects AS ob1 WHERE objects.kpath LIKE 'NNL%' AND objects.parent_id = ob1.id AND ob1.id = links.target_id AND links.relation_id = 4 AND links.source_id = ? GROUP BY objects.id}, id]"
11
+
12
+ objects_from_recipients:
13
+ res: "[%Q{SELECT objects.* FROM links,objects,objects AS ob1 WHERE objects.parent_id = ob1.id AND ob1.id = links.target_id AND links.relation_id = 4 AND links.source_id = ? GROUP BY objects.id}, id]"
14
+
15
+ parent_from_parent:
16
+ sxp: '[:query, [:from, [:relation, "parent"], [:relation, "parent"]]]'
17
+ res: "[%Q{SELECT objects.* FROM objects,objects AS ob1 WHERE objects.id = ob1.parent_id AND ob1.id = ? GROUP BY objects.id}, parent_id]"
18
+
19
+ children_from_objects_in_project:
20
+ res: "[%Q{SELECT objects.* FROM objects,objects AS ob1 WHERE objects.parent_id = ob1.id AND ob1.project_id = ? GROUP BY objects.id}, project_id]"
21
+
22
+ tags:
23
+ sxp: '[:query, [:relation, "tags"]]'
24
+ res: "%Q{SELECT objects.* FROM objects INNER JOIN tags ON objects.id = tags.node_id}"
25
+
26
+ complex_from_with_scopes:
27
+ src: "letters where name = 'foo' in project from letters in section"
28
+ sxp: '[:query, [:from, [:scope, [:filter, [:relation, "letters"], [:"=", [:field, "name"], [:string, "foo"]]], "project"], [:scope, [:relation, "letters"], "section"]]]'
29
+
30
+ letters_in_project_from_letters:
31
+ sxp: '[:query, [:from, [:scope, [:relation, "letters"], "project"], [:relation, "letters"]]]'
32
+ res: "[%Q{SELECT objects.* FROM objects,objects AS ob1 WHERE objects.kpath LIKE 'NNL%' AND objects.project_id = ob1.id AND ob1.kpath LIKE 'NNL%' AND ob1.parent_id = ? GROUP BY objects.id}, id]"
33
+
34
+ letters_in_project_from_letters_group_by:
35
+ src: "letters in project from letters group by name,id"
36
+ sxp: '[:query, [:group, [:from, [:scope, [:relation, "letters"], "project"], [:relation, "letters"]], [:field, "name"], [:field, "id"]]]'
37
+ res: "[%Q{SELECT objects.* FROM objects,objects AS ob1 WHERE objects.kpath LIKE 'NNL%' AND objects.project_id = ob1.id AND ob1.kpath LIKE 'NNL%' AND ob1.parent_id = ? GROUP BY objects.name, objects.id}, id]"
@@ -0,0 +1,18 @@
1
+ users_from_objects:
2
+ sxp: '[:query, [:from, [:relation, "users"], [:relation, "objects"]]]'
3
+ res: "TestUser: [%Q{SELECT users.* FROM objects AS ob1,users WHERE users.node_id = ob1.id AND ob1.parent_id = ? GROUP BY users.id ORDER BY users.name ASC, users.first_name ASC}, id]"
4
+
5
+ users_where_name_from_objects:
6
+ src: "users where name eq 'bob' from objects"
7
+ res: "TestUser: [%Q{SELECT users.* FROM objects AS ob1,users WHERE users.name = 'bob' AND users.node_id = ob1.id AND ob1.parent_id = ? GROUP BY users.id ORDER BY users.name ASC, users.first_name ASC}, id]"
8
+
9
+ objects_from_users_from_objects:
10
+ src: "objects from users where name = 'foo' from objects where event_at > REF_DATE order by event_at asc"
11
+ res: "[%Q{SELECT objects.* FROM objects,objects AS ob1,users AS us1 WHERE objects.id = us1.node_id AND us1.name = 'foo' AND us1.node_id = ob1.id AND ob1.event_at > now() AND ob1.parent_id = ? GROUP BY objects.id ORDER BY objects.event_at ASC}, id]"
12
+
13
+ users:
14
+ res: "TestUser: [%Q{SELECT users.* FROM users WHERE users.node_id = ? ORDER BY users.name ASC, users.first_name ASC}, id]"
15
+
16
+ users_with_filter:
17
+ src: "users where name = 'foo'"
18
+ res: "TestUser: [%Q{SELECT users.* FROM users WHERE users.name = 'foo' AND users.node_id = ? ORDER BY users.name ASC, users.first_name ASC}, id]"
@@ -0,0 +1,15 @@
1
+ parsing:
2
+ src: 'objects where name like "#{name}%" or event_at > #{params[:blow]} or name = #{this.is.ruby("with more #{stuff}")}'
3
+ sxp: '[:query, [:filter, [:relation, "objects"], [:or, [:or, [:like, [:field, "name"], [:dstring, "\#{name}%"]], [:>, [:field, "event_at"], [:rubyless, "params[:blow]"]]], [:"=", [:field, "name"], [:rubyless, "this.is.ruby(\"with more \#{stuff}\")"]]]]]'
4
+
5
+ dstring_eval:
6
+ src: 'objects where name like "#{params[:name]}%"'
7
+ res: '[%Q{SELECT objects.* FROM objects WHERE objects.name LIKE ? AND objects.parent_id = ?}, "#{get_params[:name]}%", id]'
8
+
9
+ eval:
10
+ src: 'objects where name = #{params[:name]}'
11
+ res: '[%Q{SELECT objects.* FROM objects WHERE objects.name = ? AND objects.parent_id = ?}, get_params[:name], id]'
12
+
13
+ date_function:
14
+ src: 'objects where name = #{params[:name]}.year'
15
+ res: "/objects.name = strftime\('%Y',\?\)/"
@@ -0,0 +1,111 @@
1
+ require 'test_helper'
2
+ require 'benchmark'
3
+
4
+ class StringHash
5
+ end
6
+
7
+ class DummyQueryBuilder < Test::Unit::TestCase
8
+ yamltest
9
+ include RubyLess::SafeClass
10
+ safe_method :params => {:class => StringHash, :method => 'get_params'}
11
+ safe_method :id => Number, :parent_id => Number, :project_id => Number
12
+
13
+ safe_method_for StringHash, [:[], Symbol] => String
14
+ safe_method_for StringHash, [:[], String] => String
15
+
16
+ def id; 123; end
17
+ def parent_id; 333; end
18
+ def project_id; 9999; end
19
+ def connection; self; end
20
+
21
+ context 'A query processor' do
22
+ subject do
23
+ DummyProcessor
24
+ end
25
+
26
+ should 'raise a QueryBuilder::SyntaxError on syntax errors' do
27
+ assert_raise(QueryBuilder::SyntaxError) do
28
+ subject.new('this is a bad source')
29
+ end
30
+ end
31
+
32
+ should 'return a query object on query' do
33
+ assert_kind_of QueryBuilder::Query, subject.new('objects').query
34
+ end
35
+ end
36
+
37
+ context 'Including QueryBuilder' do
38
+ context 'in a class' do
39
+ subject do
40
+ Class.new do
41
+ include QueryBuilder
42
+ end
43
+ end
44
+
45
+ should 'receive class method query_compiler' do
46
+ assert_nothing_raised do
47
+ subject.query_compiler = 'Foo'
48
+ assert_equal 'Foo', subject.query_compiler
49
+ end
50
+ end
51
+
52
+ should 'receive class method query_compiler on sub_class' do
53
+ sub_class = Class.new(subject)
54
+ subject.query_compiler = 'Foo'
55
+ assert_equal 'Foo', subject.query_compiler
56
+
57
+ sub_class.query_compiler = 'Bar'
58
+ assert_equal 'Bar', sub_class.query_compiler
59
+ assert_equal 'Foo', subject.query_compiler
60
+ end
61
+ end
62
+ end # Including QueryBuilder
63
+
64
+
65
+ def yt_parse(key, source, opts)
66
+ opts = {:rubyless_helper => self}.merge(Hash[*(opts.map{|k,v| [k.to_sym, v]}.flatten)])
67
+
68
+ case key
69
+ when 'res'
70
+
71
+ begin
72
+ query = DummyProcessor.new(source, opts).query
73
+ (query.main_class != DummyClass ? "#{query.main_class}: " : '') + query.to_s
74
+ rescue QueryBuilder::Error => err
75
+ err.message
76
+ end
77
+ when 'sxp'
78
+ # s-expression
79
+ QueryBuilder::Parser.parse(source).inspect
80
+ when 'sql'
81
+ DummyProcessor.new(source, opts).query.sql(binding)
82
+ when 'count'
83
+ DummyProcessor.new(source, opts).query.to_s(:count)
84
+ when 'count_sql'
85
+ DummyProcessor.new(source, opts).query.sql(binding, :count)
86
+ else
87
+ "parse not implemented for '#{key}' in querybuilder_test.rb"
88
+ end
89
+ end
90
+ =begin
91
+ def test_benchmark
92
+ Benchmark.bmbm do |x|
93
+ ['basic', 'errors', 'filters'].each do |file_name|
94
+ x.report("#{file_name}:") do
95
+ @@test_strings[file_name].each do |name, keys|
96
+ src = keys['src'] || name.gsub('_', ' ')
97
+ 100.times do
98
+ begin
99
+ QueryBuilder::Parser.parse(src)
100
+ rescue QueryBuilder::Error => err
101
+ #
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
109
+ =end
110
+ yt_make
111
+ end
data/test/test_helper.rb CHANGED
@@ -1,7 +1,12 @@
1
+ require 'pathname'
2
+ $LOAD_PATH.unshift((Pathname(__FILE__).dirname + '..' + 'lib').expand_path)
1
3
  require 'stringio'
2
4
  require 'test/unit'
3
- require File.dirname(__FILE__) + '/../lib/QueryBuilder'
4
- require File.dirname(__FILE__) + '/mock/dummy_query'
5
- require File.dirname(__FILE__) + '/mock/user_query'
6
5
  require 'rubygems'
6
+ require 'querybuilder'
7
+ require 'shoulda'
7
8
  require 'yamltest'
9
+
10
+ require 'mock/dummy_processor'
11
+ require 'mock/user_processor'
12
+ require 'mock/dummy'
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 5
8
- - 9
9
- version: 0.5.9
7
+ - 7
8
+ - 0
9
+ version: 0.7.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Gaspard Bucher
@@ -14,11 +14,11 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-08-30 00:00:00 +02:00
17
+ date: 2010-05-27 00:00:00 +02:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
- name: yamltest
21
+ name: rubyless
22
22
  prerelease: false
23
23
  requirement: &id001 !ruby/object:Gem::Requirement
24
24
  requirements:
@@ -29,8 +29,34 @@ dependencies:
29
29
  - 5
30
30
  - 0
31
31
  version: 0.5.0
32
- type: :development
32
+ type: :runtime
33
33
  version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: shoulda
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ version: "0"
44
+ type: :development
45
+ version_requirements: *id002
46
+ - !ruby/object:Gem::Dependency
47
+ name: yamltest
48
+ prerelease: false
49
+ requirement: &id003 !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ segments:
54
+ - 0
55
+ - 5
56
+ - 0
57
+ version: 0.5.0
58
+ type: :development
59
+ version_requirements: *id003
34
60
  description: |-
35
61
  QueryBuilder is an interpreter for the "pseudo sql" language. This language
36
62
  can be used for two purposes:
@@ -50,24 +76,42 @@ files:
50
76
  - Manifest.txt
51
77
  - README.rdoc
52
78
  - Rakefile
79
+ - lib/extconf.rb
53
80
  - lib/query_builder.rb
81
+ - lib/query_builder/error.rb
82
+ - lib/query_builder/info.rb
83
+ - lib/query_builder/parser.rb
84
+ - lib/query_builder/processor.rb
85
+ - lib/query_builder/query.rb
54
86
  - lib/querybuilder.rb
87
+ - lib/querybuilder_ext.c
88
+ - lib/querybuilder_ext.rl
89
+ - lib/querybuilder_rb.rb
90
+ - lib/querybuilder_rb.rl
91
+ - lib/querybuilder_syntax.rl
92
+ - old_QueryBuilder.rb
55
93
  - querybuilder.gemspec
56
94
  - script/console
57
95
  - script/destroy
58
96
  - script/generate
97
+ - tasks/build.rake
98
+ - test/dummy_test.rb
59
99
  - test/mock/custom_queries/test.yml
60
- - test/mock/dummy_query.rb
100
+ - test/mock/dummy.rb
101
+ - test/mock/dummy_processor.rb
61
102
  - test/mock/queries/bar.yml
62
103
  - test/mock/queries/foo.yml
63
- - test/mock/user_query.rb
64
- - test/query_builder/basic.yml
65
- - test/query_builder/custom.yml
66
- - test/query_builder/errors.yml
67
- - test/query_builder/filters.yml
68
- - test/query_builder/joins.yml
69
- - test/query_builder/mixed.yml
70
- - test/query_builder_test.rb
104
+ - test/mock/user_processor.rb
105
+ - test/query_test.rb
106
+ - test/querybuilder/basic.yml
107
+ - test/querybuilder/custom.yml
108
+ - test/querybuilder/errors.yml
109
+ - test/querybuilder/filters.yml
110
+ - test/querybuilder/group.yml
111
+ - test/querybuilder/joins.yml
112
+ - test/querybuilder/mixed.yml
113
+ - test/querybuilder/rubyless.yml
114
+ - test/querybuilder_test.rb
71
115
  - test/test_helper.rb
72
116
  has_rdoc: true
73
117
  homepage: http://zenadmin.org/524
@@ -98,9 +142,12 @@ rubyforge_project:
98
142
  rubygems_version: 1.3.6
99
143
  signing_key:
100
144
  specification_version: 3
101
- summary: QueryBuilder is an interpreter for the "pseudo sql" language
145
+ summary: QueryBuilder is an interpreter for the "pseudo sql" language.
102
146
  test_files:
103
- - test/mock/dummy_query.rb
104
- - test/mock/user_query.rb
105
- - test/query_builder_test.rb
147
+ - test/dummy_test.rb
148
+ - test/mock/dummy.rb
149
+ - test/mock/dummy_processor.rb
150
+ - test/mock/user_processor.rb
151
+ - test/query_test.rb
152
+ - test/querybuilder_test.rb
106
153
  - test/test_helper.rb