rare_map 2.1.1 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 35d4ce6e64d68bef4eb2893fa6468d8b854b2c32
4
- data.tar.gz: c2a4f131953a569b8a5fd4484ff069fefed37644
3
+ metadata.gz: d2a5bcbd97c37310f2e809a4328490c44076bd06
4
+ data.tar.gz: f7fb2de31bbf07022673ad8a3e4655351f902e8a
5
5
  SHA512:
6
- metadata.gz: 0c5132d0e2da33a6bb4048165baaf4e8974bc3488bf0915434ffbfe78570235d316634518af8a0c5037d3180ab0c9c01d0f674f70f30761f3d714af6205d5a1a
7
- data.tar.gz: 78f48e16fdf5c9c7880cfc447d324d3bf1ef4dca2f217846e835cd1a31a07ccd327e685e9047c5c89cc94618fcb185968c9104e59ffba5e9d11d5dbacea69181
6
+ metadata.gz: 839fb36c3ea95902213b7b2507ba2231b1238cee119fc9703a44af158b948d9add23725f2208f992623e7f472e7c1eefb94c23cce6e108435733f2da77044d1c
7
+ data.tar.gz: 8c1f2ccfe9102b00e9b43f03004a16a5f8e2e141e79cd107f7b0d5e3bd16c7fda53122dc2e4abd92d37d920e5c0976817bfa3c8c8b888b24297188cc4ec44186
data/Rakefile CHANGED
@@ -4,24 +4,9 @@ begin
4
4
  rescue LoadError
5
5
  puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
6
  end
7
- begin
8
- require 'rdoc/task'
9
- rescue LoadError
10
- require 'rdoc/rdoc'
11
- require 'rake/rdoctask'
12
- RDoc::Task = Rake::RDocTask
13
- end
14
-
15
- RDoc::Task.new(:rdoc) do |rdoc|
16
- rdoc.rdoc_dir = 'rdoc'
17
- rdoc.title = 'RareMap'
18
- rdoc.options << '--line-numbers'
19
- rdoc.rdoc_files.include('README.rdoc')
20
- rdoc.rdoc_files.include('lib/**/*.rb')
21
- end
22
-
23
-
24
7
 
8
+ require 'yard'
9
+ YARD::Rake::YardocTask.new
25
10
 
26
11
  Bundler::GemHelper.install_tasks
27
12
 
@@ -34,5 +19,4 @@ Rake::TestTask.new(:test) do |t|
34
19
  t.verbose = false
35
20
  end
36
21
 
37
-
38
- task :default => :test
22
+ task :default => :test
@@ -5,20 +5,29 @@ require 'rare_map/schema_parser'
5
5
  require 'rare_map/model_builder'
6
6
  require 'rare_map/model_generator'
7
7
 
8
+ # RareMap
9
+ # @author Wei-Ming Wu
8
10
  module RareMap
11
+ # A class method to make RareMap::Mapper#mapping easy to be called.
9
12
  def self.mapping
10
13
  Mapper.new.mapping
11
14
  end
12
15
 
16
+ # RareMap::Mapper converts relational databases into ActiveRecord files.
17
+ # @author Wei-Ming Wu
13
18
  class Mapper
14
19
  include RailsLocator, ConfigLoader, SchemaReader, SchemaParser, ModelBuilder, ModelGenerator
15
20
 
21
+ # Creates a Mapper.
22
+ #
23
+ # @return [Mapper] a Mapper object
16
24
  def initialize
17
25
  @rails_root = locate_rails_root
18
26
  end
19
27
 
28
+ # Converts relational databases into ActiveRecord files by given RareMap config yaml file.
20
29
  def mapping
21
- @db_profiles = load_config @rails_root ? @rails_root + 'config/' : './'
30
+ @db_profiles = load_config @rails_root ? File.join(@rails_root, 'config') : '.'
22
31
  @db_profiles.each do |profile|
23
32
  profile.schema = read_schema profile
