ez_model 1.0.5 → 1.0.6

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,54 +1,12 @@
1
1
  # EZModel
2
2
 
3
- 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 insane 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.
4
-
5
- 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.
6
-
7
-
8
- ## How it works
9
-
10
- First let's take a look at what it does.
11
-
12
- In ~/app/models/ez_models/, it will generate model files inherit ActiveRecord::Base
13
-
14
- ~/app/models/ez_models/billing_info.rb
15
-
16
- # This file is auto-generated from the current state of the database registered
17
- # in ~config/database.yml. Instead of editing this file, please go to ~/app/models/
18
- # and find the file with same name and class that inherits this class
19
- module EZModel
20
- module ActiveRecord
21
- class BillingInfo < ::ActiveRecord::Base
22
- belongs_to :users, :class_name => 'User', :foreign_key => :user_id
23
- belongs_to :invoices, :class_name => 'Invoice', :foreign_key => :invoice_id
24
- has_many :chargebacks, :class_name => 'Chargeback'
25
- end
26
- end
27
- end
28
-
29
- Isn't model files supposed to be in ~/app/models/? Take a look at the following first
30
- In ~/app/models/, it will generate same model files and inherit the above classes
31
-
32
- ~/app/models/billing_info.rb
33
-
34
- require File.expand_path('../ez_models/billing_info', __FILE__)
35
- # Please add your own methods to this class.
36
- # It's strongly recommended to check this file into your version control system.
37
- class BillingInfo < EZModel::ActiveRecord::BillingInfo
38
-
39
- end
40
-
3
+ Automatically generate model files from database.
41
4
 
42
5
  ## How to use it
43
6
 
44
- ###Prerequisite
7
+ ###1. Setup database
45
8
 
46
- ####1. Setup database schema, if you already have a database set up, skip this step;
47
-
48
- there are many tools can be use for database design, you can then export scripts to generate db schema;
49
- checkout mysql-workbench and its forward-engineering feature for more details about designing ER diagram and generate schema;
50
-
51
- ####2. Prepare ~/config/database.yml, here is a sample:
9
+ ###2. Prepare ~/config/database.yml, here is a sample:
52
10
 
53
11
  development:
54
12
  adapter: mysql2
@@ -89,13 +47,6 @@ or
89
47
 
90
48
  ezmodel -g -e development
91
49
 
92
- generate model files and overwrite existing ones in ~/app/models/
93
- use this command only if the model files in ~/app/models/ don't inherit EZModel::ActiveRecord
94
- backup your models files is strongly suggested if you are not sure what it is doing
95
- use it at your own risk
96
-
97
- ezmodel -g -o
98
-
99
50
  see help
100
51
 
101
52
  ezmodel -h
data/bin/ezmodel CHANGED
@@ -5,6 +5,7 @@ $LOAD_PATH.unshift lib unless $LOAD_PATH.include?(lib)
5
5
  require "yaml"
6
6
  require "optparse"
7
7
  require "erubis"
8
+ require "fileutils"
8
9
  require "ez_model"
9
10
  require "rmre"
10
11
 
@@ -20,11 +21,13 @@ optparse = OptionParser.new do |opts|
20
21
  options[:generate] = true
21
22
  end
22
23
 
24
+ =begin
23
25
  options[:overwrite] = false
24
26
  opts.on("-o", "--overwrite",
25
27
  "Overwrite model files (before you do so, back up your models in '~app/models/')") do
26
28
  options[:overwrite] = true
27
29
  end
30
+ =end
28
31
 
29
32
  options[:dbconfig] = "config/database.yml"
