k_domain 0.0.1 → 0.0.14
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +39 -1
- data/Gemfile +10 -0
- data/Guardfile +30 -0
- data/Rakefile +3 -4
- data/STORIES.md +63 -0
- data/USAGE.md +19 -0
- data/k_domain.gemspec +4 -0
- data/lib/k_domain/domain_model/load.rb +29 -0
- data/lib/k_domain/domain_model/transform.rb +110 -0
- data/lib/k_domain/domain_model/transform_steps/_.rb +10 -0
- data/lib/k_domain/domain_model/transform_steps/step.rb +142 -0
- data/lib/k_domain/domain_model/transform_steps/step1_attach_db_schema.rb +21 -0
- data/lib/k_domain/domain_model/transform_steps/step2_attach_models.rb +62 -0
- data/lib/k_domain/domain_model/transform_steps/step3_attach_columns.rb +137 -0
- data/lib/k_domain/domain_model/transform_steps/step4_attach_erd_files.rb +454 -0
- data/lib/k_domain/domain_model/transform_steps/step5_attach_dictionary.rb +58 -0
- data/lib/k_domain/domain_model/transform_steps/step8_locate_rails_models.rb +44 -0
- data/lib/k_domain/raw_db_schema/load.rb +29 -0
- data/lib/k_domain/raw_db_schema/transform.rb +82 -0
- data/lib/k_domain/schemas/_.rb +15 -0
- data/lib/k_domain/schemas/database/_.rb +7 -0
- data/lib/k_domain/schemas/database/foreign_key.rb +14 -0
- data/lib/k_domain/schemas/database/index.rb +14 -0
- data/lib/k_domain/schemas/database/schema.rb +31 -0
- data/lib/k_domain/schemas/database/table.rb +32 -0
- data/lib/k_domain/schemas/dictionary.rb +19 -0
- data/lib/k_domain/schemas/domain/_.rb +65 -0
- data/lib/k_domain/schemas/domain/domain.rb +11 -0
- data/lib/k_domain/schemas/domain/erd_file.rb +80 -0
- data/lib/k_domain/schemas/domain/models/column.rb +49 -0
- data/lib/k_domain/schemas/domain/models/model.rb +111 -0
- data/lib/k_domain/schemas/domain/old/belongs_to.rb +25 -0
- data/lib/k_domain/schemas/domain/old/column_old.rb +225 -0
- data/lib/k_domain/schemas/domain/old/domain_statistics.rb +29 -0
- data/lib/k_domain/schemas/domain/old/entity.rb +338 -0
- data/lib/k_domain/schemas/domain/old/entity_statistics.rb +22 -0
- data/lib/k_domain/schemas/domain/old/foreign_key.rb +17 -0
- data/lib/k_domain/schemas/domain/old/has_and_belongs_to_many.rb +20 -0
- data/lib/k_domain/schemas/domain/old/has_many.rb +27 -0
- data/lib/k_domain/schemas/domain/old/has_one.rb +41 -0
- data/lib/k_domain/schemas/domain/old/name_options.rb +10 -0
- data/lib/k_domain/schemas/domain/old/rails_controller.rb +10 -0
- data/lib/k_domain/schemas/domain/old/rails_model.rb +92 -0
- data/lib/k_domain/schemas/domain/old/related_entity.rb +36 -0
- data/lib/k_domain/schemas/domain/old/statistics.rb +21 -0
- data/lib/k_domain/schemas/domain/old/validate.rb +25 -0
- data/lib/k_domain/schemas/domain/old/validates.rb +50 -0
- data/lib/k_domain/schemas/domain_model.rb +14 -0
- data/lib/k_domain/schemas/investigate.rb +15 -0
- data/lib/k_domain/schemas/rails_resource.rb +16 -0
- data/lib/k_domain/version.rb +1 -1
- data/lib/k_domain.rb +22 -1
- data/templates/load_schema.rb +226 -0
- metadata +91 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c236bd2b714a21b40f5727765bc2b9c049f0c265e7c592e5864a6a6e34330b37
|
4
|
+
data.tar.gz: 8ecf79ec6e1805ad6660218ac6aa6931ef67a48b3ca56dd339c7a6a0f6c50886
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4b3a6c9c9af39c37fdeba462a209a0bd395a72c1887505c0852f1f37a58406c929cc080c63bb9ed5b4de937be51d722e0511a6194d7de389840cb5ca831e7135
|
7
|
+
data.tar.gz: f71d09378bf35ec9146692bd137b02176095ba934fbba711c6204896541af27365aeeeb67997d89d43cea7498f2d7361322cba566dd0c31ed1674fb190656968
|
data/.rubocop.yml
CHANGED
@@ -6,12 +6,37 @@ AllCops:
|
|
6
6
|
NewCops: enable
|
7
7
|
Exclude:
|
8
8
|
- "_/**/*"
|
9
|
-
- "spec/
|
9
|
+
- "spec/sample_input/**/*"
|
10
|
+
- "spec/sample_output/**/*"
|
11
|
+
- "lib/k_domain/raw_db_schema/template.rb"
|
12
|
+
|
13
|
+
Metrics/PerceivedComplexity:
|
14
|
+
Exclude:
|
15
|
+
- "lib/k_domain/domain_model/transform_steps/*.rb"
|
16
|
+
- "lib/k_domain/domain_model/dtos/entity.rb"
|
17
|
+
- "lib/k_domain/domain_model/dtos/old/entity.rb"
|
18
|
+
|
19
|
+
Metrics/AbcSize:
|
20
|
+
Exclude:
|
21
|
+
- "lib/k_domain/domain_model/transform_steps/*.rb"
|
22
|
+
- "lib/k_domain/domain_model/dtos/rails_model.rb"
|
23
|
+
- "lib/k_domain/domain_model/dtos/entity.rb"
|
24
|
+
- "lib/k_domain/domain_model/dtos/column_old.rb"
|
25
|
+
- "lib/k_domain/domain_model/dtos/old/column_old.rb"
|
26
|
+
- "lib/k_domain/domain_model/dtos/old/rails_model.rb"
|
27
|
+
- "lib/k_domain/domain_model/dtos/old/entity.rb"
|
28
|
+
|
29
|
+
Metrics/CyclomaticComplexity:
|
30
|
+
Exclude:
|
31
|
+
- "lib/k_domain/domain_model/transform_steps/*.rb"
|
32
|
+
- "lib/k_domain/domain_model/dtos/entity.rb"
|
33
|
+
- "lib/k_domain/domain_model/dtos/old/entity.rb"
|
10
34
|
|
11
35
|
Metrics/BlockLength:
|
12
36
|
Exclude:
|
13
37
|
- "**/spec/**/*"
|
14
38
|
- "*.gemspec"
|
39
|
+
- 'lib/k_domain/domain_model/dtos/erd_file.rb'
|
15
40
|
IgnoredMethods:
|
16
41
|
- configure
|
17
42
|
- context
|
@@ -34,12 +59,19 @@ Metrics/BlockLength:
|
|
34
59
|
|
35
60
|
Metrics/MethodLength:
|
36
61
|
Max: 25
|
62
|
+
Exclude:
|
63
|
+
- "lib/k_domain/domain_model/transform_steps/*.rb"
|
64
|
+
- "lib/k_domain/domain_model/dtos/rails_model.rb"
|
65
|
+
- "lib/k_domain/domain_model/dtos/old/entity.rb"
|
66
|
+
- "lib/k_domain/domain_model/dtos/old/rails_model.rb"
|
37
67
|
|
38
68
|
Layout/LineLength:
|
39
69
|
Max: 200
|
40
70
|
# Ignores annotate output
|
41
71
|
IgnoredPatterns: ['\A# \*\*']
|
42
72
|
IgnoreCopDirectives: true
|
73
|
+
Exclude:
|
74
|
+
- "lib/k_domain/domain_model/transform_steps/*.rb"
|
43
75
|
|
44
76
|
Lint/UnusedMethodArgument:
|
45
77
|
AllowUnusedKeywordArguments: true
|
@@ -77,6 +109,12 @@ Lint/AmbiguousBlockAssociation:
|
|
77
109
|
Style/AccessorGrouping:
|
78
110
|
Enabled: false
|
79
111
|
|
112
|
+
Style/FormatStringToken:
|
113
|
+
Enabled: false
|
114
|
+
|
115
|
+
Style/Documentation:
|
116
|
+
Enabled: false
|
117
|
+
|
80
118
|
Layout/SpaceBeforeComma:
|
81
119
|
Enabled: false
|
82
120
|
# My Preferences - End
|
data/Gemfile
CHANGED
@@ -23,3 +23,13 @@ group :development, :test do
|
|
23
23
|
gem 'rubocop-rake', require: false
|
24
24
|
gem 'rubocop-rspec', require: false
|
25
25
|
end
|
26
|
+
|
27
|
+
# If local dependency
|
28
|
+
if ENV['KLUE_LOCAL_GEMS']&.to_s&.downcase == 'true'
|
29
|
+
group :development, :test do
|
30
|
+
puts 'Using Local GEMs'
|
31
|
+
gem 'peeky' , path: '../peeky'
|
32
|
+
gem 'k_log' , path: '../k_log'
|
33
|
+
gem 'k_util' , path: '../k_util'
|
34
|
+
end
|
35
|
+
end
|
data/Guardfile
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
guard :bundler, cmd: 'bundle install' do
|
4
|
+
watch('Gemfile')
|
5
|
+
watch('k_domain.gemspec')
|
6
|
+
end
|
7
|
+
|
8
|
+
group :green_pass_then_cop, halt_on_fail: true do
|
9
|
+
guard :rspec, cmd: 'bundle exec rspec -f doc' do
|
10
|
+
require 'guard/rspec/dsl'
|
11
|
+
dsl = Guard::RSpec::Dsl.new(self)
|
12
|
+
|
13
|
+
# RSpec files
|
14
|
+
rspec = dsl.rspec
|
15
|
+
watch(rspec.spec_helper) { rspec.spec_dir }
|
16
|
+
watch(rspec.spec_support) { rspec.spec_dir }
|
17
|
+
watch(rspec.spec_files)
|
18
|
+
|
19
|
+
# Ruby files
|
20
|
+
ruby = dsl.ruby
|
21
|
+
dsl.watch_spec_files_for(ruby.lib_files)
|
22
|
+
watch(%r{^lib/k_domain/**/(.+)\.rb$}) { |m| "spec/unit/#{m[1]}_spec.rb" }
|
23
|
+
watch(%r{^lib/k_domain/commands/(.+)\.rb$}) { |m| "spec/unit/commands/#{m[1]}_spec.rb" }
|
24
|
+
end
|
25
|
+
|
26
|
+
# guard :rubocop, all_on_start: false, cli: ['--format', 'clang'] do
|
27
|
+
# watch(/{.+\.rb$/)
|
28
|
+
# watch(%r{(?:.+/)?\.rubocop(?:_todo)?\.yml$}) { |m| File.dirname(m[0]) }
|
29
|
+
# end
|
30
|
+
end
|
data/Rakefile
CHANGED
@@ -7,11 +7,8 @@ GEM_NAME = 'k_domain'
|
|
7
7
|
require 'pry'
|
8
8
|
require 'bundler/gem_tasks'
|
9
9
|
require 'rspec/core/rake_task'
|
10
|
-
puts 'xxxxxxxxxx'
|
11
10
|
require 'k_domain'
|
12
11
|
require 'k_domain/version'
|
13
|
-
puts 'xxxxxxxxxx2'
|
14
|
-
binding.pry
|
15
12
|
|
16
13
|
RSpec::Core::RakeTask.new(:spec)
|
17
14
|
|
@@ -29,7 +26,9 @@ task :publish do
|
|
29
26
|
system 'gem build'
|
30
27
|
system "gem push #{GEM_NAME}-#{KDomain::VERSION}.gem"
|
31
28
|
end
|
32
|
-
|
29
|
+
task :build do
|
30
|
+
system 'gem build'
|
31
|
+
end
|
33
32
|
desc 'Remove old *.gem files'
|
34
33
|
task :clean do
|
35
34
|
system 'rm *.gem'
|
data/STORIES.md
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
# K Domain
|
2
|
+
|
3
|
+
> K Domain builds complex domain schemas by combining the database schema with a rich entity relationship DSLs
|
4
|
+
|
5
|
+
As an Application Developer, I need a rich and configurable ERD schema, so I can generate enterprise applications quickly
|
6
|
+
|
7
|
+
## Development radar
|
8
|
+
|
9
|
+
### Stories next on list
|
10
|
+
|
11
|
+
As a Developer, I can print any of the domain structures, so that I can visually my domain
|
12
|
+
|
13
|
+
- Hook up log.structure
|
14
|
+
|
15
|
+
As a Developer, I can customize domain configuration, so that I can have opinions about names and types
|
16
|
+
|
17
|
+
- Handle traits
|
18
|
+
|
19
|
+
As a Developer, I can read native rails model data, so that I can leverage existing rails applications for ERD modeling
|
20
|
+
|
21
|
+
- Use Meta Programming and re-implement ActiveRecord::Base
|
22
|
+
|
23
|
+
### Tasks next on list
|
24
|
+
|
25
|
+
Refactor / Simply
|
26
|
+
|
27
|
+
- Replace complex objects an with structs for ancillary data structures such as investigate
|
28
|
+
|
29
|
+
User acceptance testing
|
30
|
+
|
31
|
+
- Provide sample printers for each data structure to visually check data is loading
|
32
|
+
- Point raw_db_schema loader towards a complex ERD and check how it performs
|
33
|
+
|
34
|
+
## Stories and tasks
|
35
|
+
|
36
|
+
### Tasks - completed
|
37
|
+
|
38
|
+
Setup RubyGems and RubyDoc
|
39
|
+
|
40
|
+
- Build and deploy gem to [rubygems.org](https://rubygems.org/gems/k_domain)
|
41
|
+
- Attach documentation to [rubydoc.info](https://rubydoc.info/github/to-do-/k_domain/master)
|
42
|
+
|
43
|
+
Setup project management, requirement and SCRUM documents
|
44
|
+
|
45
|
+
- Setup readme file
|
46
|
+
- Setup user stories and tasks
|
47
|
+
- Setup a project backlog
|
48
|
+
- Setup an examples/usage document
|
49
|
+
|
50
|
+
Setup GitHub Action (test and lint)
|
51
|
+
|
52
|
+
- Setup Rspec action
|
53
|
+
- Setup RuboCop action
|
54
|
+
|
55
|
+
Setup new Ruby GEM
|
56
|
+
|
57
|
+
- Build out a standard GEM structure
|
58
|
+
- Add automated semantic versioning
|
59
|
+
- Add Rspec unit testing framework
|
60
|
+
- Add RuboCop linting
|
61
|
+
- Add Guard for automatic watch and test
|
62
|
+
- Add GitFlow support
|
63
|
+
- Add GitHub Repository
|
data/USAGE.md
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# K Domain
|
2
|
+
|
3
|
+
> K Domain builds complex domain schemas by combining the database schema with a rich entity relationship DSLs
|
4
|
+
|
5
|
+
As an Application Developer, I need a rich and configurable ERD schema, so I can generate enterprise applications quickly
|
6
|
+
|
7
|
+
## Usage
|
8
|
+
|
9
|
+
### Sample Classes
|
10
|
+
|
11
|
+
#### Simple example
|
12
|
+
|
13
|
+
Description for a simple example that shows up in the USAGE.MD
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
class SomeRuby
|
17
|
+
def initialize; end
|
18
|
+
end
|
19
|
+
```
|
data/k_domain.gemspec
CHANGED
@@ -33,10 +33,14 @@ Gem::Specification.new do |spec|
|
|
33
33
|
f.match(%r{^(test|spec|features)/})
|
34
34
|
end
|
35
35
|
end
|
36
|
+
|
36
37
|
spec.bindir = 'exe'
|
37
38
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
38
39
|
spec.require_paths = ['lib']
|
39
40
|
# spec.extensions = ['ext/k_domain/extconf.rb']
|
40
41
|
|
42
|
+
spec.add_dependency 'activesupport' , '~> 6'
|
43
|
+
spec.add_dependency 'dry-struct', '~> 1'
|
41
44
|
spec.add_dependency 'k_log' , '~> 0.0.0'
|
45
|
+
spec.add_dependency 'peeky' , '~> 0.0.0'
|
42
46
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Annotates the original schema with methods that implement existing method calls
|
4
|
+
# that are already in the schema so that we can build a hash.
|
5
|
+
#
|
6
|
+
# Writes a new annotated schema.rb file with a public method called load that
|
7
|
+
# builds the hash
|
8
|
+
|
9
|
+
module KDomain
|
10
|
+
module DomainModel
|
11
|
+
class Load
|
12
|
+
include KLog::Logging
|
13
|
+
|
14
|
+
attr_reader :source_file
|
15
|
+
attr_reader :data
|
16
|
+
|
17
|
+
def initialize(source_file)
|
18
|
+
@source_file = source_file
|
19
|
+
end
|
20
|
+
|
21
|
+
def call
|
22
|
+
json = File.read(source_file)
|
23
|
+
data = KUtil.data.json_parse(json, as: :hash_symbolized)
|
24
|
+
|
25
|
+
@data = KDomain::Schemas::DomainModel.new(data)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Loads the db schema object and works through a series of enrichment steps to
|
4
|
+
# that builds the domain modal
|
5
|
+
|
6
|
+
module KDomain
|
7
|
+
module DomainModel
|
8
|
+
class Transform
|
9
|
+
include KLog::Logging
|
10
|
+
|
11
|
+
attr_reader :db_schema
|
12
|
+
attr_reader :target_step_file
|
13
|
+
attr_reader :target_file
|
14
|
+
attr_reader :erd_path
|
15
|
+
|
16
|
+
def initialize(db_schema: , target_file: , target_step_file: , erd_path:)
|
17
|
+
@db_schema = db_schema
|
18
|
+
@target_step_file = target_step_file
|
19
|
+
@target_file = target_file
|
20
|
+
@erd_path = erd_path
|
21
|
+
end
|
22
|
+
|
23
|
+
def call
|
24
|
+
valid = true
|
25
|
+
valid &&= step1
|
26
|
+
valid &&= step2
|
27
|
+
valid &&= step3
|
28
|
+
valid &&= step4
|
29
|
+
valid &&= step5
|
30
|
+
valid &&= step8 # NOT SURE WHERE THIS BELONGS
|
31
|
+
|
32
|
+
raise 'DomainModal transform failed' unless valid
|
33
|
+
|
34
|
+
write
|
35
|
+
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
|
39
|
+
def step1
|
40
|
+
Step1AttachDbSchema.run(domain_data, db_schema: db_schema)
|
41
|
+
write(step: '1-attach-db-schema')
|
42
|
+
end
|
43
|
+
|
44
|
+
def step2
|
45
|
+
Step2AttachModels.run(domain_data, erd_path: erd_path)
|
46
|
+
write(step: '2-attach-model')
|
47
|
+
end
|
48
|
+
|
49
|
+
def step3
|
50
|
+
Step3AttachColumns.run(domain_data)
|
51
|
+
write(step: '3-attach-columns')
|
52
|
+
end
|
53
|
+
|
54
|
+
def step4
|
55
|
+
Step4AttachErdFiles.run(domain_data, erd_path: erd_path)
|
56
|
+
write(step: '4-attach-erd-files')
|
57
|
+
end
|
58
|
+
|
59
|
+
def step5
|
60
|
+
Step5AttachDictionary.run(domain_data, erd_path: erd_path)
|
61
|
+
write(step: '5-attach-dictionary')
|
62
|
+
end
|
63
|
+
|
64
|
+
def step8
|
65
|
+
Step8LocateRailsModels.run(domain_data, erd_path: erd_path)
|
66
|
+
write(step: '8-rails-files-models')
|
67
|
+
end
|
68
|
+
|
69
|
+
def write(step: nil)
|
70
|
+
file = if step.nil?
|
71
|
+
target_file
|
72
|
+
else
|
73
|
+
format(target_step_file, step: step)
|
74
|
+
end
|
75
|
+
FileUtils.mkdir_p(File.dirname(file))
|
76
|
+
File.write(file, JSON.pretty_generate(domain_data))
|
77
|
+
end
|
78
|
+
|
79
|
+
def domain_data
|
80
|
+
# The initial domain model structure is created here, but populated during the workflows.
|
81
|
+
@domain_data ||= {
|
82
|
+
domain: {
|
83
|
+
models: [],
|
84
|
+
erd_files: [],
|
85
|
+
},
|
86
|
+
rails: {
|
87
|
+
models: [],
|
88
|
+
controllers: [],
|
89
|
+
},
|
90
|
+
rails_resource: {
|
91
|
+
models: [],
|
92
|
+
controllers: [],
|
93
|
+
},
|
94
|
+
dictionary: {
|
95
|
+
items: []
|
96
|
+
},
|
97
|
+
database: {
|
98
|
+
tables: [],
|
99
|
+
indexes: [],
|
100
|
+
foreign_keys: [],
|
101
|
+
meta: {}
|
102
|
+
},
|
103
|
+
investigate: {
|
104
|
+
issues: []
|
105
|
+
}
|
106
|
+
}
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# The require order is important due to dependencies
|
4
|
+
require_relative './step'
|
5
|
+
require_relative './step1_attach_db_schema'
|
6
|
+
require_relative './step2_attach_models'
|
7
|
+
require_relative './step3_attach_columns'
|
8
|
+
require_relative './step4_attach_erd_files'
|
9
|
+
require_relative './step5_attach_dictionary'
|
10
|
+
require_relative './step8_locate_rails_models'
|
@@ -0,0 +1,142 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KDomain
|
4
|
+
module DomainModel
|
5
|
+
class Step
|
6
|
+
include KLog::Logging
|
7
|
+
|
8
|
+
attr_reader :domain_data
|
9
|
+
attr_reader :opts
|
10
|
+
attr_reader :valid
|
11
|
+
alias valid? valid
|
12
|
+
|
13
|
+
def initialize(domain_data, **opts)
|
14
|
+
# Useful for debugging
|
15
|
+
# log.info "Initialize #{self.class.name}"
|
16
|
+
|
17
|
+
@domain_data = domain_data
|
18
|
+
@opts = opts
|
19
|
+
@valid = true
|
20
|
+
end
|
21
|
+
|
22
|
+
def call; end
|
23
|
+
|
24
|
+
def self.run(domain_data, **opts)
|
25
|
+
step = new(domain_data, **opts)
|
26
|
+
step.call
|
27
|
+
step
|
28
|
+
end
|
29
|
+
|
30
|
+
def guard(message)
|
31
|
+
log.error message
|
32
|
+
@valid = false
|
33
|
+
end
|
34
|
+
|
35
|
+
# Domain Model Accessor/Helpers
|
36
|
+
def domain
|
37
|
+
guard('domain is missing') if domain_data[:domain].nil?
|
38
|
+
|
39
|
+
domain_data[:domain]
|
40
|
+
end
|
41
|
+
|
42
|
+
def domain_models
|
43
|
+
domain[:models]
|
44
|
+
end
|
45
|
+
|
46
|
+
# Rails File Accessor/Helpers
|
47
|
+
def rails_resource
|
48
|
+
guard('rails_resource is missing') if domain_data[:rails_resource].nil?
|
49
|
+
|
50
|
+
domain_data[:rails_resource]
|
51
|
+
end
|
52
|
+
|
53
|
+
def rails_resource_models
|
54
|
+
rails_resource[:models]
|
55
|
+
end
|
56
|
+
|
57
|
+
def rails_resource_models=(value)
|
58
|
+
rails_resource[:models] = value
|
59
|
+
end
|
60
|
+
|
61
|
+
def rails_resource_controllers
|
62
|
+
rails_resource[:controllers]
|
63
|
+
end
|
64
|
+
|
65
|
+
# Database Accessor/Helpers
|
66
|
+
def database=(value)
|
67
|
+
domain_data[:database] = value
|
68
|
+
end
|
69
|
+
|
70
|
+
def database
|
71
|
+
guard('database is missing') if domain_data[:database].nil?
|
72
|
+
|
73
|
+
domain_data[:database]
|
74
|
+
end
|
75
|
+
|
76
|
+
def database_tables
|
77
|
+
guard('database_tables is missing') if database[:tables].nil?
|
78
|
+
|
79
|
+
database[:tables]
|
80
|
+
end
|
81
|
+
|
82
|
+
def database_foreign_keys
|
83
|
+
guard('database_foreign_keys is missing') if database[:foreign_keys].nil?
|
84
|
+
|
85
|
+
database[:foreign_keys]
|
86
|
+
end
|
87
|
+
|
88
|
+
def find_table_for_model(model)
|
89
|
+
database_tables.find { |table| table[:name] == model[:table_name] }
|
90
|
+
end
|
91
|
+
|
92
|
+
def table_name_exist?(table_name)
|
93
|
+
if table_name.nil?
|
94
|
+
guard('table_name_exist? was provided with a table_name: nil')
|
95
|
+
return false
|
96
|
+
end
|
97
|
+
database_table_name_hash.key?(table_name)
|
98
|
+
end
|
99
|
+
|
100
|
+
def find_foreign_table(lhs_table_name, column_name)
|
101
|
+
fk = database_foreign_keys.find { |foreign_key| foreign_key[:left] == lhs_table_name && foreign_key[:column] == column_name }
|
102
|
+
return fk[:right] if fk
|
103
|
+
|
104
|
+
nil
|
105
|
+
end
|
106
|
+
|
107
|
+
def investigate(step:, location:, key:, message:)
|
108
|
+
unique_key = build_key(step, location, key)
|
109
|
+
|
110
|
+
return if issue_hash.key?(unique_key)
|
111
|
+
|
112
|
+
value = { step: step, location: location, key: key, message: message }
|
113
|
+
|
114
|
+
issues << value # list
|
115
|
+
issue_hash[unique_key] = value # lookup
|
116
|
+
end
|
117
|
+
|
118
|
+
def issues
|
119
|
+
domain_data[:investigate][:issues]
|
120
|
+
end
|
121
|
+
|
122
|
+
private
|
123
|
+
|
124
|
+
def database_table_name_hash
|
125
|
+
@database_table_name_hash ||= database_tables.to_h { |table| [table[:name], table[:name]] }
|
126
|
+
end
|
127
|
+
|
128
|
+
def build_key(*values)
|
129
|
+
values.join('-')
|
130
|
+
end
|
131
|
+
|
132
|
+
def issue_hash
|
133
|
+
return @issue_hash if defined? @issue_hash
|
134
|
+
|
135
|
+
@issue_hash = issues.to_h do |issue|
|
136
|
+
unique_key = build_key(issue[:step], issue[:location], issue[:key])
|
137
|
+
[unique_key, issue]
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KDomain
|
4
|
+
module DomainModel
|
5
|
+
class Step1AttachDbSchema < KDomain::DomainModel::Step
|
6
|
+
# Map database schema to domain model
|
7
|
+
def call
|
8
|
+
raise 'Schema not supplied' if opts[:db_schema].nil?
|
9
|
+
|
10
|
+
self.database = opts[:db_schema].clone
|
11
|
+
|
12
|
+
guard('tables are missing') if database[:tables].nil?
|
13
|
+
guard('indexes are missing') if database[:indexes].nil?
|
14
|
+
guard('foreign keys are missing') if database[:foreign_keys].nil?
|
15
|
+
guard('rails version is missing') if database[:meta][:rails].nil?
|
16
|
+
guard('postgres extensions are missing') if database[:meta][:db_info][:extensions].nil?
|
17
|
+
guard('unique keys are missing') if database[:meta][:unique_keys].nil?
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Loop through the db_schema tables and build up a
|
4
|
+
# basic model for each table
|
5
|
+
class Step2AttachModels < KDomain::DomainModel::Step
|
6
|
+
# Map database schema to domain model
|
7
|
+
def call
|
8
|
+
raise 'ERD path not supplied' if opts[:erd_path].nil?
|
9
|
+
|
10
|
+
# Schema is re-shaped into a format designed for domain modeling
|
11
|
+
domain[:models] = database_tables.map { |table| model(table) }
|
12
|
+
end
|
13
|
+
|
14
|
+
def model(table)
|
15
|
+
table_name = table[:name].to_s
|
16
|
+
model_name = table_name.singularize
|
17
|
+
|
18
|
+
{
|
19
|
+
name: model_name,
|
20
|
+
name_plural: table_name, # need to check if this is correct as I know it is wrong for account_history_datum
|
21
|
+
table_name: table_name,
|
22
|
+
pk: primary_key(table),
|
23
|
+
erd_location: location(table_name, model_name),
|
24
|
+
statistics: {}, # Load in future step
|
25
|
+
columns: [] # Load in future step
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
def primary_key(table)
|
30
|
+
{
|
31
|
+
name: table[:primary_key],
|
32
|
+
type: table[:primary_key_type],
|
33
|
+
exist: !table[:primary_key].nil?
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
# Location of source code
|
38
|
+
def location(table_name, model_name)
|
39
|
+
file_normal = File.join(opts[:erd_path], "#{model_name}.rb")
|
40
|
+
file_custom = File.join(opts[:erd_path], "#{table_name}.rb")
|
41
|
+
file_exist = true
|
42
|
+
state = []
|
43
|
+
|
44
|
+
if File.exist?(file_normal)
|
45
|
+
file = file_normal
|
46
|
+
state.push(:has_ruby_model)
|
47
|
+
elsif File.exist?(file_custom)
|
48
|
+
file = file_custom
|
49
|
+
state.push(:has_ruby_model)
|
50
|
+
state.push(:nonconventional_name)
|
51
|
+
else
|
52
|
+
file = ''
|
53
|
+
file_exist = false
|
54
|
+
end
|
55
|
+
|
56
|
+
{
|
57
|
+
file: file,
|
58
|
+
exist: file_exist,
|
59
|
+
state: state # display_state: state.join(' ')
|
60
|
+
}
|
61
|
+
end
|
62
|
+
end
|