24
33
  profile.tables = parse_schema profile.schema
@@ -37,11 +46,12 @@ module RareMap
37
46
  end
38
47
  @models
39
48
 
40
- rescue ConfigNotFoundError => e
41
- puts "Please put your database config in `#{'config/' if @rails_root}rare_map.yml`."
49
+ rescue ConfigNotFoundError => e
50
+ puts "Please put your database config in `#{'config/' if @rails_root}rare_map.yml`."
42
51
  end
43
52
 
44
53
  private
54
+
45
55
  def generate_demo
46
56
  f = File.new('demo.rb', 'w')
47
57
  f.write "require 'active_record'\n"
@@ -0,0 +1,42 @@
1
+ module RareMap
2
+ # RareMap::Column defines a column of a database table.
3
+ # @author Wei-Ming Wu
4
+ # @!attribute [r] name
5
+ # @return [String] the name of this Column
6
+ # @!attribute [r] type
7
+ # @return [String] the type of this Column
8
+ # @!attribute unique
9
+ # @return [true, false] the uniqueness of this Column
10
+ # @!attribute ref_table
11
+ # @return [String] the reference table of this Column
12
+ class Column
13
+ attr_reader :name, :type
14
+ attr_accessor :unique
15
+ attr_accessor :ref_table
16
+
17
+ # Creates a Column.
18
+ #
19
+ # @param name [String] the name of column
20
+ # @param type [String] the type of column
21
+ # @return [Column] a Column object
22
+ def initialize(name, type, opts = {})
23
+ @name = name
24
+ @type = type
25
+ @unique = opts[:unique] == true
26
+ end
27
+
28
+ # Checks if this Column is unique.
29
+ #
30
+ # @return [true, false] true if it's unique, false otherwise
31
+ def unique?
32
+ @unique
33
+ end
34
+
35
+ # Checks if this Column is a foreign key.
36
+ #
37
+ # @return [true, false] true if it's a foreign key, false otherwise
38
+ def foreign_key?
39
+ @ref_table ? true : false
40
+ end
41
+ end
42
+ end
@@ -1,17 +1,29 @@
1
1
  require 'yaml'
2
2
  require 'rare_map/errors'
3
+ require 'rare_map/database_profile'
4
+ require 'rare_map/options'
3
5
 
4
6
  module RareMap
7
+ # RareMap::ConfigLoader translates a rare_map.yml into DatabaseProfile.
8
+ # @author Wei-Ming Wu
5
9
  module ConfigLoader
10
+ # The key of rare map options inside a config YAML.
6
11
  OPTS_KEY = 'rare_map_opts'
7
-
8
- def load_config(path, file_name = 'rare_map.yml')
9
- raise ConfigNotFoundError unless File.exist? "#{path}#{file_name}"
10
- config = YAML.load_file "#{path}#{file_name}"
12
+ include Errors
13
+
14
+ # Translates a rare_map.yaml into an Array of DatabaseProfile.
15
+ #
16
+ # @param [String] path the folder which contains the RareMap config
17
+ # @param [String] file_name the name of the RareMap config
18
+ # @return [Array] an Array of DatabaseProfile
19
+ def load_config(path = '.', file_name = 'rare_map.yml')
20
+ raise ConfigNotFoundError unless File.exist? File.join(path, file_name)
21
+ config = YAML.load_file File.join(path, file_name)
11
22
  organize_config_properties config['rare_map'] || config || {}
12
23
  end
13
24
 
14
25
  private
26
+
15
27
  def organize_config_properties(raw_config)
16
28
  db_profiles = []
17
29
  global_opts = Options.new(raw_config.delete OPTS_KEY)
@@ -26,11 +38,11 @@ module RareMap
26
38
  end
27
39
  when 'Array'
28
40
  v = v.reduce(:merge)
29
- group_opts = Options.new(v.delete(OPTS_KEY) || global_opts.opts, k)
41
+ group_opts = Options.new((v.delete(OPTS_KEY) || global_opts.opts).merge(group: k))
30
42
 
