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.
- 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
|