30
33
  opts.on("-d", "--dbconfig PATH",
@@ -91,8 +94,9 @@ options[:db].merge!(:host => db_config[d_environment]["host"])
91
94
  options[:db].merge!(:port => db_config[d_environment]["port"])
92
95
  options[:db][:timeout] = 5000
93
96
  options[:dump_schema] = rails_root_path + "db/schema.rb"
94
- options[:out_path] = rails_root_path + "app/models/ez_models/"
97
+ options[:out_path] = rails_root_path + "app/models/"
95
98
  options[:model_path] = rails_root_path + "app/models/"
99
+ options[:old_model_path] = rails_root_path + "app/models/ez_models/"
96
100
 
97
101
  ########################################################################################################
98
102
  # generate ez_models using external rmre
@@ -142,9 +146,9 @@ end
142
146
 
143
147
  if options[:dump_schema]
144
148
  _backup_schema_file = options[:dump_schema]+".bak"
145
- if(File.exists?(options[:dump_schema]))
146
- puts "Backing up schema file to #{_backup_schema_file}"
147
- File.rename(options[:dump_schema], _backup_schema_file)
149
+ if (File.exists?(options[:dump_schema]))
150
+ puts "Backing up schema file to #{_backup_schema_file}"
151
+ File.rename(options[:dump_schema], _backup_schema_file)
148
152
  end
149
153
  puts "Dumping schema to #{options[:dump_schema]}..."
150
154
  File.open(options[:dump_schema], 'w') do |file|
@@ -152,15 +156,17 @@ if options[:dump_schema]
152
156
  end
153
157
  end
154
158
 
155
- puts "Generating base models in #{options[:out_path]}..."
159
+ puts "Generating models in #{options[:out_path]}..."
156
160
  generator.create_models(generator.connection.tables)
157
161
 
158
162
  ########################################################################################################
159
163
  # generate models
160
164
  ########################################################################################################
161
165
 
162
- puts "Generating models in #{options[:model_path]}..."
163
- EZModel::Generator.CreateModels(options[:model_path], generator.connection.tables, options[:overwrite])
166
+ #puts "Generating models in #{options[:model_path]}..."
167
+ #EZModel::Generator.CreateModels(options[:model_path], generator.connection.tables, options[:overwrite])
168
+
169
+ # remove old base model
170
+ FileUtils.rm_rf(options[:old_model_path]) if Dir.exists?(options[:old_model_path])
164
171
 
165
- puts "Congratulations, your schema.rb and all of your models have been generated"
166
- puts "Feel free to customize your model in ~/app/models/"
172
+ puts "Congratulations, your schema.rb and models have been generated"
@@ -1,3 +1,3 @@
1
1
  module EZModel
2
- VERSION = "1.0.5" unless defined?(::EZModel::VERSION)
2
+ VERSION = "1.0.6" unless defined?(::EZModel::VERSION)
3
3
  end
@@ -0,0 +1,14 @@
1
+ ##########BEGIN-EZMODEL-AUTO-GENERATED-SECTION##########
2
+ <% unless table_name == table_name.tableize %>
3
+ <%= "set_table_name '#{table_name}'" + "\n" -%>
4
+ <% end %>
5
+ <% unless "id" == primary_key || primary_key.nil? %>
6
+ <%= "set_primary_key :#{primary_key}" + "\n" -%>
7
+ <% end %>
8
+ <% if has_type_column %>
9
+ <%= "set_inheritance_column :ruby_type" + "\n" -%>
10
+ <% end %>
11
+ <% constraints.each do |constraint| %>
12
+ <%= constraint + "\n" -%>
13
+ <% end %>
14
+ ##########END-EZMODEL-AUTO-GENERATED-SECTION##########
@@ -10,6 +10,9 @@ module Rmre
10
10
 
11
11
  SETTINGS_ROOT = File.expand_path('../../../../db', __FILE__)
12
12
 
13
+ BEGIN_TAG = "##########BEGIN-EZMODEL-AUTO-GENERATED-SECTION##########"
14
+ END_TAG = "##########END-EZMODEL-AUTO-GENERATED-SECTION##########"
15
+
13
16
  def initialize(options, out_path, include)
14
17
  @connection_options = options
15
18
  @connection = nil
@@ -39,16 +42,72 @@ module Rmre
39
42
  end
40
43
 
41
44
  def create_model(table_name)
42
- File.open(File.join(output_path, "#{table_name.tableize.singularize}.rb"), "w") do |file|
43
- constraints = []
45
+ constraints = []
46
+
47
+ foreign_keys.each do |fk|
48
+ src = constraint_src(table_name, fk)
49
+ constraints << src unless src.nil?
50
+ end
51
+
52
+ _file_path = File.join(output_path, "#{table_name.tableize.singularize}.rb")
53
+ if (!File.exists?(_file_path))
54
+ content = generate_model_source(table_name, constraints)
55
+ else
56
+
57
+ # read file content
58
+ file = File.open(_file_path, "r+")
59
+ content = ""
60
+ line_begin = -1
61
+ line_end = -1
62
+ i = -1
63
+ while (!file.eof?)
64
+ i = i+1
65
+ _line = file.readline
66
+
67
+ # remove old code
68
+ if (_line.include?(table_name.tableize.classify) &&
69
+ _line.include?("EZModel::ActiveRecord"))
70
+ _line = "class #{table_name.tableize.classify} < ActiveRecord::Base \n"
71
+ end
72
+
73
+ if (_line.include?(BEGIN_TAG))
74
+ line_begin = i
75
+ end
76
+ if (_line.include?(END_TAG))
77
+ line_end = i
78
+ end
79
+
80
+ content += _line
81
+ end
82
+ file.close()
83
+
84
+ # remove auto generated code
85
+ if (line_begin<line_end)
86
+ content = content.gsub(/#{BEGIN_TAG}(.*)#{END_TAG}/im, "")
87
+ end
44
88
 
45
- foreign_keys.each do |fk|
46
- src = constraint_src(table_name, fk)
47
- constraints << src unless src.nil?
89
+ _text = content
90
+ content = ""
91
+ _text.split("\n").each do |_line|
92
+
93
+ # remove include header from old version
94
+ unless (_line.include?("require File.expand_path('../ez_models"))
95
+ content += _line + "\n"
96
+ end
97
+
98
+ # add auto-gen code below class
99
+ if (_line.include?(table_name.tableize.classify) &&
100
+ _line.include?("ActiveRecord::Base"))
101
+ _body = generate_model_content(table_name, constraints)
102
+ content += _body + "\n"
103
+ end
48
104
  end
105
+ end
49
106
 
50
- file.write generate_model_source(table_name, constraints)
107
+ File.open(_file_path, "w") do |file|
108
+ file.write(content)
51
109
  end
110
+
52
111
  end
53
112
 
54
113
  def process?(table_name)
@@ -69,16 +128,16 @@ module Rmre
69
128
  def fetch_foreign_keys
70
129
  fk = []
71
130
  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
131
+ when 'mysql'
132
+ fk = mysql_foreign_keys
133
+ when 'mysql2'
134
+ fk = mysql_foreign_keys
135
+ when 'postgresql'
136
+ fk = psql_foreign_keys
137
+ when 'sqlserver'
138
+ fk = mssql_foreign_keys
139
+ when 'oracle_enhanced'
140
+ fk = oracle_foreign_keys
82
141
  end
83
142
  fk
84
143
  end
@@ -96,10 +155,19 @@ module Rmre
96
155
  def generate_model_source(table_name, constraints)
97
156
  eruby = Erubis::Eruby.new(File.read(File.join(File.expand_path("../", __FILE__), 'model.eruby')))
98
157
  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' })
158
+ :table_name => table_name,
159
+ :primary_key => connection.primary_key(table_name),
160
+ :constraints => constraints,
161
+ :has_type_column => connection.columns(table_name).find { |col| col.name == 'type' })
162
+ end
163
+
164
+ def generate_model_content(table_name, constraints)
165
+ eruby = Erubis::Eruby.new(File.read(File.join(File.expand_path("../", __FILE__), 'content.eruby')))
166
+ eruby.result(
167
+ :table_name => table_name,
168
+ :primary_key => connection.primary_key(table_name),
169
+ :constraints => constraints,
170
+ :has_type_column => connection.columns(table_name).find { |col| col.name == 'type' })
103
171
  end
104
172
 
105
173
  def mysql_foreign_keys
@@ -113,7 +181,7 @@ from information_schema.KEY_COLUMN_USAGE
113
181
  where referenced_table_schema like '%'
114
182
  and constraint_schema = '#{@connection_options[:database]}'
115
183
  and referenced_table_name is not null
116
- SQL
184
+ SQL
117
185
  connection.select_all(sql)
118
186
  end
119
187
 
@@ -139,7 +207,7 @@ SELECT tc.table_name as from_table,
139
207
  AND rc.unique_constraint_name = ccu.constraint_name
140
208
  WHERE tc.table_name like '%'
141
209
  AND tc.constraint_type = 'FOREIGN KEY';
142
- SQL
210
+ SQL
143
211
  connection.select_all(sql)
144
212
  end
145
213
 
@@ -164,7 +232,7 @@ FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS C
164
232
  AND C2.CONSTRAINT_NAME = KCU2.CONSTRAINT_NAME
165
233
  AND KCU.ORDINAL_POSITION = KCU2.ORDINAL_POSITION
166
234
  WHERE C.CONSTRAINT_TYPE = 'FOREIGN KEY'
167
- SQL
235
+ SQL
168
236
  connection.select_all(sql)
169
237
  end
170
238
 
@@ -172,10 +240,10 @@ SQL
172
240
  fk = []
173
241
  connection.tables.each do |table|
174
242
  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] }