31
43
  v.each do |db, config|
32
44
  if config[OPTS_KEY]
33
- db_profiles << DatabaseProfile.new(db, remove_opts(config), Options.new(config[OPTS_KEY], k))
45
+ db_profiles << DatabaseProfile.new(db, remove_opts(config), Options.new(config[OPTS_KEY].merge(group: k)))
34
46
  else
35
47
  db_profiles << DatabaseProfile.new(db, config, group_opts)
36
48
  end
@@ -45,67 +57,4 @@ module RareMap
45
57
  db.select { |k, _| k != OPTS_KEY }
46
58
  end
47
59
  end
48
-
49
- class DatabaseProfile
50
- attr_reader :name, :connection, :options
51
- attr_accessor :schema, :tables
52
-
53
- def initialize(name, connection, options)
54
- @name, @connection = name, connection
55
- @options = options || Options.new
56
- @tables = []
57
- end
58
- end
59
-
60
- class Options
61
- attr_reader :opts
62
-
63
- def initialize(raw_opts = nil, group = nil)
64
- @opts = { 'group' => 'default',
65
- 'primary_key' => {},
66
- 'foreign_key' => { 'suffix' => nil, 'alias' => {} } }
67
-
68
- if raw_opts and raw_opts.kind_of? Hash
69
- if raw_opts['group']
70
- @opts['group'] = raw_opts['group']
71
- end
72
- if raw_opts['primary_key'].kind_of? Hash
73
- @opts['primary_key'] = raw_opts['primary_key'].select { |k, v| k.kind_of? String and v.kind_of? String }
74
- end
75
- if raw_opts['foreign_key'] and raw_opts['foreign_key']['suffix'].kind_of? String
76
- @opts['foreign_key']['suffix'] = raw_opts['foreign_key']['suffix']
77
- end
78
- if raw_opts['foreign_key'] and raw_opts['foreign_key']['alias'].kind_of? Hash
79
- @opts['foreign_key']['alias'] = raw_opts['foreign_key']['alias'].select { |k, v| k.kind_of? String and v.kind_of? String }
80
- end
81
- end
82
- @opts['group'] = group if group.kind_of? String
83
- end
84
-
85
- def group?
86
- @opts['group'] != 'default'
87
- end
88
-
89
- def group
90
- @opts['group'] || 'default'
91
- end
92
-
93
- def find_primary_key_by_table(table_name)
94
- @opts['primary_key'].each { |k, v| return v if k == table_name }
95
- nil
96
- end
97
-
98
- def find_table_by_foreign_key(column_name)
99
- @opts['foreign_key']['alias'].each { |k, v| return v if k == column_name }
100
- nil
101
- end
102
-
103
- def fk_suffix
104
- @opts['foreign_key']['suffix']
105
- end
106
-
107
- def to_s
108
- @opts.to_s
109
- end
110
- end
111
60
  end
@@ -0,0 +1,32 @@
1
+ require 'rare_map/options'
2
+
3
+ module RareMap
4
+ # RareMap::DatabaseProfile defines all metadata of a database.
5
+ # @author Wei-Ming Wu
6
+ # @!attribute [r] name
7
+ # @return [String] the name of this DatabaseProfile
8
+ # @!attribute [r] connection
9
+ # @return [Hash] the connection config of this DatabaseProfile
10
+ # @!attribute [r] options
11
+ # @return [Options] the Options of this DatabaseProfile
12
+ # @!attribute schema
13
+ # @return [String] the schema dump of this DatabaseProfile
14
+ # @!attribute tables
15
+ # @return [Array] an Array of Table of this DatabaseProfile
16
+ class DatabaseProfile
17
+ attr_reader :name, :connection, :options
18
+ attr_accessor :schema, :tables
19
+
20
+ # Creates a DatabaseProfile.
21
+ #
22
+ # @param [String] name the name of this DatabaseProfile
23
+ # @param [Hash] connection the connection config of this DatabaseProfile
24
+ # @param [Options] options the Options of this DatabaseProfile
25
+ # @return [DatabaseProfile] a DatabaseProfile object
26
+ def initialize(name, connection, options = nil)
27
+ @name, @connection = name, connection
28
+ @options = options || Options.new
29
+ @tables = []
30
+ end
31
+ end
32
+ end
@@ -1,4 +1,10 @@
1
1
  module RareMap
