mkxms-mssql 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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