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.
- checksums.yaml +4 -4
- data/README.md +4 -10
- data/lib/mkxms/mssql.rb +18 -0
- data/lib/mkxms/mssql/adoption_script_writer.rb +759 -91
- data/lib/mkxms/mssql/clr_aggregate_handler.rb +98 -0
- data/lib/mkxms/mssql/clr_assembly_handler.rb +92 -0
- data/lib/mkxms/mssql/clr_function_handler.rb +172 -0
- data/lib/mkxms/mssql/clr_impl.rb +58 -0
- data/lib/mkxms/mssql/clr_stored_procedure_handler.rb +88 -0
- data/lib/mkxms/mssql/clr_type_handler.rb +92 -0
- data/lib/mkxms/mssql/database_handler.rb +124 -3
- data/lib/mkxms/mssql/declaratives_creator.rb +206 -0
- data/lib/mkxms/mssql/dml_trigger_handler.rb +107 -0
- data/lib/mkxms/mssql/filegroup_handler.rb +1 -4
- data/lib/mkxms/mssql/function_handler.rb +1 -4
- data/lib/mkxms/mssql/indented_string_builder.rb +8 -2
- data/lib/mkxms/mssql/index_handler.rb +1 -4
- data/lib/mkxms/mssql/keywords.rb +492 -0
- data/lib/mkxms/mssql/primary_key_handler.rb +1 -4
- data/lib/mkxms/mssql/property_handler.rb +8 -0
- data/lib/mkxms/mssql/query_cursor.rb +12 -4
- data/lib/mkxms/mssql/references_handler.rb +24 -0
- data/lib/mkxms/mssql/role_handler.rb +1 -4
- data/lib/mkxms/mssql/scalar_type_handler.rb +108 -0
- data/lib/mkxms/mssql/schema_handler.rb +1 -4
- data/lib/mkxms/mssql/sql_string_manipulators.rb +4 -4
- data/lib/mkxms/mssql/statistics_handler.rb +1 -4
- data/lib/mkxms/mssql/stored_procedure_handler.rb +1 -4
- data/lib/mkxms/mssql/synonym_handler.rb +40 -0
- data/lib/mkxms/mssql/table_handler.rb +2 -8
- data/lib/mkxms/mssql/table_type_handler.rb +254 -0
- data/lib/mkxms/mssql/utils.rb +96 -0
- data/lib/mkxms/mssql/version.rb +1 -1
- data/lib/mkxms/mssql/view_handler.rb +1 -4
- data/spec/utils/indented_string_builder_spec.rb +21 -0
- data/spec/utils/query_cursor_spec.rb +2 -2
- data/spec/utils/sql_string_manipulators_spec.rb +59 -0
- metadata +18 -3
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'mkxms/mssql/property_handler'
|
2
|
+
require 'mkxms/mssql/clr_impl'
|
3
|
+
require 'mkxms/mssql/utils'
|
4
|
+
|
5
|
+
module Mkxms; end
|
6
|
+
|
7
|
+
module Mkxms::Mssql
|
8
|
+
class ClrAggregate
|
9
|
+
include ExtendedProperties, Property::Hosting, Property::SchemaScoped
|
10
|
+
include Utils::SchemaQualifiedName
|
11
|
+
extend Utils::InitializedAttributes
|
12
|
+
|
13
|
+
SQL_OBJECT_TYPE = 'AGGREGATE'
|
14
|
+
|
15
|
+
def initialize(attrs)
|
16
|
+
@schema = attrs['schema']
|
17
|
+
@name = attrs['name']
|
18
|
+
@execute_as = attrs['execute-as']
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_accessor :schema, :name, :execute_as, :clr_impl, :returns
|
22
|
+
attr_init(:params) {[]}
|
23
|
+
|
24
|
+
def to_sql
|
25
|
+
(procedure_def_sql + extended_properties_sql + param_properties_sql)
|
26
|
+
end
|
27
|
+
|
28
|
+
def procedure_def_sql
|
29
|
+
[[].tap do |lines|
|
30
|
+
lines << "IF NOT EXISTS ("
|
31
|
+
lines << " SELECT * FROM xmigra.ignored_clr_assemblies asm"
|
32
|
+
lines << " WHERE asm.name = #{clr_impl.assembly.sql_quoted}"
|
33
|
+
lines << ")"
|
34
|
+
lines << "CREATE AGGREGATE [{filename}] ("
|
35
|
+
lines << params.map do |param|
|
36
|
+
" #{param.name} #{param.type_spec}".tap do |param_spec|
|
37
|
+
param_spec << " = #{param.default_value}" if param.default_value
|
38
|
+
end
|
39
|
+
end.join(",\n")
|
40
|
+
lines << ")"
|
41
|
+
lines << "RETURNS #{returns.type_spec}" if returns
|
42
|
+
lines << "EXTERNAL NAME #{clr_impl.full_specifier};"
|
43
|
+
end.join("\n")]
|
44
|
+
end
|
45
|
+
|
46
|
+
def param_properties_sql
|
47
|
+
params.map do |param|
|
48
|
+
subitem_extended_properties_sql(param)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class ClrArggregateHandler
|
54
|
+
include PropertyHandler::ElementHandler
|
55
|
+
|
56
|
+
def initialize(aggregates, node)
|
57
|
+
a = node.attributes
|
58
|
+
|
59
|
+
@aggregate = ClrAggregate.new(a).tap do |agg|
|
60
|
+
store_properties_on agg
|
61
|
+
aggregates << agg
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def handle_implementation_element(parse)
|
66
|
+
a = parse.node.attributes
|
67
|
+
@aggregate.clr_impl = ClrClass.new(a['assembly'], a['class'])
|
68
|
+
end
|
69
|
+
|
70
|
+
def handle_parameter_element(parse)
|
71
|
+
a = parse.node.attributes
|
72
|
+
Parameter.new(
|
73
|
+
a['name'],
|
74
|
+
a['type-schema'],
|
75
|
+
a['type'],
|
76
|
+
a['capacity'],
|
77
|
+
a['precision'],
|
78
|
+
a['scale'],
|
79
|
+
a['default'],
|
80
|
+
a['output'],
|
81
|
+
).tap do |param|
|
82
|
+
@aggregate.params << param
|
83
|
+
parse.context = ParameterHandler.new(param)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def handle_returns_element(parse)
|
88
|
+
a = parse.node.attributes
|
89
|
+
@aggregate.returns = ResultType.new(
|
90
|
+
a['type-schema'],
|
91
|
+
a['type'],
|
92
|
+
a['capacity'],
|
93
|
+
a['precision'],
|
94
|
+
a['scale'],
|
95
|
+
)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'mkxms/mssql/utils'
|
2
|
+
|
3
|
+
module Mkxms; end
|
4
|
+
|
5
|
+
module Mkxms::Mssql
|
6
|
+
class ClrAssembly
|
7
|
+
include ExtendedProperties
|
8
|
+
|
9
|
+
RaiserrorSource = Utils::RaiserrorWriter.new("%s: Missing or misconfigured assembly %s")
|
10
|
+
|
11
|
+
def initialize(name, lib_name = "", access:, owner: nil)
|
12
|
+
@name = name
|
13
|
+
@error_stmt = RaiserrorSource.next_statement("ERROR".sql_quoted, name.sql_quoted, severity: :error)
|
14
|
+
@warning_stmt = RaiserrorSource.next_statement("WARNING".sql_quoted, name.sql_quoted, severity: :warning)
|
15
|
+
@lib_name = lib_name
|
16
|
+
@access = access
|
17
|
+
@owner = owner
|
18
|
+
end
|
19
|
+
|
20
|
+
attr_reader :name, :error_stmt, :warning_stmt
|
21
|
+
attr_accessor :lib_name, :owner, :access
|
22
|
+
|
23
|
+
def self.setup_sql
|
24
|
+
[].tap do |s|
|
25
|
+
s << "IF NOT EXISTS (SELECT * FROM sys.tables t WHERE t.object_id = OBJECT_ID(N'xmigra.ignored_clr_assemblies'))"
|
26
|
+
s << " CREATE TABLE xmigra.ignored_clr_assemblies (name SYSNAME PRIMARY KEY);"
|
27
|
+
|
28
|
+
s << "" # Give a newline at the end
|
29
|
+
end.join("\n")
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_sql
|
33
|
+
[].tap do |s|
|
34
|
+
s << "IF NOT EXISTS ("
|
35
|
+
s << " SELECT asm.name"
|
36
|
+
s << " FROM sys.assemblies asm"
|
37
|
+
s << " WHERE asm.is_visible = 1"
|
38
|
+
s << " AND QUOTENAME(asm.name) = #{name.sql_quoted}"
|
39
|
+
s << " UNION ALL"
|
40
|
+
s << " SELECT asm.name"
|
41
|
+
s << " FROM xmigra.ignored_clr_assemblies asm"
|
42
|
+
s << " WHERE asm.name = #{name.sql_quoted}"
|
43
|
+
s << ") #{error_stmt};"
|
44
|
+
|
45
|
+
s << "IF NOT EXISTS ("
|
46
|
+
s << " SELECT asm.name, QUOTENAME(owner.name) as owner, REPLACE(LOWER(asm.permission_set_desc), '_', '-') as permission_set, asm.clr_name as library"
|
47
|
+
s << " FROM sys.assemblies asm"
|
48
|
+
s << " JOIN sys.database_principals owner ON asm.principal_id = owner.principal_id" if owner
|
49
|
+
s << " WHERE asm.is_visible = 1"
|
50
|
+
s << " AND QUOTENAME(asm.name) = #{name.sql_quoted}"
|
51
|
+
s << " -- #{warning_stmt.error_marker} Run the query up to this point for assembly configuration --"
|
52
|
+
cols = [
|
53
|
+
["owner", owner],
|
54
|
+
["permission_set", access],
|
55
|
+
["library", lib_name],
|
56
|
+
].map {|t, v| [t.ljust(v.length), v.ljust(t.length)]}
|
57
|
+
s << (" -- " + cols.map {|e| e[0]}.join(' ') + ' --')
|
58
|
+
s << (" -- Expected values: " + cols.map {|e| e[1]}.join(' ') + ' --')
|
59
|
+
s << " AND QUOTENAME(owner.name) = #{owner.sql_quoted}" if owner
|
60
|
+
s << " AND REPLACE(LOWER(asm.permission_set_desc), '_', '-') = #{access.sql_quoted}"
|
61
|
+
s << " AND asm.clr_name = #{lib_name.sql_quoted}"
|
62
|
+
s << " UNION ALL"
|
63
|
+
s << " SELECT asm.name, NULL, NULL, NULL"
|
64
|
+
s << " FROM xmigra.ignored_clr_assemblies asm"
|
65
|
+
s << " WHERE asm.name = #{name.sql_quoted}"
|
66
|
+
s << ") #{warning_stmt};"
|
67
|
+
|
68
|
+
s << "" # Gives a newline at the end
|
69
|
+
end.join("\n")
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
class ClrAssemblyHandler
|
74
|
+
include PropertyHandler::ElementHandler
|
75
|
+
|
76
|
+
def initialize(assemblies, node)
|
77
|
+
a = node.attributes
|
78
|
+
|
79
|
+
@assembly = ClrAssembly.new(
|
80
|
+
a['name'],
|
81
|
+
owner: a['owner'],
|
82
|
+
access: a['permission-set']
|
83
|
+
).tap do |asm|
|
84
|
+
assemblies << asm
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def handle_text(content, parent_node)
|
89
|
+
@assembly.lib_name << content
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,172 @@
|
|
1
|
+
require 'mkxms/mssql/property_handler'
|
2
|
+
require 'mkxms/mssql/clr_impl'
|
3
|
+
require 'mkxms/mssql/utils'
|
4
|
+
|
5
|
+
module Mkxms; end
|
6
|
+
|
7
|
+
module Mkxms::Mssql
|
8
|
+
class ClrFunction
|
9
|
+
include ExtendedProperties, Property::Hosting, Property::SchemaScoped
|
10
|
+
include Utils::SchemaQualifiedName
|
11
|
+
extend Utils::InitializedAttributes
|
12
|
+
|
13
|
+
SQL_OBJECT_TYPE = 'FUNCTION'
|
14
|
+
|
15
|
+
class ResultTable
|
16
|
+
extend Utils::InitializedAttributes
|
17
|
+
|
18
|
+
attr_init(:columns) {[]}
|
19
|
+
|
20
|
+
class Column
|
21
|
+
include ExtendedProperties
|
22
|
+
|
23
|
+
SQL_OBJECT_TYPE = 'COLUMN'
|
24
|
+
|
25
|
+
def initialize(name, result_type)
|
26
|
+
@name = name
|
27
|
+
@result_type = result_type
|
28
|
+
end
|
29
|
+
|
30
|
+
attr_accessor :name, :result_type
|
31
|
+
|
32
|
+
def type_spec
|
33
|
+
result_type.type_spec
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def initialize(attrs)
|
39
|
+
@schema = attrs['schema']
|
40
|
+
@name = attrs['name']
|
41
|
+
@execute_as = attrs['execute-as']
|
42
|
+
end
|
43
|
+
|
44
|
+
attr_accessor :schema, :name, :execute_as, :clr_impl, :returns, :result_table
|
45
|
+
attr_init(:params) {[]}
|
46
|
+
|
47
|
+
def to_sql
|
48
|
+
(procedure_def_sql + extended_properties_sql + param_properties_sql + result_column_properties_sql).join("\n")
|
49
|
+
end
|
50
|
+
|
51
|
+
def procedure_def_sql
|
52
|
+
[[].tap do |lines|
|
53
|
+
lines << "CREATE FUNCTION [{filename}] ("
|
54
|
+
lines << params.map do |param|
|
55
|
+
" #{param.name} #{param.type_spec}".tap do |param_spec|
|
56
|
+
param_spec << " = #{param.default_value}" if param.default_value
|
57
|
+
end
|
58
|
+
end.join(",\n")
|
59
|
+
lines << ")"
|
60
|
+
case
|
61
|
+
when returns
|
62
|
+
lines << "RETURNS #{returns.type_spec}"
|
63
|
+
when result_table
|
64
|
+
lines << "RETURNS TABLE ("
|
65
|
+
lines << result_table.columns.map do |col|
|
66
|
+
" #{col.name} #{col.type_spec}"
|
67
|
+
end.join(",\n")
|
68
|
+
lines << ")"
|
69
|
+
else
|
70
|
+
raise RuntimeError.new("Function return not defined")
|
71
|
+
end
|
72
|
+
case execute_as
|
73
|
+
when "OWNER"
|
74
|
+
lines << "WITH EXECUTE AS OWNER"
|
75
|
+
when String
|
76
|
+
lines << "WITH EXECUTE AS '#{Utils.unquoted_name execute_as}'"
|
77
|
+
end
|
78
|
+
lines << "AS EXTERNAL NAME #{clr_impl.full_specifier};"
|
79
|
+
end.join("\n")]
|
80
|
+
end
|
81
|
+
|
82
|
+
def param_properties_sql
|
83
|
+
params.map do |param|
|
84
|
+
subitem_extended_properties_sql(param)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def result_column_properties_sql
|
89
|
+
return [] unless result_table
|
90
|
+
result_table.columns.map do |col|
|
91
|
+
subitem_extended_properties_sql(col)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
class ClrFunctionHandler
|
97
|
+
include PropertyHandler::ElementHandler
|
98
|
+
|
99
|
+
class ResultTableColumnHandler
|
100
|
+
include PropertyHandler::ElementHandler
|
101
|
+
|
102
|
+
def initialize(column)
|
103
|
+
@column = store_properties_on(column)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def initialize(functions, node)
|
108
|
+
a = node.attributes
|
109
|
+
|
110
|
+
@function = ClrFunction.new(a).tap do |f|
|
111
|
+
store_properties_on f
|
112
|
+
functions << f
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def handle_implementation_element(parse)
|
117
|
+
a = parse.node.attributes
|
118
|
+
@function.clr_impl = ClrMethod.new(a['assembly'], a['class'], a['method'])
|
119
|
+
end
|
120
|
+
|
121
|
+
def handle_parameter_element(parse)
|
122
|
+
a = parse.node.attributes
|
123
|
+
Parameter.new(
|
124
|
+
a['name'],
|
125
|
+
a['type-schema'],
|
126
|
+
a['type'],
|
127
|
+
a['capacity'],
|
128
|
+
a['precision'],
|
129
|
+
a['scale'],
|
130
|
+
a['default'],
|
131
|
+
a['output'],
|
132
|
+
).tap do |param|
|
133
|
+
@function.params << param
|
134
|
+
parse.context = ParameterHandler.new(param)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def handle_returns_element(parse)
|
139
|
+
a = parse.node.attributes
|
140
|
+
@function.returns = ResultType.new(
|
141
|
+
a['type-schema'],
|
142
|
+
a['type'],
|
143
|
+
a['capacity'],
|
144
|
+
a['precision'],
|
145
|
+
a['scale'],
|
146
|
+
)
|
147
|
+
end
|
148
|
+
|
149
|
+
def handle_result_table_element(parse)
|
150
|
+
@function.result_table = @result_table = ClrFunction::ResultTable.new
|
151
|
+
end
|
152
|
+
|
153
|
+
def handle_column_element(parse)
|
154
|
+
a = parse.node.attributes
|
155
|
+
ClrFunction::ResultTable::Column.new(
|
156
|
+
a['name'],
|
157
|
+
ResultType.new(
|
158
|
+
a['type-schema'],
|
159
|
+
a['type'],
|
160
|
+
a['capacity'],
|
161
|
+
a['precision'],
|
162
|
+
a['scale'],
|
163
|
+
a['collation'],
|
164
|
+
)
|
165
|
+
).tap do |col|
|
166
|
+
@result_table.columns << col
|
167
|
+
# Dispatch parse for column properties
|
168
|
+
parse.context = ResultTableColumnHandler.new(col)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'mkxms/mssql/property_handler'
|
2
|
+
|
3
|
+
module Mkxms; end
|
4
|
+
|
5
|
+
module Mkxms::Mssql
|
6
|
+
ClrMethod = Struct.new(:assembly, :asm_class, :method) do
|
7
|
+
def full_specifier
|
8
|
+
to_a.join('.')
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
ClrClass = Struct.new(:assembly, :asm_class) do
|
13
|
+
def full_specifier
|
14
|
+
to_a.join('.')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# The Parameter class(es) are defined here because they are only important
|
19
|
+
# for CLR-linked objects
|
20
|
+
Parameter = Struct.new(
|
21
|
+
:name,
|
22
|
+
:type_schema, :type, :capacity, :precision, :scale,
|
23
|
+
:default_value,
|
24
|
+
:output
|
25
|
+
) do
|
26
|
+
include ExtendedProperties
|
27
|
+
|
28
|
+
SQL_OBJECT_TYPE = 'PARAMETER'
|
29
|
+
|
30
|
+
def type_spec
|
31
|
+
[type_schema, type].compact.join(".").tap do |result|
|
32
|
+
result << "(#{capacity})" if capacity
|
33
|
+
result << "(#{[precision, scale].compact.join(', ')})" if precision
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class ParameterHandler
|
39
|
+
include PropertyHandler::ElementHandler
|
40
|
+
|
41
|
+
def initialize(parameter)
|
42
|
+
@parameter = parameter
|
43
|
+
end
|
44
|
+
|
45
|
+
attr_reader :parameter
|
46
|
+
end
|
47
|
+
|
48
|
+
# Used for scalar and result table column type specification
|
49
|
+
ResultType = Struct.new(:schema, :name, :capacity, :precision, :scale, :collation) do
|
50
|
+
def type_spec
|
51
|
+
[schema, name].compact.join('.').tap do |result|
|
52
|
+
result << "(#{capacity})" if capacity
|
53
|
+
result << "(#{[precision, scale].compact.join(', ')})"
|
54
|
+
result << " COLLATE #{collation}" if collation
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'mkxms/mssql/property_handler'
|
2
|
+
require 'mkxms/mssql/clr_impl'
|
3
|
+
require 'mkxms/mssql/utils'
|
4
|
+
|
5
|
+
module Mkxms; end
|
6
|
+
|
7
|
+
module Mkxms::Mssql
|
8
|
+
class ClrStoredProcedure
|
9
|
+
include ExtendedProperties, Property::Hosting, Property::SchemaScoped
|
10
|
+
include Utils::SchemaQualifiedName
|
11
|
+
extend Utils::InitializedAttributes
|
12
|
+
|
13
|
+
SQL_OBJECT_TYPE = 'PROCEDURE'
|
14
|
+
|
15
|
+
def initialize(attrs)
|
16
|
+
@schema = attrs['schema']
|
17
|
+
@name = attrs['name']
|
18
|
+
@execute_as = attrs['execute-as']
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_accessor :schema, :name, :clr_impl, :execute_as
|
22
|
+
attr_init(:params) {[]}
|
23
|
+
|
24
|
+
def to_sql
|
25
|
+
(procedure_def_sql + extended_properties_sql + param_properties_sql).join("\n")
|
26
|
+
end
|
27
|
+
|
28
|
+
def procedure_def_sql
|
29
|
+
[[].tap do |lines|
|
30
|
+
lines << "CREATE PROCEDURE [{filename}]"
|
31
|
+
lines << params.map do |param|
|
32
|
+
" #{param.name} #{param.type_spec}".tap do |param_spec|
|
33
|
+
param_spec << " = #{param.default_value}" if param.default_value
|
34
|
+
param_spec << " OUT" if param.output
|
35
|
+
end
|
36
|
+
end.join(",\n")
|
37
|
+
case execute_as
|
38
|
+
when "OWNER"
|
39
|
+
lines << "WITH EXECUTE AS OWNER"
|
40
|
+
when String
|
41
|
+
lines << "WITH EXECUTE AS '#{Utils.unquoted_name execute_as}'"
|
42
|
+
end
|
43
|
+
lines << "AS EXTERNAL NAME #{clr_impl.full_specifier};"
|
44
|
+
end.join("\n")]
|
45
|
+
end
|
46
|
+
|
47
|
+
def param_properties_sql
|
48
|
+
params.map do |param|
|
49
|
+
subitem_extended_properties_sql(param)
|
50
|
+
end.flatten
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class ClrStoredProcedureHandler
|
55
|
+
include PropertyHandler::ElementHandler
|
56
|
+
|
57
|
+
def initialize(procedures, node)
|
58
|
+
a = node.attributes
|
59
|
+
|
60
|
+
@procedure = ClrStoredProcedure.new(a).tap do |sp|
|
61
|
+
store_properties_on sp
|
62
|
+
procedures << sp
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def handle_implementation_element(parse)
|
67
|
+
a = parse.node.attributes
|
68
|
+
@procedure.clr_impl = ClrMethod.new(a['assembly'], a['class'], a['method'])
|
69
|
+
end
|
70
|
+
|
71
|
+
def handle_parameter_element(parse)
|
72
|
+
a = parse.node.attributes
|
73
|
+
Parameter.new(
|
74
|
+
a['name'],
|
75
|
+
a['type-schema'],
|
76
|
+
a['type'],
|
77
|
+
a['capacity'],
|
78
|
+
a['precision'],
|
79
|
+
a['scale'],
|
80
|
+
a['default'],
|
81
|
+
a['output'],
|
82
|
+
).tap do |param|
|
83
|
+
@procedure.params << param
|
84
|
+
parse.context = ParameterHandler.new(param)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|