schema_to_dbml 0.0.3 → 0.0.5

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: 9032720a1b5f18280931f1c79673a0f1bd19fe11984b7648fe8a51daa4845cad
4
- data.tar.gz: e255d62a37be7d8c1980ef5920f447993bff019119ac86cb45e2102d35a65ff1
3
+ metadata.gz: dc54963544b87bb99449b5bcb2129a64211378ffbfec57cfbbebce562bdf0c0b
4
+ data.tar.gz: 06c18c1b57f71d0c064ae1d01ee2df9de0600bd68da6748c657af1f51f819927
5
5
  SHA512:
6
- metadata.gz: 51f4a20647f1a6a050b08e45c4d6d0a7c8be8dab2ae1ffed85bcfb94b08d002dd1291247bf6487494e661f5ce993e4378e5ef540542282bee5ae9c4096fb90f9
7
- data.tar.gz: 84e5fdc4390ed090174685f6ac18c9f29e278bc82ea99452f5d8dccae9f874c49031daac59bc135c31a2befb990f1ad3795ec024d72bd12bea91697dff0634cc
6
+ metadata.gz: 7733b4a827bff5432bd663e6900f9c8cb7388b89b6eaabc7135cf01acfa09ff4f527262c127d9ec15fbe82cb5536a5fc96bf67511956572d34e78ae51c999a5f
7
+ data.tar.gz: e86975d104f9cc120f6a20e88d6a412534ef9b47286940a08f2ebaf3ec5a1d59ff7a7d7280995ada45f1676b9b91437a39b380ee29ea6f41002c6ba56aa53ef5
data/.rubocop.yml CHANGED
@@ -1,8 +1,12 @@
1
+ inherit_from: .rubocop_todo.yml
2
+
3
+ require:
4
+ - rubocop-rspec
5
+
1
6
  AllCops:
2
7
  TargetRubyVersion: 3.1.2
3
8
  Exclude:
4
- - spec/lib/schema_to_dbml/support/*
5
- - spec/shared_examples/*
9
+ - spec/support/**/*
6
10
  - vendor/bundle/**/*
7
11
  NewCops: enable
8
12
 
@@ -71,9 +75,9 @@ Style/RedundantFetchBlock:
71
75
 
72
76
  Style/MethodCallWithArgsParentheses:
73
77
  Enabled: false
74
-
78
+
75
79
  Gemspec/DevelopmentDependencies:
76
80
  Enabled: false
77
81
 
78
82
  Metrics/ParameterLists:
