mkxms-mssql 1.0.0 → 1.1.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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -10
  3. data/lib/mkxms/mssql.rb +18 -0
  4. data/lib/mkxms/mssql/adoption_script_writer.rb +759 -91
  5. data/lib/mkxms/mssql/clr_aggregate_handler.rb +98 -0
  6. data/lib/mkxms/mssql/clr_assembly_handler.rb +92 -0
  7. data/lib/mkxms/mssql/clr_function_handler.rb +172 -0
  8. data/lib/mkxms/mssql/clr_impl.rb +58 -0
  9. data/lib/mkxms/mssql/clr_stored_procedure_handler.rb +88 -0
  10. data/lib/mkxms/mssql/clr_type_handler.rb +92 -0
  11. data/lib/mkxms/mssql/database_handler.rb +124 -3
  12. data/lib/mkxms/mssql/declaratives_creator.rb +206 -0
  13. data/lib/mkxms/mssql/dml_trigger_handler.rb +107 -0
  14. data/lib/mkxms/mssql/filegroup_handler.rb +1 -4
  15. data/lib/mkxms/mssql/function_handler.rb +1 -4
  16. data/lib/mkxms/mssql/indented_string_builder.rb +8 -2
  17. data/lib/mkxms/mssql/index_handler.rb +1 -4
  18. data/lib/mkxms/mssql/keywords.rb +492 -0
  19. data/lib/mkxms/mssql/primary_key_handler.rb +1 -4
  20. data/lib/mkxms/mssql/property_handler.rb +8 -0
  21. data/lib/mkxms/mssql/query_cursor.rb +12 -4
  22. data/lib/mkxms/mssql/references_handler.rb +24 -0
  23. data/lib/mkxms/mssql/role_handler.rb +1 -4
  24. data/lib/mkxms/mssql/scalar_type_handler.rb +108 -0
  25. data/lib/mkxms/mssql/schema_handler.rb +1 -4
  26. data/lib/mkxms/mssql/sql_string_manipulators.rb +4 -4
  27. data/lib/mkxms/mssql/statistics_handler.rb +1 -4
  28. data/lib/mkxms/mssql/stored_procedure_handler.rb +1 -4
  29. data/lib/mkxms/mssql/synonym_handler.rb +40 -0
  30. data/lib/mkxms/mssql/table_handler.rb +2 -8
  31. data/lib/mkxms/mssql/table_type_handler.rb +254 -0
  32. data/lib/mkxms/mssql/utils.rb +96 -0
  33. data/lib/mkxms/mssql/version.rb +1 -1
  34. data/lib/mkxms/mssql/view_handler.rb +1 -4
  35. data/spec/utils/indented_string_builder_spec.rb +21 -0
  36. data/spec/utils/query_cursor_spec.rb +2 -2
  37. data/spec/utils/sql_string_manipulators_spec.rb +59 -0
  38. metadata +18 -3
@@ -50,6 +50,92 @@ module Mkxms::Mssql::Utils
50
50
  item.send(@children_message).each(&blk)
51
51
  end
52
52
  end
