ez_model 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +41 -0
- data/LICENSE +20 -0
- data/README.md +69 -0
- data/bin/ezmodel +165 -0
- data/ez_model.gemspec +29 -0
- data/lib/ez_model/generator.rb +24 -0
- data/lib/ez_model/model.eruby +7 -0
- data/lib/ez_model/version.rb +3 -0
- data/lib/ez_model.rb +2 -0
- data/lib/rmre/LICENSE.txt +20 -0
- data/lib/rmre/active_record/schema_dumper.rb +27 -0
- data/lib/rmre/generator.rb +185 -0
- data/lib/rmre/load_file.eruby +14 -0
- data/lib/rmre/model.eruby +24 -0
- data/lib/rmre/version.rb +3 -0
- data/lib/rmre.rb +2 -0
- metadata +64 -0
data/.gitignore
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# Compiled source #
|
2
|
+
###################
|
3
|
+
*.com
|
4
|
+
*.class
|
5
|
+
*.dll
|
6
|
+
*.exe
|
7
|
+
*.o
|
8
|
+
*.so
|
9
|
+
*.gem
|
10
|
+
.yardoc
|
11
|
+
|
12
|
+
# Packages #
|
13
|
+
############
|
14
|
+
# it's better to unpack these files and commit the raw source
|
15
|
+
# git has its own built in compression methods
|
16
|
+
*.7z
|
17
|
+
*.dmg
|
18
|
+
*.gz
|
19
|
+
*.iso
|
20
|
+
*.jar
|
21
|
+
*.rar
|
22
|
+
*.tar
|
23
|
+
*.zip
|
24
|
+
|
25
|
+
# Logs and databases #
|
26
|
+
######################
|
27
|
+
*.log
|
28
|
+
*.sql
|
29
|
+
*.sqlite
|
30
|
+
|
31
|
+
# OS generated files #
|
32
|
+
######################
|
33
|
+
.DS_Store*
|
34
|
+
ehthumbs.db
|
35
|
+
Icon?
|
36
|
+
Thumbs.db
|
37
|
+
|
38
|
+
# IDE generated files #
|
39
|
+
#######################
|
40
|
+
.idea
|
41
|
+
*~
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Tianyu Huang
|
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,69 @@
|
|
1
|
+
# EZModel
|
2
|
+
Generate models and schema.rb from existing database just in one command line. If you prefer design ER diagram and export scripts to generate database schema, or if you have to work with a legacy database, this can save you insame amount of time. All you need to do is to have a database.yml configuraiton file in ~/config/. Besides creating all models it sets proper table name and primary key if tables and columns naming doesn’t follow Rails convention. It also tries to read all foreign keys data from a database.
|
3
|
+
|
4
|
+
It uses [Rmre](https://github.com/bosko/rmre "Rmre") as underlying reverse engine to generate models. I made some modifications to Rmre to support mysql2 adapter, and had those auto-generated model files placed in a subfolder inside ~/app/models/ez_models/ instead of the default ~/app/models/, so that regenerating models will not overwrite the existing ones. Over the times, db schema can ge changed, all it needs is to run the command again to regenerate models, developers can feel free to add methods to the models classes in ~/app/models/ without worrying about being overwritten.
|
5
|
+
|
6
|
+
## How to use it
|
7
|
+
###Prerequisite
|
8
|
+
####1. Setup database server, mysql is suggested;
|
9
|
+
|
10
|
+
####2. Setup database schema, if you already have a database set up, skip this step;
|
11
|
+
there are many tools can be use for database design, you can then export scripts to generate db schema;
|
12
|
+
checkout mysql-workbench and its forward-engineering feature for more details about designing ER diagram and generate schema;
|
13
|
+
|
14
|
+
####3. Prepare ~/config/database.yml, here is a sample:
|
15
|
+
|
16
|
+
development:
|
17
|
+
adapter: mysql2
|
18
|
+
reconnect: false
|
19
|
+
database: MySchema_development
|
20
|
+
pool: 5
|
21
|
+
username: root
|
22
|
+
password: "123456"
|
23
|
+
socket: /var/run/mysqld/mysqld.sock
|
24
|
+
test:
|
25
|
+
adapter: mysql2
|
26
|
+
reconnect: false
|
27
|
+
database: MySchema_test
|
28
|
+
pool: 5
|
29
|
+
username: root
|
30
|
+
password: "123456"
|
31
|
+
socket: /var/run/mysqld/mysqld.sock
|
32
|
+
production:
|
33
|
+
adapter: mysql2
|
34
|
+
reconnect: false
|
35
|
+
database: MySchema_production
|
36
|
+
pool: 5
|
37
|
+
username: root
|
38
|
+
password: "123456"
|
39
|
+
socket: /var/run/mysqld/mysqld.sock
|
40
|
+
|
41
|
+
###Generate models
|
42
|
+
# generate model files
|
43
|
+
# it will take development as default db environment when environment is not specified
|
44
|
+
ezmodel -g
|
45
|
+
#or
|
46
|
+
ezmodel -g -e development
|
47
|
+
|
48
|
+
# generate model files and overwrite existing ones in ~/app/models/
|
49
|
+
# use this command only if the model files in ~/app/models/ don't inherit EZModel::ActiveRecord
|
50
|
+
# backup your models files is strongly suggested if you are not sure what it is doing
|
51
|
+
# use it at your own risk
|
52
|
+
ezmodel -g -o
|
53
|
+
|
54
|
+
# see help
|
55
|
+
ezmodel -h
|
56
|
+
|
57
|
+
# see version
|
58
|
+
ezmodel -v
|
59
|
+
|
60
|
+
## Installation
|
61
|
+
gem instal ez_model
|
62
|
+
|
63
|
+
See here for more details: [http://rubygems.org/gems/ez_model](http://rubygems.org/gems/ez_model "EZModel RubyGem Page")
|
64
|
+
|
65
|
+
## Author
|
66
|
+
Tianyu Huang
|
67
|
+
The reverse engine for generating models was created by Bosko Ivanisevic, check out https://github.com/bosko/rmre for details
|
68
|
+
|
69
|
+
|
data/bin/ezmodel
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
lib = File.expand_path("../../lib/", __FILE__)
|
2
|
+
$LOAD_PATH.unshift lib unless $LOAD_PATH.include?(lib)
|
3
|
+
|
4
|
+
require "yaml"
|
5
|
+
require "optparse"
|
6
|
+
require "erubis"
|
7
|
+
require "ez_model"
|
8
|
+
require "rmre"
|
9
|
+
|
10
|
+
########################################################################################################
|
11
|
+
# get options from user input
|
12
|
+
########################################################################################################
|
13
|
+
options = {:db => {}}
|
14
|
+
optparse = OptionParser.new do |opts|
|
15
|
+
opts.banner = "Usage: ezmodel -g [options]"
|
16
|
+
|
17
|
+
options[:generate] = false
|
18
|
+
opts.on("-g", "--generate", "Generate models") do
|
19
|
+
options[:generate] = true
|
20
|
+
end
|
21
|
+
|
22
|
+
options[:overwrite] = false
|
23
|
+
opts.on("-o", "--overwrite",
|
24
|
+
"Overwrite models files (back up your models in '~app/models/' before you do so, use it at your own risk)") do
|
25
|
+
options[:overwrite] = true
|
26
|
+
end
|
27
|
+
|
28
|
+
options[:dbconfig] = "config/database.yml"
|
29
|
+
opts.on("-d", "--dbconfig [PATH]",
|
30
|
+
"the path to db config file (default 'config/database.yml')") do |e|
|
31
|
+
options[:environment] = e unless e.nil?
|
32
|
+
end
|
33
|
+
|
34
|
+
options[:environment] = "development"
|
35
|
+
opts.on("-e", "--environment [ENVIRONMENT]",
|
36
|
+
"from which db config you want to choose, choose from 'development/test/production' (default 'development')") do |e|
|
37
|
+
options[:environment] = e unless e.nil?
|
38
|
+
end
|
39
|
+
|
40
|
+
opts.on("-h", "--help", "Display this help screen") do
|
41
|
+
puts opts
|
42
|
+
exit
|
43
|
+
end
|
44
|
+
|
45
|
+
opts.on("-v", "--version", "Show version") do |v|
|
46
|
+
puts "rmre version #{Rmre::VERSION} (modified)"
|
47
|
+
puts "ezmodel version #{EZModel::VERSION}"
|
48
|
+
exit
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
########################################################################################################
|
55
|
+
# parse options
|
56
|
+
########################################################################################################
|
57
|
+
begin
|
58
|
+
optparse.parse!
|
59
|
+
rescue OptionParser::ParseError => pe
|
60
|
+
puts pe.message
|
61
|
+
puts optparse
|
62
|
+
exit
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
if (options[:generate].nil? || options[:generate] == false)
|
67
|
+
puts "Required action is not specified"
|
68
|
+
puts optparse
|
69
|
+
exit
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
########################################################################################################
|
74
|
+
# setup options
|
75
|
+
########################################################################################################
|
76
|
+
d_environment = options[:environment].downcase
|
77
|
+
|
78
|
+
rails_root_path = Dir.pwd + "/"
|
79
|
+
|
80
|
+
puts "Loading db config..."
|
81
|
+
db_config_path = rails_root_path + options[:dbconfig]
|
82
|
+
db_config = YAML::load(File.open(db_config_path))
|
83
|
+
puts "from #{db_config_path}..."
|
84
|
+
|
85
|
+
options[:db].merge!(:adapter => db_config[d_environment]["adapter"])
|
86
|
+
options[:db].merge!(:database => db_config[d_environment]["database"])
|
87
|
+
options[:db].merge!(:username => db_config[d_environment]["username"])
|
88
|
+
options[:db].merge!(:password => db_config[d_environment]["password"])
|
89
|
+
options[:db].merge!(:host => db_config[d_environment]["host"])
|
90
|
+
options[:db].merge!(:port => db_config[d_environment]["port"])
|
91
|
+
options[:db][:timeout] = 5000
|
92
|
+
options[:dump_schema] = rails_root_path + "db/schema.rb"
|
93
|
+
options[:out_path] = rails_root_path + "app/models/ez_models/"
|
94
|
+
options[:model_path] = rails_root_path + "app/models/"
|
95
|
+
|
96
|
+
########################################################################################################
|
97
|
+
# generate ez_models using external rmre
|
98
|
+
# require rmre installed, please use the built-in one instead
|
99
|
+
########################################################################################################
|
100
|
+
|
101
|
+
=begin
|
102
|
+
cmd = ` rmre \
|
103
|
+
-a #{options[:db][:adapter]} \
|
104
|
+
-d #{options[:db][:database]} \
|
105
|
+
-u #{options[:db][:username]} \
|
106
|
+
-p #{options[:db][:password]} \
|
107
|
+
--host #{options[:db][:host]} \
|
108
|
+
--port #{options[:db][:port]} \
|
109
|
+
--out #{options[:out_path]} \
|
110
|
+
--dump-schema #{options[:dump_schema]} \
|
111
|
+
|
112
|
+
`
|
113
|
+
puts cmd
|
114
|
+
=end
|
115
|
+
|
116
|
+
|
117
|
+
########################################################################################################
|
118
|
+
# generate ez_models using built-in rmre(modified)
|
119
|
+
# does not require rmre installed
|
120
|
+
# added mysql2 support and improved model structure
|
121
|
+
########################################################################################################
|
122
|
+
|
123
|
+
FileUtils.mkdir_p options[:out_path] unless File.exist? options[:out_path]
|
124
|
+
|
125
|
+
options = YAML.load_file(options[:file]) if options[:file] && File.exists?(options[:file])
|
126
|
+
|
127
|
+
unless options[:db][:adapter]
|
128
|
+
puts "Missing required arguments -d (--dbconfig) and -e (--environment)"
|
129
|
+
puts optparse
|
130
|
+
exit
|
131
|
+
end
|
132
|
+
|
133
|
+
generator = Rmre::Generator.new(options[:db], options[:out_path], options[:include])
|
134
|
+
|
135
|
+
begin
|
136
|
+
generator.connect
|
137
|
+
rescue Exception => e
|
138
|
+
puts e.message
|
139
|
+
exit
|
140
|
+
end
|
141
|
+
|
142
|
+
if options[:dump_schema]
|
143
|
+
_backup_schema_file = options[:dump_schema]+".bak"
|
144
|
+
if(File.exists?(options[:dump_schema]))
|
145
|
+
puts "Backing up schema file to #{_backup_schema_file}"
|
146
|
+
File.rename(options[:dump_schema], _backup_schema_file)
|
147
|
+
end
|
148
|
+
puts "Dumping schema to #{options[:dump_schema]}..."
|
149
|
+
File.open(options[:dump_schema], 'w') do |file|
|
150
|
+
generator.dump_schema(file)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
puts "Generating base models in #{options[:out_path]}..."
|
155
|
+
generator.create_models(generator.connection.tables)
|
156
|
+
|
157
|
+
########################################################################################################
|
158
|
+
# generate models
|
159
|
+
########################################################################################################
|
160
|
+
|
161
|
+
puts "Generating models in #{options[:model_path]}..."
|
162
|
+
EZModel::Generator.CreateModels(options[:model_path], generator.connection.tables, options[:overwrite])
|
163
|
+
|
164
|
+
puts "Congratulations, your schema.rb and all of your models have been generated"
|
165
|
+
puts "Feel free to customize your model in ~/app/models/"
|
data/ez_model.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
lib = File.expand_path("../lib/", __FILE__)
|
2
|
+
$:.unshift lib unless $:.include?(lib)
|
3
|
+
|
4
|
+
require "ez_model/version"
|
5
|
+
require "rmre/version"
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
|
9
|
+
# Basic info
|
10
|
+
s.name = "ez_model"
|
11
|
+
s.version = ::EZModel::VERSION
|
12
|
+
s.platform = Gem::Platform::RUBY
|
13
|
+
s.date = "2012-04-10"
|
14
|
+
s.summary = "Make it easier to generate easier"
|
15
|
+
s.description = "Generate model files automatically when you have database schema created."
|
16
|
+
s.authors = ["Tianyu Huang"]
|
17
|
+
s.email = ["tianhsky@yahoo.com"]
|
18
|
+
s.homepage = "http://rubygems.org/gems/ez_model"
|
19
|
+
|
20
|
+
# Dependencies
|
21
|
+
# s.required_rubygems_version = ">= 1.3.6"
|
22
|
+
|
23
|
+
# Files
|
24
|
+
s.files = `git ls-files`.split("\n")
|
25
|
+
s.extra_rdoc_files = ["README.md"]
|
26
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
27
|
+
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "tmpdir"
|
2
|
+
require "fileutils"
|
3
|
+
require "erubis"
|
4
|
+
|
5
|
+
module EZModel
|
6
|
+
module Generator
|
7
|
+
def self.CreateModels(path, tables, overwrite=false)
|
8
|
+
return unless tables.is_a? Array
|
9
|
+
|
10
|
+
FileUtils.mkdir_p(path) if !Dir.exists?(path)
|
11
|
+
|
12
|
+
tables.each do |table_name|
|
13
|
+
_file_path = File.join(path, "#{table_name.tableize.singularize}.rb")
|
14
|
+
if (!File.exists?(_file_path) || overwrite)
|
15
|
+
File.open(_file_path, "w") do |file|
|
16
|
+
_eruby = Erubis::Eruby.new(File.read(File.join(File.expand_path("../", __FILE__), 'model.eruby')))
|
17
|
+
_eruby_file = _eruby.result(:table_name => table_name)
|
18
|
+
file.write(_eruby_file)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
require File.expand_path('../ez_models/<%= table_name.tableize.singularize %>', __FILE__)
|
2
|
+
|
3
|
+
# Please add your own methods to this class.
|
4
|
+
# It's strongly recommended to check this file into your version control system.
|
5
|
+
class <%= table_name.tableize.classify %> < EZModel::ActiveRecord::<%= table_name.tableize.classify %>
|
6
|
+
|
7
|
+
end
|
data/lib/ez_model.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Boško Ivanišević
|
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.
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "active_record"
|
2
|
+
require "active_record/base"
|
3
|
+
require "active_record/schema_dumper"
|
4
|
+
|
5
|
+
module ActiveRecord
|
6
|
+
class SchemaDumper
|
7
|
+
def self.dump_with_fk(connection=ActiveRecord::Base.connection, foreign_keys=[], stream=STDOUT)
|
8
|
+
new(connection).dump_with_fk(foreign_keys, stream)
|
9
|
+
stream
|
10
|
+
end
|
11
|
+
|
12
|
+
def dump_with_fk(foreign_keys, stream)
|
13
|
+
header(stream)
|
14
|
+
tables(stream)
|
15
|
+
|
16
|
+
foreign_keys.each do |fk|
|
17
|
+
stream.puts <<-SQL
|
18
|
+
execute "ALTER TABLE #{fk['from_table']} ADD CONSTRAINT fk_#{fk['from_table']}_#{fk['to_table']}
|
19
|
+
FOREIGN KEY (#{fk['from_column']}) REFERENCES #{fk['to_table']}(#{fk['to_column']})"
|
20
|
+
SQL
|
21
|
+
end
|
22
|
+
|
23
|
+
trailer(stream)
|
24
|
+
stream
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,185 @@
|
|
1
|
+
require "tmpdir"
|
2
|
+
require "fileutils"
|
3
|
+
require "erubis"
|
4
|
+
require "rmre/active_record/schema_dumper"
|
5
|
+
|
6
|
+
module Rmre
|
7
|
+
class Generator
|
8
|
+
attr_reader :connection
|
9
|
+
attr_reader :output_path
|
10
|
+
|
11
|
+
SETTINGS_ROOT = File.expand_path('../../../../db', __FILE__)
|
12
|
+
|
13
|
+
def initialize(options, out_path, include)
|
14
|
+
@connection_options = options
|
15
|
+
@connection = nil
|
16
|
+
@output_path = out_path
|
17
|
+
@include_prefixes = include
|
18
|
+
end
|
19
|
+
|
20
|
+
def connect
|
21
|
+
return if @connection_options.empty?
|
22
|
+
|
23
|
+
ActiveRecord::Base.establish_connection(@connection_options)
|
24
|
+
@connection = ActiveRecord::Base.connection
|
25
|
+
end
|
26
|
+
|
27
|
+
def create_models(tables)
|
28
|
+
return unless tables.is_a? Array
|
29
|
+
|
30
|
+
FileUtils.mkdir_p(@output_path) if !Dir.exists?(@output_path)
|
31
|
+
|
32
|
+
tables.each do |table_name|
|
33
|
+
create_model(table_name) if process?(table_name)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def dump_schema(stream)
|
38
|
+
ActiveRecord::SchemaDumper.dump_with_fk(connection, foreign_keys, stream)
|
39
|
+
end
|
40
|
+
|
41
|
+
def create_model(table_name)
|
42
|
+
File.open(File.join(output_path, "#{table_name.tableize.singularize}.rb"), "w") do |file|
|
43
|
+
constraints = []
|
44
|
+
|
45
|
+
foreign_keys.each do |fk|
|
46
|
+
src = constraint_src(table_name, fk)
|
47
|
+
constraints << src unless src.nil?
|
48
|
+
end
|
49
|
+
|
50
|
+
file.write generate_model_source(table_name, constraints)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def process?(table_name)
|
55
|
+
return true if @include_prefixes.nil? || @include_prefixes.empty?
|
56
|
+
|
57
|
+
@include_prefixes.each do |prefix|
|
58
|
+
return true if table_name =~ /^#{prefix}/
|
59
|
+
end
|
60
|
+
|
61
|
+
false
|
62
|
+
end
|
63
|
+
|
64
|
+
def foreign_keys
|
65
|
+
@foreign_keys ||= fetch_foreign_keys
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
def fetch_foreign_keys
|
70
|
+
fk = []
|
71
|
+
case @connection_options[:adapter].downcase
|
72
|
+
when 'mysql'
|
73
|
+
fk = mysql_foreign_keys
|
74
|
+
when 'mysql2'
|
75
|
+
fk = mysql_foreign_keys
|
76
|
+
when 'postgresql'
|
77
|
+
fk = psql_foreign_keys
|
78
|
+
when 'sqlserver'
|
79
|
+
fk = mssql_foreign_keys
|
80
|
+
when 'oracle_enhanced'
|
81
|
+
fk = oracle_foreign_keys
|
82
|
+
end
|
83
|
+
fk
|
84
|
+
end
|
85
|
+
|
86
|
+
def constraint_src(table_name, fk={})
|
87
|
+
src = nil
|
88
|
+
if fk['from_table'] == table_name
|
89
|
+
src = "belongs_to :#{fk['to_table'].downcase}, :class_name => '#{fk['to_table'].tableize.classify}', :foreign_key => :#{fk['from_column']}"
|
90
|
+
elsif fk['to_table'] == table_name
|
91
|
+
src = "has_many :#{fk['from_table'].downcase.pluralize}, :class_name => '#{fk['from_table'].tableize.classify}'"
|
92
|
+
end
|
93
|
+
src
|
94
|
+
end
|
95
|
+
|
96
|
+
def generate_model_source(table_name, constraints)
|
97
|
+
eruby = Erubis::Eruby.new(File.read(File.join(File.expand_path("../", __FILE__), 'model.eruby')))
|
98
|
+
eruby.result(
|
99
|
+
:table_name => table_name,
|
100
|
+
:primary_key => connection.primary_key(table_name),
|
101
|
+
:constraints => constraints,
|
102
|
+
:has_type_column => connection.columns(table_name).find { |col| col.name == 'type' })
|
103
|
+
end
|
104
|
+
|
105
|
+
def mysql_foreign_keys
|
106
|
+
sql = <<-SQL
|
107
|
+
select
|
108
|
+
table_name as from_table,
|
109
|
+
column_name as from_column,
|
110
|
+
referenced_table_name as to_table,
|
111
|
+
referenced_column_name as to_column
|
112
|
+
from information_schema.KEY_COLUMN_USAGE
|
113
|
+
where referenced_table_schema like '%'
|
114
|
+
and constraint_schema = '#{@connection_options[:database]}'
|
115
|
+
and referenced_table_name is not null
|
116
|
+
SQL
|
117
|
+
connection.select_all(sql)
|
118
|
+
end
|
119
|
+
|
120
|
+
def psql_foreign_keys
|
121
|
+
sql = <<-SQL
|
122
|
+
SELECT tc.table_name as from_table,
|
123
|
+
kcu.column_name as from_column,
|
124
|
+
ccu.table_name AS to_table,
|
125
|
+
ccu.column_name AS to_column
|
126
|
+
FROM information_schema.table_constraints tc
|
127
|
+
LEFT JOIN information_schema.key_column_usage kcu
|
128
|
+
ON tc.constraint_catalog = kcu.constraint_catalog
|
129
|
+
AND tc.constraint_schema = kcu.constraint_schema
|
130
|
+
AND tc.constraint_name = kcu.constraint_name
|
131
|
+
|
132
|
+
LEFT JOIN information_schema.referential_constraints rc
|
133
|
+
ON tc.constraint_catalog = rc.constraint_catalog
|
134
|
+
AND tc.constraint_schema = rc.constraint_schema
|
135
|
+
AND tc.constraint_name = rc.constraint_name
|
136
|
+
LEFT JOIN information_schema.constraint_column_usage ccu
|
137
|
+
ON rc.unique_constraint_catalog = ccu.constraint_catalog
|
138
|
+
AND rc.unique_constraint_schema = ccu.constraint_schema
|
139
|
+
AND rc.unique_constraint_name = ccu.constraint_name
|
140
|
+
WHERE tc.table_name like '%'
|
141
|
+
AND tc.constraint_type = 'FOREIGN KEY';
|
142
|
+
SQL
|
143
|
+
connection.select_all(sql)
|
144
|
+
end
|
145
|
+
|
146
|
+
def mssql_foreign_keys
|
147
|
+
sql = <<-SQL
|
148
|
+
SELECT C.TABLE_NAME [from_table],
|
149
|
+
KCU.COLUMN_NAME [from_column],
|
150
|
+
C2.TABLE_NAME [to_table],
|
151
|
+
KCU2.COLUMN_NAME [to_column]
|
152
|
+
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS C
|
153
|
+
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU
|
154
|
+
ON C.CONSTRAINT_SCHEMA = KCU.CONSTRAINT_SCHEMA
|
155
|
+
AND C.CONSTRAINT_NAME = KCU.CONSTRAINT_NAME
|
156
|
+
INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS RC
|
157
|
+
ON C.CONSTRAINT_SCHEMA = RC.CONSTRAINT_SCHEMA
|
158
|
+
AND C.CONSTRAINT_NAME = RC.CONSTRAINT_NAME
|
159
|
+
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS C2
|
160
|
+
ON RC.UNIQUE_CONSTRAINT_SCHEMA = C2.CONSTRAINT_SCHEMA
|
161
|
+
AND RC.UNIQUE_CONSTRAINT_NAME = C2.CONSTRAINT_NAME
|
162
|
+
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU2
|
163
|
+
ON C2.CONSTRAINT_SCHEMA = KCU2.CONSTRAINT_SCHEMA
|
164
|
+
AND C2.CONSTRAINT_NAME = KCU2.CONSTRAINT_NAME
|
165
|
+
AND KCU.ORDINAL_POSITION = KCU2.ORDINAL_POSITION
|
166
|
+
WHERE C.CONSTRAINT_TYPE = 'FOREIGN KEY'
|
167
|
+
SQL
|
168
|
+
connection.select_all(sql)
|
169
|
+
end
|
170
|
+
|
171
|
+
def oracle_foreign_keys
|
172
|
+
fk = []
|
173
|
+
connection.tables.each do |table|
|
174
|
+
connection.foreign_keys(table).each do |oracle_fk|
|
175
|
+
table_fk = { 'from_table' => oracle_fk.from_table,
|
176
|
+
'from_column' => oracle_fk.options[:columns][0],
|
177
|
+
'to_table' => oracle_fk.to_table,
|
178
|
+
'to_column' => oracle_fk.options[:references][0] }
|
179
|
+
fk << table_fk
|
180
|
+
end
|
181
|
+
end
|
182
|
+
fk
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require "yaml"
|
2
|
+
require "active_record"
|
3
|
+
|
4
|
+
<%= "dir = File.join('#{out_path}', '*.rb')" %>
|
5
|
+
Dir.glob(dir) { |file| require file }
|
6
|
+
|
7
|
+
def connect
|
8
|
+
<%= "settings_file = './#{file_name}.yml'" %>
|
9
|
+
exit unless File.exists?(settings_file)
|
10
|
+
settings = YAML.load_file(settings_file)
|
11
|
+
ActiveRecord::Base.establish_connection(settings[:db])
|
12
|
+
ActiveRecord::Base.connection
|
13
|
+
end
|
14
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# This file is auto-generated from the current state of the database registered
|
2
|
+
# in ~config/database.yml. Instead of editing this file, please go to ~/app/models/
|
3
|
+
# and find the file with same name and class that inherits this class
|
4
|
+
module EZModel
|
5
|
+
module ActiveRecord
|
6
|
+
class <%= table_name.tableize.classify %> < ActiveRecord::Base
|
7
|
+
<% unless table_name == table_name.tableize %>
|
8
|
+
<%= "set_table_name '#{table_name}'" + "\n" -%>
|
9
|
+
<% end %>
|
10
|
+
|
11
|
+
<% unless "id" == primary_key || primary_key.nil? %>
|
12
|
+
<%= "set_primary_key :#{primary_key}" + "\n" -%>
|
13
|
+
<% end %>
|
14
|
+
|
15
|
+
<% if has_type_column %>
|
16
|
+
<%= "set_inheritance_column :ruby_type" + "\n" -%>
|
17
|
+
<% end %>
|
18
|
+
|
19
|
+
<% constraints.each do |constraint| %>
|
20
|
+
<%= constraint + "\n" -%>
|
21
|
+
<% end %>
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/rmre/version.rb
ADDED
data/lib/rmre.rb
ADDED
metadata
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ez_model
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Tianyu Huang
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-04-10 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Generate model files automatically when you have database schema created.
|
15
|
+
email:
|
16
|
+
- tianhsky@yahoo.com
|
17
|
+
executables:
|
18
|
+
- ezmodel
|
19
|
+
extensions: []
|
20
|
+
extra_rdoc_files:
|
21
|
+
- README.md
|
22
|
+
files:
|
23
|
+
- .gitignore
|
24
|
+
- LICENSE
|
25
|
+
- README.md
|
26
|
+
- bin/ezmodel
|
27
|
+
- ez_model.gemspec
|
28
|
+
- lib/ez_model.rb
|
29
|
+
- lib/ez_model/generator.rb
|
30
|
+
- lib/ez_model/model.eruby
|
31
|
+
- lib/ez_model/version.rb
|
32
|
+
- lib/rmre.rb
|
33
|
+
- lib/rmre/LICENSE.txt
|
34
|
+
- lib/rmre/active_record/schema_dumper.rb
|
35
|
+
- lib/rmre/generator.rb
|
36
|
+
- lib/rmre/load_file.eruby
|
37
|
+
- lib/rmre/model.eruby
|
38
|
+
- lib/rmre/version.rb
|
39
|
+
homepage: http://rubygems.org/gems/ez_model
|
40
|
+
licenses: []
|
41
|
+
post_install_message:
|
42
|
+
rdoc_options: []
|
43
|
+
require_paths:
|
44
|
+
- lib
|
45
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
46
|
+
none: false
|
47
|
+
requirements:
|
48
|
+
- - ! '>='
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '0'
|
51
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ! '>='
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
requirements: []
|
58
|
+
rubyforge_project:
|
59
|
+
rubygems_version: 1.8.17
|
60
|
+
signing_key:
|
61
|
+
specification_version: 3
|
62
|
+
summary: Make it easier to generate easier
|
63
|
+
test_files: []
|
64
|
+
has_rdoc:
|