k_domain 0.0.1 → 0.0.2

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
  SHA256:
3
- metadata.gz: ee3ac6f9a2143cc6329183f38515615569399067e0919ba83eff7e5485a31b30
4
- data.tar.gz: c5e8016c595b30265436ae90acdcd28cbd2db9def4ea83308cf479840b04b173
3
+ metadata.gz: a69b94955a43f91d71e034b94a5caf0d3fdbb7b130c480d4eabc45818bbe2262
4
+ data.tar.gz: 0f4a126ee7c9bed5d99ac7449e5f97ec558030b126dbaa3c6194cdb5ce8430bd
5
5
  SHA512:
6
- metadata.gz: 1ccc3e4d22125ddebed3eb122d4dcd21392fcca079237ede44fb50b3ba351a780ebe894170e4e25bb08055d93f66ba7059127b4590e8c21f8956717fc5b78dec
7
- data.tar.gz: 7ab779bf4c936bc7465fa0667d24b5c459475a0d4e00a57cc9276310f3fb84ddd44683d1262f40e79b5de712609d0aefffab954b2d6d0f97a90251290dbe0cd6
6
+ metadata.gz: 3a7a877e80c9f23cdb93ab7952e027bdddc89bd6e888212c6fc0622cc0d5ae6d9b73e3e9651949ecd1afa2f1323e6446045f579cb6e83c030c5d8d711979deaa
7
+ data.tar.gz: 434275e01ec2308d4a1407f5e8bd7ab9ec9708218510b6a719c144e2d9b6abb7e2caafa67efc617ac33295cd276c2326ccd961468ee4870b38266ef1b1295296
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
 