53
+
54
+ module StringHelpers
55
+ def expand_tabs(tabstops_every = 8)
56
+ self.lines.map do |l|
57
+ if l.include?("\t")
58
+ segs = l.split("\t")
59
+ segs[0...-1].map do |seg|
60
+ # seg length must _increase_ to a multiple of 8
61
+ spaces_needed = tabstops_every - (seg.length + 1) % tabstops_every + 1
62
+ seg + ' ' * spaces_needed
63
+ end.join('') + segs[-1]
64
+ else
65
+ l
66
+ end
67
+ end.join('')
68
+ end
69
+
70
+ def sql_quoted
71
+ %Q{N'#{gsub("'", "''")}'}
72
+ end
73
+ end
74
+
75
+ # Primes in the interval [100, 255]. This enumerator can be queried by
76
+ # classes that generate RAISERROR statements to provide unique-ish context
77
+ # by passing the next multiple of one of the values taken from this
78
+ # enumerator for each RAISERROR statement output (as a literal number in
79
+ # the generated SQL). This will assist
80
+ RAISERROR_STATE_BASE = [
81
+ 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163 ,167, 173,
82
+ 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251
83
+ ].each unless defined? RAISERROR_STATE_BASE
84
+
85
+ # Create one instance of this class to write a sequence of similar
86
+ # RAISERROR messages. The state of each message will be unique within the
87
+ # sequence until the 256th message. The particular order is unique to
88
+ # all other instances of this class.
89
+ class RaiserrorWriter
90
+ # Severity:
91
+ # 11 is the minimum to transfer into a CATCH
92
+ # 19 or higher can only be raised by sysadmin
93
+ # 20 or higher is fatal to the connection
94
+
95
+ SYMBOLIC_SEVERITIES = {
96
+ :warning => 1,
97
+ :error => 11,
98
+ }
99
+
100
+ def initialize(message, severity: 11)
101
+ # Get a unique prime to use as an ideal to generate the 0-255 state-value
102
+ # space. With luck, the number is fairly unique to the message.
103
+ severity = map_severity(severity)
104
+ @state_base = RAISERROR_STATE_BASE.next
105
+ @index = 1 # Start at 1 because 0 is the kernel -- every @state_base * 0 == 0
106
+ @message = message
107
+ @severity = severity
108
+ end
109
+
110
+ attr_reader :state_base
111
+ attr_accessor :message, :severity
112
+
113
+ def map_severity(value)
114
+ SYMBOLIC_SEVERITIES.fetch(value, value)
115
+ end
116
+
117
+ def current_statement(*args, severity: nil)
118
+ severity = map_severity(severity || self.severity)
119
+ state_str = current_error_marker
120
+ full_message = %Q{N'#{message.gsub("'", "''")} (search for "#{state_str}")'}
121
+ trailing_args = ([state_str] + args.map(&:to_s)).join(', ')
122
+ %Q{RAISERROR (#{full_message}, #{severity}, #{trailing_args})}.tap do |stmt|
123
+ stmt.define_singleton_method(:error_marker) {state_str}
124
+ end
125
+ end
126
+
127
+ def current_error_marker
128
+ "/*ERR*/ #{current_state} /*ERR*/"
129
+ end
130
+
131
+ def current_state
132
+ (state_base * @index) % 256
133
+ end
134
+
135
+ def next_statement(*args, **kwargs)
136
+ current_statement(*args, **kwargs).tap {@index += 1}
137
+ end
138
+ end
53
139
  end
54
140
 
55
141
  class << Mkxms::Mssql::Utils
@@ -80,4 +166,14 @@ class << Mkxms::Mssql::Utils
80
166
  l
81
167
  end.join('')
82
168
  end
169
+
170
+ def dry_run?
171
+ @dry_run.tap do |v|
172
+ (break @dry_run = !!(ENV.fetch('DRY_RUN', '') =~ /^(y(es)?|t(rue)?|1)$/i)) if v.nil?
173
+ end
174
+ end
175
+ end
176
+
177
+ class String
178
+ include Mkxms::Mssql::Utils::StringHelpers
83
179
  end
@@ -1,5 +1,5 @@
1
1
  module Mkxms
2
2
  module Mssql
3
- VERSION = "1.0.0"
3
+ VERSION = "1.1.0"
4
4
  end
5
5
  end
@@ -34,14 +34,11 @@ module Mkxms::Mssql
34
34
  a = node.attributes
35
35
 
36
36
  @view = View.new(a).tap do |v|
37
+ store_properties_on v
37
38
  views << v
38
39
  end
39
40
  end
40
41
 
41
- def extended_properties
42
- @view.extended_properties
43
- end
44
-
45
42
  def handle_definition_element(parse); end
46
43
 
47
44
  def handle_references_element(parse)
@@ -213,6 +213,27 @@ describe Mkxms::Mssql::IndentedStringBuilder do
213
213
  test_instance = test_class.new
214
214
  expect(test_instance.to_s).to eql("BEGIN\n command\nEND\n")
215
215
  end
216
+
217
+ it "handles blank lines properly" do
218
+ test_class = Class.new(described_class) do
219
+ def initialize
220
+ super
221
+
222
+ add_level_one
223
+ end
224
+
225
+ def add_level_one
226
+ dsl {
227
+ puts "foo"
228
+ puts
229
+ }
230
+ puts "bar"
231
+ end
232
+ end
233
+
234
+ test_instance = test_class.new
235
+ expect(test_instance.to_s).to eql("foo\n\nbar\n")
236
+ end
216
237
  end
217
238
  end
218
239
  end
@@ -16,7 +16,7 @@ describe Mkxms::Mssql::QueryCursor do
16
16
  sql.puts " -- Handle a row"
17
17
  end
18
18
 
19
- expect(sql.string).to eql("DECLARE @schema_id INT, @schema_name SYSNAME;\nDECLARE test_cursor CURSOR LOCAL FOR\nSELECT schema_id, name FROM sys.schemas;\nFETCH NEXT FROM test_cursor INTO @schema_id, @schema_name;\nWHILE @@FETCH_STATUS = 0\nBEGIN\n -- Handle a row\n FETCH NEXT FROM test_cursor INTO @schema_id, @schema_name;\nEND;\n")
19
+ expect(sql.string).to eql("DECLARE @schema_id INT, @schema_name SYSNAME;\nDECLARE test_cursor CURSOR LOCAL FOR\nSELECT schema_id, name FROM sys.schemas;\nOPEN test_cursor;\nFETCH NEXT FROM test_cursor INTO @schema_id, @schema_name;\nWHILE @@FETCH_STATUS = 0\nBEGIN\n -- Handle a row\n FETCH NEXT FROM test_cursor INTO @schema_id, @schema_name;\nEND;\n")
20
20
  end
21
21
 
22
22
  it "provides a expectation loop" do
@@ -52,6 +52,6 @@ describe Mkxms::Mssql::QueryCursor do
52
52
  end
53
53
  end
54
54
 
55
- expect(sql.string).to eql("DECLARE @column_name SYSNAME, @is_sorted_descending BIT;\nDECLARE test_cursor CURSOR LOCAL FOR\nSELECT c.name, ic.is_descending_key FROM sys.index_columns ic JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id WHERE ic.object_id = @relation_id AND ic.index_id = @index_id AND ic.key_ordinal >= 1 ORDER BY ic.key_ordinal;\nFETCH NEXT FROM test_cursor INTO @column_name, @is_sorted_descending;\nIF @@FETCH_STATUS <> 0\nBEGIN\n-- Handle missing entry\nEND ELSE BEGIN\n-- Test column name is foo.\n-- Test is ascending.\nEND;\nFETCH NEXT FROM test_cursor INTO @column_name, @is_sorted_descending;\nIF @@FETCH_STATUS <> 0\nBEGIN\n-- Handle missing entry\nEND ELSE BEGIN\n-- Test column name is bar.\n-- Test is ascending.\nEND;\nFETCH NEXT FROM test_cursor INTO @column_name, @is_sorted_descending;\nIF @@FETCH_STATUS <> 0\nBEGIN\n-- Handle missing entry\nEND ELSE BEGIN\n-- Test column name is baz.\n-- Test is descending.\nEND;\nFETCH NEXT FROM test_cursor INTO @column_name, @is_sorted_descending;\nIF @@FETCH_STATUS = 0\nBEGIN\n-- Handle extra entry/ies\nEND;\nCLOSE test_cursor; DEALLOCATE test_cursor;\n")
55
+ expect(sql.string).to eql("DECLARE @column_name SYSNAME, @is_sorted_descending BIT;\nDECLARE test_cursor CURSOR LOCAL FOR\nSELECT c.name, ic.is_descending_key FROM sys.index_columns ic JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id WHERE ic.object_id = @relation_id AND ic.index_id = @index_id AND ic.key_ordinal >= 1 ORDER BY ic.key_ordinal;\nOPEN test_cursor;\n\nFETCH NEXT FROM test_cursor INTO @column_name, @is_sorted_descending;\nIF @@FETCH_STATUS <> 0\nBEGIN\n-- Handle missing entry\nEND ELSE BEGIN\n-- Test column name is foo.\n-- Test is ascending.\nEND;\n\nFETCH NEXT FROM test_cursor INTO @column_name, @is_sorted_descending;\nIF @@FETCH_STATUS <> 0\nBEGIN\n-- Handle missing entry\nEND ELSE BEGIN\n-- Test column name is bar.\n-- Test is ascending.\nEND;\n\nFETCH NEXT FROM test_cursor INTO @column_name, @is_sorted_descending;\nIF @@FETCH_STATUS <> 0\nBEGIN\n-- Handle missing entry\nEND ELSE BEGIN\n-- Test column name is baz.\n-- Test is descending.\nEND;\nFETCH NEXT FROM test_cursor INTO @column_name, @is_sorted_descending;\nIF @@FETCH_STATUS = 0\nBEGIN\n-- Handle extra entry/ies\nEND;\nCLOSE test_cursor; DEALLOCATE test_cursor;\n")
56
56
  end
57
57
  end
@@ -0,0 +1,59 @@
1
+ require 'mkxms/mssql/sql_string_manipulators'
2
+
3
+ describe Mkxms::Mssql::SqlStringManipulators do
4
+ module T
5
+ extend Mkxms::Mssql::SqlStringManipulators
6
+ end
7
+
8
+ context "dedenting" do
9
+ it "handles a string with no newlines" do
10
+ expect(T.dedent("foo")).to eq("foo")
11
+ end
12
+
13
+ it "handles a string with a all lines at a constant indent" do
14
+ s = T.dedent %Q{
15
+ Jack and Jill went up the hill
16
+ to fetch a pail of water
17
+ }
18
+ expect(s.lines.size).to eq(2)
19
+ expect(s.lines[0]).not_to start_with(' ')
20
+ end
21
+
22
+ it "handles nested indentation" do
23
+ s = T.dedent %Q{
24
+ one
25
+ two
26
+ one
27
+ two
28
+ }
29
+ expect(s.lines.size).to eq(4)
30
+ expect(s.lines[0]).not_to start_with(' ')
31
+ expect(s.lines[1]).to start_with(' t')
32
+ end
33
+
34
+ it "allows leading blank lines" do
35
+ s = T.dedent %Q{
36
+
37
+ after the break
38
+ }
39
+ expect(s.lines[0]).to match(/^\s*$/)
40
+ end
41
+
42
+ it "allows trailing blank lines" do
43
+ s = T.dedent %Q{
44
+ before the break
45
+
46
+ }
47
+ expect(s.lines[1]).to match(/^\s*$/)
48
+ end
49
+
50
+ it "allows internal blank lines" do
51
+ s = T.dedent %Q{
52
+ before
53
+
54
+ after
55
+ }
56
+ expect(s.lines[1]).to eq("\n")
57
+ end
58
+ end
59
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mkxms-mssql
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Weeks
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-28 00:00:00.000000000 Z
11
+ date: 2018-02-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: xmigra
@@ -85,8 +85,16 @@ files:
85
85
  - lib/mkxms/mssql/access_object_definition.rb
86
86
  - lib/mkxms/mssql/adoption_script_writer.rb
87
87
  - lib/mkxms/mssql/check_constraint_handler.rb
88
+ - lib/mkxms/mssql/clr_aggregate_handler.rb
89
+ - lib/mkxms/mssql/clr_assembly_handler.rb
90
+ - lib/mkxms/mssql/clr_function_handler.rb
91
+ - lib/mkxms/mssql/clr_impl.rb
92
+ - lib/mkxms/mssql/clr_stored_procedure_handler.rb
93
+ - lib/mkxms/mssql/clr_type_handler.rb
88
94
  - lib/mkxms/mssql/database_handler.rb
95
+ - lib/mkxms/mssql/declaratives_creator.rb
89
96
  - lib/mkxms/mssql/default_constraint_handler.rb
97
+ - lib/mkxms/mssql/dml_trigger_handler.rb
90
98
  - lib/mkxms/mssql/engine.rb
91
99
  - lib/mkxms/mssql/exceptions.rb
92
100
  - lib/mkxms/mssql/filegroup_handler.rb
@@ -96,16 +104,21 @@ files:
96
104
  - lib/mkxms/mssql/index_column.rb
97
105
  - lib/mkxms/mssql/index_handler.rb
98
106
  - lib/mkxms/mssql/keylike_constraint_helper.rb
107
+ - lib/mkxms/mssql/keywords.rb
99
108
  - lib/mkxms/mssql/permission_handler.rb
100
109
  - lib/mkxms/mssql/primary_key_handler.rb
101
110
  - lib/mkxms/mssql/property_handler.rb
102
111
  - lib/mkxms/mssql/query_cursor.rb
112
+ - lib/mkxms/mssql/references_handler.rb
103
113
  - lib/mkxms/mssql/role_handler.rb
114
+ - lib/mkxms/mssql/scalar_type_handler.rb
104
115
  - lib/mkxms/mssql/schema_handler.rb
105
116
  - lib/mkxms/mssql/sql_string_manipulators.rb
106
117
  - lib/mkxms/mssql/statistics_handler.rb
107
118
  - lib/mkxms/mssql/stored_procedure_handler.rb
119
+ - lib/mkxms/mssql/synonym_handler.rb
108
120
  - lib/mkxms/mssql/table_handler.rb
121
+ - lib/mkxms/mssql/table_type_handler.rb
109
122
  - lib/mkxms/mssql/unique_constraint_handler.rb
110
123
  - lib/mkxms/mssql/utils.rb
111
124
  - lib/mkxms/mssql/version.rb
@@ -113,6 +126,7 @@ files:
113
126
  - mkxms-mssql.gemspec
114
127
  - spec/utils/indented_string_builder_spec.rb
115
128
  - spec/utils/query_cursor_spec.rb
129
+ - spec/utils/sql_string_manipulators_spec.rb
116
130
  homepage: ''
117
131
  licenses:
118
132
  - MIT
@@ -133,10 +147,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
133
147
  version: '0'
134
148
  requirements: []
135
149
  rubyforge_project:
136
- rubygems_version: 2.2.1
150
+ rubygems_version: 2.4.8
137
151
  signing_key:
138
152
  specification_version: 4
139
153
  summary: XMigra source files from MS-SQL database description.
140
154
  test_files:
141
155
  - spec/utils/indented_string_builder_spec.rb
142
156
  - spec/utils/query_cursor_spec.rb
157
+ - spec/utils/sql_string_manipulators_spec.rb