dynamic_query 0.4.0 → 0.5.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.
- data/README.md +3 -3
- data/Rakefile +30 -39
- data/app/helpers/_combined_result.html.erb +72 -0
- data/app/helpers/{dynamic_query.erb → _dynamic_query.html.erb} +23 -2
- data/app/helpers/_dynamic_result.html.erb +59 -0
- data/app/helpers/dynamic_query_helper.rb +15 -1
- data/lib/dynamic_query/combine_query.rb +144 -0
- data/lib/dynamic_query/helper.rb +15 -1
- data/lib/dynamic_query/joiner.rb +47 -0
- data/lib/dynamic_query/validator.rb +21 -0
- data/lib/dynamic_query/version.rb +5 -7
- data/lib/dynamic_query.rb +4 -18
- data/lib/generators/helper_generator.rb +3 -1
- metadata +57 -53
- data/app/assets/javascripts/dynamic_query.js +0 -16
- data/lib/generators/dynamic_query_generator.rb +0 -9
data/README.md
CHANGED
@@ -8,9 +8,6 @@ Installation:
|
|
8
8
|
## Gemfile for Rails 3
|
9
9
|
gem 'dynamic_query'
|
10
10
|
|
11
|
-
## rails generator
|
12
|
-
rails g dynamic_query
|
13
|
-
|
14
11
|
## you may skip this step unless you want to customize your own helper
|
15
12
|
## Regenerate the helper after upgrade dynamic_query
|
16
13
|
rails g dynamic_query:helper
|
@@ -29,6 +26,9 @@ dq = dynamic_query(List, Entry)
|
|
29
26
|
|
30
27
|
## render query panel in the view:
|
31
28
|
<%= dynamic_query @panel %>
|
29
|
+
|
30
|
+
## render query result in the view:
|
31
|
+
<%= dynamic_result @lists %>
|
32
32
|
```
|
33
33
|
|
34
34
|
## Advanced usage of dynamic_query
|
data/Rakefile
CHANGED
@@ -1,48 +1,39 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require 'rubygems'
|
4
|
-
require 'bundler'
|
1
|
+
#!/usr/bin/env rake
|
5
2
|
begin
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
exit e.status_code
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'bundler/gem_tasks'
|
5
|
+
rescue LoadError
|
6
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
11
7
|
end
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
require '
|
16
|
-
|
17
|
-
|
18
|
-
gem.name = "dynamic_query"
|
19
|
-
gem.homepage = "http://github.com/wnameless/dynamic_query"
|
20
|
-
gem.license = "Apache License, Version 2.0"
|
21
|
-
gem.version = DynamicQuery::Version::STRING
|
22
|
-
gem.summary = "dynamic_query-#{gem.version}"
|
23
|
-
gem.description = %Q{A dynamic query gui for ActiveRecord}
|
24
|
-
gem.email = "wnameless@gmail.com"
|
25
|
-
gem.authors = ["Wei-Ming Wu"]
|
26
|
-
# dependencies defined in Gemfile
|
27
|
-
gem.files = Dir["{app,lib}/**/*"] + ["LICENSE.txt", "Rakefile", "README.md"]
|
8
|
+
begin
|
9
|
+
require 'rdoc/task'
|
10
|
+
rescue LoadError
|
11
|
+
require 'rdoc/rdoc'
|
12
|
+
require 'rake/rdoctask'
|
13
|
+
RDoc::Task = Rake::RDocTask
|
28
14
|
end
|
29
|
-
Jeweler::RubygemsDotOrgTasks.new
|
30
15
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
16
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
17
|
+
rdoc.rdoc_dir = 'rdoc'
|
18
|
+
rdoc.title = 'DynamicQuery'
|
19
|
+
rdoc.options << '--line-numbers'
|
20
|
+
rdoc.rdoc_files.include('README.md')
|
21
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
36
22
|
end
|
37
23
|
|
38
|
-
task :default => :test
|
39
24
|
|
40
|
-
require 'rdoc/task'
|
41
|
-
Rake::RDocTask.new do |rdoc|
|
42
|
-
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
43
25
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
26
|
+
|
27
|
+
Bundler::GemHelper.install_tasks
|
28
|
+
|
29
|
+
require 'rake/testtask'
|
30
|
+
|
31
|
+
Rake::TestTask.new(:test) do |t|
|
32
|
+
t.libs << 'lib'
|
33
|
+
t.libs << 'test'
|
34
|
+
t.pattern = 'test/**/*_test.rb'
|
35
|
+
t.verbose = false
|
48
36
|
end
|
37
|
+
|
38
|
+
|
39
|
+
task :default => :test
|
@@ -0,0 +1,72 @@
|
|
1
|
+
<% completed_row = result.first %>
|
2
|
+
|
3
|
+
<center id="combined_result">
|
4
|
+
|
5
|
+
<table id="combined_result_table" style="text-align: center">
|
6
|
+
<% if completed_row %>
|
7
|
+
<tr>
|
8
|
+
<%= completed_row.map { |record|
|
9
|
+
"<th colspan='#{record.attributes.size}'>#{record.table_name}</th>" }.join.html_safe %>
|
10
|
+
</tr>
|
11
|
+
<tr>
|
12
|
+
<%= completed_row.map{ |rec|
|
13
|
+
rec.attributes.map { |k, _| k } }.flatten.map { |col| "<th>#{col}</th>" }.join.html_safe %>
|
14
|
+
</tr>
|
15
|
+
<% end %>
|
16
|
+
<% result.each do |row| %>
|
17
|
+
<tr>
|
18
|
+
<% row.map { |rec| rec.attributes.map { |k ,v| v } }.flatten.each do |col| %>
|
19
|
+
<td><%= col %></td>
|
20
|
+
<% end %>
|
21
|
+
</tr>
|
22
|
+
<% end %>
|
23
|
+
</table>
|
24
|
+
|
25
|
+
<button id="table2csv">Download CSV</button>
|
26
|
+
|
27
|
+
<script>
|
28
|
+
var regulateCSVCell = function( cell ) {
|
29
|
+
if ( cell.indexOf( ',' ) == -1 ) {
|
30
|
+
return cell;
|
31
|
+
}
|
32
|
+
return '"' + cell + '"';
|
33
|
+
};
|
34
|
+
|
35
|
+
var ary2CSV = function( ary ) {
|
36
|
+
csv = '';
|
37
|
+
for ( var row in ary ) {
|
38
|
+
for ( var col in ary[row] ) {
|
39
|
+
if ( col == 0 ) {
|
40
|
+
csv += regulateCSVCell( ary[row][col] )
|
41
|
+
} else {
|
42
|
+
csv += ',' + regulateCSVCell( ary[row][col] )
|
43
|
+
}
|
44
|
+
}
|
45
|
+
csv += "\n"
|
46
|
+
}
|
47
|
+
return csv;
|
48
|
+
};
|
49
|
+
|
50
|
+
var saveCSV = function( csv ) {
|
51
|
+
var href = 'data:application/csv;charset=utf-8,'
|
52
|
+
href += encodeURIComponent( csv );
|
53
|
+
window.open( href );
|
54
|
+
};
|
55
|
+
|
56
|
+
$( '#table2csv' ).on( 'click', function() {
|
57
|
+
var table = [];
|
58
|
+
$( '#combined_result_table tr' ).each( function( index ) {
|
59
|
+
if ( index > 0 ) {
|
60
|
+
var row = [];
|
61
|
+
$( this ).children().each( function() {
|
62
|
+
row.push( $( this ).text() );
|
63
|
+
});
|
64
|
+
table.push( row );
|
65
|
+
}
|
66
|
+
});
|
67
|
+
|
68
|
+
saveCSV( ary2CSV( table ) );
|
69
|
+
});
|
70
|
+
</script>
|
71
|
+
|
72
|
+
</center>
|
@@ -1,11 +1,14 @@
|
|
1
|
+
<% or_disable = opt[:or_disable]; opt.delete(:or_disable) %>
|
2
|
+
|
1
3
|
<%= form_tag(request.path, { :method => :get, :style => 'text-align: center;' }.merge(opt)) %>
|
4
|
+
<%= html %>
|
2
5
|
<% if panel %>
|
3
6
|
<table style="margin-left: auto; margin-right: auto;">
|
4
7
|
<% panel.select { |k, _| k =~ /^or_\d+$/ }.each_with_index do |(or_key, or_val), idx1| %>
|
5
8
|
<% or_val.each_with_index do |(and_key, and_val), idx2| %>
|
6
9
|
<tr>
|
7
10
|
<td>
|
8
|
-
<%= submit_tag 'ǁ', :name => "query[action][add_or]", :style => 'color: purple;', :title => 'OR' if idx1 == 0 && idx2 == 0 %>
|
11
|
+
<%= submit_tag 'ǁ', :name => "query[action][add_or]", :style => 'color: purple;', :title => 'OR' if idx1 == 0 && idx2 == 0 and !or_disable %>
|
9
12
|
<%= submit_tag '-', :name => "query[action][remove_#{or_key}]", :style => 'color: red;' if idx1 != 0 && idx2 == 0 %>
|
10
13
|
</td>
|
11
14
|
<td><%= select_tag "query[#{or_key}][#{and_key}][column]", options_for_select(panel[:columns], and_val[:column]) %></td>
|
@@ -34,6 +37,24 @@
|
|
34
37
|
<% end %>
|
35
38
|
<% end %>
|
36
39
|
</table>
|
37
|
-
<br />
|
38
40
|
<%= submit_tag 'Query', :style => 'width: 150px;'%>
|
39
41
|
</form>
|
42
|
+
|
43
|
+
<script>
|
44
|
+
$('.query_op').on('change', function() {
|
45
|
+
var _ref, _ref1;
|
46
|
+
if ((_ref = $(this).val()) === 'IS NULL' || _ref === 'IS NOT NULL') {
|
47
|
+
$('#' + $(this).attr('id').split(/_/).slice(0, -1).join('_') + '_value1').val('');
|
48
|
+
$('#' + $(this).attr('id').split(/_/).slice(0, -1).join('_') + '_value2').val('');
|
49
|
+
$('#' + $(this).attr('id').split(/_/).slice(0, -1).join('_') + '_value1').hide();
|
50
|
+
return $('#' + $(this).attr('id').split(/_/).slice(0, -1).join('_') + '_value2').hide();
|
51
|
+
} else if ((_ref1 = $(this).val()) === 'BETWEEN' || _ref1 === 'NOT BETWEEN') {
|
52
|
+
$('#' + $(this).attr('id').split(/_/).slice(0, -1).join('_') + '_value1').show();
|
53
|
+
return $('#' + $(this).attr('id').split(/_/).slice(0, -1).join('_') + '_value2').show();
|
54
|
+
} else {
|
55
|
+
$('#' + $(this).attr('id').split(/_/).slice(0, -1).join('_') + '_value1').show();
|
56
|
+
$('#' + $(this).attr('id').split(/_/).slice(0, -1).join('_') + '_value2').val('');
|
57
|
+
return $('#' + $(this).attr('id').split(/_/).slice(0, -1).join('_') + '_value2').hide();
|
58
|
+
}
|
59
|
+
});
|
60
|
+
</script>
|
@@ -0,0 +1,59 @@
|
|
1
|
+
<center>
|
2
|
+
<table id="dynamic_result_table">
|
3
|
+
<% if result.first %>
|
4
|
+
<tr>
|
5
|
+
<%= result.first.attributes.map { |k, _| "<th>#{k}</th>" }.join.html_safe %>
|
6
|
+
</tr>
|
7
|
+
<% end %>
|
8
|
+
<% result.each do |patient| %>
|
9
|
+
<tr>
|
10
|
+
<%= patient.attributes.map { |_, v| "<td>#{v}</td>" }.join.html_safe %>
|
11
|
+
</tr>
|
12
|
+
<% end if result %>
|
13
|
+
</table>
|
14
|
+
|
15
|
+
<button id="table2csv">Download CSV</button>
|
16
|
+
|
17
|
+
<script>
|
18
|
+
var regulateCSVCell = function( cell ) {
|
19
|
+
if ( cell.indexOf( ',' ) == -1 ) {
|
20
|
+
return cell;
|
21
|
+
}
|
22
|
+
return '"' + cell + '"';
|
23
|
+
};
|
24
|
+
|
25
|
+
var ary2CSV = function( ary ) {
|
26
|
+
csv = '';
|
27
|
+
for( var row in ary ) {
|
28
|
+
for( var col in ary[row] ) {
|
29
|
+
if ( col == 0 ) {
|
30
|
+
csv += regulateCSVCell( ary[row][col] )
|
31
|
+
} else {
|
32
|
+
csv += ',' + regulateCSVCell( ary[row][col] )
|
33
|
+
}
|
34
|
+
}
|
35
|
+
csv += "\n"
|
36
|
+
}
|
37
|
+
return csv;
|
38
|
+
};
|
39
|
+
|
40
|
+
var saveCSV = function( csv ) {
|
41
|
+
var href = 'data:application/csv;charset=utf-8,'
|
42
|
+
href += encodeURIComponent( csv );
|
43
|
+
window.open( href );
|
44
|
+
};
|
45
|
+
|
46
|
+
$( '#table2csv' ).on( 'click', function() {
|
47
|
+
var table = [];
|
48
|
+
$( '#dynamic_result_table tr' ).each( function( index ) {
|
49
|
+
var row = [];
|
50
|
+
$( this ).children().each( function() {
|
51
|
+
row.push( $( this ).text() );
|
52
|
+
});
|
53
|
+
table.push( row );
|
54
|
+
});
|
55
|
+
|
56
|
+
saveCSV( ary2CSV( table ) );
|
57
|
+
});
|
58
|
+
</script>
|
59
|
+
</center>
|
@@ -1,6 +1,20 @@
|
|
1
1
|
module DynamicQueryHelper
|
2
2
|
def dynamic_query(panel, opt = {})
|
3
|
-
|
3
|
+
html = ''
|
4
|
+
yield html if block_given?
|
5
|
+
template = ERB.new(File.read(File.dirname(__FILE__) + '/_dynamic_query.html.erb'))
|
6
|
+
content = template.result(binding)
|
7
|
+
content.html_safe
|
8
|
+
end
|
9
|
+
|
10
|
+
def dynamic_result(result)
|
11
|
+
template = ERB.new(File.read(File.dirname(__FILE__) + '/_dynamic_result.html.erb'))
|
12
|
+
content = template.result(binding)
|
13
|
+
content.html_safe
|
14
|
+
end
|
15
|
+
|
16
|
+
def combined_result(result)
|
17
|
+
template = ERB.new(File.read(File.dirname(__FILE__) + '/_combined_result.html.erb'))
|
4
18
|
content = template.result(binding)
|
5
19
|
content.html_safe
|
6
20
|
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
require 'dynamic_query/validator'
|
2
|
+
require 'dynamic_query/joiner'
|
3
|
+
|
4
|
+
module DynamicQuery
|
5
|
+
module CombineQuery
|
6
|
+
include Validator, Joiner
|
7
|
+
|
8
|
+
def conditions(query, table = nil)
|
9
|
+
query ||= {}
|
10
|
+
query = query.clone
|
11
|
+
query = filter_valid_info(query)
|
12
|
+
|
13
|
+
conditions = []
|
14
|
+
query.each do |_, ands|
|
15
|
+
conditions << ands.map { |_, v| condition_to_pair v }
|
16
|
+
end
|
17
|
+
|
18
|
+
cond = []
|
19
|
+
conditions.each do |condition|
|
20
|
+
c = {}
|
21
|
+
condition.each do |pair|
|
22
|
+
pair.each do |k, v|
|
23
|
+
c[k] ||= []
|
24
|
+
c[k].concat v
|
25
|
+
end
|
26
|
+
end
|
27
|
+
c.keys.each { |k| c[k] = Hash[ c[k].each_slice(2).to_a ] }
|
28
|
+
cond << c
|
29
|
+
end
|
30
|
+
cond.map! { |c| c[table.to_s] } if table
|
31
|
+
cond
|
32
|
+
end
|
33
|
+
|
34
|
+
def combine_query(query, relations, opts = {})
|
35
|
+
conds = conditions(query).first || {}
|
36
|
+
models = relations.each_slice(3).map { |sec| sec.first }
|
37
|
+
foreign_keys = relations - models
|
38
|
+
|
39
|
+
selected_records = filter_conditioned_records(models, foreign_keys, conds)
|
40
|
+
selected_records = remove_unlinked_records(selected_records, foreign_keys)
|
41
|
+
result = join(selected_records, foreign_keys)
|
42
|
+
|
43
|
+
result.delete_if { |row| row.include? nil } unless opts[:accept_null]
|
44
|
+
result.map { |row| row.map { |rec| rec.attributes.keep_if { |k, _| k.to_s !~ /id$/ } } } unless opts[:reveal_id]
|
45
|
+
|
46
|
+
result
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
def remove_unlinked_records(selected_records, foreign_keys)
|
51
|
+
foreign_keys = foreign_keys.clone
|
52
|
+
|
53
|
+
selected_records.each_with_index do |records, idx|
|
54
|
+
unless foreign_keys.empty?
|
55
|
+
delete_unlinked_records(records, foreign_keys.shift, selected_records[idx + 1], foreign_keys.shift)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
selected_records
|
60
|
+
end
|
61
|
+
|
62
|
+
def delete_unlinked_records(tgt, fks1, ref, fks2)
|
63
|
+
ref_val = ref.map { |r| fks2.map { |fk| r.send(fk) } }
|
64
|
+
tgt.keep_if { |t| ref_val.include?(fks1.map { |fk| t.send(fk) }) }
|
65
|
+
end
|
66
|
+
|
67
|
+
def filter_conditioned_records(models, foreign_keys, conds)
|
68
|
+
foreign_keys = foreign_keys.clone
|
69
|
+
|
70
|
+
selected_records = []
|
71
|
+
determinate_values = nil
|
72
|
+
models.each do |m|
|
73
|
+
selected_records << m.where(conds[m.table_name]).all
|
74
|
+
if determinate_values
|
75
|
+
trim_records(selected_records.last, determinate_values, foreign_keys.shift)
|
76
|
+
end
|
77
|
+
if foreign_keys.empty?
|
78
|
+
determinate_values = nil
|
79
|
+
else
|
80
|
+
fks = foreign_keys.shift
|
81
|
+
determinate_values = selected_records.last.map { |r| fks.map { |fk| r.send(fk) } }
|
82
|
+
end
|
83
|
+
end
|
84
|
+
selected_records
|
85
|
+
end
|
86
|
+
|
87
|
+
def trim_records(records, det_val, fks)
|
88
|
+
records.keep_if { |r| det_val.include?(fks.map { |fk| r[fk] }) }
|
89
|
+
end
|
90
|
+
|
91
|
+
def condition_to_pair(cond)
|
92
|
+
table, column = cond[:column].split(/\./)
|
93
|
+
{ table => ["#{column}.#{convert_op cond[:operator]}", convert_val(cond[:operator], cond[:value1], cond[:value2])] }
|
94
|
+
end
|
95
|
+
|
96
|
+
def convert_val(op, val1, val2)
|
97
|
+
case op
|
98
|
+
when 'IN', 'NOT IN'
|
99
|
+
val1.split(/,/).delete_if { |word| word.blank? }.map { |word| word.strip }
|
100
|
+
when 'BETWEEN', 'NOT BETWEEN'
|
101
|
+
[val1, val2]
|
102
|
+
when 'IS NULL', 'IS NOT NULL'
|
103
|
+
nil
|
104
|
+
else
|
105
|
+
val1
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def convert_op(op)
|
110
|
+
case op
|
111
|
+
when '='
|
112
|
+
'eq'
|
113
|
+
when '>'
|
114
|
+
'gt'
|
115
|
+
when '>='
|
116
|
+
'ge'
|
117
|
+
when '<'
|
118
|
+
'lt'
|
119
|
+
when '<='
|
120
|
+
'le'
|
121
|
+
when '!='
|
122
|
+
'not_eq'
|
123
|
+
when 'LIKE'
|
124
|
+
'like'
|
125
|
+
when 'NOT LIKE'
|
126
|
+
'not_like'
|
127
|
+
when 'IN'
|
128
|
+
'in'
|
129
|
+
when 'NOT IN'
|
130
|
+
'not_in'
|
131
|
+
when 'BETWEEN'
|
132
|
+
'btw'
|
133
|
+
when 'NOT BETWEEN'
|
134
|
+
'not_btw'
|
135
|
+
when 'IS NULL'
|
136
|
+
'is'
|
137
|
+
when 'IS NOT NULL'
|
138
|
+
'is_not'
|
139
|
+
else
|
140
|
+
'eq'
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
data/lib/dynamic_query/helper.rb
CHANGED
@@ -1,7 +1,21 @@
|
|
1
1
|
module DynamicQuery
|
2
2
|
module Helper
|
3
3
|
def dynamic_query(panel, opt = {})
|
4
|
-
|
4
|
+
html = ''
|
5
|
+
yield html if block_given?
|
6
|
+
template = ERB.new(File.read(File.dirname(__FILE__) + '/../../app/helpers/_dynamic_query.html.erb'))
|
7
|
+
content = template.result(binding)
|
8
|
+
content.html_safe
|
9
|
+
end
|
10
|
+
|
11
|
+
def dynamic_result(result)
|
12
|
+
template = ERB.new(File.read(File.dirname(__FILE__) + '/../../app/helpers/_dynamic_result.html.erb'))
|
13
|
+
content = template.result(binding)
|
14
|
+
content.html_safe
|
15
|
+
end
|
16
|
+
|
17
|
+
def combined_result(result)
|
18
|
+
template = ERB.new(File.read(File.dirname(__FILE__) + '/../../app/helpers/_combined_result.html.erb'))
|
5
19
|
content = template.result(binding)
|
6
20
|
content.html_safe
|
7
21
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module DynamicQuery
|
2
|
+
module Joiner
|
3
|
+
def join(records, keys)
|
4
|
+
result = []
|
5
|
+
li = find_logest_index(records)
|
6
|
+
result << records[li]
|
7
|
+
(1..li).to_a.reverse.each do |idx|
|
8
|
+
ref_ary = records[idx - 1]
|
9
|
+
new_ary = []
|
10
|
+
result.first.each do |record|
|
11
|
+
tgt_k = keys[idx * 2 - 1]
|
12
|
+
ref_k = keys[idx * 2 - 2]
|
13
|
+
new_ary << ref_ary.find { |r| ref_k.map { |rfk| r[rfk] } == tgt_k.map { |tfk| record[tfk] } }
|
14
|
+
end
|
15
|
+
result.unshift new_ary
|
16
|
+
end if li != 0
|
17
|
+
(li + 1..records.size - 1).each do |idx|
|
18
|
+
ref_ary = records[idx]
|
19
|
+
new_ary = []
|
20
|
+
result.last.each do |record|
|
21
|
+
if record.nil?
|
22
|
+
new_ary << nil
|
23
|
+
next
|
24
|
+
end
|
25
|
+
tgt_k = keys[idx * 2 - 2]
|
26
|
+
ref_k = keys[idx * 2 - 1]
|
27
|
+
new_ary << ref_ary.find { |r| ref_k.map { |rfk| r[rfk] } == tgt_k.map { |tfk| record[tfk] } }
|
28
|
+
end
|
29
|
+
result.unshift << new_ary
|
30
|
+
end
|
31
|
+
result.reduce(:zip).map! { |row| row.flatten }
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
def find_logest_index(records)
|
36
|
+
index = 0
|
37
|
+
max = 0
|
38
|
+
records.each_with_index do |r, idx|
|
39
|
+
if r.size > max
|
40
|
+
max = r.size
|
41
|
+
index = idx
|
42
|
+
end
|
43
|
+
end
|
44
|
+
index
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module DynamicQuery
|
2
|
+
module Validator
|
3
|
+
def filter_valid_info(query)
|
4
|
+
output = {}
|
5
|
+
|
6
|
+
query.each do |or_key, or_val|
|
7
|
+
if or_key =~ /^or_\d+$/ && or_val.kind_of?(Hash)
|
8
|
+
or_val.each do |and_key, and_val|
|
9
|
+
if and_key =~ /^and_\d+$/ && and_val.kind_of?(Hash) &&
|
10
|
+
(['column', 'operator', 'value1', 'value2'] - and_val.keys.map { |k| k.to_s }).empty?
|
11
|
+
output[or_key] ||= {}; output[or_key][and_key] ||= {}
|
12
|
+
output[or_key][and_key] = and_val
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
output
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/dynamic_query.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'dynamic_query/railtie' if defined?(Rails)
|
2
2
|
require 'generators/helper_generator' if defined?(Rails)
|
3
|
+
require 'dynamic_query/combine_query'
|
4
|
+
require 'dynamic_query/validator'
|
3
5
|
|
4
6
|
module DynamicQuery
|
5
7
|
OPERATOR = ['=', '>', '>=', '<', '<=', '!=',
|
@@ -11,6 +13,8 @@ module DynamicQuery
|
|
11
13
|
end
|
12
14
|
|
13
15
|
class DynamicQueryInstance
|
16
|
+
include CombineQuery, Validator
|
17
|
+
|
14
18
|
def initialize(*models, opt)
|
15
19
|
@reveal_keys = false
|
16
20
|
@white_list = []
|
@@ -163,24 +167,6 @@ module DynamicQuery
|
|
163
167
|
end
|
164
168
|
|
165
169
|
private
|
166
|
-
def filter_valid_info(query)
|
167
|
-
output = {}
|
168
|
-
|
169
|
-
query.each do |or_key, or_val|
|
170
|
-
if or_key =~ /^or_\d+$/ && or_val.kind_of?(Hash)
|
171
|
-
or_val.each do |and_key, and_val|
|
172
|
-
if and_key =~ /^and_\d+$/ && and_val.kind_of?(Hash) &&
|
173
|
-
(['column', 'operator', 'value1', 'value2'] - and_val.keys.map { |k| k.to_s }).empty?
|
174
|
-
output[or_key] ||= {}; output[or_key][and_key] ||= {}
|
175
|
-
output[or_key][and_key] = and_val
|
176
|
-
end
|
177
|
-
end
|
178
|
-
end
|
179
|
-
end
|
180
|
-
|
181
|
-
output
|
182
|
-
end
|
183
|
-
|
184
170
|
def panel_action(panel, action)
|
185
171
|
case action.keys.first
|
186
172
|
when /^add_or$/
|
@@ -6,7 +6,9 @@ module DynamicQuery
|
|
6
6
|
|
7
7
|
def manifest
|
8
8
|
copy_file 'app/helpers/dynamic_query_helper.rb', 'app/helpers/dynamic_query_helper.rb'
|
9
|
-
copy_file 'app/helpers/
|
9
|
+
copy_file 'app/helpers/_dynamic_query.html.erb', 'app/helpers/_dynamic_query.html.erb'
|
10
|
+
copy_file 'app/helpers/_dynamic_result.html.erb', 'app/helpers/_dynamic_result.html.erb'
|
11
|
+
copy_file 'app/helpers/_combined_result.html.erb', 'app/helpers/_combined_result.html.erb'
|
10
12
|
end
|
11
13
|
end
|
12
14
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dynamic_query
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,140 +9,141 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-02-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
15
|
+
name: rails
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
|
-
- -
|
19
|
+
- - ~>
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
21
|
+
version: 3.2.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
none: false
|
26
26
|
requirements:
|
27
|
-
- -
|
27
|
+
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
29
|
+
version: 3.2.0
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
|
-
name: rails
|
31
|
+
name: jquery-rails
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
33
33
|
none: false
|
34
34
|
requirements:
|
35
|
-
- -
|
35
|
+
- - ~>
|
36
36
|
- !ruby/object:Gem::Version
|
37
|
-
version:
|
37
|
+
version: 2.2.0
|
38
38
|
type: :runtime
|
39
39
|
prerelease: false
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
41
|
none: false
|
42
42
|
requirements:
|
43
|
-
- -
|
43
|
+
- - ~>
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
version:
|
45
|
+
version: 2.2.0
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
|
-
name:
|
47
|
+
name: sqlite3
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
49
49
|
none: false
|
50
50
|
requirements:
|
51
|
-
- -
|
51
|
+
- - ~>
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version:
|
53
|
+
version: 1.3.7
|
54
54
|
type: :development
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
57
|
none: false
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ~>
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: 1.3.7
|
62
62
|
- !ruby/object:Gem::Dependency
|
63
|
-
name:
|
63
|
+
name: shoulda
|
64
64
|
requirement: !ruby/object:Gem::Requirement
|
65
65
|
none: false
|
66
66
|
requirements:
|
67
|
-
- -
|
67
|
+
- - ~>
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
version:
|
69
|
+
version: 3.3.2
|
70
70
|
type: :development
|
71
71
|
prerelease: false
|
72
72
|
version_requirements: !ruby/object:Gem::Requirement
|
73
73
|
none: false
|
74
74
|
requirements:
|
75
|
-
- -
|
75
|
+
- - ~>
|
76
76
|
- !ruby/object:Gem::Version
|
77
|
-
version:
|
77
|
+
version: 3.3.2
|
78
78
|
- !ruby/object:Gem::Dependency
|
79
|
-
name:
|
79
|
+
name: rdoc
|
80
80
|
requirement: !ruby/object:Gem::Requirement
|
81
81
|
none: false
|
82
82
|
requirements:
|
83
|
-
- -
|
83
|
+
- - ~>
|
84
84
|
- !ruby/object:Gem::Version
|
85
|
-
version:
|
85
|
+
version: '3.12'
|
86
86
|
type: :development
|
87
87
|
prerelease: false
|
88
88
|
version_requirements: !ruby/object:Gem::Requirement
|
89
89
|
none: false
|
90
90
|
requirements:
|
91
|
-
- -
|
91
|
+
- - ~>
|
92
92
|
- !ruby/object:Gem::Version
|
93
|
-
version:
|
93
|
+
version: '3.12'
|
94
94
|
- !ruby/object:Gem::Dependency
|
95
|
-
name:
|
95
|
+
name: bundler
|
96
96
|
requirement: !ruby/object:Gem::Requirement
|
97
97
|
none: false
|
98
98
|
requirements:
|
99
|
-
- -
|
99
|
+
- - ~>
|
100
100
|
- !ruby/object:Gem::Version
|
101
|
-
version: 1.
|
101
|
+
version: '1.3'
|
102
102
|
type: :development
|
103
103
|
prerelease: false
|
104
104
|
version_requirements: !ruby/object:Gem::Requirement
|
105
105
|
none: false
|
106
106
|
requirements:
|
107
|
-
- -
|
107
|
+
- - ~>
|
108
108
|
- !ruby/object:Gem::Version
|
109
|
-
version: 1.
|
109
|
+
version: '1.3'
|
110
110
|
- !ruby/object:Gem::Dependency
|
111
|
-
name:
|
111
|
+
name: rake
|
112
112
|
requirement: !ruby/object:Gem::Requirement
|
113
113
|
none: false
|
114
114
|
requirements:
|
115
|
-
- -
|
115
|
+
- - '>='
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version:
|
117
|
+
version: '0'
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
none: false
|
122
122
|
requirements:
|
123
|
-
- -
|
123
|
+
- - '>='
|
124
124
|
- !ruby/object:Gem::Version
|
125
|
-
version:
|
125
|
+
version: '0'
|
126
126
|
description: A dynamic query gui for ActiveRecord
|
127
127
|
email: wnameless@gmail.com
|
128
128
|
executables: []
|
129
129
|
extensions: []
|
130
|
-
extra_rdoc_files:
|
131
|
-
- LICENSE.txt
|
132
|
-
- README.md
|
130
|
+
extra_rdoc_files: []
|
133
131
|
files:
|
134
|
-
-
|
135
|
-
- README.md
|
136
|
-
- Rakefile
|
137
|
-
- app/assets/javascripts/dynamic_query.js
|
138
|
-
- app/helpers/dynamic_query.erb
|
139
|
-
- app/helpers/dynamic_query_helper.rb
|
140
|
-
- lib/dynamic_query.rb
|
132
|
+
- lib/dynamic_query/combine_query.rb
|
141
133
|
- lib/dynamic_query/helper.rb
|
134
|
+
- lib/dynamic_query/joiner.rb
|
142
135
|
- lib/dynamic_query/railtie.rb
|
136
|
+
- lib/dynamic_query/validator.rb
|
143
137
|
- lib/dynamic_query/version.rb
|
144
|
-
- lib/
|
138
|
+
- lib/dynamic_query.rb
|
145
139
|
- lib/generators/helper_generator.rb
|
140
|
+
- app/helpers/_combined_result.html.erb
|
141
|
+
- app/helpers/_dynamic_query.html.erb
|
142
|
+
- app/helpers/_dynamic_result.html.erb
|
143
|
+
- app/helpers/dynamic_query_helper.rb
|
144
|
+
- LICENSE.txt
|
145
|
+
- Rakefile
|
146
|
+
- README.md
|
146
147
|
homepage: http://github.com/wnameless/dynamic_query
|
147
148
|
licenses:
|
148
149
|
- Apache License, Version 2.0
|
@@ -153,22 +154,25 @@ require_paths:
|
|
153
154
|
required_ruby_version: !ruby/object:Gem::Requirement
|
154
155
|
none: false
|
155
156
|
requirements:
|
156
|
-
- -
|
157
|
+
- - '>='
|
157
158
|
- !ruby/object:Gem::Version
|
158
159
|
version: '0'
|
159
160
|
segments:
|
160
161
|
- 0
|
161
|
-
hash:
|
162
|
+
hash: 919103459980238385
|
162
163
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
163
164
|
none: false
|
164
165
|
requirements:
|
165
|
-
- -
|
166
|
+
- - '>='
|
166
167
|
- !ruby/object:Gem::Version
|
167
168
|
version: '0'
|
169
|
+
segments:
|
170
|
+
- 0
|
171
|
+
hash: 919103459980238385
|
168
172
|
requirements: []
|
169
173
|
rubyforge_project:
|
170
|
-
rubygems_version: 1.8.
|
174
|
+
rubygems_version: 1.8.25
|
171
175
|
signing_key:
|
172
176
|
specification_version: 3
|
173
|
-
summary: dynamic_query-0.
|
177
|
+
summary: dynamic_query-0.5.0
|
174
178
|
test_files: []
|
@@ -1,16 +0,0 @@
|
|
1
|
-
$('.query_op').live('change', function() {
|
2
|
-
var _ref, _ref1;
|
3
|
-
if ((_ref = $(this).val()) === 'IS NULL' || _ref === 'IS NOT NULL') {
|
4
|
-
$('#' + $(this).attr('id').split(/_/).slice(0, -1).join('_') + '_value1').val('');
|
5
|
-
$('#' + $(this).attr('id').split(/_/).slice(0, -1).join('_') + '_value2').val('');
|
6
|
-
$('#' + $(this).attr('id').split(/_/).slice(0, -1).join('_') + '_value1').hide();
|
7
|
-
return $('#' + $(this).attr('id').split(/_/).slice(0, -1).join('_') + '_value2').hide();
|
8
|
-
} else if ((_ref1 = $(this).val()) === 'BETWEEN' || _ref1 === 'NOT BETWEEN') {
|
9
|
-
$('#' + $(this).attr('id').split(/_/).slice(0, -1).join('_') + '_value1').show();
|
10
|
-
return $('#' + $(this).attr('id').split(/_/).slice(0, -1).join('_') + '_value2').show();
|
11
|
-
} else {
|
12
|
-
$('#' + $(this).attr('id').split(/_/).slice(0, -1).join('_') + '_value1').show();
|
13
|
-
$('#' + $(this).attr('id').split(/_/).slice(0, -1).join('_') + '_value2').val('');
|
14
|
-
return $('#' + $(this).attr('id').split(/_/).slice(0, -1).join('_') + '_value2').hide();
|
15
|
-
}
|
16
|
-
});
|
@@ -1,9 +0,0 @@
|
|
1
|
-
require 'rails/generators'
|
2
|
-
|
3
|
-
class DynamicQueryGenerator < Rails::Generators::Base
|
4
|
-
source_root File.expand_path("../../../", __FILE__)
|
5
|
-
|
6
|
-
def manifest
|
7
|
-
copy_file 'app/assets/javascripts/dynamic_query.js', 'app/assets/javascripts/dynamic_query.js'
|
8
|
-
end
|
9
|
-
end
|