rare_map 2.1.1 → 2.2.0

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 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