Updated Firebird provider with latest sources from sourceforge
[mono.git] / mcs / class / FirebirdSql.Data.Firebird / FirebirdSql.Data.Firebird / DbSchema / FbColumns.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 FbColumns : FbDbSchema\r
29         {\r
30                 #region Constructors\r
31 \r
32                 public FbColumns() : base("Columns")\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 TABLE_CATALOG, " +\r
48                                         "null AS TABLE_SCHEMA, " +\r
49                                         "rfr.rdb$relation_name AS TABLE_NAME, " +\r
50                                         "rfr.rdb$field_name AS COLUMN_NAME, " +\r
51                                         "null AS COLUMN_DATA_TYPE, " +\r
52                                         "fld.rdb$field_sub_type AS COLUMN_SUB_TYPE, " +\r
53                                         "cast(fld.rdb$field_length AS integer) AS COLUMN_SIZE, " +\r
54                                         "cast(fld.rdb$field_precision AS integer) AS NUMERIC_PRECISION, " +\r
55                                         "cast(fld.rdb$field_scale AS integer) AS NUMERIC_SCALE, " +\r
56                                         "cast(fld.rdb$character_length AS integer) AS CHARACTER_LENGTH, " +\r
57                                         "cast(fld.rdb$field_length AS integer) AS CHARACTER_OCTET_LENGTH, " +\r
58                                         "rfr.rdb$field_position AS ORDINAL_POSITION, " +\r
59                                         "null AS DOMAIN_CATALOG, " +\r
60                                         "null AS DOMAIN_SCHEMA, " +\r
61                                         "rfr.rdb$field_source AS DOMAIN_NAME, " +\r
62                                         "fld.rdb$default_source AS COLUMN_DEFAULT, " +\r
63                                         "fld.rdb$computed_source AS COMPUTED_SOURCE, " +\r
64                                         "fld.rdb$dimensions AS IS_ARRAY, " +\r
65                                         "rfr.rdb$null_flag AS IS_NULLABLE, " +\r
66                                         "0 AS IS_READONLY, " +\r
67                                         "fld.rdb$field_type AS FIELD_TYPE, " +\r
68                                         "null AS CHARACTER_SET_CATALOG, " +\r
69                                         "null AS CHARACTER_SET_SCHEMA, " +\r
70                                         "cs.rdb$character_set_name AS CHARACTER_SET_NAME, " +\r
71                                         "null AS COLLATION_CATALOG, " +\r
72                                         "null AS COLLATION_SCHEMA, " +\r
73                                         "coll.rdb$collation_name AS COLLATION_NAME, " +\r
74                                         "rfr.rdb$description AS DESCRIPTION " +\r
75                                 "FROM " +\r
76                                         "rdb$relation_fields rfr " +\r
77                                         "left join rdb$fields fld ON rfr.rdb$field_source = fld.rdb$field_name " +\r
78                                         "left join rdb$character_sets cs ON cs.rdb$character_set_id = fld.rdb$character_set_id " +\r
79                                         "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
80 \r
81                         if (restrictions != null)\r
82                         {\r
83                                 int index = 0;\r
84 \r
85                                 /* TABLE_CATALOG */\r
86                                 if (restrictions.Length >= 1 && restrictions[0] != null)\r
87                                 {\r
88                                 }\r
89 \r
90                                 /* TABLE_SCHEMA */\r
91                                 if (restrictions.Length >= 2 && restrictions[1] != null)\r
92                                 {\r
93                                 }\r
94 \r
95                                 /* TABLE_NAME */\r
96                                 if (restrictions.Length >= 3 && restrictions[2] != null)\r
97                                 {\r
98                                         where.AppendFormat(CultureInfo.CurrentCulture, "rfr.rdb$relation_name = @p{0}", index++);\r
99                                 }\r
100 \r
101                                 /* COLUMN_NAME */\r
102                                 if (restrictions.Length >= 4 && restrictions[3] != null)\r
103                                 {\r
104                                         if (where.Length > 0)\r
105                                         {\r
106                                                 where.Append(" AND ");\r
107                                         }\r
108 \r
109                                         where.AppendFormat(CultureInfo.CurrentCulture, "rfr.rdb$field_name = @p{0}", index++);\r
110                                 }\r
111                         }\r
112 \r
113                         if (where.Length > 0)\r
114                         {\r
115                                 sql.AppendFormat(CultureInfo.CurrentCulture, " WHERE {0} ", where.ToString());\r
116                         }\r
117 \r
118                         sql.Append(" ORDER BY rfr.rdb$relation_name, rfr.rdb$field_position");\r
119 \r
120                         return sql;\r
121                 }\r
122 \r
123                 protected override DataTable ProcessResult(DataTable schema)\r
124                 {\r
125                         schema.BeginLoadData();\r
126 \r
127                         foreach (DataRow row in schema.Rows)\r
128                         {\r
129                                 int blrType = Convert.ToInt32(row["FIELD_TYPE"], CultureInfo.InvariantCulture);\r
130 \r
131                                 int subType = 0;\r
132                                 if (row["COLUMN_SUB_TYPE"] != System.DBNull.Value)\r
133                                 {\r
134                                         subType = Convert.ToInt32(row["COLUMN_SUB_TYPE"], CultureInfo.InvariantCulture);\r
135                                 }\r
136 \r
137                                 int scale = 0;\r
138                                 if (row["NUMERIC_SCALE"] != System.DBNull.Value)\r
139                                 {\r
140                                         scale = Convert.ToInt32(row["NUMERIC_SCALE"], CultureInfo.InvariantCulture);\r
141                                 }\r
142 \r
143                                 if (row["IS_NULLABLE"] == DBNull.Value)\r
144                                 {\r
145                                         row["IS_NULLABLE"] = true;\r
146                                 }\r
147                                 else\r
148                                 {\r
149                                         row["IS_NULLABLE"] = false;\r
150                                 }\r
151 \r
152                                 if (row["IS_ARRAY"] == DBNull.Value)\r
153                                 {\r
154                                         row["IS_ARRAY"] = false;\r
155                                 }\r
156                                 else\r
157                                 {\r
158                                         row["IS_ARRAY"] = true;\r
159                                 }\r
160 \r
161                                 FbDbType dbType = (FbDbType)TypeHelper.GetDbDataType(blrType, subType, scale);\r
162                                 row["COLUMN_DATA_TYPE"] = TypeHelper.GetDataTypeName((DbDataType)dbType).ToLower(CultureInfo.CurrentCulture);\r
163 \r
164                                 if (dbType == FbDbType.Binary || dbType == FbDbType.Text)\r
165                                 {\r
166                                         row["COLUMN_SIZE"] = Int32.MaxValue;\r
167                                 }\r
168 \r
169                                 if (dbType == FbDbType.Char || dbType == FbDbType.VarChar)\r
170                                 {\r
171                                         row["COLUMN_SIZE"] = row["CHARACTER_LENGTH"];\r
172                                 }\r
173                                 else\r
174                                 {\r
175                                         row["CHARACTER_OCTET_LENGTH"] = 0;\r
176                                 }\r
177 \r
178                                 if (row["NUMERIC_PRECISION"] == System.DBNull.Value &&\r
179                                    (dbType == FbDbType.Decimal || dbType == FbDbType.Numeric))\r
180                                 {\r
181                                         row["NUMERIC_PRECISION"] = row["COLUMN_SIZE"];\r
182                                 }\r
183 \r
184                                 row["NUMERIC_SCALE"] = (-1) * scale;\r
185 \r
186                                 string domainName = row["DOMAIN_NAME"].ToString();\r
187                                 if (domainName != null && domainName.StartsWith("RDB$"))\r
188                                 {\r
189                                         row["DOMAIN_NAME"] = null;\r
190                                 }\r
191                         }\r
192 \r
193                         schema.EndLoadData();\r
194                         schema.AcceptChanges();\r
195 \r
196                         // Remove not more needed columns\r
197                         schema.Columns.Remove("FIELD_TYPE");\r
198                         schema.Columns.Remove("CHARACTER_LENGTH");\r
199 \r
200                         return schema;\r
201                 }\r
202 \r
203                 #endregion\r
204         }\r
205 }\r