annotato 0.1.15 → 0.1.16
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 +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +1 -0
- data/lib/annotato/annotation_builder.rb +9 -0
- data/lib/annotato/check_constraint_formatter.rb +17 -0
- data/lib/annotato/index_formatter.rb +2 -66
- data/lib/annotato/version.rb +1 -1
- data/lib/annotato/wrap_helper.rb +68 -0
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 53d8c10c79ec7a147fde40ed706fa11b77e62a65f1afbb87a204b8f2153d6f29
|
|
4
|
+
data.tar.gz: 488da6fb4970e359d266cc6e817502a72cdfc29a2d7ab59f10219c1e73978ef6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6dd785f4e27b78b9a2084d2f846e531aba53774be945e5534386a179165c9509028bb8010f97fbab57c31693ed33aeda2fc2ec7f3ee807b711f7ad4086270048
|
|
7
|
+
data.tar.gz: 52d70e99d63296a518007970d09f20c209b15b5bb993b1c4f114c0912ba143c28d79e091491b74c7585898fef9c0c1140486db61df1a9782deefe935849720aa
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative "wrap_helper"
|
|
3
4
|
require_relative "column_formatter"
|
|
4
5
|
require_relative "index_formatter"
|
|
5
6
|
require_relative "trigger_formatter"
|
|
6
7
|
require_relative "line_formatter"
|
|
7
8
|
require_relative "enum_formatter"
|
|
9
|
+
require_relative "check_constraint_formatter"
|
|
8
10
|
|
|
9
11
|
module Annotato
|
|
10
12
|
class AnnotationBuilder
|
|
@@ -41,6 +43,13 @@ module Annotato
|
|
|
41
43
|
lines += triggers
|
|
42
44
|
end
|
|
43
45
|
|
|
46
|
+
check_constraints = CheckConstraintFormatter.format(conn, table_name)
|
|
47
|
+
unless check_constraints.empty?
|
|
48
|
+
lines << ""
|
|
49
|
+
lines << "Check Constraints:"
|
|
50
|
+
lines += check_constraints
|
|
51
|
+
end
|
|
52
|
+
|
|
44
53
|
LineFormatter.format(lines)
|
|
45
54
|
end
|
|
46
55
|
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Annotato
|
|
4
|
+
class CheckConstraintFormatter
|
|
5
|
+
extend WrapHelper
|
|
6
|
+
|
|
7
|
+
def self.format(conn, table_name)
|
|
8
|
+
conn.check_constraints(table_name).map do |chk|
|
|
9
|
+
expr_clause = ""
|
|
10
|
+
if chk.expression
|
|
11
|
+
expr_clause = "\n" + wrap_sql(chk.expression, first_prefix: "# (", cont_prefix: "# ")
|
|
12
|
+
end
|
|
13
|
+
"# #{chk.name}#{expr_clause}"
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Annotato
|
|
4
4
|
class IndexFormatter
|
|
5
|
-
|
|
5
|
+
extend WrapHelper
|
|
6
6
|
|
|
7
7
|
def self.format(conn, table_name)
|
|
8
8
|
conn.indexes(table_name).map do |idx|
|
|
@@ -11,75 +11,11 @@ module Annotato
|
|
|
11
11
|
|
|
12
12
|
where_clause = ""
|
|
13
13
|
if idx.where
|
|
14
|
-
where_clause = "\n" +
|
|
14
|
+
where_clause = "\n" + wrap_sql(idx.where, first_prefix: "# where (", cont_prefix: "# ")
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
"# #{idx.name} (#{cols_list})#{unique_clause}#{where_clause}"
|
|
18
18
|
end
|
|
19
19
|
end
|
|
20
|
-
|
|
21
|
-
# Produces one or more lines, each already prefixed with "# "
|
|
22
|
-
# First line: "# where (..."
|
|
23
|
-
# Next lines: "# ..." (aligned under the "(")
|
|
24
|
-
def self.wrap_where(where_sql, max_len:)
|
|
25
|
-
first_prefix = "# where ("
|
|
26
|
-
cont_prefix = "# " # aligns under the "(" after "where "
|
|
27
|
-
|
|
28
|
-
text = where_sql.to_s
|
|
29
|
-
lines = []
|
|
30
|
-
|
|
31
|
-
# If it already fits, keep it one-liner
|
|
32
|
-
if (first_prefix.length + text.length + 1) <= max_len
|
|
33
|
-
return "#{first_prefix}#{text})"
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
remaining = text.dup
|
|
37
|
-
current_prefix = first_prefix
|
|
38
|
-
|
|
39
|
-
while remaining.length > 0
|
|
40
|
-
available = max_len - current_prefix.length - 1 # -1 for closing ")" on last line (or just safety)
|
|
41
|
-
available = 20 if available < 20
|
|
42
|
-
|
|
43
|
-
if remaining.length <= available
|
|
44
|
-
lines << "#{current_prefix}#{remaining}"
|
|
45
|
-
remaining = ""
|
|
46
|
-
break
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
# Prefer breaking on logical operators within the window
|
|
50
|
-
window = remaining[0, available]
|
|
51
|
-
cut =
|
|
52
|
-
window.rindex(" AND ") ||
|
|
53
|
-
window.rindex(" OR ") ||
|
|
54
|
-
window.rindex(", ") ||
|
|
55
|
-
window.rindex(") ") ||
|
|
56
|
-
window.rindex(" ") # last resort: whitespace
|
|
57
|
-
|
|
58
|
-
# If we found a breakpoint, include it in the line (so operators stay visible)
|
|
59
|
-
if cut
|
|
60
|
-
# If we’re cutting on AND/OR/comma, keep that token at the end of the line when possible
|
|
61
|
-
if window[cut, 5] == " AND " || window[cut, 4] == " OR "
|
|
62
|
-
cut += (window[cut, 5] == " AND " ? 5 : 4)
|
|
63
|
-
elsif window[cut, 2] == ", "
|
|
64
|
-
cut += 2
|
|
65
|
-
elsif window[cut, 2] == ") "
|
|
66
|
-
cut += 2
|
|
67
|
-
else
|
|
68
|
-
cut += 1
|
|
69
|
-
end
|
|
70
|
-
else
|
|
71
|
-
cut = available
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
lines << "#{current_prefix}#{remaining[0, cut].rstrip}"
|
|
75
|
-
remaining = remaining[cut..].to_s.lstrip
|
|
76
|
-
current_prefix = cont_prefix
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
# Close the paren on the last line
|
|
80
|
-
lines[-1] = "#{lines[-1]})"
|
|
81
|
-
|
|
82
|
-
lines.join("\n")
|
|
83
|
-
end
|
|
84
20
|
end
|
|
85
21
|
end
|
data/lib/annotato/version.rb
CHANGED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Annotato
|
|
4
|
+
module WrapHelper
|
|
5
|
+
MAX_LINE = 100
|
|
6
|
+
|
|
7
|
+
# Produces one or more lines, each already prefixed with "# "
|
|
8
|
+
# First line: "# where (..."
|
|
9
|
+
# Next lines: "# ..." (aligned under the "(")
|
|
10
|
+
def wrap_sql(sql, first_prefix:, cont_prefix:, max_len: MAX_LINE)
|
|
11
|
+
text = sql.to_s
|
|
12
|
+
lines = []
|
|
13
|
+
|
|
14
|
+
# If it already fits, keep it one-liner
|
|
15
|
+
if (first_prefix.length + text.length + 1) <= max_len
|
|
16
|
+
return "#{first_prefix}#{text})"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
remaining = text.dup
|
|
20
|
+
current_prefix = first_prefix
|
|
21
|
+
|
|
22
|
+
while remaining.length > 0
|
|
23
|
+
available = max_len - current_prefix.length - 1 # -1 for closing ")" on last line (or just safety)
|
|
24
|
+
available = 20 if available < 20
|
|
25
|
+
|
|
26
|
+
if remaining.length <= available
|
|
27
|
+
lines << "#{current_prefix}#{remaining}"
|
|
28
|
+
remaining = ""
|
|
29
|
+
break
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Prefer breaking on logical operators within the window
|
|
33
|
+
window = remaining[0, available]
|
|
34
|
+
cut =
|
|
35
|
+
window.rindex(" AND ") ||
|
|
36
|
+
window.rindex(" OR ") ||
|
|
37
|
+
window.rindex(", ") ||
|
|
38
|
+
window.rindex(") ") ||
|
|
39
|
+
window.rindex(" ") # last resort: whitespace
|
|
40
|
+
|
|
41
|
+
# If we found a breakpoint, include it in the line (so operators stay visible)
|
|
42
|
+
if cut
|
|
43
|
+
# If we’re cutting on AND/OR/comma, keep that token at the end of the line when possible
|
|
44
|
+
if window[cut, 5] == " AND " || window[cut, 4] == " OR "
|
|
45
|
+
cut += (window[cut, 5] == " AND " ? 5 : 4)
|
|
46
|
+
elsif window[cut, 2] == ", "
|
|
47
|
+
cut += 2
|
|
48
|
+
elsif window[cut, 2] == ") "
|
|
49
|
+
cut += 2
|
|
50
|
+
else
|
|
51
|
+
cut += 1
|
|
52
|
+
end
|
|
53
|
+
else
|
|
54
|
+
cut = available
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
lines << "#{current_prefix}#{remaining[0, cut].rstrip}"
|
|
58
|
+
remaining = remaining[cut..].to_s.lstrip
|
|
59
|
+
current_prefix = cont_prefix
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Close the paren on the last line
|
|
63
|
+
lines[-1] = "#{lines[-1]})"
|
|
64
|
+
|
|
65
|
+
lines.join("\n")
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: annotato
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Serhii Bodnaruk
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 2026-01-23 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: rails
|
|
@@ -45,6 +45,7 @@ files:
|
|
|
45
45
|
- bin/setup
|
|
46
46
|
- lib/annotato.rb
|
|
47
47
|
- lib/annotato/annotation_builder.rb
|
|
48
|
+
- lib/annotato/check_constraint_formatter.rb
|
|
48
49
|
- lib/annotato/column_formatter.rb
|
|
49
50
|
- lib/annotato/enum_formatter.rb
|
|
50
51
|
- lib/annotato/index_formatter.rb
|
|
@@ -53,6 +54,7 @@ files:
|
|
|
53
54
|
- lib/annotato/railtie.rb
|
|
54
55
|
- lib/annotato/trigger_formatter.rb
|
|
55
56
|
- lib/annotato/version.rb
|
|
57
|
+
- lib/annotato/wrap_helper.rb
|
|
56
58
|
- lib/tasks/annotato.rake
|
|
57
59
|
- sig/annotato.rbs
|
|
58
60
|
homepage: https://github.com/boserh/annotato
|