2
- class ConfigNotFoundError < Exception
2
+ # RareMap::Errors defines all kinds of errors of RareMap.
3
+ # @author Wei-Ming Wu
4
+ module Errors
5
+ # ConfigNotFoundError is an Exception.
6
+ class ConfigNotFoundError < Exception ; end
7
+ # RelationNotDefinedError is an Exception.
8
+ class RelationNotDefinedError < Exception ; end
3
9
  end
4
10
  end
@@ -0,0 +1,48 @@
1
+ require 'active_support/inflector'
2
+ require 'active_support/core_ext/hash'
3
+
4
+ module RareMap
5
+ # RareMap::Model defines the details of an ActiveRecord model.
6
+ # @author Wei-Ming Wu
7
+ # @!attribute [r] db_name
8
+ # @return [String] the name of the database
9
+ # @!attribute [r] connection
10
+ # @return [Hash] the connection config of this Model
11
+ # @!attribute [r] table
12
+ # @return [Table] the Table of this Model
13
+ # @!attribute [r] group
14
+ # @return [String] the group of this Model
15
+ # @!attribute relations
16
+ # @return [Array] an Array of Relation of this Model
17
+ class Model
18
+ include Errors
19
+ attr_reader :db_name, :connection, :table, :group
20
+ attr_accessor :relations
21
+
22
+ # Creates a Model.
23
+ #
24
+ # @param db_name [String] the name of database
25
+ # @param connection [Hash] the connection config of ActiveRecord
26
+ # @param table [Table] the database table
27
+ # @param group [String] the group name of this Model
28
+ # @return [Model] a Model object
29
+ def initialize(db_name, connection, table, group = 'default')
30
+ @db_name, @connection, @table, @group = db_name, connection, table, group
31
+ @relations = []
32
+ end
33
+
34
+ # Checks if this Model belongs to a group.
35
+ #
36
+ # @return [true, false] true if this Model contains a group, false otherwise
37
+ def group?
38
+ group != 'default'
39
+ end
40
+
41
+ # Returns the class name of this Model.
42
+ #
43
+ # @return [String] the class name of this Model
44
+ def classify
45
+ "#{table.name}".pluralize.classify
46
+ end
47
+ end
48
+ end
@@ -1,7 +1,14 @@
1
1
  require 'active_support/inflector'
2
+ require 'rare_map/model'
3
+ require 'rare_map/relation'
2
4
 
3
5
  module RareMap
6
+ # RareMap::ModelBuilder converts an Array of DatabaseProfile into an Array of Model.
7
+ # @author Wei-Ming Wu
4
8
  module ModelBuilder
9
+ # Creaetes an Array of Model by given DatabaseProfile(s).
10
+ #
11
+ # @return [Array] an Array of Model
5
12
  def build_models(db_profiles)
6
13
  models = []
7
14
 
@@ -12,9 +19,9 @@ module RareMap
12
19
  set_foreign_keys_by_options(table, opts)
13
20
  set_fk_suffix_by_options(table, opts)
14
21
  if opts.group?
15
- models << Model.new(db_prof.connection, table, opts.group, db_prof.name)
22
+ models << Model.new(db_prof.name, db_prof.connection, table, opts.group)
16
23
  else
17
- models << Model.new(db_prof.connection, table, 'default', db_prof.name)
24
+ models << Model.new(db_prof.name, db_prof.connection, table)
18
25
  end
19
26
  end