data/STORIES.md ADDED
@@ -0,0 +1,44 @@
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 DO_SOMETHING, so that I QUALITY_OF_LIFE
12
+
13
+ - Subtask
14
+
15
+ ## Stories and tasks
16
+
17
+ ### Tasks - completed
18
+
19
+ Setup RubyGems and RubyDoc
20
+
21
+ - Build and deploy gem to [rubygems.org](https://rubygems.org/gems/k_domain)
22
+ - Attach documentation to [rubydoc.info](https://rubydoc.info/github/to-do-/k_domain/master)
23
+
24
+ Setup project management, requirement and SCRUM documents
25
+
26
+ - Setup readme file
27
+ - Setup user stories and tasks
28
+ - Setup a project backlog
29
+ - Setup an examples/usage document
30
+
31
+ Setup GitHub Action (test and lint)
32
+
33
+ - Setup Rspec action
34
+ - Setup RuboCop action
35
+
36
+ Setup new Ruby GEM
37
+
38
+ - Build out a standard GEM structure
39
+ - Add automated semantic versioning
40
+ - Add Rspec unit testing framework
41
+ - Add RuboCop linting
42
+ - Add Guard for automatic watch and test
43
+ - Add GitFlow support
44
+ - 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
+ ```
@@ -0,0 +1,226 @@
1
+ class LoadSchema
2
+ attr_reader :schema
3
+
4
+ def initialize
5
+ @unique_keys = {}
6
+ @current_table = nil
7
+ @rails_version = 4
8
+ @schema = {
9
+ tables: [],
10
+ foreign_keys: [],
11
+ indexes: [],
12
+ meta: {
13
+ rails: @rails_version,
14
+ database: {
15
+ type: 'postgres',
16
+ version: nil, # TODO
17
+ extensions: []
18
+ },
19
+ unique_keys: []
20
+ }
21
+ }
22
+ end
23
+
24
+ # ----------------------------------------------------------------------
25
+ # Inject start
26
+ # original file: {{source_file}}
27
+ # ----------------------------------------------------------------------
28
+ def load_schema
29
+ {{rails_schema}}
30
+ end
31
+
32
+ # ----------------------------------------------------------------------
33
+ # original file: {{source_file}}
34
+ # Inject end
35
+ # ----------------------------------------------------------------------
36
+
37
+ def write_json(file)
38
+ schema[:meta][:rails] = @rails_version
39
+ File.write(file, JSON.pretty_generate(schema))
40
+ end
41
+
42
+ # This is the rails timestamp and will be replaced by the action rails version
43
+ def load(version:)
44
+ start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
45
+ # puts 'about to load'
46
+ yield if block_given?
47
+
48
+ schema[:meta][:rails] = @rails_version
49
+
50
+ sort
51
+ # code to time
52
+
53
+ # log.kv 'extensions', schema[:database][:extensions].length
54
+ # log.kv 'tables', schema[:tables].length
55
+ # log.kv 'indexes', schema[:indexes].length
56
+ # # a low foreign_keys count is indicative of not using SQL referential integrity
57
+ # log.kv 'foreign_keys', schema[:foreign_keys].length
58
+ # log.kv 'Time Taken', (finish - start)
59
+
60
+ # puts schema[:database][:extensions]
61
+ # print_unique_keys(type: :foreign_keys, title: 'unique options for foreign_keys')
62
+ # print_unique_keys(type: :columns, title: 'unique options for columns')
63
+ # print_unique_keys(type: :fields, category: :integer , title: 'unique options for column - integer')
64
+ # print_unique_keys(type: :fields, category: :decimal , title: 'unique options for column - decimal')
65
+ # print_unique_keys(type: :fields, category: :string , title: 'unique options for column - string')
66
+ # print_unique_keys(type: :fields, category: :datetime, title: 'unique options for column - datetime')
67
+ # print_unique_keys(type: :fields, category: :date , title: 'unique options for column - date')
68
+ # print_unique_keys(type: :fields, category: :text , title: 'unique options for column - text')
69
+ # print_unique_keys(type: :fields, category: :boolean , title: 'unique options for column - boolean')
70
+ # print_unique_keys(type: :fields, category: :jsonb , title: 'unique options for column - jsonb')
71
+ # print_unique_keys(type: :fields, category: :hstore , title: 'unique options for column - hstore')
72
+ # print_unique_keys(type: :fields, category: :float , title: 'unique options for column - float')
73
+ end
74
+
75
+ def enable_extension(name)
76
+ # puts "enable_extension(#{name})"
77
+ schema[:meta][:database][:extensions] << name
78
+ end
79
+
80
+ def create_table(name, **opts)
81
+ id = opts[:id]
82
+ primary_key = opts[:primary_key] || (id == false ? nil : "id")
83
+ primary_key_type = if id == false
84
+ nil
85
+ elsif id.nil?
86
+ "bigint"
87
+ else
88
+ id
89
+ end
90
+
91
+ @current_table = {
92
+ name: name,
93
+ primary_key: primary_key, # infer the actual value that should be in the database
94
+ primary_key_type: primary_key_type, # infer the actual value that should be in the database
95
+ columns: [],
96
+ indexes: [],
97
+ rails_schema: { # as reported by the rails schema
98
+ primary_key: opts[:primary_key],
99
+ id: id,
100
+ force: opts[:force]
101
+ }
102
+ }
103
+ # schema[:tables][name] = @current_table
104
+ schema[:tables] << @current_table
105
+
106
+ yield(self) if block_given?
107
+ end
108
+
109
+ def add_field(name, type, **opts)
110
+ # puts "add_field(#{name}, #{type})"
111
+ row = { name: name, type: type, **opts }
112
+ @current_table[:columns] << row
113
+
114
+ add_unique_keys(row.keys, type: :columns)
115
+ add_unique_keys(row.keys, type: :fields, category: type)
116
+ end
117
+
118
+ def add_index(name, fields, **opts)
119
+ # puts "add_index(#{name})"
120
+ row = { name: name, fields: fields, **opts }
121
+ @current_table[:indexes] << row
122
+ schema[:indexes] << row
123
+ add_unique_keys(row.keys, type: :indexes)
124
+ end
125
+
126
+ # This method was introduced onto the schema in rails 5
127
+ def index(fields, **opts)
128
+ @rails_version = 5
129
+ name = opts[:name]
130
+ opts.delete(:name)
131
+ add_index(name, fields, **opts)
132
+ end
133
+
134
+
135
+ def add_foreign_key(left_table, right_table, **opts)
136
+ # puts "add_foreign_key(#{left_table}, #{right_table})"
137
+ row = { left: left_table, right: right_table, **opts }
138
+ schema[:foreign_keys] << row
139
+ add_unique_keys(row.keys, type: :foreign_keys)
140
+ end
141
+
142
+ def add_unique_keys(keys, type:, category: nil)
143
+ key = [type, category, keys.join('-')].compact.join('|')
144
+ return if @unique_keys.key?(key)
145
+
146
+ @unique_keys[key] = key
147
+ schema[:meta][:unique_keys] << { type: type, category: category, key: keys.join(','), keys: keys }
148
+ end
149
+
150
+ def print_unique_keys(type:, category: nil, title: )
151
+ log.section_heading(title)
152
+
153
+ filter_key_infos = schema[:meta][:unique_keys].select { |key_info| key_info[:type] == type && (category.nil? || key_info[:category] == category) }
154
+
155
+ # log.kv 'all', filter_key_infos.flat_map { |key_info| key_info[:keys] }.uniq, 50
156
+
157
+ filter_key_infos.each do |key_info|
158
+ log.kv key_info[:key], key_info[:keys], 50
159
+ end
160
+ end
161
+
162
+ def integer(name, **opts)
163
+ add_field(name, :integer, **opts)
164
+ end
165
+
166
+ def bigint(name, **opts)
167
+ add_field(name, :bigint, **opts)
168
+ end
169
+
170
+ def decimal(name, **opts)
171
+ add_field(name, :decimal, **opts)
172
+ end
173
+
174
+ def string(name, **opts)
175
+ add_field(name, :string, **opts)
176
+ end
177
+
178
+ def datetime(name, **opts)
179
+ add_field(name, :datetime, **opts)
180
+ end
181
+
182
+ def date(name, **opts)
183
+ add_field(name, :date, **opts)
184
+ end
185
+
186
+ def text(name, **opts)
187
+ add_field(name, :text, **opts)
188
+ end
189
+
190
+ def boolean(name, **opts)
191
+ add_field(name, :boolean, **opts)
192
+ end
193
+
194
+ def jsonb(name, **opts)
195
+ add_field(name, :jsonb, **opts)
196
+ end
197
+
198
+ def hstore(name, **opts)
199
+ add_field(name, :hstore, **opts)
200
+ end
201
+
202
+ def float(name, **opts)
203
+ add_field(name, :float, **opts)
204
+ end
205
+
206
+ def sort
207
+ schema[:indexes].sort_by! { |i| i[:name] }
208
+ schema[:tables].each { |table| table[:indexes].sort_by! { |i| i[:name] } }
209
+
210
+ # Insert a key that represents all unique keys, and then sort
211
+ unique_keys_per_group = schema[:meta][:unique_keys]
212
+ .group_by { |key_info| [key_info[:type], key_info[:category]] }
213
+ .map do |group, values|
214
+ all_keys = values.flat_map { |key_info| key_info[:keys] }.uniq
215
+ {
216
+ type: group[0],
217
+ category: group[01],
218
+ key: 'all',
219
+ keys: all_keys
220
+ }
221
+ end
222
+
223
+ schema[:meta][:unique_keys].concat(unique_keys_per_group)
224
+ schema[:meta][:unique_keys].sort! { |a,b| ([a[:type], a[:category],a[:key]] <=> [b[:type], b[:category],b[:key]]) }
225
+ end
226
+ end
@@ -0,0 +1,67 @@
1
+ # Annotates the original schema with methods that implement existing method calls
2
+ # that are already in the schema so that we can build a hash.
3
+ #
4
+ # Writes a new annotated schema.rb file with a public method called load that
5
+ # builds the hash
6
+ # frozen_string_literal: true
7
+
8
+ module KDomain
9
+ module RawSchema
10
+ class Transform
11
+ include KLog::Logging
12
+
13
+ attr_reader :source_file
14
+ attr_reader :template_file
15
+ attr_reader :target_ruby_class
16
+
17
+ def initialize(source_file)#, target_file)
18
+ @source_file = source_file
19
+ @template_file = 'lib/k_domain/raw_schema/template.rb'
20
+ end
21
+
22
+ def call
23
+ # log.kv 'source_file', source_file
24
+ # log.kv 'template_file', template_file
25
+ # log.kv 'source_file?', File.exist?(source_file)
26
+ # log.kv 'template_file?', File.exist?(template_file)
27
+
28
+ log.error "Template not found: #{template_file}" unless File.exist?(template_file)
29
+
30
+ content = File.read(source_file)
31
+ content
32
+ .gsub!(/ActiveRecord::Schema.define/, 'load')
33
+
34
+ lines = content.lines.map { |line| " #{line}" }.join()
35
+
36
+ @target_ruby_class = File
37
+ .read(template_file)
38
+ .gsub('{{source_file}}', source_file)
39
+ .gsub('{{rails_schema}}', lines)
40
+ end
41
+
42
+ def write_target(target_file)
43
+ if target_ruby_class.nil?
44
+ puts '.call method has not been executed'
45
+ return
46
+ end
47
+
48
+ FileUtils.mkdir_p(File.dirname(target_file))
49
+ File.write(target_file, target_ruby_class)
50
+ end
51
+
52
+ def json
53
+ if target_ruby_class.nil?
54
+ puts '.call method has not been executed'
55
+ return
56
+ end
57
+
58
+ # load target_file
59
+ eval target_ruby_class
60
+
61
+ loader = LoadSchema.new
62
+ loader.load_schema()
63
+ loader.schema
64
+ end
65
+ end
66
+ end
67
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module KDomain
4
- VERSION = '0.0.1'
4
+ VERSION = '0.0.2'
5
5
  end
data/lib/k_domain.rb CHANGED
@@ -2,8 +2,7 @@
2
2
 
3
3
  require 'k_log'
4
4
  require 'k_domain/version'
5
-
6
-
5
+ require 'k_domain/raw_schema/transform'
7
6
 
8
7
  module KDomain
9
8
  # raise KDomain::Error, 'Sample message'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: k_domain
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Cruwys
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-09-25 00:00:00.000000000 Z
11
+ date: 2021-09-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: k_log
@@ -38,9 +38,12 @@ files:
38
38
  - ".rubocop.yml"
39
39
  - CODE_OF_CONDUCT.md
40
40
  - Gemfile
41
+ - Guardfile
41
42
  - LICENSE.txt
42
43
  - README.md
43
44
  - Rakefile
45
+ - STORIES.md
46
+ - USAGE.md
44
47
  - bin/console
45
48
  - bin/k
46
49
  - bin/kgitsync
@@ -50,6 +53,8 @@ files:
50
53
  - hooks/update-version
51
54
  - k_domain.gemspec
52
55
  - lib/k_domain.rb
56
+ - lib/k_domain/raw_schema/template.rb
57
+ - lib/k_domain/raw_schema/transform.rb
53
58
  - lib/k_domain/version.rb
54
59
  homepage: http://appydave.com/gems/k-domain
55
60
  licenses: