schemard 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,56 @@
1
+ module SchemaRD::Utils
2
+ module Singularizer
3
+ def singularize
4
+ return self if NO_SINGULAR_WORDS.include?(self)
5
+
6
+ found = SINGULAR_RULES.find{|regexp, _| self =~ regexp }
7
+ found ? self.gsub(found[0], found[1]) : self
8
+ end
9
+ SINGULAR_RULES = [
10
+ [/(z)ombies$/i, "\\1ombie"],
11
+ [/(z)ombie$/i, "\\1ombie"],
12
+ [/(m)oves$/i, "\\1ove"],
13
+ [/(m)ove$/i, "\\1ove"],
14
+ [/(s)exes$/i, "\\1ex"],
15
+ [/(s)ex$/i, "\\1ex"],
16
+ [/(c)hildren$/i, "\\1hild"],
17
+ [/(c)hild$/i, "\\1hild"],
18
+ [/(m)en$/i, "\\1an"],
19
+ [/(m)an$/i, "\\1an"],
20
+ [/(p)eople$/i, "\\1erson"],
21
+ [/(p)erson$/i, "\\1erson"],
22
+ [/(database)s$/i, "\\1"],
23
+ [/(quiz)zes$/i, "\\1"],
24
+ [/(matr)ices$/i, "\\1ix"],
25
+ [/(vert|ind)ices$/i, "\\1ex"],
26
+ [/^(ox)en/i, "\\1"],
27
+ [/(alias|status)(es)?$/i, "\\1"],
28
+ [/(octop|vir)(us|i)$/i, "\\1us"],
29
+ [/^(a)x[ie]s$/i, "\\1xis"],
30
+ [/(cris|test)(is|es)$/i, "\\1is"],
31
+ [/(shoe)s$/i, "\\1"],
32
+ [/(o)es$/i, "\\1"],
33
+ [/(bus)(es)?$/i, "\\1"],
34
+ [/^(m|l)ice$/i, "\\1ouse"],
35
+ [/(x|ch|ss|sh)es$/i, "\\1"],
36
+ [/(m)ovies$/i, "\\1ovie"],
37
+ [/(s)eries$/i, "\\1eries"],
38
+ [/([^aeiouy]|qu)ies$/i, "\\1y"],
39
+ [/([lr])ves$/i, "\\1f"],
40
+ [/(tive)s$/i, "\\1"],
41
+ [/(hive)s$/i, "\\1"],
42
+ [/([^f])ves$/i, "\\1fe"],
43
+ [/(^analy)(sis|ses)$/i, "\\1sis"],
44
+ [/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$/i, "\\1sis"],
45
+ [/([ti])a$/i, "\\1um"],
46
+ [/(n)ews$/i, "\\1ews"],
47
+ [/(ss)$/i, "\\1"],
48
+ [/s$/i, ""]
49
+ ]
50
+ NO_SINGULAR_WORDS = %w(equipment information rice money species series fish sheep jeans police)
51
+ end
52
+ end
53
+
54
+ class String
55
+ include SchemaRD::Utils::Singularizer
56
+ end
@@ -0,0 +1,12 @@
1
+ module SchemaRD
2
+ module Utils
3
+ module StructAssigner
4
+ def assign(hash)
5
+ hash && self.members.each do |key|
6
+ self[key] = hash[key] if hash.has_key?(key)
7
+ self[key] = hash[key.to_sym] if hash.has_key?(key.to_sym)
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,56 @@
1
+ require 'webrick'
2
+ require_relative "controller"
3
+
4
+ module SchemaRD
5
+ class WebServer
6
+ attr_reader :config
7
+ def initialize(config)
8
+ @config = config
9
+ end
10
+ def setup(srv, options)
11
+ Signal.trap("INT"){ srv.shutdown }
12
+ Signal.trap("TERM"){ srv.shutdown }
13
+
14
+ # アクションメソッド
15
+ srv.mount_proc '/' do |req, res|
16
+ controller = SchemaRD::Controller.new(self.config)
17
+ case req.path
18
+ when "/", "/index"
19
+ controller.index(req, res)
20
+ when /\/tables\/.+/
21
+ controller.show(req, res) if req.request_method == "GET"
22
+ controller.update(req, res) if req.request_method == "POST"
23
+ when /.*\.(js|css|ico)/
24
+ controller.static_file(req, res)
25
+ else
26
+ res.status = Rack::Utils.status_code(404)
27
+ end
28
+ end
29
+ end
30
+
31
+ def start()
32
+ options = {
33
+ :Host => config.webserver_host,
34
+ :Port => config.webserver_port,
35
+ :ServerType => WEBrick::SimpleServer,
36
+ :Logger => WEBrick::Log.new(config.log_output),
37
+ }
38
+ begin
39
+ srv = WEBrick::HTTPServer.new(options);
40
+ setup(srv, options)
41
+ srv.start
42
+ rescue Errno::EADDRINUSE => e
43
+ (options[:Logger] || Logger.new(STDOUT)).error("#{__FILE__}: #{e.to_s}")
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ if $0 == __FILE__
50
+ config = SchemaRD::Configuration.new(ARGV)
51
+ if config.valid?
52
+ SchemaRD::WebServer.new(config).start()
53
+ else
54
+ config.errors.each{|err| puts err }
55
+ end
56
+ end
data/lib/schemard.rb ADDED
@@ -0,0 +1,6 @@
1
+ require_relative 'schemard/web_server'
2
+ require_relative 'schemard/controller'
3
+
4
+ module SchemaRD
5
+ VERSION = "0.2.0"
6
+ end
@@ -0,0 +1,81 @@
1
+ <!DOCTYPE html>
2
+ <html lang="<%= locale.lang %>">
3
+ <head>
4
+ <meta charset="utf-8"/>
5
+ <link href="normalize.css" rel="stylesheet" media="all">
6
+ <style type="text/css">
7
+ body {
8
+ font-size: small;
9
+ width: 1600px;
10
+ height: 960px;
11
+ }
12
+ div.table {
13
+ position: absolute;
14
+ border: solid 1px #a0a0a0;
15
+ border-radius: 4px;
16
+ display: inline-block;
17
+ z-index: 10;
18
+ user-select: none;
19
+ min-width: 120px;
20
+ padding-bottom: 6px;
21
+ background-color: #ffffff;
22
+ margin: 2px;
23
+ -moz-user-select: none; /* Firefox */
24
+ -webkit-user-select: none; /* Safari、Chrome */
25
+ -ms-user-select: none; /* overIE10 */
26
+ }
27
+ div.default-position {
28
+ position: relative !important;
29
+ }
30
+ .table div { padding: 2px 10px }
31
+ .table div.title {
32
+ background-color: #4078c0;
33
+ color: #ffffff;
34
+ cursor: pointer;
35
+ }
36
+ .editable {
37
+ display: inline-block;
38
+ padding: 4px;
39
+ color: #4078c0;
40
+ position: absolute;
41
+ top: 5px;
42
+ left: 10px;
43
+ z-index: 1000;
44
+ background-color: white;
45
+ }
46
+ .editing { border: solid 3px #b0c4de !important; margin: 0 !important; cursor: -webkit-grab; cursor: -moz-grab; }
47
+ .dragging { cursor: -webkit-grabbing !important; cursor: -moz-grabbing !important; }
48
+ .editing div.title { cursor: -webkit-grab; cursor: -moz-grab; }
49
+ .dragging div.title { cursor: -webkit-grabbing !important; cursor: -moz-grabbing !important; }
50
+ .relation-line, .relation-edge {
51
+ position: absolute;
52
+ z-index: 0;
53
+ }
54
+ .relation-edge-diagonal {
55
+ position: absolute;
56
+ z-index: 0;
57
+ border-bottom: solid 1px black;
58
+ }
59
+ .relation-line .child-1, .relation-line .child-2 { position: absolute; display: inline-block; }
60
+ </style>
61
+ <link rel="shortcut icon" href="favicon.ico">
62
+ <title>ERD</title>
63
+ <script type="text/javascript" src="jquery2.min.js" ></script>
64
+ <script type="text/javascript" src="tableViewer.js" ></script>
65
+ </head>
66
+ <body>
67
+ <label class="editable" ><input type="checkbox" ><%= locale.t("views.edit_checkbox_label") %></label>
68
+ <%- schema.tables.each do |t| -%>
69
+ <div class="table<% if t.default_position? %> default-position<% end %>" data-table-name="<%= t.name %>"
70
+ data-pos-left="<%= t.position["left"]%>" data-pos-top="<%= t.position["top"] %>"
71
+ data-relation-to="<%= t.relations_as_parent.map{|r| r.child_table.name }.join(',') %>"
72
+ data-relation-cardinality="<%=
73
+ t.relations_as_parent.map{|r| r.child_table.name + ":" + r.child_cardinality }.join(',') %>" >
74
+ <div class="title" ><%= t.display_name %></div>
75
+ <% t.columns.each do |c| %>
76
+ <div class="column"><%= c.display_name %></div>
77
+ <%- end -%>
78
+ </div>
79
+ <%- end -%>
80
+ </body>
81
+ </html>
@@ -0,0 +1,156 @@
1
+ <!DOCTYPE html>
2
+ <html lang="<%= locale.lang %>">
3
+ <head>
4
+ <meta charset="utf-8"/>
5
+ <link href="../normalize.css" rel="stylesheet" media="all">
6
+ <style type="text/css">
7
+ body { font-size: small; }
8
+ header {
9
+ padding: 10px 0;
10
+ border-bottom: solid 2px #87cefa;
11
+ background-color: #004680;
12
+ color: #ffffff;
13
+ }
14
+ header a { color: #ffffff; cursor: pointer; }
15
+ header .title {
16
+ width: 90%;
17
+ margin: 0 auto;
18
+ font-size: large;
19
+ }
20
+ header .title #img {
21
+ background-image: url(../favicon.ico);
22
+ background-size: contain;
23
+ display: inline-block;
24
+ width: 30px;
25
+ }
26
+ header .title span { padding: 5px; }
27
+ section { width: 90%; margin: 0 auto; }
28
+ section > h3 {
29
+ color: #004680;
30
+ font-weight: normal;
31
+ border-bottom: solid 2px #d3d3d3;
32
+ margin: 12px 0;
33
+ font-size: 1.5em;
34
+ }
35
+ th { font-weight: normal; }
36
+ table.no-grid th {
37
+ text-align: right;
38
+ vertical-align: top;
39
+ color: #004680;
40
+ }
41
+ table.no-grid td { padding: 2px 15px; }
42
+ pre { font-family: sans-serif; font-size: medium; }
43
+ table.grid { width: 100%; }
44
+ table.grid th, table.grid td { padding: 2px 10px; border: solid 1px #d3d3d3; }
45
+ table.grid th {
46
+ text-align: left;
47
+ color: #ffffff;
48
+ background-color: #004680;
49
+ }
50
+ div.wrap { margin-bottom: 30px; }
51
+ </style>
52
+ <link rel="shortcut icon" href="../favicon.ico">
53
+ <%-
54
+ table = schema.table(table_name)
55
+ -%>
56
+ <title>ERD [<%= table.display_name %>]</title>
57
+ <script type="text/javascript" src="../jquery2.min.js" ></script>
58
+ <script type="text/javascript" src="../tableViewer.js" ></script>
59
+ </head>
60
+ <body>
61
+ <body>
62
+ <div class="wrap">
63
+ <header>
64
+ <div class="title">
65
+ <span><a data-link-url="/" ><i id="img" >&nbsp;</i>ERD</a></span>
66
+ <span>▶</span>
67
+ <span><%= table.display_name %><% if table_name != table.display_name %>(<%= table_name %>)<% end %></span>
68
+ </div>
69
+ </header>
70
+
71
+ <section>
72
+ <h3><%= locale.t("views.table_summary_title") %></h3>
73
+ <table class="no-grid">
74
+ <tbody>
75
+ <tr>
76
+ <th> <%= locale.t("views.table_name") %> </th><td> <%= table.display_name %> </td>
77
+ </tr>
78
+ <%- if locale.lang != "en" %>
79
+ <tr>
80
+ <th> <%= locale.t("views.table_name_en") %> </th><td> <%= table.name %> </td>
81
+ </tr>
82
+ <%- end -%>
83
+ <tr>
84
+ <th> <%= locale.t("views.parent_tables") %> </th>
85
+ <td> <%= table.relations_as_child.map(&:parent_table).map do |t|
86
+ "<a data-link-url='#{t.name}' >#{t.display_name}</a>"
87
+ end.join(", ") -%> </td>
88
+ </tr>
89
+ <tr>
90
+ <th> <%= locale.t("views.child_tables") %> </th>
91
+ <td> <%= table.relations_as_parent.map(&:child_table).map do |t|
92
+ "<a data-link-url='#{t.name}' >#{t.display_name}</a>"
93
+ end.join(", ") -%> </td>
94
+ </tr>
95
+ </tbody>
96
+ </table>
97
+ </section>
98
+
99
+ <section>
100
+ <h3><%= locale.t("views.description") %></h3>
101
+ <pre><%= table.description %></pre>
102
+ </section>
103
+
104
+ <section>
105
+ <h3><%= locale.t("views.column_definition") %></h3>
106
+ <table class="grid">
107
+ <tbody>
108
+ <tr>
109
+ <th> <%= locale.t("views.column_name") %> </th>
110
+ <%- if locale.lang != "en" %>
111
+ <th> <%= locale.t("views.column_name_en") %> </th>
112
+ <%- end -%>
113
+ <th> <%= locale.t("views.column_type") %> </th>
114
+ <th> <%= locale.t("views.column_precision") %> </th>
115
+ <th> NULL </th>
116
+ <th> <%= locale.t("views.column_default") %> </th>
117
+ <th> <%= locale.t("views.description") %> </th>
118
+ </tr>
119
+ <%- table.columns.each do |col| -%>
120
+ <tr>
121
+ <td> <%= col.display_name %> </td>
122
+ <%- if locale.lang != "en" %>
123
+ <td> <%= col.name %></td>
124
+ <%- end -%>
125
+ <td> <%= col.type %></td>
126
+ <td> <%= col.type == "decimal" ? "#{col.precision},#{col.scale}" : col.limit %> </td>
127
+ <td> <%= col.null || "false" %> </td>
128
+ <td> <%= col.default || "NULL" %> </td>
129
+ <td> <%= col.description %> </td>
130
+ </tr>
131
+ <%- end -%>
132
+ </tbody>
133
+ </table>
134
+ </section>
135
+
136
+ <section>
137
+ <h3><%= locale.t("views.index_definition") %></h3>
138
+ <table class="grid">
139
+ <tbody>
140
+ <tr>
141
+ <th> <%= locale.t("views.index_unique") %> </th>
142
+ <th> <%= locale.t("views.index_target_columns") %> </th>
143
+ <th> <%= locale.t("views.index_name") %> </th>
144
+ </tr>
145
+ <%- table.indexes.each do |idx| -%>
146
+ <tr>
147
+ <td> <%= idx.unique %> </td>
148
+ <td> <%= idx.columns.map {|c| col = table.columns.find{|col| col.name == c }; col && col.display_name }.join(", ") %> </td>
149
+ <td> <%= idx.name %> </td>
150
+ </tr>
151
+ <%- end -%>
152
+ </section>
153
+
154
+ </div><!-- wrap -->
155
+ </body>
156
+ </html>
data/schemard.gemspec ADDED
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "schemard"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "schemard"
8
+ spec.version = SchemaRD::VERSION
9
+ spec.authors = ["ken TANAKA"]
10
+ spec.email = ["x.tanaka.ken.at.gmail.com"]
11
+
12
+ spec.summary = "SchemaRD is a ERD Viewer for schema.rb."
13
+ spec.description = <<-eof
14
+ SchemaRD is a Entity Relationship Diagram Viewer for schema.rb which is used on Ruby On Rails.
15
+ You can browse Entity Relationship Diagram of your schema.rb, on your WebBrowser.
16
+ eof
17
+ spec.homepage = "https://github.com/xketanaka/schemard"
18
+ spec.license = "MIT"
19
+
20
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
21
+ f.match(%r{^(test|spec|features)/})
22
+ end
23
+ spec.executables = ["schemard"]
24
+ spec.require_paths = ["lib"]
25
+
26
+ spec.add_development_dependency "bundler", "~> 1.0"
27
+ spec.add_development_dependency "rake", "~> 0.9"
28
+ end
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: schemard
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - ken TANAKA
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-08-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.9'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.9'
41
+ description: |2
42
+ SchemaRD is a Entity Relationship Diagram Viewer for schema.rb which is used on Ruby On Rails.
43
+ You can browse Entity Relationship Diagram of your schema.rb, on your WebBrowser.
44
+ email:
45
+ - x.tanaka.ken.at.gmail.com
46
+ executables:
47
+ - schemard
48
+ extensions: []
49
+ extra_rdoc_files: []
50
+ files:
51
+ - ".gitignore"
52
+ - Gemfile
53
+ - LICENSE.txt
54
+ - README.ja.md
55
+ - README.md
56
+ - Rakefile
57
+ - bin/schemard
58
+ - lib/contents/favicon.ico
59
+ - lib/contents/jquery2.min.js
60
+ - lib/contents/normalize.css
61
+ - lib/contents/tableViewer.js
62
+ - lib/locales/messages.yml
63
+ - lib/schemard.rb
64
+ - lib/schemard/controller.rb
65
+ - lib/schemard/metadata.rb
66
+ - lib/schemard/rdoc_parser.rb
67
+ - lib/schemard/relation_generator.rb
68
+ - lib/schemard/schema.rb
69
+ - lib/schemard/schema_parser.rb
70
+ - lib/schemard/utils/localizer.rb
71
+ - lib/schemard/utils/singularizer.rb
72
+ - lib/schemard/utils/struct_assigner.rb
73
+ - lib/schemard/web_server.rb
74
+ - lib/templates/index.html.erb
75
+ - lib/templates/show.html.erb
76
+ - schemard.gemspec
77
+ homepage: https://github.com/xketanaka/schemard
78
+ licenses:
79
+ - MIT
80
+ metadata: {}
81
+ post_install_message:
82
+ rdoc_options: []
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ requirements: []
96
+ rubyforge_project:
97
+ rubygems_version: 2.6.11
98
+ signing_key:
99
+ specification_version: 4
100
+ summary: SchemaRD is a ERD Viewer for schema.rb.
101
+ test_files: []