datatable 0.1.0alpha2
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/.bundle/config +3 -0
- data/.gitignore +7 -0
- data/.rspec +1 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +83 -0
- data/MIT-LICENSE +20 -0
- data/README.md +135 -0
- data/Rakefile +27 -0
- data/TODO +71 -0
- data/datatable.gemspec +20 -0
- data/example_app/.DS_Store +0 -0
- data/example_app/.gitignore +6 -0
- data/example_app/.rspec +1 -0
- data/example_app/Gemfile +35 -0
- data/example_app/Gemfile.lock +126 -0
- data/example_app/Rakefile +7 -0
- data/example_app/app/controllers/application_controller.rb +3 -0
- data/example_app/app/controllers/orders_controller.rb +13 -0
- data/example_app/app/datatables/orders_index.rb +31 -0
- data/example_app/app/helpers/application_helper.rb +2 -0
- data/example_app/app/models/customer.rb +4 -0
- data/example_app/app/models/item.rb +4 -0
- data/example_app/app/models/order.rb +5 -0
- data/example_app/app/models/order_item.rb +4 -0
- data/example_app/app/models/sales_rep.rb +3 -0
- data/example_app/app/views/layouts/application.html.erb +12 -0
- data/example_app/app/views/orders/index.html.erb +14 -0
- data/example_app/config/application.rb +41 -0
- data/example_app/config/boot.rb +6 -0
- data/example_app/config/database.yml.mysql +20 -0
- data/example_app/config/database.yml.pg +20 -0
- data/example_app/config/environment.rb +5 -0
- data/example_app/config/environments/development.rb +28 -0
- data/example_app/config/environments/production.rb +49 -0
- data/example_app/config/environments/test.rb +35 -0
- data/example_app/config/initializers/backtrace_silencers.rb +7 -0
- data/example_app/config/initializers/datatable.rb +6 -0
- data/example_app/config/initializers/inflections.rb +10 -0
- data/example_app/config/initializers/mime_types.rb +5 -0
- data/example_app/config/initializers/secret_token.rb +9 -0
- data/example_app/config/initializers/session_store.rb +8 -0
- data/example_app/config/locales/en.yml +5 -0
- data/example_app/config/routes.rb +6 -0
- data/example_app/config.ru +4 -0
- data/example_app/db/migrate/20110429185712_create_customers.rb +15 -0
- data/example_app/db/migrate/20110429185742_create_sales_reps.rb +14 -0
- data/example_app/db/migrate/20110429185807_create_items.rb +15 -0
- data/example_app/db/migrate/20110429185913_create_orders.rb +15 -0
- data/example_app/db/migrate/20110429190005_create_order_items.rb +14 -0
- data/example_app/db/schema.rb +53 -0
- data/example_app/db/seeds.rb +49 -0
- data/example_app/lib/tasks/.gitkeep +0 -0
- data/example_app/lib/tasks/setup.rake +12 -0
- data/example_app/public/404.html +26 -0
- data/example_app/public/422.html +26 -0
- data/example_app/public/500.html +26 -0
- data/example_app/public/datatable/css/demo_page.css +99 -0
- data/example_app/public/datatable/css/demo_table.css +539 -0
- data/example_app/public/datatable/css/demo_table_jui.css +521 -0
- data/example_app/public/datatable/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/example_app/public/datatable/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/example_app/public/datatable/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/example_app/public/datatable/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/example_app/public/datatable/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/example_app/public/datatable/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/example_app/public/datatable/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/example_app/public/datatable/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/example_app/public/datatable/css/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/example_app/public/datatable/css/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/example_app/public/datatable/css/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/example_app/public/datatable/css/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/example_app/public/datatable/css/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/example_app/public/datatable/css/smoothness/jquery-ui-1.8.14.custom.css +568 -0
- data/example_app/public/datatable/images/back_disabled.jpg +0 -0
- data/example_app/public/datatable/images/back_enabled.jpg +0 -0
- data/example_app/public/datatable/images/favicon.ico +0 -0
- data/example_app/public/datatable/images/forward_disabled.jpg +0 -0
- data/example_app/public/datatable/images/forward_enabled.jpg +0 -0
- data/example_app/public/datatable/images/sort_asc.png +0 -0
- data/example_app/public/datatable/images/sort_asc_disabled.png +0 -0
- data/example_app/public/datatable/images/sort_both.png +0 -0
- data/example_app/public/datatable/images/sort_desc.png +0 -0
- data/example_app/public/datatable/images/sort_desc_disabled.png +0 -0
- data/example_app/public/datatable/js/jquery-ui-1.8.14.custom.min.js +789 -0
- data/example_app/public/datatable/js/jquery.dataTables.js +7347 -0
- data/example_app/public/datatable/js/jquery.dataTables.min.js +151 -0
- data/example_app/public/favicon.ico +0 -0
- data/example_app/public/flash/copy_cvs_xls.swf +0 -0
- data/example_app/public/flash/copy_cvs_xls_pdf.swf +0 -0
- data/example_app/public/images/rails.png +0 -0
- data/example_app/public/javascripts/application.js +2 -0
- data/example_app/public/javascripts/jquery.js +8936 -0
- data/example_app/public/javascripts/jquery.min.js +18 -0
- data/example_app/public/javascripts/jquery_ujs.js +316 -0
- data/example_app/public/robots.txt +5 -0
- data/example_app/public/stylesheets/.gitkeep +0 -0
- data/example_app/script/rails +6 -0
- data/example_app/spec/datatables/active_record_dsl_spec.rb +59 -0
- data/example_app/spec/datatables/active_record_link_to_spec.rb +22 -0
- data/example_app/spec/datatables/active_record_pagination_spec.rb +94 -0
- data/example_app/spec/datatables/active_record_table_operations_spec.rb +180 -0
- data/example_app/spec/datatables/config_spec.rb +10 -0
- data/example_app/spec/datatables/query_params_spec.rb +73 -0
- data/example_app/spec/datatables/sql_default_spec.rb +22 -0
- data/example_app/spec/datatables/sql_pagination_spec.rb +177 -0
- data/example_app/spec/datatables/sql_search_cast_spec.rb +6 -0
- data/example_app/spec/datatables/sql_search_global_spec.rb +107 -0
- data/example_app/spec/datatables/sql_search_individual_spec.rb +113 -0
- data/example_app/spec/datatables/sql_search_where_spec.rb +87 -0
- data/example_app/spec/datatables/sql_sorting_spec.rb +80 -0
- data/example_app/spec/datatables/sql_variables_spec.rb +104 -0
- data/example_app/spec/factories/customer_factory.rb +4 -0
- data/example_app/spec/factories/item_factory.rb +2 -0
- data/example_app/spec/factories/order_factory.rb +7 -0
- data/example_app/spec/factories/order_item_factory.rb +2 -0
- data/example_app/spec/factories/sales_rep_factory.rb +4 -0
- data/example_app/spec/helpers/aocolumn_spec.rb +239 -0
- data/example_app/spec/helpers/data_table_helper_spec.rb +148 -0
- data/example_app/spec/helpers/headings_spec.rb +71 -0
- data/example_app/spec/spec_helper.rb +29 -0
- data/generators.txt +6 -0
- data/images/datatable_screenshot.png +0 -0
- data/lib/datatable/active_record_dsl.rb +49 -0
- data/lib/datatable/errors.rb +5 -0
- data/lib/datatable/helper.rb +199 -0
- data/lib/datatable/railtie.rb +17 -0
- data/lib/datatable/version.rb +4 -0
- data/lib/datatable.rb +341 -0
- data/lib/generators/datatable/install_generator.rb +58 -0
- data/lib/generators/datatable/new_generator.rb +46 -0
- data/lib/generators/templates/datatable.rb +33 -0
- data/lib/generators/templates/datatable_initializer.rb +6 -0
- data/vendor/datatable/Readme.txt +11 -0
- data/vendor/datatable/extras/TableTools/media/css/TableTools.css +264 -0
- data/vendor/datatable/extras/TableTools/media/css/TableTools_JUI.css +182 -0
- data/vendor/datatable/extras/TableTools/media/images/background.png +0 -0
- data/vendor/datatable/extras/TableTools/media/images/collection.png +0 -0
- data/vendor/datatable/extras/TableTools/media/images/collection_hover.png +0 -0
- data/vendor/datatable/extras/TableTools/media/images/copy.png +0 -0
- data/vendor/datatable/extras/TableTools/media/images/copy_hover.png +0 -0
- data/vendor/datatable/extras/TableTools/media/images/csv.png +0 -0
- data/vendor/datatable/extras/TableTools/media/images/csv_hover.png +0 -0
- data/vendor/datatable/extras/TableTools/media/images/pdf.png +0 -0
- data/vendor/datatable/extras/TableTools/media/images/pdf_hover.png +0 -0
- data/vendor/datatable/extras/TableTools/media/images/print.png +0 -0
- data/vendor/datatable/extras/TableTools/media/images/print_hover.png +0 -0
- data/vendor/datatable/extras/TableTools/media/images/xls.png +0 -0
- data/vendor/datatable/extras/TableTools/media/images/xls_hover.png +0 -0
- data/vendor/datatable/extras/TableTools/media/js/TableTools.js +2410 -0
- data/vendor/datatable/extras/TableTools/media/js/TableTools.min.js +78 -0
- data/vendor/datatable/extras/TableTools/media/js/TableTools.min.js.gz +0 -0
- data/vendor/datatable/extras/TableTools/media/js/ZeroClipboard.js +365 -0
- data/vendor/datatable/extras/TableTools/media/swf/copy_cvs_xls.swf +0 -0
- data/vendor/datatable/extras/TableTools/media/swf/copy_cvs_xls_pdf.swf +0 -0
- data/vendor/datatable/license-bsd.txt +10 -0
- data/vendor/datatable/license-gpl2.txt +339 -0
- data/vendor/datatable/media/css/demo_page.css +99 -0
- data/vendor/datatable/media/css/demo_table.css +539 -0
- data/vendor/datatable/media/css/demo_table_jui.css +521 -0
- data/vendor/datatable/media/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/vendor/datatable/media/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/vendor/datatable/media/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/vendor/datatable/media/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/vendor/datatable/media/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/vendor/datatable/media/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/vendor/datatable/media/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/vendor/datatable/media/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/vendor/datatable/media/css/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/vendor/datatable/media/css/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/vendor/datatable/media/css/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/vendor/datatable/media/css/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/vendor/datatable/media/css/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/vendor/datatable/media/css/smoothness/jquery-ui-1.8.14.custom.css +568 -0
- data/vendor/datatable/media/images/back_disabled.jpg +0 -0
- data/vendor/datatable/media/images/back_enabled.jpg +0 -0
- data/vendor/datatable/media/images/favicon.ico +0 -0
- data/vendor/datatable/media/images/forward_disabled.jpg +0 -0
- data/vendor/datatable/media/images/forward_enabled.jpg +0 -0
- data/vendor/datatable/media/images/sort_asc.png +0 -0
- data/vendor/datatable/media/images/sort_asc_disabled.png +0 -0
- data/vendor/datatable/media/images/sort_both.png +0 -0
- data/vendor/datatable/media/images/sort_desc.png +0 -0
- data/vendor/datatable/media/images/sort_desc_disabled.png +0 -0
- data/vendor/datatable/media/js/jquery-ui-1.8.14.custom.min.js +789 -0
- data/vendor/datatable/media/js/jquery.dataTables.js +7347 -0
- data/vendor/datatable/media/js/jquery.dataTables.min.js +151 -0
- metadata +270 -0
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'SQL defined datatable supports global search' do
|
4
|
+
before do
|
5
|
+
Object.send(:remove_const, :T) rescue nil
|
6
|
+
class T < Datatable::Base
|
7
|
+
sql <<-SQL
|
8
|
+
SELECT
|
9
|
+
id,
|
10
|
+
order_number,
|
11
|
+
memo
|
12
|
+
FROM
|
13
|
+
orders
|
14
|
+
SQL
|
15
|
+
columns(
|
16
|
+
{'orders.id' => {:type => :integer}},
|
17
|
+
{'orders.order_number' => {:type => :integer}},
|
18
|
+
{'orders.memo' => {:type => :string }}
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
@params = {
|
23
|
+
"iColumns" => 4,
|
24
|
+
"bSearchable_0" => true,
|
25
|
+
"bSearchable_1" => true,
|
26
|
+
"bSearchable_2" => true,
|
27
|
+
"bSortable_0" => true,
|
28
|
+
"bSortable_1" => true,
|
29
|
+
"bSortable_2" => true,
|
30
|
+
"sSearch_0" => nil,
|
31
|
+
"sSearch_1" => nil,
|
32
|
+
"sSearch_2" => nil,
|
33
|
+
"sSearch" => nil }
|
34
|
+
|
35
|
+
Order.delete_all
|
36
|
+
@orders = [*0..20].map do
|
37
|
+
Factory(:order, :order_number => (42 + rand(2)), :memo => rand(2).even? ? 'hello' : 'goodbye')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'string columns' do
|
42
|
+
@params['sSearch'] = 'ello'
|
43
|
+
expected = Order.where("memo like '%ello%'").map{|row| row.id.to_s }.sort
|
44
|
+
actual = T.query(@params).to_json['aaData'].map{|row| row[0]}.sort
|
45
|
+
actual.should == expected
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'integer columns' do
|
49
|
+
order_id = Order.all[rand(Order.count)].id.to_s
|
50
|
+
@params['sSearch'] = order_id
|
51
|
+
T.query(@params).to_json['aaData'][0][0].should == order_id
|
52
|
+
T.query(@params).to_json['aaData'].length.should == 1
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'integer columns do not return results unless a number appears in the search string' do
|
56
|
+
order = Order.first
|
57
|
+
order.order_number = 0
|
58
|
+
order.save
|
59
|
+
@params['sSearch'] = "0"
|
60
|
+
T.query(@params).to_json['aaData'][0][0].should == order.id.to_s
|
61
|
+
@params['sSearch'] = "a value without the integer zero"
|
62
|
+
T.query(@params).to_json['aaData'].should == []
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'should only search columns that have the bSearchable_int not equal to false' do
|
66
|
+
# Order number is set as a non searchable column with the
|
67
|
+
# bSearchable flag below. It should be ignored during
|
68
|
+
# the search. To prove that we copy the first orders id
|
69
|
+
# value into the last orders order_number attribute. Then
|
70
|
+
# we do the search. Since order_numbers are unsearchable
|
71
|
+
# and ids are unique we should still only get a single
|
72
|
+
# value returned
|
73
|
+
order1 = Order.order(:id).first
|
74
|
+
order2 = Order.order(:id).last
|
75
|
+
order2.update_attribute(:order_number, order1.id)
|
76
|
+
@params['bSearchable_1'] = false
|
77
|
+
@params['sSearch'] = order1.id.to_s
|
78
|
+
T.query(@params).to_json['aaData'].should == [[order1.id.to_s,order1.order_number.to_s, order1.memo.to_s]]
|
79
|
+
end
|
80
|
+
|
81
|
+
it "don't fail when no columns is searchable" do
|
82
|
+
@params['bSearchable_0'] = false
|
83
|
+
@params['bSearchable_1'] = false
|
84
|
+
@params['bSearchable_2'] = false
|
85
|
+
@params['sSearch'] = "foo"
|
86
|
+
T.query(@params)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should ignore columns that are flagged bSearchable=false" do
|
90
|
+
T.columns(
|
91
|
+
{'orders.id' => {:type => :integer, :bSearchable => false}},
|
92
|
+
{'orders.order_number' => {:type => :integer }},
|
93
|
+
{'orders.memo' => {:type => :string }}
|
94
|
+
)
|
95
|
+
order = Order.last
|
96
|
+
@params['sSearch'] = order.id.to_s
|
97
|
+
T.query(@params).to_json['aaData'].should == []
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should strip whitespace off of search parameters" do
|
101
|
+
@params['sSearch'] = ' hello '
|
102
|
+
expected = Order.where("memo like '%hello%'").all.map{|o| o.id.to_s }
|
103
|
+
actual = T.query(@params).to_json['aaData'].map{|r| r[0] }
|
104
|
+
expected.should == actual
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'SQL defined datatable supports individual column search' do
|
4
|
+
before do
|
5
|
+
Object.send(:remove_const, :T) rescue nil
|
6
|
+
class T < Datatable::Base
|
7
|
+
sql <<-SQL
|
8
|
+
SELECT
|
9
|
+
id,
|
10
|
+
order_number,
|
11
|
+
memo
|
12
|
+
FROM
|
13
|
+
orders
|
14
|
+
SQL
|
15
|
+
columns(
|
16
|
+
{'orders.id' => {:type => :integer}},
|
17
|
+
{'orders.order_number' => {:type => :integer}},
|
18
|
+
{'orders.memo' => {:type => :string }}
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
@params = {
|
23
|
+
"iColumns" => 3,
|
24
|
+
"bSearchable_0" => true,
|
25
|
+
"bSearchable_1" => true,
|
26
|
+
"bSearchable_2" => true,
|
27
|
+
"bSortable_0" => true,
|
28
|
+
"bSortable_1" => true,
|
29
|
+
"bSortable_2" => true,
|
30
|
+
"sSearch_0" => nil,
|
31
|
+
"sSearch_1" => nil,
|
32
|
+
"sSearch_2" => nil,
|
33
|
+
"sSearch" => nil }
|
34
|
+
|
35
|
+
Order.delete_all
|
36
|
+
@orders = [*0..20].map do
|
37
|
+
Factory(:order, :order_number => (42 + rand(2)), :memo => rand(2).even? ? 'hello' : 'goodbye')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should search by one string column' do
|
42
|
+
@params['bSearchable_2'] = true # col2 = memo
|
43
|
+
@params['sSearch_2'] = "hello"
|
44
|
+
T.query(@params).to_json['aaData'].length.should == Order.where('memo LIKE ?', '%hello%').count
|
45
|
+
T.query(@params).to_json['aaData'].map { |r| r[2] }.uniq.should == ['hello']
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should search order number column for integer value' do
|
49
|
+
@params['bSearchable_1'] = true
|
50
|
+
@params['sSearch_1'] = "42"
|
51
|
+
expected = Order.where(:order_number => 42 ).map{|row| row.id.to_s }.sort
|
52
|
+
actual = T.query(@params).to_json['aaData'].map{|row| row[0]}.sort
|
53
|
+
actual.should == expected
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'integer columns do not return results unless a number appears in the search string' do
|
57
|
+
order = Order.first
|
58
|
+
order.order_number = 0
|
59
|
+
order.save
|
60
|
+
@params['bSearchable_1'] = true
|
61
|
+
@params['sSearch_1'] = "0"
|
62
|
+
T.query(@params).to_json['aaData'][0][0].should == order.id.to_s
|
63
|
+
@params['sSearch_1'] = "a value without the integer zero"
|
64
|
+
T.query(@params).to_json['aaData'].should == []
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
it 'should search by multiple columns' do
|
69
|
+
@params['bSearchable_1'] = true
|
70
|
+
@params['sSearch_1'] = "42"
|
71
|
+
@params['bSearchable_2'] = true
|
72
|
+
@params['sSearch_2'] = "hello"
|
73
|
+
expected = Order.where('memo LIKE ?', '%hello%').where(:order_number => 42).map{|row| row.id.to_s }.sort
|
74
|
+
actual = T.query(@params).to_json['aaData'].map{|row| row[0] }.sort
|
75
|
+
actual.should == expected
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should ignore columns that are flagged bSearchable=false" do
|
79
|
+
T.columns(
|
80
|
+
{'orders.id' => {:type => :integer, :bSearchable => false}},
|
81
|
+
{'orders.order_number' => {:type => :integer}},
|
82
|
+
{'orders.memo' => {:type => :string }}
|
83
|
+
)
|
84
|
+
@params['bSearchable_0'] = true
|
85
|
+
@params['sSearch_0'] = Order.last.id
|
86
|
+
lambda { T.query(@params) }.should raise_error
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should strip whitespace off of search parameters" do
|
90
|
+
@params['bSearchable_2'] = true
|
91
|
+
@params['sSearch_2'] = ' hello '
|
92
|
+
expected = Order.where("memo like '%hello%'").all.map{|o| o.id.to_s }
|
93
|
+
actual = T.query(@params).to_json['aaData'].map{|r| r[0] }
|
94
|
+
expected.should == actual
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'should account for non searchable columns' do
|
98
|
+
# T.columns(
|
99
|
+
# {'orders.id' => {:type => :integer, :bSearchable => false}},
|
100
|
+
# {'orders.order_number' => {:type => :integer}},
|
101
|
+
# {'orders.memo' => {:type => :string }} )
|
102
|
+
#
|
103
|
+
# # order_number is column zero since the first column is unsearchable
|
104
|
+
# order = Order.first
|
105
|
+
# @params['bSearchable_0'] = true
|
106
|
+
# @params['sSearch_0'] = order.order_number.to_s
|
107
|
+
# expected = Order.where(:order_number => order.order_number).all.map{|o| o.id.to_s }
|
108
|
+
# actual = T.query(@params).to_json['aaData'].map{|a| a[0] }
|
109
|
+
# actual.should == expected
|
110
|
+
pending
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'SQL defined datatable supports searching when WHERE clause exists' do
|
4
|
+
before do
|
5
|
+
Object.send(:remove_const, :T) rescue nil
|
6
|
+
class T < Datatable::Base
|
7
|
+
sql <<-SQL
|
8
|
+
SELECT
|
9
|
+
id,
|
10
|
+
order_number,
|
11
|
+
memo
|
12
|
+
FROM
|
13
|
+
orders
|
14
|
+
SQL
|
15
|
+
columns(
|
16
|
+
{'orders.id' => {:type => :integer}},
|
17
|
+
{'orders.order_number' => {:type => :integer}},
|
18
|
+
{'orders.memo' => {:type => :string }}
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
@params = {
|
23
|
+
"iColumns" => 4,
|
24
|
+
"bSearchable_0" => true,
|
25
|
+
"bSearchable_1" => true,
|
26
|
+
"bSearchable_2" => true,
|
27
|
+
"bSortable_0" => true,
|
28
|
+
"bSortable_1" => true,
|
29
|
+
"bSortable_2" => true,
|
30
|
+
"sSearch_0" => nil,
|
31
|
+
"sSearch_1" => nil,
|
32
|
+
"sSearch_2" => nil,
|
33
|
+
"sSearch" => nil }
|
34
|
+
|
35
|
+
Order.delete_all
|
36
|
+
@orders = [*0..20].map do
|
37
|
+
Factory(:order, :order_number => (42 + rand(2)), :memo => rand(2).even? ? 'hello' : 'goodbye')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
it "demonstrate that you can't include a where in the base sql fragment" do
|
43
|
+
T.sql <<-SQL
|
44
|
+
SELECT
|
45
|
+
id,
|
46
|
+
order_number,
|
47
|
+
memo
|
48
|
+
FROM
|
49
|
+
orders
|
50
|
+
WHERE
|
51
|
+
memo LIKE '%ello%'
|
52
|
+
SQL
|
53
|
+
@params['sSearch'] = Order.order(:id).first.id.to_s
|
54
|
+
lambda { T.query(@params) }.should raise_error(ActiveRecord::StatementInvalid)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "handles where in separate call" do
|
58
|
+
T.where <<-SQL
|
59
|
+
memo LIKE 'foo bar baz'
|
60
|
+
SQL
|
61
|
+
T.sql <<-SQL
|
62
|
+
SELECT
|
63
|
+
id,
|
64
|
+
order_number,
|
65
|
+
memo
|
66
|
+
FROM
|
67
|
+
orders
|
68
|
+
SQL
|
69
|
+
# create search parameters that use both global and individual
|
70
|
+
# column search to find an order known to exist
|
71
|
+
order = Order.order('order_number DESC').first
|
72
|
+
@params['sSearch'] = order.id.to_s
|
73
|
+
@params['bSearchable_1'] = true
|
74
|
+
@params['sSearch_1'] = order.order_number.to_s
|
75
|
+
|
76
|
+
# test to make sure it's not present in result because where clause excluded it
|
77
|
+
T.query(@params).to_json['aaData'].should be_empty
|
78
|
+
|
79
|
+
# modify this order so it will satisfy the query
|
80
|
+
order.memo = "foo bar baz"
|
81
|
+
order.save
|
82
|
+
|
83
|
+
# test to make sure it is present in result because where clause excluded it
|
84
|
+
T.query(@params).to_json['aaData'][0][0].should == order.id.to_s
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'query responds to sort parameters on sql defined datatable' do
|
4
|
+
before do
|
5
|
+
Object.send(:remove_const, :T) rescue nil
|
6
|
+
class T < Datatable::Base
|
7
|
+
sql <<-SQL
|
8
|
+
SELECT
|
9
|
+
id,
|
10
|
+
order_number,
|
11
|
+
memo
|
12
|
+
FROM
|
13
|
+
orders
|
14
|
+
SQL
|
15
|
+
columns(
|
16
|
+
{'orders.id' => {:type => :integer}},
|
17
|
+
{'orders.order_number' => {:type => :integer}},
|
18
|
+
{'orders.memo' => {:type => :string }}
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
@params = {
|
23
|
+
"iColumns" => 4,
|
24
|
+
"bSearchable_0" => true,
|
25
|
+
"bSearchable_1" => true,
|
26
|
+
"bSearchable_2" => true,
|
27
|
+
"bSortable_0" => true,
|
28
|
+
"bSortable_1" => true,
|
29
|
+
"bSortable_2" => true,
|
30
|
+
"sSearch_0" => nil,
|
31
|
+
"sSearch_1" => nil,
|
32
|
+
"sSearch_2" => nil,
|
33
|
+
"sSearch" => nil }
|
34
|
+
|
35
|
+
Order.delete_all
|
36
|
+
@orders = [*0..20].map do
|
37
|
+
Factory(:order, :order_number => (42 + rand(2)), :memo => rand(2).even? ? 'hello' : 'goodbye')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'sorts single column' do
|
42
|
+
@params['iSortCol_0'] = 0
|
43
|
+
@params['sSortDir_0'] = 'desc' # Assume first col is ID
|
44
|
+
@params['iSortingCols'] = 1
|
45
|
+
T.query(@params).to_json['aaData'][0][0].should == Order.order("id desc").first.id.to_s
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'sorts multiple columns' do
|
49
|
+
@params['iSortCol_0'] = 2 # Memo
|
50
|
+
@params['sSortDir_0'] = 'asc'
|
51
|
+
|
52
|
+
@params['iSortCol_1'] = 0 # ID
|
53
|
+
@params['sSortDir_1'] = 'desc'
|
54
|
+
|
55
|
+
@params['iSortingCols'] = 2
|
56
|
+
|
57
|
+
|
58
|
+
T.query(@params).to_json['aaData'][0][0].should == Order.order('memo asc, id desc')[0].id.to_s
|
59
|
+
T.query(@params).to_json['aaData'][-1][0].should == Order.order('memo asc, id desc')[-1].id.to_s
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'sorts ascending and descending' do
|
63
|
+
@params['iSortCol_0'] = 2 # Memo
|
64
|
+
@params['sSortDir_0'] = 'desc'
|
65
|
+
|
66
|
+
@params['iSortCol_1'] = 0 # ID
|
67
|
+
@params['sSortDir_1'] = 'asc'
|
68
|
+
|
69
|
+
@params['iSortingCols'] = 2
|
70
|
+
|
71
|
+
|
72
|
+
T.query(@params).to_json['aaData'][0][0].should == Order.order('memo desc, id asc')[0].id.to_s
|
73
|
+
T.query(@params).to_json['aaData'][-1][0].should == Order.order('memo desc, id asc')[-1].id.to_s
|
74
|
+
end
|
75
|
+
|
76
|
+
it "it does not sort columns where bSortable is false"
|
77
|
+
|
78
|
+
|
79
|
+
|
80
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'variable substitution' do
|
4
|
+
|
5
|
+
before do
|
6
|
+
Object.send(:remove_const, :T) rescue nil
|
7
|
+
3.times { Factory(:order) }
|
8
|
+
@params = { "iColumns" => 1 }
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "in sql clause" do
|
12
|
+
it 'of simple variables' do
|
13
|
+
class T < Datatable::Base
|
14
|
+
sql <<-SQL
|
15
|
+
SELECT
|
16
|
+
orders.id
|
17
|
+
FROM
|
18
|
+
orders
|
19
|
+
WHERE
|
20
|
+
orders.id = {{order_id}}
|
21
|
+
SQL
|
22
|
+
columns(
|
23
|
+
{'orders.id' => {:type => :integer}}
|
24
|
+
)
|
25
|
+
end
|
26
|
+
order_id = Order.last.id
|
27
|
+
T.query(@params, :order_id => order_id).to_json['aaData'].length.should == 1
|
28
|
+
T.query(@params, :order_id => order_id).to_json['aaData'].flatten.first.should == order_id.to_s
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'of arrays' do
|
32
|
+
class T < Datatable::Base
|
33
|
+
sql <<-SQL
|
34
|
+
SELECT
|
35
|
+
orders.id
|
36
|
+
FROM
|
37
|
+
orders
|
38
|
+
WHERE
|
39
|
+
orders.id IN {{order_ids}}
|
40
|
+
SQL
|
41
|
+
columns(
|
42
|
+
{'orders.id' => {:type => :integer}}
|
43
|
+
)
|
44
|
+
end
|
45
|
+
order_ids = Order.all.map{|order| order.id }.sort
|
46
|
+
T.query(@params, :order_ids => order_ids).to_json['aaData'].flatten.sort.should == Order.order(:id).all.map {|o| o.id.to_s }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'in count clause' do
|
51
|
+
class T < Datatable::Base
|
52
|
+
count <<-SQL
|
53
|
+
SELECT
|
54
|
+
count(orders.id)
|
55
|
+
FROM
|
56
|
+
orders
|
57
|
+
SQL
|
58
|
+
sql <<-SQL
|
59
|
+
SELECT
|
60
|
+
orders.id
|
61
|
+
FROM
|
62
|
+
orders
|
63
|
+
SQL
|
64
|
+
where <<-SQL
|
65
|
+
orders.id = {{order_id}}
|
66
|
+
SQL
|
67
|
+
columns(
|
68
|
+
{'orders.id' => {:type => :integer}}
|
69
|
+
)
|
70
|
+
end
|
71
|
+
order_id = Order.last.id
|
72
|
+
T.query(@params, :order_id => order_id).to_json['aaData'].length.should == 1
|
73
|
+
T.query(@params, :order_id => order_id).to_json['aaData'].should == [[order_id.to_s]]
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "in where and count clause" do
|
77
|
+
it "should do something" do
|
78
|
+
class T < Datatable::Base
|
79
|
+
count <<-SQL
|
80
|
+
SELECT
|
81
|
+
count(orders.id)
|
82
|
+
FROM
|
83
|
+
orders
|
84
|
+
SQL
|
85
|
+
sql <<-SQL
|
86
|
+
SELECT
|
87
|
+
orders.id
|
88
|
+
FROM
|
89
|
+
orders
|
90
|
+
SQL
|
91
|
+
where <<-SQL
|
92
|
+
orders.id = {{order_id}}
|
93
|
+
SQL
|
94
|
+
columns(
|
95
|
+
{'orders.id' => {:type => :integer}}
|
96
|
+
)
|
97
|
+
end
|
98
|
+
order_id = Order.last.id
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
|
104
|
+
end
|