243
+ table_fk = {'from_table' => oracle_fk.from_table,
244
+ 'from_column' => oracle_fk.options[:columns][0],
245
+ 'to_table' => oracle_fk.to_table,
246
+ 'to_column' => oracle_fk.options[:references][0]}
179
247
  fk << table_fk
180
248
  end
181
249
  end
data/lib/rmre/model.eruby CHANGED
@@ -1,24 +1,19 @@
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
1
 
11
- <% unless "id" == primary_key || primary_key.nil? %>
12
- <%= "set_primary_key :#{primary_key}" + "\n" -%>
13
- <% end %>
2
+ class <%= table_name.tableize.classify %> < ActiveRecord::Base
3
+ ##########BEGIN-EZMODEL-AUTO-GENERATED-SECTION##########
4
+ <% unless table_name == table_name.tableize %>
5
+ <%= "set_table_name '#{table_name}'" + "\n" -%>
6
+ <% end %>
7
+ <% unless "id" == primary_key || primary_key.nil? %>
8
+ <%= "set_primary_key :#{primary_key}" + "\n" -%>
9
+ <% end %>
10
+ <% if has_type_column %>
11
+ <%= "set_inheritance_column :ruby_type" + "\n" -%>
12
+ <% end %>
13
+ <% constraints.each do |constraint| %>
14
+ <%= constraint + "\n" -%>
15
+ <% end %>
16
+ ##########END-EZMODEL-AUTO-GENERATED-SECTION##########
14
17
 
15
- <% if has_type_column %>
16
- <%= "set_inheritance_column :ruby_type" + "\n" -%>
17
- <% end %>
18
18
 
19
- <% constraints.each do |constraint| %>
20
- <%= constraint + "\n" -%>
21
- <% end %>
22
- end
23
- end
24
19
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ez_model
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.5
4
+ version: 1.0.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -72,6 +72,7 @@ files:
72
72
  - lib/rmre.rb
73
73
  - lib/rmre/LICENSE.txt
74
74
  - lib/rmre/active_record/schema_dumper.rb
75
+ - lib/rmre/content.eruby
75
76
  - lib/rmre/generator.rb
76
77
  - lib/rmre/load_file.eruby
77
78
  - lib/rmre/model.eruby