query_storage 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/Gemfile +6 -0
- data/Rakefile +1 -0
- data/lib/generators/query_storage/install/install_generator.rb +34 -0
- data/lib/generators/templates/controllers/queries_controller.rb +127 -0
- data/lib/generators/templates/views/_form.html.erb +29 -0
- data/lib/generators/templates/views/_list.html.erb +24 -0
- data/lib/generators/templates/views/edit.html.erb +8 -0
- data/lib/generators/templates/views/index.html.erb +3 -0
- data/lib/generators/templates/views/new.html.erb +7 -0
- data/lib/generators/templates/views/show.html.erb +106 -0
- data/lib/query_storage/version.rb +3 -0
- data/lib/query_storage.rb +35 -0
- data/query_storage.gemspec +24 -0
- metadata +56 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ca2171330d366349e4f9196f1dd19f355aedb0efb94b10008eefce2b741162ba
|
4
|
+
data.tar.gz: 9a3b6b454e35e0410dec963df4d3439ea2aff8717ac56768c568159eacb82702
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 249fd11d92fc14653116e0dc74e58bc816f443127d08e1b2ad207aeba373e67f2508ee00244a697aba35b0bf98ada97c2b8612a0bfa61cc12d62e003c75cc574
|
7
|
+
data.tar.gz: 3140930ce7c2eb2eb614f92bccef378a45d7b31502cc3530af807b63f0ff4ea790eacf37547168ba029eff9bae83a307eb3bb286fb48ec41fb87d8876a110ddc
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'rails'
|
2
|
+
|
3
|
+
class QueryStorage::InstallGenerator < Rails::Generators::NamedBase
|
4
|
+
source_root File.expand_path('../../../templates', __FILE__)
|
5
|
+
CONTROLLERS = %w(queries).freeze
|
6
|
+
VIEWS = %w(index show edit new _form _list).freeze
|
7
|
+
|
8
|
+
def add_routes
|
9
|
+
devise_route = <<-EOF
|
10
|
+
resources :#{class_name.underscore.pluralize} do
|
11
|
+
member do
|
12
|
+
get :download_csv
|
13
|
+
get :download_tsv
|
14
|
+
end
|
15
|
+
end
|
16
|
+
EOF
|
17
|
+
route devise_route
|
18
|
+
end
|
19
|
+
|
20
|
+
def create_models
|
21
|
+
generate 'model', "#{class_name} title:string sql:text"
|
22
|
+
end
|
23
|
+
|
24
|
+
def create_controllers
|
25
|
+
CONTROLLERS.each do |name|
|
26
|
+
template "controllers/#{name}_controller.rb",
|
27
|
+
"app/controllers/#{name}_controller.rb"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def create_views
|
32
|
+
directory "views", "app/views/#{class_name.underscore.pluralize}"
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
class QueriesController < ApplicationController
|
2
|
+
# layout 'base'
|
3
|
+
# before_action :set_query, only: [:show, :edit, :update, :destroy]
|
4
|
+
require 'csv'
|
5
|
+
# require 'query_storage'
|
6
|
+
|
7
|
+
# GET /queries
|
8
|
+
# GET /queries.json
|
9
|
+
def index
|
10
|
+
@queries = Query.all
|
11
|
+
# if @queries.present?
|
12
|
+
# @queries.order(:updated_at).reverse_order
|
13
|
+
# end
|
14
|
+
end
|
15
|
+
|
16
|
+
# GET /queries/1
|
17
|
+
# GET /queries/1.json
|
18
|
+
def show
|
19
|
+
@query = Query.find_by_id(params[:id])
|
20
|
+
sql = @query.sql
|
21
|
+
@result = QueryStorage.execute_sql(sql)
|
22
|
+
# has_header = true
|
23
|
+
# @csv_date = QueryStorage.get_csv_data(@result, has_header)
|
24
|
+
# @tsv_date = QueryStorage.get_tsv_data(@result, has_header)
|
25
|
+
@header = @result[0].keys
|
26
|
+
@result = Kaminari.paginate_array(@result.to_a).page(params[:page]).per(1000)
|
27
|
+
end
|
28
|
+
|
29
|
+
# GET /queries/new
|
30
|
+
def new
|
31
|
+
@query = Query.new
|
32
|
+
end
|
33
|
+
|
34
|
+
# GET /queries/1/edit
|
35
|
+
def edit
|
36
|
+
@query = Query.find_by_id(params[:id])
|
37
|
+
end
|
38
|
+
|
39
|
+
# POST /queries
|
40
|
+
# POST /queries.json
|
41
|
+
def create
|
42
|
+
@query = Query.new(params[:query])
|
43
|
+
# update,insert文だと思われる場合は登録を禁止する。
|
44
|
+
if QueryStorage.is_insert_or_update_sql(@query.sql)
|
45
|
+
flash.now[:alert] = "更新処理(UPDATE文,INSERT文)の恐れがあるため登録を禁止します."
|
46
|
+
render :new
|
47
|
+
return
|
48
|
+
end
|
49
|
+
|
50
|
+
respond_to do |format|
|
51
|
+
if @query.save
|
52
|
+
format.html { redirect_to @query, :notice => 'Query was successfully created.' }
|
53
|
+
format.json { render :show, :status => :created, :location => @query }
|
54
|
+
else
|
55
|
+
format.html { render :new }
|
56
|
+
format.json { render :json => @query.errors, :status => :unprocessable_entity }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# PATCH/PUT /queries/1
|
62
|
+
# PATCH/PUT /queries/1.json
|
63
|
+
def update
|
64
|
+
@query = Query.find_by_id(params[:id])
|
65
|
+
# update,insert文だと思われる場合は登録を禁止する。
|
66
|
+
if QueryStorage.is_insert_or_update_sql(@query.sql)
|
67
|
+
flash.now[:alert] = "更新処理(UPDATE文,INSERT文)の恐れがあるため登録を禁止します."
|
68
|
+
render :edit
|
69
|
+
return
|
70
|
+
end
|
71
|
+
respond_to do |format|
|
72
|
+
if @query.update_attributes(params[:query])
|
73
|
+
format.html { redirect_to @query, :notice => 'Query was successfully updated.' }
|
74
|
+
format.json { render :show, :status => :ok, :location => @query }
|
75
|
+
else
|
76
|
+
format.html { render :edit }
|
77
|
+
format.json { render :json => @query.errors, :status => :unprocessable_entity }
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# DELETE /queries/1
|
83
|
+
# DELETE /queries/1.json
|
84
|
+
def destroy
|
85
|
+
@query = Query.find_by_id(params[:id])
|
86
|
+
@query.destroy
|
87
|
+
respond_to do |format|
|
88
|
+
format.html { redirect_to queries_url, :notice => 'Query was successfully destroyed.' }
|
89
|
+
format.json { head :no_content }
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def download_csv
|
94
|
+
query = Query.find_by_id(params[:id])
|
95
|
+
result = QueryStorage.execute_sql(query.sql)
|
96
|
+
has_header = true
|
97
|
+
csv_data = QueryStorage.get_csv_data(result, has_header)
|
98
|
+
csv_data = csv_data.encode(Encoding::SJIS, :invalid => :replace, :undef => :replace)
|
99
|
+
respond_to do |format|
|
100
|
+
format.html
|
101
|
+
format.csv { send_data csv_data, :type => 'text/csv; charset=shift_jis', :filename => query.title+".csv" }
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def download_tsv
|
106
|
+
query = Query.find_by_id(params[:id])
|
107
|
+
result = QueryStorage.execute_sql(query.sql)
|
108
|
+
has_header = true
|
109
|
+
csv_data = QueryStorage.get_tsv_data(result, has_header)
|
110
|
+
csv_data = csv_data.encode(Encoding::SJIS, :invalid => :replace, :undef => :replace)
|
111
|
+
respond_to do |format|
|
112
|
+
format.html
|
113
|
+
format.csv { send_data csv_data, :type => 'text/csv; charset=shift_jis', :filename => query.title+".tsv" }
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
private
|
118
|
+
# Use callbacks to share common setup or constraints between actions.
|
119
|
+
def set_query
|
120
|
+
@query = Query.find(params[:id])
|
121
|
+
end
|
122
|
+
|
123
|
+
# Never trust parameters from the scary internet, only allow the white list through.
|
124
|
+
def query_params
|
125
|
+
params.require(:query).permit(:title, :sql, :category_id)
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
<%= form_for(query, :local => true) do |form| %>
|
2
|
+
<% if query.errors.any? %>
|
3
|
+
<div id="error_explanation">
|
4
|
+
<h2><%= pluralize(query.errors.count, "error") %> prohibited this query from being saved:</h2>
|
5
|
+
|
6
|
+
<ul>
|
7
|
+
<% query.errors.full_messages.each do |message| %>
|
8
|
+
<li><%= message %></li>
|
9
|
+
<% end %>
|
10
|
+
</ul>
|
11
|
+
</div>
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
<div class="field">
|
15
|
+
<%= form.label :title %>
|
16
|
+
<%= form.text_field :title, :id => :query_title, :size => "100" %>
|
17
|
+
</div>
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
<div class="field">
|
22
|
+
<%= form.label :sql %>
|
23
|
+
<%= form.text_area :sql, :id => :query_sql, :size => "100x30" %>
|
24
|
+
</div>
|
25
|
+
|
26
|
+
<div class="actions">
|
27
|
+
<%= form.submit %>
|
28
|
+
</div>
|
29
|
+
<% end %>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<table border="1">
|
2
|
+
<thead>
|
3
|
+
<tr>
|
4
|
+
<% if false %><th>Category</th><% end %>
|
5
|
+
<th>Title</th>
|
6
|
+
<th colspan="3">Action</th>
|
7
|
+
<th>updated_at</th>
|
8
|
+
</tr>
|
9
|
+
</thead>
|
10
|
+
|
11
|
+
<tbody>
|
12
|
+
<% @queries.each do |query| %>
|
13
|
+
<tr>
|
14
|
+
<%# TODO %>
|
15
|
+
<% if false %><td><%= link_to query.category.name, query.category %></td><% end %>
|
16
|
+
<td><%= link_to query.title, query %></td>
|
17
|
+
<td><%= link_to 'Show', query %></td>
|
18
|
+
<td><%= link_to 'Edit', edit_query_path(query) %></td>
|
19
|
+
<td><%= link_to 'Destroy', query, :method => :delete, :data => { :confirm => 'Are you sure?' } %></td>
|
20
|
+
<td><%= query.updated_at %></td>
|
21
|
+
</tr>
|
22
|
+
<% end %>
|
23
|
+
</tbody>
|
24
|
+
</table>
|
@@ -0,0 +1,106 @@
|
|
1
|
+
<link rel="stylesheet" href="https://cdn.datatables.net/t/bs-3.3.6/jqc-1.12.0,dt-1.10.11/datatables.min.css"/>
|
2
|
+
<script src="https://cdn.datatables.net/t/bs-3.3.6/jqc-1.12.0,dt-1.10.11/datatables.min.js"></script>
|
3
|
+
<link rel="stylesheet" type="text/css" href="/stylesheets/highlight/styles/tomorrow.css" />
|
4
|
+
<script src="/javascript/highlight.pack.js"></script>
|
5
|
+
|
6
|
+
<script>
|
7
|
+
//SQLのシンタックスハイライトを有効にする
|
8
|
+
hljs.initHighlightingOnLoad();
|
9
|
+
|
10
|
+
jQuery(function($){
|
11
|
+
$("#queryTable").DataTable({
|
12
|
+
"lengthMenu": [[-1, 50, 100, 500, 1000], ["ALL", 50, 100, 500, 1000]],
|
13
|
+
// ソート機能 無効
|
14
|
+
// ordering: false,
|
15
|
+
// ページング機能 無効
|
16
|
+
paging: false
|
17
|
+
});
|
18
|
+
|
19
|
+
$('#csv_copy').click(function(e) {
|
20
|
+
execCopy($('#csv_date').val())
|
21
|
+
});
|
22
|
+
$('#tsv_copy').click(function(e) {
|
23
|
+
execCopy($('#tsv_date').val())
|
24
|
+
});
|
25
|
+
});
|
26
|
+
|
27
|
+
//
|
28
|
+
function execCopy(string){
|
29
|
+
var temp = document.createElement('div');
|
30
|
+
|
31
|
+
temp.appendChild(document.createElement('pre')).textContent = string;
|
32
|
+
|
33
|
+
var s = temp.style;
|
34
|
+
s.position = 'fixed';
|
35
|
+
s.left = '-100%';
|
36
|
+
|
37
|
+
document.body.appendChild(temp);
|
38
|
+
document.getSelection().selectAllChildren(temp);
|
39
|
+
|
40
|
+
var result = document.execCommand('copy');
|
41
|
+
|
42
|
+
document.body.removeChild(temp);
|
43
|
+
// true なら実行できている falseなら失敗か対応していないか
|
44
|
+
if(result){
|
45
|
+
alert('コピーできました');
|
46
|
+
}
|
47
|
+
else {
|
48
|
+
alert('このブラウザでは対応していません');
|
49
|
+
}
|
50
|
+
return ;
|
51
|
+
}
|
52
|
+
|
53
|
+
</script>
|
54
|
+
|
55
|
+
|
56
|
+
<p>
|
57
|
+
<strong>Title:</strong>
|
58
|
+
<%= @query.title %>
|
59
|
+
</p>
|
60
|
+
|
61
|
+
<%# TODO %>
|
62
|
+
<% if false %>
|
63
|
+
<p>
|
64
|
+
<strong>category:</strong>
|
65
|
+
<%= @query.category.name %>
|
66
|
+
</p>
|
67
|
+
<% end %>
|
68
|
+
|
69
|
+
<p>
|
70
|
+
<strong>Sql:</strong>
|
71
|
+
<pre style="margin:30px; width:1000px;"><code class="sql"><%=@query.sql%></code></pre>
|
72
|
+
</p>
|
73
|
+
<hr>
|
74
|
+
<%= link_to 'Edit', edit_query_path(@query) %> |
|
75
|
+
<%= link_to 'Back', queries_path %> |
|
76
|
+
<%= link_to 'Download CSV', download_csv_query_path(@query, :format => "csv") %> |
|
77
|
+
<%= link_to 'Download TSV', download_tsv_query_path(@query, :format => "csv") %>
|
78
|
+
|
79
|
+
<textarea id="csv_date" cols="30" rows="1" hidden><%= @csv_date %></textarea>
|
80
|
+
<button id='csv_copy'>CSV形式でコピー</button>
|
81
|
+
<textarea id="tsv_date" cols="30" rows="1" hidden><%= @tsv_date %></textarea>
|
82
|
+
<button id='tsv_copy'>TSV形式でコピー</button>
|
83
|
+
|
84
|
+
<table id="queryTable" border="1">
|
85
|
+
<thead>
|
86
|
+
<tr>
|
87
|
+
<% @header.each do |h| %>
|
88
|
+
<th><%= h %></th>
|
89
|
+
<% end %>
|
90
|
+
</tr>
|
91
|
+
</thead>
|
92
|
+
<tbody>
|
93
|
+
<%= paginate @result %>
|
94
|
+
<% @result.each do |record| %>
|
95
|
+
<tr>
|
96
|
+
<% @header.each do |h| %>
|
97
|
+
<% if record[h].to_s.match(/^http.*/).present? %>
|
98
|
+
<td><a href="<%= record[h].to_s %>"><%= record[h].to_s %></a></td>
|
99
|
+
<% else %>
|
100
|
+
<td><%= record[h] %></td>
|
101
|
+
<% end %>
|
102
|
+
<% end %>
|
103
|
+
</tr>
|
104
|
+
<% end %>
|
105
|
+
</tbody>
|
106
|
+
</table>
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require "query_storage/version"
|
2
|
+
|
3
|
+
module QueryStorage
|
4
|
+
class << self
|
5
|
+
|
6
|
+
def execute_sql sql
|
7
|
+
con = ActiveRecord::Base.connection
|
8
|
+
con.select_all(sql)
|
9
|
+
end
|
10
|
+
|
11
|
+
def is_insert_or_update_sql sql
|
12
|
+
return sql.match(/\bupdate\b|\binsert\b/).present?
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
def get_csv_data input_data, has_header=false
|
17
|
+
csv_data = CSV.generate("", :headers => input_data[0].keys, :write_headers => has_header) do |csv|
|
18
|
+
input_data.each_with_index do |record, index|
|
19
|
+
csv << record
|
20
|
+
end
|
21
|
+
end
|
22
|
+
return csv_data
|
23
|
+
end
|
24
|
+
|
25
|
+
def get_tsv_data input_data, has_header=false
|
26
|
+
tsv_data = CSV.generate("", :headers => input_data[0].keys, :write_headers => has_header, :col_sep => "\t") do |tsv|
|
27
|
+
input_data.each_with_index do |record, index|
|
28
|
+
tsv << record
|
29
|
+
end
|
30
|
+
end
|
31
|
+
return tsv_data
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "query_storage/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "query_storage"
|
7
|
+
s.version = QueryStorage::VERSION
|
8
|
+
s.authors = ["Keisuke Nakama"]
|
9
|
+
s.email = [""]
|
10
|
+
s.homepage = "https://github.com/adebadayo/query-storage"
|
11
|
+
s.summary = %q{}
|
12
|
+
s.description = %q{I will write this section when I finish creating this gem}
|
13
|
+
|
14
|
+
s.rubyforge_project = "query_storage"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
# specify any dependencies here; for example:
|
22
|
+
# s.add_development_dependency "rspec"
|
23
|
+
# s.add_runtime_dependency "rest-client"
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: query_storage
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Keisuke Nakama
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-06-03 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: I will write this section when I finish creating this gem
|
14
|
+
email:
|
15
|
+
- ''
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- ".gitignore"
|
21
|
+
- Gemfile
|
22
|
+
- Rakefile
|
23
|
+
- lib/generators/query_storage/install/install_generator.rb
|
24
|
+
- lib/generators/templates/controllers/queries_controller.rb
|
25
|
+
- lib/generators/templates/views/_form.html.erb
|
26
|
+
- lib/generators/templates/views/_list.html.erb
|
27
|
+
- lib/generators/templates/views/edit.html.erb
|
28
|
+
- lib/generators/templates/views/index.html.erb
|
29
|
+
- lib/generators/templates/views/new.html.erb
|
30
|
+
- lib/generators/templates/views/show.html.erb
|
31
|
+
- lib/query_storage.rb
|
32
|
+
- lib/query_storage/version.rb
|
33
|
+
- query_storage.gemspec
|
34
|
+
homepage: https://github.com/adebadayo/query-storage
|
35
|
+
licenses: []
|
36
|
+
metadata: {}
|
37
|
+
post_install_message:
|
38
|
+
rdoc_options: []
|
39
|
+
require_paths:
|
40
|
+
- lib
|
41
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '0'
|
51
|
+
requirements: []
|
52
|
+
rubygems_version: 3.0.1
|
53
|
+
signing_key:
|
54
|
+
specification_version: 4
|
55
|
+
summary: ''
|
56
|
+
test_files: []
|