Skip to content

Commit 001c470

Browse files
committed
Function arguments
1 parent 1ee7859 commit 001c470

File tree

4 files changed

+222
-6
lines changed

4 files changed

+222
-6
lines changed

Provider/src/FirebirdSql.Data.FirebirdClient.Tests/FbSchemaTests.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,15 @@ public async Task ForeignKeyColumns()
9696
}
9797
}
9898

99+
[Test]
100+
public async Task FunctionArguments()
101+
{
102+
await Connection.GetSchemaAsync("FunctionArguments");
103+
104+
var procedureParameters = Connection.GetSchema("FunctionArguments", new string[] { null, null, "TEST_FUNC" });
105+
Assert.AreEqual(2, procedureParameters.Rows.Count);
106+
}
107+
99108
[Test]
100109
public async Task FunctionPrivileges()
101110
{
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
/*
2+
* The contents of this file are subject to the Initial
3+
* Developer's Public License Version 1.0 (the "License");
4+
* you may not use this file except in compliance with the
5+
* License. You may obtain a copy of the License at
6+
* https://github.com/FirebirdSQL/NETProvider/blob/master/license.txt.
7+
*
8+
* Software distributed under the License is distributed on
9+
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
10+
* express or implied. See the License for the specific
11+
* language governing rights and limitations under the License.
12+
*
13+
* All Rights Reserved.
14+
*/
15+
16+
//$Authors = Jiri Cincura (jiri@cincura.net)
17+
18+
using System;
19+
using System.Data;
20+
using System.Globalization;
21+
using System.Text;
22+
23+
using FirebirdSql.Data.Common;
24+
using FirebirdSql.Data.FirebirdClient;
25+
26+
namespace FirebirdSql.Data.Schema
27+
{
28+
internal class FbFunctionArguments : FbSchema
29+
{
30+
#region Protected Methods
31+
32+
protected override StringBuilder GetCommandText(string[] restrictions)
33+
{
34+
var sql = new StringBuilder();
35+
var where = new StringBuilder();
36+
37+
sql.AppendFormat(
38+
@"SELECT
39+
null AS FUNCTION_CATALOG,
40+
null AS FUNCTION_SCHEMA,
41+
fa.rdb$function_name AS FUNCTION_NAME,
42+
fa.rdb$argument_name AS ARGUMENT_NAME,
43+
null AS PARAMETER_DATA_TYPE,
44+
fld.rdb$field_sub_type AS PARAMETER_SUB_TYPE,
45+
fa.rdb$argument_position AS ORDINAL_POSITION,
46+
CAST(fld.rdb$field_length AS integer) AS PARAMETER_SIZE,
47+
CAST(fld.rdb$field_precision AS integer) AS NUMERIC_PRECISION,
48+
CAST(fld.rdb$field_scale AS integer) AS NUMERIC_SCALE,
49+
CAST(fld.rdb$character_length AS integer) AS CHARACTER_MAX_LENGTH,
50+
CAST(fld.rdb$field_length AS integer) AS CHARACTER_OCTET_LENGTH,
51+
coalesce(fld.rdb$null_flag, fa.rdb$null_flag) AS COLUMN_NULLABLE,
52+
null AS CHARACTER_SET_CATALOG,
53+
null AS CHARACTER_SET_SCHEMA,
54+
cs.rdb$character_set_name AS CHARACTER_SET_NAME,
55+
null AS COLLATION_CATALOG,
56+
null AS COLLATION_SCHEMA,
57+
coll.rdb$collation_name AS COLLATION_NAME,
58+
null AS COLLATION_CATALOG,
59+
null AS COLLATION_SCHEMA,
60+
fa.rdb$description AS DESCRIPTION,
61+
fld.rdb$field_type AS FIELD_TYPE,
62+
{0} AS PACKAGE_NAME
63+
FROM rdb$function_arguments fa
64+
LEFT JOIN rdb$fields fld ON fa.rdb$field_source = fld.rdb$field_name
65+
LEFT JOIN rdb$character_sets cs ON cs.rdb$character_set_id = fld.rdb$character_set_id
66+
LEFT JOIN rdb$collations coll ON (coll.rdb$collation_id = fld.rdb$collation_id AND coll.rdb$character_set_id = fld.rdb$character_set_id)",
67+
MajorVersionNumber >= 3 ? "fa.rdb$package_name" : "null");
68+
69+
if (restrictions != null)
70+
{
71+
var index = 0;
72+
73+
/* FUNCTION_CATALOG */
74+
if (restrictions.Length >= 1 && restrictions[0] != null)
75+
{
76+
}
77+
78+
/* FUNCTION_SCHEMA */
79+
if (restrictions.Length >= 2 && restrictions[1] != null)
80+
{
81+
}
82+
83+
/* FUNCTION_NAME */
84+
if (restrictions.Length >= 3 && restrictions[2] != null)
85+
{
86+
where.AppendFormat("fa.rdb$function_name = @p{0}", index++);
87+
}
88+
89+
/* PARAMETER_NAME */
90+
if (restrictions.Length >= 4 && restrictions[3] != null)
91+
{
92+
if (where.Length > 0)
93+
{
94+
where.Append(" AND ");
95+
}
96+
97+
where.AppendFormat("fa.rdb$argument_name = @p{0}", index++);
98+
}
99+
}
100+
101+
if (where.Length > 0)
102+
{
103+
sql.AppendFormat(" WHERE {0} ", where.ToString());
104+
}
105+
106+
sql.Append(" ORDER BY PACKAGE_NAME, FUNCTION_NAME, ORDINAL_POSITION");
107+
108+
return sql;
109+
}
110+
111+
protected override void ProcessResult(DataTable schema)
112+
{
113+
schema.BeginLoadData();
114+
schema.Columns.Add("IS_NULLABLE", typeof(bool));
115+
116+
foreach (DataRow row in schema.Rows)
117+
{
118+
var blrType = Convert.ToInt32(row["FIELD_TYPE"], CultureInfo.InvariantCulture);
119+
120+
var subType = 0;
121+
if (row["PARAMETER_SUB_TYPE"] != DBNull.Value)
122+
{
123+
subType = Convert.ToInt32(row["PARAMETER_SUB_TYPE"], CultureInfo.InvariantCulture);
124+
}
125+
126+
var scale = 0;
127+
if (row["NUMERIC_SCALE"] != DBNull.Value)
128+
{
129+
scale = Convert.ToInt32(row["NUMERIC_SCALE"], CultureInfo.InvariantCulture);
130+
}
131+
132+
row["IS_NULLABLE"] = (row["COLUMN_NULLABLE"] == DBNull.Value);
133+
134+
var dbType = (FbDbType)TypeHelper.GetDbDataTypeFromBlrType(blrType, subType, scale);
135+
row["PARAMETER_DATA_TYPE"] = TypeHelper.GetDataTypeName((DbDataType)dbType).ToLowerInvariant();
136+
137+
if (dbType == FbDbType.Char || dbType == FbDbType.VarChar)
138+
{
139+
row["PARAMETER_SIZE"] = row["CHARACTER_MAX_LENGTH"];
140+
}
141+
else
142+
{
143+
row["CHARACTER_OCTET_LENGTH"] = 0;
144+
}
145+
146+
if (dbType == FbDbType.Binary || dbType == FbDbType.Text)
147+
{
148+
row["PARAMETER_SIZE"] = Int32.MaxValue;
149+
}
150+
151+
if (row["NUMERIC_PRECISION"] == DBNull.Value)
152+
{
153+
row["NUMERIC_PRECISION"] = 0;
154+
}
155+
156+
if ((dbType == FbDbType.Decimal || dbType == FbDbType.Numeric) &&
157+
(row["NUMERIC_PRECISION"] == DBNull.Value || Convert.ToInt32(row["NUMERIC_PRECISION"]) == 0))
158+
{
159+
row["NUMERIC_PRECISION"] = row["PARAMETER_SIZE"];
160+
}
161+
162+
row["NUMERIC_SCALE"] = (-1) * scale;
163+
}
164+
165+
schema.EndLoadData();
166+
schema.AcceptChanges();
167+
168+
// Remove not more needed columns
169+
schema.Columns.Remove("COLUMN_NULLABLE");
170+
schema.Columns.Remove("FIELD_TYPE");
171+
schema.Columns.Remove("CHARACTER_MAX_LENGTH");
172+
}
173+
174+
#endregion
175+
}
176+
}

Provider/src/FirebirdSql.Data.FirebirdClient/Schema/FbMetaData.xml

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,12 @@
164164
<NumberOfIdentifierParts>0</NumberOfIdentifierParts>
165165
<PopulationMechanism>PrepareCollection</PopulationMechanism>
166166
</MetaDataCollections>
167+
<MetaDataCollections>
168+
<CollectionName>FunctionArguments</CollectionName>
169+
<NumberOfRestrictions>4</NumberOfRestrictions>
170+
<NumberOfIdentifierParts>0</NumberOfIdentifierParts>
171+
<PopulationMechanism>PrepareCollection</PopulationMechanism>
172+
</MetaDataCollections>
167173
<MetaDataCollections>
168174
<CollectionName>FunctionPrivileges</CollectionName>
169175
<NumberOfRestrictions>5</NumberOfRestrictions>
@@ -497,22 +503,46 @@
497503
<RestrictionDefault>column_name</RestrictionDefault>
498504
<RestrictionNumber>5</RestrictionNumber>
499505
</Restrictions>
506+
<Restrictions>
507+
<CollectionName>FunctionArguments</CollectionName>
508+
<RestrictionName>FunctionCatalog</RestrictionName>
509+
<RestrictionDefault>function_catalog</RestrictionDefault>
510+
<RestrictionNumber>1</RestrictionNumber>
511+
</Restrictions>
512+
<Restrictions>
513+
<CollectionName>FunctionArguments</CollectionName>
514+
<RestrictionName>FunctionSchema</RestrictionName>
515+
<RestrictionDefault>function_schema</RestrictionDefault>
516+
<RestrictionNumber>2</RestrictionNumber>
517+
</Restrictions>
518+
<Restrictions>
519+
<CollectionName>FunctionArguments</CollectionName>
520+
<RestrictionName>FunctionName</RestrictionName>
521+
<RestrictionDefault>function_name</RestrictionDefault>
522+
<RestrictionNumber>3</RestrictionNumber>
523+
</Restrictions>
524+
<Restrictions>
525+
<CollectionName>FunctionArguments</CollectionName>
526+
<RestrictionName>Name</RestrictionName>
527+
<RestrictionDefault>function_argument</RestrictionDefault>
528+
<RestrictionNumber>4</RestrictionNumber>
529+
</Restrictions>
500530
<Restrictions>
501531
<CollectionName>FunctionPrivileges</CollectionName>
502-
<RestrictionName>ProcedureCatalog</RestrictionName>
503-
<RestrictionDefault>procedure_catalog</RestrictionDefault>
532+
<RestrictionName>FunctionCatalog</RestrictionName>
533+
<RestrictionDefault>function_catalog</RestrictionDefault>
504534
<RestrictionNumber>1</RestrictionNumber>
505535
</Restrictions>
506536
<Restrictions>
507537
<CollectionName>FunctionPrivileges</CollectionName>
508-
<RestrictionName>ProcedureSchema</RestrictionName>
509-
<RestrictionDefault>procedure_schema</RestrictionDefault>
538+
<RestrictionName>FunctionSchema</RestrictionName>
539+
<RestrictionDefault>function_schema</RestrictionDefault>
510540
<RestrictionNumber>2</RestrictionNumber>
511541
</Restrictions>
512542
<Restrictions>
513543
<CollectionName>FunctionPrivileges</CollectionName>
514-
<RestrictionName>ProcedureName</RestrictionName>
515-
<RestrictionDefault>procedure_name</RestrictionDefault>
544+
<RestrictionName>FunctionName</RestrictionName>
545+
<RestrictionDefault>function_name</RestrictionDefault>
516546
<RestrictionNumber>3</RestrictionNumber>
517547
</Restrictions>
518548
<Restrictions>

Provider/src/FirebirdSql.Data.FirebirdClient/Schema/FbSchemaFactory.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ private static Task<DataTable> PrepareCollection(FbConnection connection, string
117117
"FOREIGNKEYCOLUMNS" => new FbForeignKeyColumns(),
118118
"FOREIGNKEYS" => new FbForeignKeys(),
119119
"FUNCTIONS" => new FbFunctions(),
120+
"FUNCTIONARGUMENTS" => new FbFunctionArguments(),
120121
"FUNCTIONPRIVILEGES" => new FbFunctionPrivileges(),
121122
"GENERATORS" => new FbGenerators(),
122123
"INDEXCOLUMNS" => new FbIndexColumns(),

0 commit comments

Comments
 (0)