79
- Max: 7
83
+ Max: 8
data/.rubocop_todo.yml ADDED
@@ -0,0 +1,16 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config`
3
+ # on 2024-03-03 11:08:02 UTC using RuboCop version 1.61.0.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Offense count: 2
10
+ RSpec/MultipleExpectations:
11
+ Max: 3
12
+
13
+ # Offense count: 1
14
+ # Configuration parameters: AllowSubject.
15
+ RSpec/MultipleMemoizedHelpers:
16
+ Max: 6
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 3.3.0
data/Gemfile.lock CHANGED
@@ -1,60 +1,80 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- schema_to_dbml (0.0.3)
4
+ schema_to_dbml (0.0.5)
5
5
  activesupport (>= 6.1.0)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- activesupport (7.0.5)
10
+ activesupport (7.1.3.2)
11
+ base64
12
+ bigdecimal
11
13
  concurrent-ruby (~> 1.0, >= 1.0.2)
14
+ connection_pool (>= 2.2.5)
15
+ drb
12
16
  i18n (>= 1.6, < 2)
13
17
  minitest (>= 5.1)
18
+ mutex_m
14
19
  tzinfo (~> 2.0)
15
20
  ast (2.4.2)
21
+ base64 (0.2.0)
22
+ bigdecimal (3.1.6)
16
23
  byebug (11.1.3)
17
- concurrent-ruby (1.2.2)
18
- diff-lcs (1.5.0)
24
+ concurrent-ruby (1.2.3)
25
+ connection_pool (2.4.1)
26
+ diff-lcs (1.5.1)
19
27
  docile (1.4.0)
20
- i18n (1.13.0)
28
+ drb (2.2.1)
29
+ i18n (1.14.1)
21
30
  concurrent-ruby (~> 1.0)
22
- json (2.6.3)
23
- minitest (5.18.0)
24
- parallel (1.23.0)
25
- parser (3.2.2.3)
31
+ json (2.7.1)
32
+ language_server-protocol (3.17.0.3)
33
+ minitest (5.22.2)
34
+ mutex_m (0.2.0)
35
+ parallel (1.24.0)
36
+ parser (3.3.0.5)
26
37
  ast (~> 2.4.1)
27
38
  racc
28
- racc (1.7.0)
39
+ racc (1.7.3)
29
40
  rainbow (3.1.1)
30
- rake (13.0.6)
31
- regexp_parser (2.8.1)
32
- rexml (3.2.5)
33
- rspec (3.12.0)
34
- rspec-core (~> 3.12.0)
35
- rspec-expectations (~> 3.12.0)
36
- rspec-mocks (~> 3.12.0)
37
- rspec-core (3.12.1)
38
- rspec-support (~> 3.12.0)
39
- rspec-expectations (3.12.2)
41
+ rake (13.1.0)
42
+ regexp_parser (2.9.0)
43
+ rexml (3.2.6)
44
+ rspec (3.13.0)
45
+ rspec-core (~> 3.13.0)
46
+ rspec-expectations (~> 3.13.0)
47
+ rspec-mocks (~> 3.13.0)
48
+ rspec-core (3.13.0)
49
+ rspec-support (~> 3.13.0)
50
+ rspec-expectations (3.13.0)
40
51
  diff-lcs (>= 1.2.0, < 2.0)
41
- rspec-support (~> 3.12.0)
42
- rspec-mocks (3.12.5)
52
+ rspec-support (~> 3.13.0)
53
+ rspec-mocks (3.13.0)
43
54
  diff-lcs (>= 1.2.0, < 2.0)
44
- rspec-support (~> 3.12.0)
45
- rspec-support (3.12.0)
46
- rubocop (1.52.1)
55
+ rspec-support (~> 3.13.0)
56
+ rspec-support (3.13.0)
57
+ rubocop (1.61.0)
47
58
  json (~> 2.3)
59
+ language_server-protocol (>= 3.17.0)
48
60
  parallel (~> 1.10)
49
- parser (>= 3.2.2.3)
61
+ parser (>= 3.3.0.2)
50
62
  rainbow (>= 2.2.2, < 4.0)
51
63
  regexp_parser (>= 1.8, < 3.0)
52
64
  rexml (>= 3.2.5, < 4.0)
53
- rubocop-ast (>= 1.28.0, < 2.0)
65
+ rubocop-ast (>= 1.30.0, < 2.0)
54
66
  ruby-progressbar (~> 1.7)
55
67
  unicode-display_width (>= 2.4.0, < 3.0)
56
- rubocop-ast (1.29.0)
57
- parser (>= 3.2.1.0)
68
+ rubocop-ast (1.31.1)
69
+ parser (>= 3.3.0.4)
70
+ rubocop-capybara (2.20.0)
71
+ rubocop (~> 1.41)
72
+ rubocop-factory_bot (2.25.1)
73
+ rubocop (~> 1.41)
74
+ rubocop-rspec (2.27.0)
75
+ rubocop (~> 1.40)
76
+ rubocop-capybara (~> 2.17)
77
+ rubocop-factory_bot (~> 2.22)
58
78
  ruby-progressbar (1.13.0)
59
79
  simplecov (0.22.0)
60
80
  docile (~> 1.1)
@@ -64,10 +84,11 @@ GEM
64
84
  simplecov_json_formatter (0.1.4)
65
85
  tzinfo (2.0.6)
66
86
  concurrent-ruby (~> 1.0)
67
- unicode-display_width (2.4.2)
87
+ unicode-display_width (2.5.0)
68
88
 
69
89
  PLATFORMS
70
90
  arm64-darwin-21
91
+ arm64-darwin-23
71
92
  x86_64-darwin-22
72
93
  x86_64-linux
73
94
 
@@ -77,6 +98,7 @@ DEPENDENCIES
77
98
  rake
78
99
  rspec
79
100
  rubocop
101
+ rubocop-rspec
80
102
  schema_to_dbml!
81
103
  simplecov
82
104
 
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'helpers/constants'
4
- require_relative './dbml_tables_formatter'
5
- require_relative './dbml_relations_formatter'
4
+ require_relative 'dbml_tables_formatter'
5
+ require_relative 'dbml_relations_formatter'
6
6
 
7
7
  class SchemaConverter
8
8
  include Helpers::Constants
@@ -18,8 +18,8 @@ class SchemaConverter
18
18
  def convert(schema_content:)
19
19
  tables = []
20
20
  relations = []
21
- schema_content.scan(TABLES_REGEXP).each do |table_name, table_comment, columns|
22
- tables << dbml_tables_formatter.format(table_name:, table_comment:, parsed_columns: columns)
21
+ schema_content.scan(TABLES_REGEXP).each do |table_name, table_comment, table_attributes|
22
+ tables << dbml_tables_formatter.format(table_name:, table_comment:, table_attributes:)
23
23
  end
24
24
 
25
25
  schema_content.scan(RELATIONS_REGEXP).each do |from_table, to_table, column, on_delete|
@@ -1,32 +1,35 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'formatters/fields_formatter'
4
+ require_relative 'formatters/index_formatter'
4
5
  require_relative 'helpers/constants'
5
6
 
6
7
  class DbmlTablesFormatter
7
8
  include Helpers::Constants
8
9
  include Formatters::FieldsFormatter
10
+ include Formatters::IndexFormatter
9
11
 
10
12
  def initialize(configuration: SchemaToDbml.configuration)
11
13
  @configuration = configuration
12
14
  end
13
15
 
14
- def format(table_name:, table_comment:, parsed_columns:)
15
- columns = build_columns(parsed_columns)
16
+ def format(table_name:, table_comment:, table_attributes:)
17
+ columns = build_columns(table_attributes)
18
+ indexes = build_indexes(table_attributes)
16
19
 
17
- format_dbml(table_name, columns, table_comment)
20
+ format_dbml(table_name, columns, indexes, table_comment)
18
21
  end
19
22
 
20
23
  private
21
24
 
22
- def build_columns(parsed_columns)
25
+ def build_columns(table_attributes)
23
26
  columns = []
24
27
 
25
- parsed_columns.scan(COLUMNS_REGEXP).each do |type, name, default, null, comment, _precision, array|
28
+ table_attributes.scan(COLUMNS_REGEXP).each do |type, name, default, null, comment, _precision, array, limit|
26
29
  formatted_comment = format_comment(comment:)
27
30
  formatted_default = format_default(default:)
28
31
  formatted_null = format_null(null:)
29
- formatted_type = format_type(type:, array:)
32
+ formatted_type = format_type(type:, array:, limit:)
30
33
 
31
34
  final_values = [formatted_default, formatted_null, formatted_comment].compact.reject(&:empty?)
32
35
  columns << build_line(name, formatted_type, final_values)
@@ -35,6 +38,18 @@ class DbmlTablesFormatter
35
38
  columns
36
39
  end
37
40
 
41
+ def build_indexes(table_definition)
42
+ indexes = []
43
+
44
+ table_definition.scan(INDEXES_REGEXP) do |columns, index_name, unique|
45
+ indexes << format_index(columns, index_name, unique)
46
+ end
47
+
48
+ return if indexes.empty?
49
+
50
+ "\n#{TAB}indexes {\n#{indexes.join("\n")}\n#{TAB}}"
51
+ end
52
+
38
53
  def build_line(name, formatted_type, final_values)
39
54
  line = " #{name} #{formatted_type}"
40
55
 
@@ -43,11 +58,12 @@ class DbmlTablesFormatter
43
58
  line << " [#{final_values.join(',')}]"
44
59
  end
45
60
 
46
- def format_dbml(table_name, columns, table_comment)
61
+ def format_dbml(table_name, columns, indexes, table_comment)
47
62
  dbml_table = "Table #{table_name} {\n"
48
- dbml_table << " #{custom_primary_key}\n"
63
+ dbml_table << "#{TAB}#{custom_primary_key}\n"
49
64
  dbml_table << columns.join("\n")
50
- dbml_table << "\n Note: '#{table_comment}'" unless table_comment.to_s.empty?
65
+ dbml_table << indexes if indexes
66
+ dbml_table << "\n#{TAB}Note: '#{table_comment}'" unless table_comment.to_s.empty?
51
67
  dbml_table << "\n}"
52
68
  dbml_table
53
69
  end
@@ -5,6 +5,11 @@ require_relative 'default_field_formatter_helper'
5
5
  module Formatters
6
6
  module FieldsFormatter
7
7
  include DefaultFieldFormatterHelper
8
+
9
+ COMMENT_MAPPER = [
10
+ { from: "'", to: "\\\\'" },
11
+ { from: '\"', to: '"' }
12
+ ].freeze
8
13
  TYPE_MAPPER = {
9
14
  string: 'varchar',
10
15
  integer: 'int',
@@ -12,12 +17,13 @@ module Formatters
12
17
  datetime: 'timestamp'
13
18
  }.freeze
14
19
 
15
- def format_type(type:, array:)
20
+ def format_type(type:, array:, limit:)
16
21
  return '' if type.to_s.empty?
17
22
 
18
23
  parsed = TYPE_MAPPER[type.to_sym] || type.to_s
19
24
 
20
25
  return "#{parsed}[]" if array == 'true'
26
+ return "#{parsed}(#{limit})" if limit
21
27
 
22
28
  parsed
23
29
  end
@@ -41,7 +47,12 @@ module Formatters
41
47
  def format_comment(comment:)
42
48
  return '' if comment.to_s.empty?
43
49
 
44
- "note: '#{comment.gsub("'", "\\\\'")}'"
50
+ note = comment.dup
51
+ COMMENT_MAPPER.each do |mapper|
52
+ note.gsub!(mapper[:from], mapper[:to])
53
+ end
54
+
55
+ "note: '#{note}'"
45
56
  end
46
57
  end
47
58
  end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../helpers/constants'
4
+
5
+ module Formatters
6
+ module IndexFormatter
7
+ include Helpers::Constants
8
+
9
+ def format_index(columns, index_name, unique)
10
+ formatted_columns = format_index_columns(columns)
11
+ formatted_settings = format_index_settings(unique)
12
+ formatted_name = "name: '#{index_name}'"
13
+ formatted_values = [formatted_settings, formatted_name].compact.join(', ')
14
+
15
+ "#{TAB * 2}(#{formatted_columns}) [#{formatted_values}]"
16
+ end
17
+
18
+ private
19
+
20
+ def format_index_columns(columns)
21
+ columns.gsub('"', '').split(', ').join(', ')
22
+ end
23
+
24
+ def format_index_settings(unique)
25
+ # There are other possible settings for indexes
26
+ # but for now we will only add unique
27
+ # https://dbml.dbdiagram.io/docs/#index-definition
28
+ return unless unique
29
+
30
+ 'unique'
31
+ end
32
+ end
33
+ end
@@ -2,13 +2,15 @@
2
2
 
3
3
  module Helpers
4
4
  module Constants
5
+ TAB = ' '
6
+
5
7
  TABLES_REGEXP = /
6
8
  create_table\s+"(?<table_name>\w+)"
7
9
  (?:,\s+comment:\s+"(?<comment>.*?)")?
8
10
  (?:,\s+force:\s+:cascade)?
9
11
  \s+do\s+\|t\|
10
12
  \n
11
- (?<table_content>(?:.*?)(?:".*?")*.*?)
13
+ (?<table_attributes>(?:.*?)(?:".*?")*.*?)
12
14
  (?<=\n)
13
15
  \s+end
14
16
  /xm
@@ -18,12 +20,19 @@ module Helpers
18
20
  (?:
19
21
  (?:,\s+(?<default>default:[^,\n]+?(?=(?:,\s)|$)))?
20
22
  (?:,\s+(?<null>null:\s+\w+))?
21
- (?:,\s+comment:\s+"(?<comment>[^"]+)")?
23
+ (?:,\s+comment:\s+"(?<comment>[^"\\]*(?:\\.[^"\\]*)*)")?
22
24
  (?:,\s+precision:\s+(?<precision>\d+))?
23
25
  (?:,\s+array:\s+(?<array>true|false))?
26
+ (?:,\s+limit:\s+(?<limit>\d+))?
24
27
  )*
25
28
  /x
26
29
 
30
+ INDEXES_REGEXP = /
31
+ t\.index\s+\[(?<columns>[^\]]+)\]
32
+ (?:,\s+name:\s+"(?<name>[^"\\]*(?:\\.[^"\\]*)*)")?
33
+ (?:,\s+unique:\s+(?<unique>true|false))?
34
+ /x
35
+
27
36
  RELATIONS_REGEXP = /
28
37
  add_foreign_key\s+"(?<from_table>\w+)",\s+"(?<to_table>\w+)"
29
38
  (?:,\s+column:\s+"(?<column>\w+)")?
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'helpers/constants'
4
- require_relative './dbml_tables_formatter'
5
- require_relative './dbml_relations_formatter'
4
+ require_relative 'dbml_tables_formatter'
5
+ require_relative 'dbml_relations_formatter'
6
6
 
7
7
  class SchemaConverter
8
8
  include Helpers::Constants
@@ -18,8 +18,8 @@ class SchemaConverter
18
18
  def convert(schema_content:)
19
19
  tables = []
20
20
  relations = []
21
- schema_content.scan(TABLES_REGEXP).each do |table_name, table_comment, columns|
22
- tables << dbml_tables_formatter.format(table_name:, table_comment:, parsed_columns: columns)
21
+ schema_content.scan(TABLES_REGEXP).each do |table_name, table_comment, table_attributes|
22
+ tables << dbml_tables_formatter.format(table_name:, table_comment:, table_attributes:)
23
23
  end
24
24
 
25
25
  schema_content.scan(RELATIONS_REGEXP).each do |from_table, to_table, column, on_delete|
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class SchemaToDbml
4
- VERSION = '0.0.3'
4
+ VERSION = '0.0.5'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: schema_to_dbml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ricardo Ribeiro
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-06-21 00:00:00.000000000 Z
11
+ date: 2024-03-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop-rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: simplecov
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -118,6 +132,8 @@ extra_rdoc_files: []
118
132
  files:
119
133
  - ".rspec"
120
134
  - ".rubocop.yml"
135
+ - ".rubocop_todo.yml"
136
+ - ".ruby-version"
121
137
  - CHANGELOG.md
122
138
  - CODE_OF_CONDUCT.md
123
139
  - CONTRIBUTE.md
@@ -139,6 +155,7 @@ files:
139
155
  - lib/schema_to_dbml/errors/schema_file_not_found_error.rb
140
156
  - lib/schema_to_dbml/formatters/default_field_formatter_helper.rb
141
157
  - lib/schema_to_dbml/formatters/fields_formatter.rb
158
+ - lib/schema_to_dbml/formatters/index_formatter.rb
142
159
  - lib/schema_to_dbml/helpers/constants.rb
143
160
  - lib/schema_to_dbml/schema_converter.rb
144
161
  - lib/schema_to_dbml/version.rb
@@ -166,7 +183,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
166
183
  - !ruby/object:Gem::Version
167
184
  version: '0'
168
185
  requirements: []
169
- rubygems_version: 3.3.7
186
+ rubygems_version: 3.5.3
170
187
  signing_key:
171
188
  specification_version: 4
172
189
  summary: A Ruby on Rails gem for converting schema.rb files to DBML.