20
27
  end
@@ -25,6 +32,7 @@ module RareMap
25
32
  end
26
33
 
27
34
  private
35
+
28
36
  def build_relations(models)
29
37
  models.each do |model|
30
38
  if model.group?
@@ -87,7 +95,7 @@ module RareMap
87
95
  def set_foreign_keys_by_options(table, options)
88
96
  table.columns.each do |col|
89
97
  ref = options.find_table_by_foreign_key col.name
90
- col.references = ref if ref
98
+ col.ref_table = ref if ref
91
99
  end
92
100
  end
93
101
 
@@ -96,29 +104,4 @@ module RareMap
96
104
  table.primary_key = pk if pk
97
105
  end
98
106
  end
99
-
100
- class Model
101
- attr_reader :connection, :table, :group, :relations, :db_name
102
-
103
- def initialize(connection, table, group = 'default', db_name)
104
- @connection, @table, @group, @db_name = connection, table, group, db_name
105
- @relations = []
106
- end
107
-
108
- def group?
109
- group != 'default'
110
- end
111
-
112
- def classify
113
- "#{table.name}".pluralize.classify
114
- end
115
- end
116
-
117
- class Relation
118
- attr_reader :type, :foreign_key, :table, :through
119
-
120
- def initialize(type, foreign_key, table, through = nil)
121
- @type, @foreign_key, @table, @through = type, foreign_key, table, through
122
- end
123
- end
124
- end
107
+ end
@@ -1,11 +1,14 @@
1
1
  require 'active_support/inflector'
2
2
 
3
3
  module RareMap
4
+ # RareMap::ModelGenerator converts an Array of Model into ActiveRecord files.
5
+ # @author Wei-Ming Wu
4
6
  module ModelGenerator
5
- def generate_models(models, root = './')
6
- root ||= './'
7
- path = root + 'app/models/'
8
- Dir.mkdir root + 'app' unless Dir.exist? root + 'app'
7
+ # Creaetes ActiveRecord files by given Model(s) under app/models directory.
8
+ def generate_models(models, root = '.')
9
+ root ||= '.'
10
+ path = File.join(root, 'app', 'models')
11
+ Dir.mkdir File.join(root, 'app') unless Dir.exist? File.join(root, 'app')
9
12
  Dir.mkdir path unless Dir.exist? path
10
13
 
11
14
  group_db2conn = generate_connection_models(models, path)
@@ -53,8 +56,8 @@ module RareMap
53
56
  output << " end\n"
54
57
  output << 'end'
55
58
 
56
- Dir.mkdir path + "#{model.group.underscore}" unless Dir.exist? path + "#{model.group}"
57
- f = File.new(path + "#{model.group.underscore}/#{model.classify.underscore}.rb", 'w')
59
+ Dir.mkdir File.join(path, "#{model.group.underscore}") unless Dir.exist? File.join(path, "#{model.group}")
60
+ f = File.new File.join(path, "#{model.group.underscore}", "#{model.classify.underscore}.rb"), 'w'
58
61
  f.write output
59
62
  f.close
60
63
  end
@@ -63,6 +66,7 @@ module RareMap
63
66
  end
64
67
 
65
68
  private
69
+
66
70
  def classify_by_table(table, model, models)
67
71
  if model.group?
68
72
  model = models.find { |m| m.table.name == table &&
@@ -93,8 +97,8 @@ module RareMap
93
97
  'end'
94
98
 
95
99
 
96
- Dir.mkdir path + "#{group.underscore}" unless Dir.exist? path + "#{group}"
97
- f = File.new(path + "#{group.underscore}/#{model.underscore}.rb", 'w')
100
+ Dir.mkdir File.join(path, "#{group.underscore}") unless Dir.exist? File.join(path, "#{group}")
101
+ f = File.new File.join(path, "#{group.underscore}", "#{model.underscore}.rb"), 'w'
98
102
  f.write output
99
103
  f.close
100
104