query_storage 0.0.1
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.
- 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: []
|