imported everything from my branch (which is slightly harmless).
[mono.git] / mcs / class / FirebirdSql.Data.Firebird / FirebirdSql.Data.Firebird / DbSchema / FbProcedureParameters.cs
1 /*\r
2  *      Firebird ADO.NET Data provider for .NET and     Mono \r
3  * \r
4  *         The contents of this file are subject to the Initial \r
5  *         Developer's Public License Version 1.0 (the "License"); \r
6  *         you may not use this file except in compliance with the \r
7  *         License. You may obtain a copy of the License at \r
8  *         http://www.firebirdsql.org/index.php?op=doc&id=idpl\r
9  *\r
10  *         Software distributed under the License is distributed on \r
11  *         an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either \r
12  *         express or implied. See the License for the specific \r
13  *         language governing rights and limitations under the License.\r
14  * \r
15  *      Copyright (c) 2002, 2005 Carlos Guzman Alvarez\r
16  *      All Rights Reserved.\r
17  */\r
18 \r
19 using System;\r
20 using System.Data;\r
21 using System.Globalization;\r
22 using System.Text;\r
23 \r
24 using FirebirdSql.Data.Common;\r
25 \r
26 namespace FirebirdSql.Data.Firebird.DbSchema\r
27 {\r
28         internal class FbProcedureParameters : FbDbSchema\r
29         {\r
30                 #region Constructors\r
31 \r
32                 public FbProcedureParameters() : base("ProcedureParameters")\r
33                 {\r
34                 }\r
35 \r
36                 #endregion\r
37 \r
38                 #region Protected Methods\r
39 \r
40                 protected override StringBuilder GetCommandText(object[] restrictions)\r
41                 {\r
42                         StringBuilder sql = new StringBuilder();\r
43                         StringBuilder where = new StringBuilder();\r
44 \r
45                         sql.Append(\r
46                                 @"SELECT " +\r
47                                         "null AS PROCEDURE_CATALOG, " +\r
48                                         "null AS PROCEDURE_SCHEMA, " +\r
49                                         "pp.rdb$procedure_name AS PROCEDURE_NAME, " +\r
50                                         "pp.rdb$parameter_name AS PARAMETER_NAME, " +\r
51                                         "null AS PARAMETER_DATA_TYPE, " +\r
52                                         "fld.rdb$field_sub_type AS PARAMETER_SUB_TYPE, " +\r
53                                         "pp.rdb$parameter_number AS ORDINAL_POSITION, " +\r
54                                         "cast(pp.rdb$parameter_type AS integer) AS PARAMETER_DIRECTION, " +\r
55                                         "cast(fld.rdb$field_length AS integer) AS PARAMETER_SIZE, " +\r
56                                         "cast(fld.rdb$field_precision AS integer) AS NUMERIC_PRECISION, " +\r
57                                         "cast(fld.rdb$field_scale AS integer) AS NUMERIC_SCALE, " +\r
58                                         "cast(fld.rdb$character_length AS integer) AS CHARACTER_LENGTH, " +\r
59                                         "cast(fld.rdb$field_length AS integer) AS CHARACTER_OCTET_LENGTH, " +\r
60                                         "null AS CHARACTER_SET_CATALOG, " +\r
61                                         "null AS CHARACTER_SET_SCHEMA, " +\r
62                                         "cs.rdb$character_set_name AS CHARACTER_SET_NAME, " +\r
63                                         "null AS COLLATION_CATALOG, " +\r
64                                         "null AS COLLATION_SCHEMA, " +\r
65                                         "coll.rdb$collation_name AS COLLATION_NAME, " +\r
66                                         "null AS COLLATION_CATALOG, " +\r
67                                         "null AS COLLATION_SCHEMA, " +\r
68                                         "pp.rdb$description AS DESCRIPTION, " +\r
69                                         "fld.rdb$field_type AS FIELD_TYPE " +\r
70                                 "FROM " +\r
71                                         "rdb$procedure_parameters pp " +\r
72                                         "left join rdb$fields fld ON pp.rdb$field_source = fld.rdb$field_name " +\r
73                                         "left join rdb$character_sets cs ON cs.rdb$character_set_id = fld.rdb$character_set_id " +\r
74                                         "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) ");\r
75 \r
76                         if (restrictions != null)\r
77                         {\r
78                                 int index = 0;\r
79 \r
80                                 /* PROCEDURE_CATALOG */\r
81                                 if (restrictions.Length >= 1 && restrictions[0] != null)\r
82                                 {\r
83                                 }\r
84 \r
85                                 /* PROCEDURE_SCHEMA     */\r
86                                 if (restrictions.Length >= 2 && restrictions[1] != null)\r
87                                 {\r
88                                 }\r
89 \r
90                                 /* PROCEDURE_NAME */\r
91                                 if (restrictions.Length >= 3 && restrictions[2] != null)\r
92                                 {\r
93                                         where.AppendFormat(CultureInfo.CurrentCulture, "pp.rdb$procedure_name = @p{0}", index++);\r
94                                 }\r
95 \r
96                                 /* PROCEDURE_PARAMETER */\r
97                                 if (restrictions.Length >= 4 && restrictions[3] != null)\r
98                                 {\r
99                                         if (where.Length > 0)\r
100                                         {\r
101                                                 where.Append(" AND ");\r
102                                         }\r
103 \r
104                                         where.AppendFormat(CultureInfo.CurrentCulture, "pp.rdb$parameter_name = @p{0}", index++);\r
105                                 }\r
106                         }\r
107 \r
108                         if (where.Length > 0)\r
109                         {\r
110                                 sql.AppendFormat(CultureInfo.CurrentCulture, " WHERE {0} ", where.ToString());\r
111                         }\r
112 \r
113                         sql.Append(" ORDER BY pp.rdb$procedure_name, pp.rdb$parameter_type, pp.rdb$parameter_number");\r
114 \r
115                         return sql;\r
116                 }\r
117 \r
118                 protected override DataTable ProcessResult(DataTable schema)\r
119                 {\r
120                         schema.BeginLoadData();\r
121 \r
122                         foreach (DataRow row in schema.Rows)\r
123                         {\r
124                                 int blrType = Convert.ToInt32(row["FIELD_TYPE"], CultureInfo.InvariantCulture);\r
125 \r
126                                 int subType = 0;\r
127                                 if (row["PARAMETER_SUB_TYPE"] != System.DBNull.Value)\r
128                                 {\r
129                                         subType = Convert.ToInt32(row["PARAMETER_SUB_TYPE"], CultureInfo.InvariantCulture);\r
130                                 }\r
131 \r
132                                 int scale = 0;\r
133                                 if (row["NUMERIC_SCALE"] != System.DBNull.Value)\r
134                                 {\r
135                                         scale = Convert.ToInt32(row["NUMERIC_SCALE"], CultureInfo.InvariantCulture);\r
136                                 }\r
137 \r
138                                 FbDbType dbType = (FbDbType)TypeHelper.GetDbDataType(blrType, subType, scale);\r
139                                 row["PARAMETER_DATA_TYPE"] = TypeHelper.GetDataTypeName((DbDataType)dbType).ToLower(CultureInfo.CurrentCulture);\r
140 \r
141                                 if (dbType == FbDbType.Char || dbType == FbDbType.VarChar)\r
142                                 {\r
143                                         row["PARAMETER_SIZE"] = row["CHARACTER_LENGTH"];\r
144                                 }\r
145                                 else\r
146                                 {\r
147                                         row["CHARACTER_OCTET_LENGTH"] = 0;\r
148                                 }\r
149 \r
150                                 if (dbType == FbDbType.Binary || dbType == FbDbType.Text)\r
151                                 {\r
152                                         row["PARAMETER_SIZE"] = Int32.MaxValue;\r
153                                 }\r
154 \r
155                                 if (row["NUMERIC_PRECISION"] == System.DBNull.Value &&\r
156                                    (dbType == FbDbType.Decimal || dbType == FbDbType.Numeric))\r
157                                 {\r
158                                         row["NUMERIC_PRECISION"] = row["PARAMETER_SIZE"];\r
159                                 }\r
160 \r
161                                 row["NUMERIC_SCALE"] = (-1) * scale;\r
162 \r
163                                 int direction = Convert.ToInt32(row["PARAMETER_DIRECTION"], CultureInfo.InvariantCulture);\r
164                                 switch (direction)\r
165                                 {\r
166                                         case 0:\r
167                                                 row["PARAMETER_DIRECTION"] = ParameterDirection.Input;\r
168                                                 break;\r
169 \r
170                                         case 1:\r
171                                                 row["PARAMETER_DIRECTION"] = ParameterDirection.Output;\r
172                                                 break;\r
173                                 }\r
174                         }\r
175 \r
176                         schema.EndLoadData();\r
177                         schema.AcceptChanges();\r
178 \r
179                         // Remove not more needed columns\r
180                         schema.Columns.Remove("FIELD_TYPE");\r
181                         schema.Columns.Remove("CHARACTER_LENGTH");\r
182 \r
183                         return schema;\r
184                 }\r
185 \r
186                 #endregion\r
187         }\r
188 }