visual_query 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +59 -0
- data/Rakefile +23 -0
- data/app/assets/images/visual_query/ajax-loader.gif +0 -0
- data/app/assets/javascripts/visual_query/index.js +288 -0
- data/app/assets/stylesheets/visual_query/visual_query.css +161 -0
- data/app/controllers/queries_controller.rb +157 -0
- data/app/helpers/application_helper.rb +5 -0
- data/app/helpers/queries_helper.rb +43 -0
- data/app/views/queries/_columns.html.erb +5 -0
- data/app/views/queries/_command.html.erb +5 -0
- data/app/views/queries/_command_results_browser.html.erb +1 -0
- data/app/views/queries/_command_save.html.erb +1 -0
- data/app/views/queries/_commands_results.html.erb +2 -0
- data/app/views/queries/_filter.html.erb +6 -0
- data/app/views/queries/_list_all_relations.html.erb +8 -0
- data/app/views/queries/_list_joinable_relations.html.erb +10 -0
- data/app/views/queries/_list_relation.html.erb +8 -0
- data/app/views/queries/_name.html.erb +8 -0
- data/app/views/queries/_results.html.erb +14 -0
- data/app/views/queries/_results_column_filter.html.erb +3 -0
- data/app/views/queries/_results_column_hide.html.erb +3 -0
- data/app/views/queries/_results_column_human_name.html.erb +8 -0
- data/app/views/queries/_results_empty.html.erb +3 -0
- data/app/views/queries/_sort.html.erb +12 -0
- data/app/views/queries/_sort_condition.html.erb +18 -0
- data/app/views/queries/_url_root.html.erb +1 -0
- data/app/views/queries/_warning_large_result_set.html.erb +12 -0
- data/app/views/queries/filters/_boolean.html.erb +6 -0
- data/app/views/queries/filters/_date.html.erb +17 -0
- data/app/views/queries/filters/_datetime.html.erb +1 -0
- data/app/views/queries/filters/_decimal.html.erb +1 -0
- data/app/views/queries/filters/_integer.html.erb +1 -0
- data/app/views/queries/filters/_numeric.html.erb +6 -0
- data/app/views/queries/filters/_string.html.erb +1 -0
- data/app/views/queries/filters/_text.html.erb +6 -0
- data/app/views/queries/index.html.erb +39 -0
- data/app/views/queries/new.html.erb +27 -0
- data/app/views/queries/not_found.html.erb +1 -0
- data/app/views/queries/show.html.erb +40 -0
- data/app/views/queries/sql_form.html.erb +16 -0
- data/config/initializers/visual_query.rb +11 -0
- data/config/routes.rb +26 -0
- data/db/migrate/20130927090319_create_visual_query_schema.rb +9 -0
- data/db/migrate/20130927090400_create_visual_query_metadata_table.rb +16 -0
- data/lib/tasks/visual_query_tasks.rake +12 -0
- data/lib/tutuf/visual_query.rb +6 -0
- data/lib/tutuf/visual_query/base.rb +268 -0
- data/lib/tutuf/visual_query/common.rb +58 -0
- data/lib/tutuf/visual_query/metadata.rb +35 -0
- data/lib/tutuf/visual_query/single.rb +111 -0
- data/lib/tutuf/visual_query/sql.rb +20 -0
- data/lib/visual_query.rb +4 -0
- data/lib/visual_query/engine.rb +4 -0
- data/lib/visual_query/version.rb +3 -0
- data/test/dummy/README.rdoc +261 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +15 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/models/account.rb +3 -0
- data/test/dummy/app/models/address.rb +3 -0
- data/test/dummy/app/models/category.rb +3 -0
- data/test/dummy/app/models/composite_pk.rb +3 -0
- data/test/dummy/app/models/customer.rb +4 -0
- data/test/dummy/app/models/order.rb +4 -0
- data/test/dummy/app/models/person.rb +4 -0
- data/test/dummy/app/models/post.rb +3 -0
- data/test/dummy/app/models/product.rb +4 -0
- data/test/dummy/app/models/product_in.rb +3 -0
- data/test/dummy/app/models/product_out.rb +3 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +53 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +12 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +29 -0
- data/test/dummy/config/environments/production.rb +65 -0
- data/test/dummy/config/environments/test.rb +33 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/visual_query.rb +1 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +3 -0
- data/test/dummy/db/migrate/20130927112446_create_tables.rb +77 -0
- data/test/dummy/db/structure.sql +651 -0
- data/test/dummy/log/development.log +1548 -0
- data/test/dummy/log/test.log +36575 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +25 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/-h/-hj2e_RSTanfbfrP0tso5Q7actRM6_clE5hetFlQ2y8.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/3B/3B_zqoNDfkO8wvAME66zxm9KzQaeDVSjnH0qC08yufM.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/5g/5g7dhxVp4YbZmFw_-T3aU2oYq2Z9Jgtps0CKneXYSS0.cache +2 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/6-/6-CtZO6uG0yfwU8-098Sdy2wnfO0W6DbFu6B6DKYuiw.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/8k/8kFIVN4cTS9KCQt_UIF5s_rcY-bMYlQpM489D98hvP4.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/Au/AukU7t3xLnyCh7qW4u45q9YFmjVcYujmIFbnaOhF4Mo.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/Bm/Bmsq0vYQqlrtfq5s-W8kcfLvwcsPT_6_5XxXt9J_QOw.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/CQ/CQLNg7a2TsUWgc7JXjDkjseMig_dPVm6AvqO2IWk5zg.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/FX/FX9ZXN3HEHR5hPzvxW8rakWEt2ot4IPJyDB67O7KPZk.cache +2 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/Hv/HvOStITEkFHlcJCgaDnND6wzPw4dMmdAdZB1Xm6JfSA.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/NW/NWCtuFzfIgixavqY71NIAa4ajbsXxRuiLNjceHgQ24M.cache +2 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/Ta/TaG641Ow168nkagg10mh6zuWS8RwWuawpHuMGakCVjU.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/VN/VNCapNKJLeponthNeFJhaBYs92UBT3P8PugENHP0474.cache +2 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/VR/VRi0Hz7tc62H5Of9XVjyAk7vSNmMr8xeYowo6lSBnZg.cache +2 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/Vg/Vgl_u6t3BvczgGi_ZJlyyo7xYSe-GgEshLofx-3QorI.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/Vq/VqGJMF3Cpvp3fw2IEIkE2tzdFo_OdcEmxN58BQwbVDY.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/W6/W6DnXCIMHJ2i5hUkEiNeDLroWxW3VU18nq292n5jlts.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/Z7/Z7fH8ST-O3GMnDUKvtKHHTSObfH2Nbs0J1QS79i80yE.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/Zh/ZhrmuPgfbHthzikN8QSHR0Q0bLtSYS1Bzl9HauWeDfU.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/bY/bYzYCY_bAGQGVGMbcxtKIhUYrgDQhmQVTmK50JrMNb8.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/eT/eTmCDSnc2m9ER5Cn85g84xyTkVLWKLbbwPFQo8eUAIg.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/h-/h-taE7cHlbq76GUb5kHenjih_y66mO0w0lIZs7vY-0s.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/ji/jikmiWyu-cXN_ZJ4hgLc3kuCAY-QJY2jmPeXS4_9vZY.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/kC/kCijps52gsNlkYgT2Qzdz9UcSaxhcMGNfNL7MIiWk54.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/kQ/kQt-OsUDJg_sl1be-FqJ6Vhw4XVguw9_msZEwXP0Nh0.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/nd/ndbe-ZZWBqU5gLx5nxauCFvv963Zm3xqVEwVYQ7X_X8.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/q6/q6BYa32YJF11eGVapO4ouNl6gayPIsARgMavlzZmoi0.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/sm/sm7AdmddDYbFx4-eo_y_kaZspanmc-jiJeM8j2DXX5k.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/ux/uxPH9lLOW42lEQxJXnBizEObZReD8qkz6Eb6fdS6Ur4.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/wn/wn0ayyM-chRdwEPI11SLkFT-7G2-GcOX8UIIC2kOWLY.cache +1 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/x7/x7KkTV3ibfIEysLB_ug5bfmnn2VLV_BldukPR3EoPBk.cache +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/xK/xKo0PfDcZuMh8oO-6Gr4j4S8eR2qUNY9Gau4kAxKIH0.cache +1 -0
- data/test/fixtures/accounts.yml +4 -0
- data/test/fixtures/categories.yml +3 -0
- data/test/fixtures/categories_posts.yml +3 -0
- data/test/fixtures/people.yml +8 -0
- data/test/fixtures/posts.yml +8 -0
- data/test/fixtures/product_ins.yml +15 -0
- data/test/fixtures/product_outs.yml +5 -0
- data/test/fixtures/products.yml +6 -0
- data/test/fixtures/saved_queries.rb +7 -0
- data/test/functional/queries_controller_test.rb +267 -0
- data/test/functional/routes_test.rb +111 -0
- data/test/integration/navigation_test.rb +10 -0
- data/test/test_helper.rb +15 -0
- data/test/unit/metadata_test.rb +10 -0
- data/test/unit/sql_test.rb +37 -0
- data/test/unit/visual_query_test.rb +648 -0
- metadata +381 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2f6ebced1d88f4c21c01c14427dceadcac9de2a6
|
4
|
+
data.tar.gz: f0342d2ef8f5ba11c3c1d1d94966c9764b19d262
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 447b93ac237dd1a7c061df09414d2056462e3ae55d09b8ff07a94540423cedf6f797f4a97a5704c72642c08b354f562f00eeeba5e4220b35d5191e5db6480b0e
|
7
|
+
data.tar.gz: fa314c031ebacb20ab219a14cbd7981666c4a6b4ab6a2b0962a048376f05f4e43504e9015e4162f6fe0f40faaf5527ac0c27966e138fa945bbd3a1fa122fc793
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2012 YOURNAME
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
VisualQuery
|
2
|
+
===========
|
3
|
+
|
4
|
+
Browser-based report generator with intuitive user interface for constructing simple database queries by end users with no SQL knowledge. It is implemented as a Rails engine, so you can drop it in your application (with caution, continue reading).
|
5
|
+
|
6
|
+
Installation
|
7
|
+
============
|
8
|
+
|
9
|
+
In your Gemfile:
|
10
|
+
|
11
|
+
gem 'visual_query'
|
12
|
+
gem 'jquery-ui-rails'
|
13
|
+
|
14
|
+
In your `config/routes.rb:`
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
mount VisualQuery::Engine => "/admin/queries", :as => "visual_query"
|
18
|
+
```
|
19
|
+
|
20
|
+
You can change the mount point path to whatever you want.
|
21
|
+
|
22
|
+
Create `config/initializers/visual_query`:
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
VisualQuery::BaseController = ApplicationController # or whatever controller you want to inherit from
|
26
|
+
QueriesController.layout('admin') # optional
|
27
|
+
```
|
28
|
+
|
29
|
+
Add the following to your `application.js`:
|
30
|
+
|
31
|
+
```javascript
|
32
|
+
//= require jquery.ui.datepicker
|
33
|
+
//= require visual_query
|
34
|
+
```
|
35
|
+
|
36
|
+
and `application.css`:
|
37
|
+
|
38
|
+
```css
|
39
|
+
/*
|
40
|
+
*= require jquery.ui.datepicker
|
41
|
+
*/
|
42
|
+
|
43
|
+
Word of Caution
|
44
|
+
===============
|
45
|
+
|
46
|
+
VisualQuery is not implemented as an isolated namespace as Rails team suggests. Thus it imports some methods in your helpers which can lead to conflicts in case
|
47
|
+
you use default Rails behaviour of including them all with `helper :all`. In case it conflicts with some method defined in your helper you can put in `config/application.rb`
|
48
|
+
`config.action_controller.include_all_helpers = false` and specify for each controller which helpers should be used.
|
49
|
+
|
50
|
+
Testing
|
51
|
+
=======
|
52
|
+
You need postgresql for testing
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
rake db:create
|
56
|
+
RAILS_ENV=test rake db:schema:load
|
57
|
+
rake test
|
58
|
+
```
|
59
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rdoc/task'
|
4
|
+
|
5
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
6
|
+
rdoc.rdoc_dir = 'html'
|
7
|
+
rdoc.title = 'VisualQuery'
|
8
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
9
|
+
rdoc.rdoc_files.include('README.rdoc')
|
10
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
11
|
+
end
|
12
|
+
|
13
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
14
|
+
load 'rails/tasks/engine.rake'
|
15
|
+
|
16
|
+
Rake::TestTask.new(:test => 'app:db:test:prepare') do |t|
|
17
|
+
t.libs << 'lib'
|
18
|
+
t.libs << 'test'
|
19
|
+
t.pattern = 'test/**/*_test.rb'
|
20
|
+
t.verbose = true
|
21
|
+
end
|
22
|
+
|
23
|
+
task :default => :test
|
Binary file
|
@@ -0,0 +1,288 @@
|
|
1
|
+
var $jq = jQuery;
|
2
|
+
|
3
|
+
Tutuf = {};
|
4
|
+
|
5
|
+
Tutuf.append_and_appear = function(parent,child){
|
6
|
+
$jq(child).css('style', 'display:none;');
|
7
|
+
$jq(parent).append(child);
|
8
|
+
$jq(child).fadeIn(1500);
|
9
|
+
return child;
|
10
|
+
};
|
11
|
+
|
12
|
+
Tutuf.VisualQuery = {};
|
13
|
+
|
14
|
+
Tutuf.VisualQuery.get_current_row_index = function() {
|
15
|
+
return $jq('span.current_relation').parent('li.relation').parent('ul.relation_path').prevAll('ul.relation_path').length;
|
16
|
+
};
|
17
|
+
|
18
|
+
Tutuf.VisualQuery.current_relation_path = function() {
|
19
|
+
return '#joined_relations_container ul.relation_path:eq('+ Tutuf.VisualQuery.get_current_row_index() +') ';
|
20
|
+
};
|
21
|
+
|
22
|
+
Tutuf.VisualQuery.list_joinable = function(args) {
|
23
|
+
args.el.on('click', function(event) {
|
24
|
+
$jq.ajax({url: Tutuf.VisualQuery.url_root + '/list_joinable/' + args.klass,
|
25
|
+
async: false,
|
26
|
+
success: function(data, text_status, jq_xhr) {
|
27
|
+
$jq('#relations_container').html(data);
|
28
|
+
Tutuf.VisualQuery.join_relations(args.klass, args.relations, args.join_conditions);
|
29
|
+
}
|
30
|
+
});
|
31
|
+
});
|
32
|
+
};
|
33
|
+
|
34
|
+
Tutuf.VisualQuery.join_relations = function(klass,relations,join_conditions){
|
35
|
+
var rel_el = $jq(Tutuf.VisualQuery.current_relation_path() + 'input[name="klass"][value="' + klass + '"]').siblings('span.relation');
|
36
|
+
if (rel_el.length === 0) {
|
37
|
+
$jq.ajax({url: Tutuf.VisualQuery.url_root + '/join_data/' + klass,
|
38
|
+
async: false,
|
39
|
+
dataType: 'json',
|
40
|
+
success: function(data, text_status, jq_xhr) {
|
41
|
+
var relation = data.relation_human_name;
|
42
|
+
var li = $jq('<li class="relation"</li>');
|
43
|
+
li.html('<span class="relation current_relation">' + relation + '</span>');
|
44
|
+
Tutuf.VisualQuery.add_join_conditions(li,join_conditions);
|
45
|
+
li.append('<input type="hidden" disabled="disabled" name="klass" value="' + klass + '"/>');
|
46
|
+
$jq.each(relations, function() {
|
47
|
+
li.append('<input type="hidden" name="relations[][rel_name]" value="' + this + '"/>');
|
48
|
+
li.append('<input type="hidden" name="relations[][row]" value="' + Tutuf.VisualQuery.get_current_row_index() + '"/>');
|
49
|
+
});
|
50
|
+
if ($jq('input[name="klass"][value="' + klass + '"]').siblings('span.relation').length < 1) {
|
51
|
+
$jq.each($jq(data.columns).filter("th"), function(){Tutuf.append_and_appear($jq('#' + this.className), this);});
|
52
|
+
}
|
53
|
+
var current_relation_path = Tutuf.VisualQuery.current_relation_path();
|
54
|
+
$jq('.current_relation').removeClass('current_relation');
|
55
|
+
Tutuf.append_and_appear($jq(current_relation_path), li);
|
56
|
+
li.children("span.relation").bind("click", function(el){Tutuf.VisualQuery.show_relation(this);});
|
57
|
+
},
|
58
|
+
error: function(jq_xhr, text_status, error_thrown){
|
59
|
+
alert("Грешка при добавяне на таблицата " + relations);
|
60
|
+
}
|
61
|
+
});
|
62
|
+
} else {
|
63
|
+
$jq('.current_relation').removeClass('current_relation');
|
64
|
+
rel_el.addClass('current_relation');
|
65
|
+
}
|
66
|
+
};
|
67
|
+
|
68
|
+
Tutuf.VisualQuery.add_join_conditions = function(li,join_conditions){
|
69
|
+
if (join_conditions === "") {
|
70
|
+
return;
|
71
|
+
}
|
72
|
+
var i,j;
|
73
|
+
for (i=0; i<join_conditions.length; i++){
|
74
|
+
for (j=0; j<2; j++){
|
75
|
+
var pos = (j === 0 ? 'left' : 'right');
|
76
|
+
li.append('<input type="hidden" name="join_conditions[]['+ pos +'_rel_name]" value="' + join_conditions[i][j].rel_name + '"/>' +
|
77
|
+
'<input type="hidden" name="join_conditions[]['+ pos +'_col_name]" value="' + join_conditions[i][j].col_name + '"/>');
|
78
|
+
}
|
79
|
+
if (join_conditions.length === 2) {
|
80
|
+
li.append('<input type="hidden" name="join_conditions[][type]" value="" />');
|
81
|
+
} else {
|
82
|
+
li.prepend('<select name="join_conditions[][type]'+ '">' +
|
83
|
+
'<option value="INNER" selected="selected">—</option>'+
|
84
|
+
'<option value="LEFT">|-</option>' +
|
85
|
+
'<option value="RIGHT">-|</option>'+
|
86
|
+
'<option value="FULL">–_</option>' +
|
87
|
+
'</select>');
|
88
|
+
}
|
89
|
+
li.append('<input type="hidden" name="join_conditions[][row]" value="' + Tutuf.VisualQuery.get_current_row_index() + '"/>');
|
90
|
+
}
|
91
|
+
};
|
92
|
+
|
93
|
+
Tutuf.VisualQuery.add_filter = function(el, params){
|
94
|
+
$jq.ajax({url: Tutuf.VisualQuery.url_root + '/filter',
|
95
|
+
data: params,
|
96
|
+
success: function(data, text_status, jq_xhr){$jq(el).replaceWith(data);}
|
97
|
+
});
|
98
|
+
};
|
99
|
+
|
100
|
+
Tutuf.VisualQuery.remove_filter = function(el, params){
|
101
|
+
$jq.ajax({url: Tutuf.VisualQuery.url_root + '/remove_filter',
|
102
|
+
data: params,
|
103
|
+
success: function(data, text_status, jq_xhr){$jq(el.parentNode).replaceWith(data);}
|
104
|
+
});
|
105
|
+
};
|
106
|
+
|
107
|
+
Tutuf.VisualQuery.result_table_rows = ['#hide', '#filter', '#relation_column'];
|
108
|
+
|
109
|
+
Tutuf.VisualQuery.th_index = function(el){
|
110
|
+
var th = el.parentNode;
|
111
|
+
return $jq(th).prevAll().length;
|
112
|
+
};
|
113
|
+
|
114
|
+
Tutuf.VisualQuery.toggle = function(el){
|
115
|
+
if ($jq(el).parent().hasClass('hidden_column')) {
|
116
|
+
Tutuf.VisualQuery.show(el);
|
117
|
+
} else {
|
118
|
+
Tutuf.VisualQuery.hide(el);
|
119
|
+
}
|
120
|
+
};
|
121
|
+
|
122
|
+
Tutuf.VisualQuery.hide = function(el){
|
123
|
+
var index = this.th_index(el);
|
124
|
+
jQuery.each(this.result_table_rows, function(){
|
125
|
+
$jq(this + ' th:eq('+ index +')').addClass('hidden_column');
|
126
|
+
});
|
127
|
+
$jq(el).text("показване");
|
128
|
+
$jq("#relation_column th:eq("+ index +") input[name^='columns[]']").attr("disabled","disabled");
|
129
|
+
};
|
130
|
+
|
131
|
+
Tutuf.VisualQuery.show = function(el){
|
132
|
+
var index = Tutuf.VisualQuery.th_index(el);
|
133
|
+
jQuery.each(this.result_table_rows, function(){
|
134
|
+
$jq(this + ' th:eq('+ index +')').removeClass('hidden_column');
|
135
|
+
});
|
136
|
+
$jq(el).text("скриване");
|
137
|
+
$jq('#relation_column th:eq('+ index +') input').removeAttr("disabled");
|
138
|
+
};
|
139
|
+
|
140
|
+
Tutuf.VisualQuery.show_relation = function(rel_el){
|
141
|
+
rel_el = $jq(rel_el);
|
142
|
+
$jq('.current_relation').removeClass('current_relation');
|
143
|
+
rel_el.addClass('current_relation');
|
144
|
+
$jq.get(Tutuf.VisualQuery.url_root + '/list_joinable/' + rel_el.siblings('input[name="klass"]').attr('value'), function(html){$jq('#relations_container').empty().append(html)});
|
145
|
+
};
|
146
|
+
|
147
|
+
Tutuf.VisualQuery.columns = function (klass,a){
|
148
|
+
var cols_el = $jq(a).siblings(".columns");
|
149
|
+
if (cols_el.length === 0) {
|
150
|
+
$jq.get(Tutuf.VisualQuery.url_root + '/columns/' + klass, function(html){$jq(a).parent().append(html);});
|
151
|
+
} else {
|
152
|
+
cols_el.toggle();
|
153
|
+
}
|
154
|
+
};
|
155
|
+
|
156
|
+
$jq(function(){
|
157
|
+
Tutuf.VisualQuery.bind_enter_in_query_name_input();
|
158
|
+
});
|
159
|
+
|
160
|
+
Tutuf.VisualQuery.bind_enter_in_query_name_input = function() {
|
161
|
+
$jq('#query_name').keypress(function(e){
|
162
|
+
var key;
|
163
|
+
if(window.event) {
|
164
|
+
key = window.event.keyCode; //IE
|
165
|
+
} else {
|
166
|
+
key = e.which; //firefox
|
167
|
+
}
|
168
|
+
if (key === 13){
|
169
|
+
Tutuf.VisualQuery.create();
|
170
|
+
return false;
|
171
|
+
}
|
172
|
+
});
|
173
|
+
};
|
174
|
+
|
175
|
+
Tutuf.VisualQuery.create = function(){
|
176
|
+
$jq.ajax({url: Tutuf.VisualQuery.url_root + '/',
|
177
|
+
type: 'POST',
|
178
|
+
data: $jq('#query').serialize(),
|
179
|
+
dataType: 'html',
|
180
|
+
success: function(data, text_status, jq_xhr){
|
181
|
+
$jq('#query_name_container').replaceWith(data);
|
182
|
+
Tutuf.VisualQuery.bind_enter_in_query_name_input();
|
183
|
+
},
|
184
|
+
error: function(jq_xhr, text_status, error_thrown){
|
185
|
+
if (jq_xhr.status === 409){
|
186
|
+
$jq('#query_name_container').replaceWith(jq_xhr.responseText);
|
187
|
+
$jq('#query_name').focus();
|
188
|
+
Tutuf.VisualQuery.bind_enter_in_query_name_input();
|
189
|
+
} else {
|
190
|
+
alert("Възникна непредвидена грешка при записа на справката :-(.");
|
191
|
+
}
|
192
|
+
}
|
193
|
+
});
|
194
|
+
};
|
195
|
+
|
196
|
+
Tutuf.VisualQuery.update_sql = function(){
|
197
|
+
$jq.ajax({url: Tutuf.VisualQuery.url_root + '/update_sql/' + $jq('[name="name"]').attr('value'),
|
198
|
+
type: 'PUT',
|
199
|
+
data: $jq('#query').serialize(),
|
200
|
+
dataType: 'html',
|
201
|
+
success: function(data, text_status, jq_xhr){
|
202
|
+
$jq('.notice').html(data);
|
203
|
+
},
|
204
|
+
error: function(jq_xhr, text_status, error_thrown){
|
205
|
+
Tutuf.VisualQuery.display_error(jq_xhr.responseText);
|
206
|
+
}
|
207
|
+
});
|
208
|
+
};
|
209
|
+
|
210
|
+
Tutuf.VisualQuery.add_balanced_query = function(){
|
211
|
+
var row_index = $jq('ul.relation_path').length;
|
212
|
+
$jq('#joined_relations_container').append('<ul class="relation_path">'+
|
213
|
+
'<li>' +
|
214
|
+
'<input type="hidden" name="rows[]" value="' + row_index + '" />' +
|
215
|
+
'<input type="button" style="visibility:hidden;" name="remove_balanced_query" value="-" onclick="Tutuf.VisualQuery.remove_balanced_query_row()"></input>'+
|
216
|
+
'</li>' +
|
217
|
+
'</ul>');
|
218
|
+
var copied_row = '#joined_relations_container ul.relation_path:eq(0) ';
|
219
|
+
if ($jq(copied_row + 'li.balancing_relation').length === 0) {
|
220
|
+
$jq(copied_row + 'li.relation').addClass("balancing_relation");
|
221
|
+
}
|
222
|
+
$jq('#joined_relations_container ul.relation_path:last').append($jq(copied_row + 'li.balancing_relation').clone(true));
|
223
|
+
$jq('#joined_relations_container ul.relation_path:last .current_relation').removeClass('current_relation');
|
224
|
+
$jq('#joined_relations_container ul.relation_path:last input[name$="[row]"]').attr('value', row_index);
|
225
|
+
};
|
226
|
+
|
227
|
+
// TODO: remove balanced query row
|
228
|
+
Tutuf.VisualQuery.remove_balanced_query_row = function(){
|
229
|
+
//remove columns of relations that are only in this ul
|
230
|
+
//remove ul
|
231
|
+
};
|
232
|
+
|
233
|
+
Tutuf.VisualQuery.results = function(){
|
234
|
+
$jq('body').prepend('<div id="synchronous_overlay"><p>Моля, изчакайте обработването на справката<br/><img src="/assets/visual_query/ajax-loader.gif"/></p></div>');
|
235
|
+
$jq.ajax({url: Tutuf.VisualQuery.url_root + '/results/' + $jq('#name').val(),
|
236
|
+
type: 'POST',
|
237
|
+
data: $jq('#query').serializeArray(),
|
238
|
+
success: function(data, text_status, jq_xhr){
|
239
|
+
$jq('#results tbody').html(data);
|
240
|
+
$jq('#synchronous_overlay').remove();
|
241
|
+
},
|
242
|
+
error: function(jq_xhr, text_status, error_thrown){
|
243
|
+
$jq('#synchronous_overlay').remove();
|
244
|
+
if ($jq('#sql')) {
|
245
|
+
Tutuf.VisualQuery.display_error(jq_xhr.responseText);
|
246
|
+
} else {
|
247
|
+
Tutuf.VisualQuery.display_error('Грешка при четене на резултата. Проверете какво сте попълнили във филтрите.');
|
248
|
+
}
|
249
|
+
}
|
250
|
+
});
|
251
|
+
};
|
252
|
+
|
253
|
+
Tutuf.VisualQuery.display_error = function(msg){
|
254
|
+
$jq('#results tbody').html('<tr><td class="error" colspan="'+ $jq('#results th.relation_column').length + '">'+ msg +'</td></tr>');
|
255
|
+
};
|
256
|
+
|
257
|
+
Tutuf.VisualQuery.sort_condition_counter = 0;
|
258
|
+
|
259
|
+
Tutuf.VisualQuery.add_sort_condition = function(el){
|
260
|
+
Tutuf.VisualQuery.sort_condition_counter += 1;
|
261
|
+
$jq.ajax({url: Tutuf.VisualQuery.url_root + '/sort_condition',
|
262
|
+
data: {index: Tutuf.VisualQuery.sort_condition_counter},
|
263
|
+
dataType: 'html',
|
264
|
+
success: function(data, text_status, jq_xhr){ $jq(el).parent().parent().append(data); },
|
265
|
+
error: function(jq_xhr, text_status, error_thrown){ alert("Грешка при добавяне на критерий за сортиране :("); }
|
266
|
+
});
|
267
|
+
};
|
268
|
+
|
269
|
+
Tutuf.VisualQuery.remove_sort_condition = function(el){
|
270
|
+
if ($jq(el).parent().siblings().size() > 0) { $jq(el).parent().remove(); }
|
271
|
+
};
|
272
|
+
|
273
|
+
Tutuf.VisualQuery.sort_options = function(el) {
|
274
|
+
if ($jq(el).children('option').size() === $jq('.relation_column').size() + 1) { return; }
|
275
|
+
var options = '<option value="o={rel_name:\'\', col_name:\'\'}">';
|
276
|
+
$jq('.relation_column').each(function() {
|
277
|
+
var rel_name = $jq(this).children('[name="columns[][rel_name]"]').val();
|
278
|
+
var col_name = $jq(this).children('[name="columns[][col_name]"]').val();
|
279
|
+
options += "<option value=\"o={'rel_name':'" + rel_name + "', 'col_name':'" + col_name + '\'}">' + $jq(this).text() + '</option>';
|
280
|
+
});
|
281
|
+
$jq(el).html(options);
|
282
|
+
};
|
283
|
+
|
284
|
+
Tutuf.VisualQuery.select_sort_option = function(el) {
|
285
|
+
var obj = eval($jq(el).children('option:selected').val());
|
286
|
+
$jq(el).siblings("[name$='[rel_name]']").val(obj.rel_name);
|
287
|
+
$jq(el).siblings("[name$='[col_name]']").val(obj.col_name);
|
288
|
+
};
|
@@ -0,0 +1,161 @@
|
|
1
|
+
#query h1 {
|
2
|
+
font-size: 120%;
|
3
|
+
margin: 0 0 0.5em 0;
|
4
|
+
}
|
5
|
+
|
6
|
+
#relations_container {
|
7
|
+
height: 20ex;
|
8
|
+
overflow-y: auto;
|
9
|
+
}
|
10
|
+
|
11
|
+
#relations_container,
|
12
|
+
#joined_relations_container {
|
13
|
+
width: 100%;
|
14
|
+
margin: 0;
|
15
|
+
padding: 0;
|
16
|
+
border: 1px solid black;
|
17
|
+
}
|
18
|
+
|
19
|
+
#joined_relations_container {
|
20
|
+
border-top: none;
|
21
|
+
padding: 0.7ex 0 0.7ex 0;
|
22
|
+
}
|
23
|
+
#command {
|
24
|
+
clear:both;
|
25
|
+
padding: 0.5em;
|
26
|
+
}
|
27
|
+
|
28
|
+
ul#relations {
|
29
|
+
list-style-type:none;
|
30
|
+
margin: 0;
|
31
|
+
padding: 0 0 0 1em;
|
32
|
+
}
|
33
|
+
|
34
|
+
ul.columns {
|
35
|
+
list-style-type:none;
|
36
|
+
margin: 0 0 0 1em;
|
37
|
+
padding: 0;
|
38
|
+
}
|
39
|
+
.columns li {
|
40
|
+
display: inline;
|
41
|
+
color: black;
|
42
|
+
background-color:#D3D3D3;
|
43
|
+
border-left: 1px solid #000;
|
44
|
+
border-right: 1px solid #000;
|
45
|
+
line-height: 1.1em;
|
46
|
+
margin: 0 0 0 -.4em;
|
47
|
+
padding: 0 .5em 0 .5em;
|
48
|
+
}
|
49
|
+
|
50
|
+
ul.relation_path {
|
51
|
+
list-style-type:none;
|
52
|
+
margin: 0.7ex 0 0.1em 1em;
|
53
|
+
padding: 0;
|
54
|
+
}
|
55
|
+
|
56
|
+
.relation_path li {
|
57
|
+
display:inline;
|
58
|
+
}
|
59
|
+
|
60
|
+
.relation_path span.relation {
|
61
|
+
margin: 0 0 0 0.5em;
|
62
|
+
border: 1px solid #000;
|
63
|
+
cursor: pointer;
|
64
|
+
}
|
65
|
+
|
66
|
+
.relation_path span.current_relation {
|
67
|
+
border: 5px solid #777;
|
68
|
+
}
|
69
|
+
|
70
|
+
.balancing_relation span.relation {
|
71
|
+
color: white;
|
72
|
+
background-color: purple;
|
73
|
+
}
|
74
|
+
|
75
|
+
table#results,
|
76
|
+
table#results tr,
|
77
|
+
table#results th,
|
78
|
+
table#results td {
|
79
|
+
border-collapse: collapse;
|
80
|
+
border: 1px solid #000;
|
81
|
+
}
|
82
|
+
|
83
|
+
table#results td {
|
84
|
+
white-space: pre-wrap;
|
85
|
+
}
|
86
|
+
|
87
|
+
.warning {
|
88
|
+
font-size: 160%;
|
89
|
+
font-weight: bold;
|
90
|
+
color: #E57F2E;
|
91
|
+
background-color: white;
|
92
|
+
}
|
93
|
+
|
94
|
+
#results .error {
|
95
|
+
font-size: 160%;
|
96
|
+
font-weight: bold;
|
97
|
+
}
|
98
|
+
|
99
|
+
.hidden_column, .hidden_column a {
|
100
|
+
background-color:#999;
|
101
|
+
}
|
102
|
+
|
103
|
+
#hide .hidden_column, #hide .hidden_column a {
|
104
|
+
background-color:#E8E8E8;
|
105
|
+
}
|
106
|
+
|
107
|
+
.filter_condition{
|
108
|
+
white-space:nowrap;
|
109
|
+
}
|
110
|
+
|
111
|
+
#synchronous_overlay {
|
112
|
+
width: 100%;
|
113
|
+
height: 100%;
|
114
|
+
position: fixed;
|
115
|
+
margin: 0;
|
116
|
+
z-index: 1000;
|
117
|
+
background-color: gray;
|
118
|
+
color: black;
|
119
|
+
opacity: 0.9;
|
120
|
+
filter:alpha(opacity=90);
|
121
|
+
}
|
122
|
+
|
123
|
+
#synchronous_overlay p {
|
124
|
+
margin-top: 16%;
|
125
|
+
width:100%;
|
126
|
+
text-align: center;
|
127
|
+
height: 100%;
|
128
|
+
vertical-align:middle;
|
129
|
+
z-index: 1000;
|
130
|
+
font-size: 4em;
|
131
|
+
}
|
132
|
+
|
133
|
+
#sort {
|
134
|
+
margin: 0.5em 0 0.5em 0;
|
135
|
+
}
|
136
|
+
|
137
|
+
#sort, #sort tr, #sort td {
|
138
|
+
border-style: none;
|
139
|
+
vertical-align: middle;
|
140
|
+
padding: 0;
|
141
|
+
}
|
142
|
+
|
143
|
+
ul#sort_conditions {
|
144
|
+
list-style-type: none;
|
145
|
+
margin: 0;
|
146
|
+
padding: 0;
|
147
|
+
}
|
148
|
+
|
149
|
+
#sort_conditions li,
|
150
|
+
#sort_conditions select {
|
151
|
+
vertical-align: middle;
|
152
|
+
}
|
153
|
+
|
154
|
+
#sort_conditions select {
|
155
|
+
margin-right: 0.5em;
|
156
|
+
}
|
157
|
+
|
158
|
+
#sort input[type="radio"],
|
159
|
+
#sort label {
|
160
|
+
margin-right: 0.2em;
|
161
|
+
}
|