Datei: NDOInterfaces/NDOAbstractProvider.cs
Last Commit (e9b343b)
1 | // |
2 | // Copyright (c) 2002-2024 Mirko Matytschak |
3 | // (www.netdataobjects.de) |
4 | // |
5 | // Author: Mirko Matytschak |
6 | // |
7 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated |
8 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation |
9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the |
10 | // Software, and to permit persons to whom the Software is furnished to do so, subject to the following |
11 | // conditions: |
12 | |
13 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions |
14 | // of the Software. |
15 | // |
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED |
17 | // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
18 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF |
19 | // CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
20 | // DEALINGS IN THE SOFTWARE. |
21 | |
22 | |
23 | using System; |
24 | using System.Data; |
25 | using System.Data.Common; |
26 | using System.Text; |
27 | using System.Collections; |
28 | using NDOInterfaces; |
29 | using NDO; |
30 | |
31 | namespace NDOInterfaces |
32 | { |
33 | ····/// <summary> |
34 | ····/// Contains standard implementation for providers. |
35 | ····/// </summary> |
36 | ····public abstract class NDOAbstractProvider : IProvider |
37 | ····{ |
38 | ········ |
39 | ···· |
40 | ········#region Implementation of IProvider |
41 | |
42 | |
43 | ········/// <summary> |
44 | ········/// See <see cref="IProvider">IProvider interface</see>. |
45 | ········/// </summary> |
46 | ········public abstract System.Data.IDbConnection NewConnection(string parameters); |
47 | |
48 | ········/// <summary> |
49 | ········/// See <see cref="IProvider">IProvider interface</see>. |
50 | ········/// </summary> |
51 | ········public abstract System.Data.IDbCommand NewSqlCommand(System.Data.IDbConnection connection); |
52 | |
53 | ········/// <summary> |
54 | ········/// See <see cref="IProvider">IProvider interface</see>. |
55 | ········/// </summary> |
56 | ········public abstract System.Data.Common.DbDataAdapter NewDataAdapter(System.Data.IDbCommand select, System.Data.IDbCommand update, System.Data.IDbCommand insert, System.Data.IDbCommand delete); |
57 | |
58 | ········/// <summary> |
59 | ········/// See <see cref="IProvider">IProvider interface</see>. |
60 | ········/// </summary> |
61 | ········public abstract object NewCommandBuilder(System.Data.Common.DbDataAdapter dataAdapter); |
62 | |
63 | ········/// <summary> |
64 | ········/// See <see cref="IProvider">IProvider interface</see>. |
65 | ········/// </summary> |
66 | ········public abstract IDataParameter AddParameter(System.Data.IDbCommand command, string parameterName, object dbType, int size, string columnName); |
67 | |
68 | ········/// <summary> |
69 | ········/// See <see cref="IProvider">IProvider interface</see>. |
70 | ········/// </summary> |
71 | ········public abstract IDataParameter AddParameter(System.Data.IDbCommand command, string parameterName, object dbType, int size, System.Data.ParameterDirection dir, bool isNullable, byte precision, byte scale, string srcColumn, System.Data.DataRowVersion srcVersion, object value); |
72 | ········ |
73 | ········/// <summary> |
74 | ········/// See <see cref="IProvider">IProvider interface</see>. |
75 | ········/// </summary> |
76 | ········public abstract object GetDbType(System.Type t); |
77 | |
78 | ········/// <summary> |
79 | ········/// See <see cref="IProvider">IProvider interface</see>. |
80 | ········/// </summary> |
81 | ········public abstract object GetDbType(string dbTypeName); |
82 | |
83 | ········/// <summary> |
84 | ········/// See <see cref="IProvider">IProvider interface</see>. |
85 | ········/// </summary> |
86 | ········public virtual int GetDefaultLength(System.Type t) |
87 | ········{ |
88 | ············if ( t == typeof(bool) ) |
89 | ················return 4; |
90 | ············else if ( t == typeof(byte) ) |
91 | ················return 1; |
92 | ············else if ( t == typeof(sbyte) ) |
93 | ················return 1; |
94 | ············else if ( t == typeof(char) ) |
95 | ················return 2; |
96 | ············else if ( t == typeof(short)) |
97 | ················return 2; |
98 | ············else if ( t == typeof(ushort)) |
99 | ················return 2; |
100 | ············else if ( t == typeof(int)) |
101 | ················return 4; |
102 | ············else if ( t == typeof(uint)) |
103 | ················return 4; |
104 | ············else if ( t == typeof(long)) |
105 | ················return 8; |
106 | ············else if ( t == typeof(ulong)) |
107 | ················return 8; |
108 | ············else if ( t == typeof(float)) |
109 | ················return 8; |
110 | ············else if ( t == typeof(double)) |
111 | ················return 8; |
112 | ············else if ( t == typeof(string)) |
113 | ················return 255; |
114 | ············else if ( t == typeof(decimal)) |
115 | ················return 11; |
116 | ············else if ( t == typeof(DateTime)) |
117 | ················return 4; |
118 | ············else if ( t == typeof(Guid)) |
119 | ················return 16; |
120 | ············else if ( t == typeof(Byte[])) |
121 | ················return 1024; |
122 | ············else if ( t.IsSubclassOf(typeof(System.Enum))) |
123 | ················return 4; |
124 | ············else |
125 | ················return 0; |
126 | ········} |
127 | |
128 | ········/// <summary> |
129 | ········/// See <see cref="IProvider">IProvider interface</see>. |
130 | ········/// </summary> |
131 | ········public virtual string Wildcard |
132 | ········{ |
133 | ············get { return "%"; } |
134 | ········} |
135 | |
136 | ········/// <summary> |
137 | ········/// See <see cref="IProvider">IProvider interface</see>. |
138 | ········/// </summary> |
139 | ········public virtual bool UseNamedParams |
140 | ········{ |
141 | ············get { return false; } |
142 | ········} |
143 | |
144 | |
145 | ········/// <summary> |
146 | ········/// See <see cref="IProvider">IProvider interface</see>. |
147 | ········/// </summary> |
148 | ········public virtual string NamedParamPrefix |
149 | ········{ |
150 | ············get { return string.Empty; } |
151 | ········} |
152 | |
153 | ········/// <summary> |
154 | ········/// See <see cref="IProvider">IProvider interface</see>. |
155 | ········/// </summary> |
156 | ········public virtual bool UseStoredProcedure |
157 | ········{ |
158 | ············get { return false; } |
159 | ········} |
160 | |
161 | ···· |
162 | ········/// <summary> |
163 | ········/// See <see cref="IProvider">IProvider interface</see>. |
164 | ········/// </summary> |
165 | ········public virtual string GetNamedParameter(string plainParameterName) |
166 | ········{ |
167 | ············return plainParameterName; |
168 | ········} |
169 | ···· |
170 | ········/// <summary> |
171 | ········/// See <see cref="IProvider">IProvider interface</see>. |
172 | ········/// </summary> |
173 | ········public virtual string GetQuotedName(string plainName) |
174 | ········{ |
175 | ············return plainName; |
176 | ········} |
177 | |
178 | ········/// <summary> |
179 | ········/// See <see cref="IProvider">IProvider interface</see>. |
180 | ········/// </summary> |
181 | ········public virtual string GetSqlLiteral(object o) |
182 | ········{ |
183 | ············if (o == null) |
184 | ················return "NULL"; |
185 | if ( o is string || o. GetType( ) . IsSubclassOf( typeof( string) ) || o is Guid) |
186 | ················return "'" + o.ToString() + "'"; |
187 | ············if (o is byte[]) |
188 | ············{ |
189 | ················StringBuilder sb = new StringBuilder(((byte[])o).Length * 2 + 2); |
190 | ················sb.Append('\''); |
191 | ················foreach (byte b in (byte[])o) |
192 | ················{ |
193 | ····················sb.Append(b.ToString("X2")); |
194 | ················} |
195 | ················sb.Append('\''); |
196 | ················return sb.ToString(); |
197 | ············} |
198 | ············return o.ToString(); |
199 | ········} |
200 | |
201 | |
202 | ········/// <summary> |
203 | ········/// See <see cref="IProvider">IProvider interface</see>. |
204 | ········/// </summary> |
205 | ········public virtual bool SupportsLastInsertedId |
206 | ········{ |
207 | ············get {return false;} |
208 | ········} |
209 | |
210 | ········/// <summary> |
211 | ········/// See <see cref="IProvider">IProvider interface</see>. |
212 | ········/// </summary> |
213 | ········public virtual string GetLastInsertedId(string tableName, string columnName) |
214 | ········{ |
215 | ············return null; |
216 | ········} |
217 | |
218 | ········/// <summary> |
219 | ········/// See <see cref="IProvider">IProvider interface</see>. |
220 | ········/// </summary> |
221 | ········public virtual bool SupportsBulkCommands |
222 | ········{ |
223 | ············get { return false; } |
224 | ········} |
225 | ········ |
226 | |
227 | ········/// <summary> |
228 | ········/// See <see cref="IProvider">IProvider interface</see>. |
229 | ········/// </summary> |
230 | ········public virtual string GenerateBulkCommand(string[] commands) |
231 | ········{ |
232 | ············return null; |
233 | ········} |
234 | |
235 | |
236 | ········/// <summary> |
237 | ········/// See <see cref="IProvider">IProvider interface</see>. |
238 | ········/// </summary> |
239 | ········public virtual int MaxBulkCommandLength |
240 | ········{ |
241 | ············get { return 0; } |
242 | ········} |
243 | |
244 | |
245 | ········/// <summary> |
246 | ········/// See <see cref="IProvider">IProvider interface</see>. |
247 | ········/// </summary> |
248 | ········public abstract string[] TypeNames { get; } |
249 | |
250 | ········/// <summary> |
251 | ········/// See <see cref="IProvider">IProvider interface</see>. |
252 | ········/// </summary> |
253 | ········public string[] GetTableNames (IDbConnection conn) |
254 | ········{ |
255 | ············return GetTableNames(conn, null); |
256 | ········} |
257 | |
258 | ········/// <summary> |
259 | ········/// See <see cref="IProvider">IProvider interface</see>. |
260 | ········/// </summary> |
261 | ········public abstract string[] GetTableNames(IDbConnection conn, string owner); |
262 | |
263 | |
264 | ········/// <summary> |
265 | ········/// Generates a DataSet with exactly the same structure elements as the database. |
266 | ········/// It maps all tables, columns, primary keys and foreign key constraints of the database |
267 | ········/// to the DataSet. |
268 | ········/// </summary> |
269 | ········/// <remarks> |
270 | ········/// This implementation fetches only the tables and columns. |
271 | ········/// </remarks> |
272 | ········public virtual DataSet GetDatabaseStructure( IDbConnection conn, string ownerName ) |
273 | ········{ |
274 | ············bool wasOpen = false; |
275 | ············if (conn.State == ConnectionState.Open) |
276 | ················wasOpen = true; |
277 | ············else |
278 | ················conn.Open(); |
279 | |
280 | ············DataSet ds = new DataSet(); |
281 | ············foreach(string tableName in this.GetTableNames(conn, ownerName)) |
282 | ············{ |
283 | ················string sql; |
284 | |
285 | ················if ( ownerName != null && ownerName.Trim() != "" ) |
286 | ················{ |
287 | ····················sql = "SELECT * FROM " + this.GetQuotedName( ownerName ) + "." + this.GetQuotedName( tableName ); |
288 | ················} |
289 | ················else |
290 | ················{ |
291 | ····················sql = "SELECT * FROM " + this.GetQuotedName( tableName ); |
292 | ················} |
293 | |
294 | ················IDbCommand cmd = this.NewSqlCommand( conn ); |
295 | ················cmd.CommandText = sql; |
296 | ················IDataAdapter da = this.NewDataAdapter( cmd, null, null, null ); |
297 | |
298 | ················da.FillSchema( ds, SchemaType.Source ); |
299 | ················ds.Tables[ds.Tables.Count - 1].TableName = tableName; |
300 | ············} |
301 | |
302 | ············if (!wasOpen) |
303 | ················conn.Close(); |
304 | ············return ds; |
305 | ········} |
306 | |
307 | |
308 | ········/// <summary> |
309 | ········/// See <see cref="IProvider">IProvider interface</see>. |
310 | ········/// </summary> |
311 | ········public abstract string Name { get; } |
312 | |
313 | ········/// <summary> |
314 | ········/// See <see cref="IProvider">IProvider interface</see>. |
315 | ········/// </summary> |
316 | ········public virtual bool SupportsInsertBatch |
317 | ········{ |
318 | ············get { return false; } |
319 | ········} |
320 | |
321 | ········/// <summary> |
322 | ········/// See <see cref="IProvider">IProvider interface</see>. |
323 | ········/// </summary> |
324 | ········public virtual void RegisterRowUpdateHandler(IRowUpdateListener handler) |
325 | ········{ |
326 | ········} |
327 | |
328 | ········/// <summary> |
329 | ········/// See <see cref="IProvider">IProvider interface</see>. |
330 | ········/// </summary> |
331 | ········public abstract bool SupportsNativeGuidType { get; } |
332 | |
333 | ········/// <summary> |
334 | ········/// Fetch limits are used for paging. If the database supports paging, it provides an addition to OrderBy which |
335 | ········/// allows to specify a count of rows to skip and a maximum count of rows to take. |
336 | ········/// </summary> |
337 | ········public virtual bool SupportsFetchLimit |
338 | ········{ |
339 | ············get { return true; } |
340 | ········} |
341 | |
342 | ········/// <summary> |
343 | ········/// Fetch limits are used for paging. If the database supports paging, it provides an addition to OrderBy which |
344 | ········/// allows to specify a count of rows to skip and a maximum count of rows to take. |
345 | ········/// </summary> |
346 | ········/// <param name="skip"></param> |
347 | ········/// <param name="take"></param> |
348 | ········/// <returns>A string, which is concatenated to the OrderBy clause</returns> |
349 | ········public virtual string FetchLimit( int skip, int take ) |
350 | ········{ |
351 | ············if (skip == 0 && take == 0) |
352 | ················return string.Empty; |
353 | ············// Standard Sql implementation |
354 | ············string fetch = String.Empty; |
355 | ············if (take != 0) |
356 | ················fetch = String.Format( " FETCH NEXT {0} ROWS ONLY", take ); |
357 | ············return String.Format("OFFSET {0} ROWS{1}", skip, fetch); |
358 | ········} |
359 | |
360 | ········/// <summary> |
361 | ········/// See <see cref="IProvider">IProvider interface</see>. |
362 | ········/// </summary> |
363 | ········public virtual string CreateDatabase(string databaseName, string connectionString, object additionalData = null) |
364 | ········{ |
365 | ············if (databaseName == null) |
366 | ················throw new ArgumentException( nameof( databaseName ) ); |
367 | ············if (connectionString == null) |
368 | ················throw new ArgumentException( nameof( connectionString ) ); |
369 | |
370 | ············string dbName = this.GetQuotedName(databaseName); |
371 | ············try |
372 | ············{ |
373 | ················IDbConnection conn = this.NewConnection(connectionString); |
374 | ················IDbCommand cmd = this.NewSqlCommand(conn); |
375 | ················cmd.CommandText = "CREATE DATABASE " + dbName; |
376 | ················bool wasOpen = true; |
377 | ················if (conn.State == ConnectionState.Closed) |
378 | ················{ |
379 | ····················conn.Open(); |
380 | ····················wasOpen = false; |
381 | ················} |
382 | ················cmd.ExecuteNonQuery(); |
383 | ················if (!wasOpen) |
384 | ····················conn.Close(); |
385 | ············} |
386 | ············catch (Exception ex) |
387 | ············{ |
388 | ················throw new NDOException(19, "Error while attempting to create a database: Exception Type: " + ex.GetType().Name + " Message: " + ex.Message); |
389 | ············} |
390 | |
391 | ············return string.Empty; |
392 | ········} |
393 | |
394 | |
395 | ········#endregion |
396 | |
397 | ········/// <summary> |
398 | ········/// Called by the providers to get the generic argument type of a Nullable. |
399 | ········/// </summary> |
400 | ········/// <param name="t">The type to convert.</param> |
401 | ········/// <returns>If t is a Nullable, the generic argument type is returned. Else t is returned.</returns> |
402 | ········public Type ConvertNullableType(Type t) |
403 | ········{ |
404 | ············if (t.IsGenericParameter) |
405 | ················return typeof(string); |
406 | ············if (t.FullName.StartsWith("System.Nullable`1")) |
407 | ················t = t.GetGenericArguments()[0]; |
408 | ············if (t.IsEnum) |
409 | ················return Enum.GetUnderlyingType(t); |
410 | ············return t; |
411 | ········} |
412 | |
413 | ········/// <summary> |
414 | ········/// Gets the string representation of the provider specific parameter type. |
415 | ········/// </summary> |
416 | ········/// <param name="parameter">An IDbDataParameter implementation.</param> |
417 | ········/// <returns>The string Representation of the parameter.</returns> |
418 | ········/// <remarks> |
419 | ········/// Each ADO.NET implementation uses it's own parameter types, e.g. SqlDbType for SqlParameter. |
420 | ········/// We need the names of this parameters to support the Loggin. |
421 | ········/// </remarks> |
422 | ········public virtual string GetDbTypeString( IDbDataParameter parameter ) |
423 | ········{ |
424 | ············return parameter.DbType.ToString(); |
425 | ········} |
426 | ····} |
427 | } |
428 |
New Commit (273289e)
1 | // |
2 | // Copyright (c) 2002-2024 Mirko Matytschak |
3 | // (www.netdataobjects.de) |
4 | // |
5 | // Author: Mirko Matytschak |
6 | // |
7 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated |
8 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation |
9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the |
10 | // Software, and to permit persons to whom the Software is furnished to do so, subject to the following |
11 | // conditions: |
12 | |
13 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions |
14 | // of the Software. |
15 | // |
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED |
17 | // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
18 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF |
19 | // CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
20 | // DEALINGS IN THE SOFTWARE. |
21 | |
22 | |
23 | using System; |
24 | using System.Data; |
25 | using System.Data.Common; |
26 | using System.Text; |
27 | using System.Collections; |
28 | using NDOInterfaces; |
29 | using NDO; |
30 | using System.Globalization; |
31 | |
32 | namespace NDOInterfaces |
33 | { |
34 | ····/// <summary> |
35 | ····/// Contains standard implementation for providers. |
36 | ····/// </summary> |
37 | ····public abstract class NDOAbstractProvider : IProvider |
38 | ····{ |
39 | ········ |
40 | ···· |
41 | ········#region Implementation of IProvider |
42 | |
43 | |
44 | ········/// <summary> |
45 | ········/// See <see cref="IProvider">IProvider interface</see>. |
46 | ········/// </summary> |
47 | ········public abstract System.Data.IDbConnection NewConnection(string parameters); |
48 | |
49 | ········/// <summary> |
50 | ········/// See <see cref="IProvider">IProvider interface</see>. |
51 | ········/// </summary> |
52 | ········public abstract System.Data.IDbCommand NewSqlCommand(System.Data.IDbConnection connection); |
53 | |
54 | ········/// <summary> |
55 | ········/// See <see cref="IProvider">IProvider interface</see>. |
56 | ········/// </summary> |
57 | ········public abstract System.Data.Common.DbDataAdapter NewDataAdapter(System.Data.IDbCommand select, System.Data.IDbCommand update, System.Data.IDbCommand insert, System.Data.IDbCommand delete); |
58 | |
59 | ········/// <summary> |
60 | ········/// See <see cref="IProvider">IProvider interface</see>. |
61 | ········/// </summary> |
62 | ········public abstract object NewCommandBuilder(System.Data.Common.DbDataAdapter dataAdapter); |
63 | |
64 | ········/// <summary> |
65 | ········/// See <see cref="IProvider">IProvider interface</see>. |
66 | ········/// </summary> |
67 | ········public abstract IDataParameter AddParameter(System.Data.IDbCommand command, string parameterName, object dbType, int size, string columnName); |
68 | |
69 | ········/// <summary> |
70 | ········/// See <see cref="IProvider">IProvider interface</see>. |
71 | ········/// </summary> |
72 | ········public abstract IDataParameter AddParameter(System.Data.IDbCommand command, string parameterName, object dbType, int size, System.Data.ParameterDirection dir, bool isNullable, byte precision, byte scale, string srcColumn, System.Data.DataRowVersion srcVersion, object value); |
73 | ········ |
74 | ········/// <summary> |
75 | ········/// See <see cref="IProvider">IProvider interface</see>. |
76 | ········/// </summary> |
77 | ········public abstract object GetDbType(System.Type t); |
78 | |
79 | ········/// <summary> |
80 | ········/// See <see cref="IProvider">IProvider interface</see>. |
81 | ········/// </summary> |
82 | ········public abstract object GetDbType(string dbTypeName); |
83 | |
84 | ········/// <summary> |
85 | ········/// See <see cref="IProvider">IProvider interface</see>. |
86 | ········/// </summary> |
87 | ········public virtual int GetDefaultLength(System.Type t) |
88 | ········{ |
89 | ············if ( t == typeof(bool) ) |
90 | ················return 4; |
91 | ············else if ( t == typeof(byte) ) |
92 | ················return 1; |
93 | ············else if ( t == typeof(sbyte) ) |
94 | ················return 1; |
95 | ············else if ( t == typeof(char) ) |
96 | ················return 2; |
97 | ············else if ( t == typeof(short)) |
98 | ················return 2; |
99 | ············else if ( t == typeof(ushort)) |
100 | ················return 2; |
101 | ············else if ( t == typeof(int)) |
102 | ················return 4; |
103 | ············else if ( t == typeof(uint)) |
104 | ················return 4; |
105 | ············else if ( t == typeof(long)) |
106 | ················return 8; |
107 | ············else if ( t == typeof(ulong)) |
108 | ················return 8; |
109 | ············else if ( t == typeof(float)) |
110 | ················return 8; |
111 | ············else if ( t == typeof(double)) |
112 | ················return 8; |
113 | ············else if ( t == typeof(string)) |
114 | ················return 255; |
115 | ············else if ( t == typeof(decimal)) |
116 | ················return 11; |
117 | ············else if ( t == typeof(DateTime)) |
118 | ················return 4; |
119 | ············else if ( t == typeof(Guid)) |
120 | ················return 16; |
121 | ············else if ( t == typeof(Byte[])) |
122 | ················return 1024; |
123 | ············else if ( t.IsSubclassOf(typeof(System.Enum))) |
124 | ················return 4; |
125 | ············else |
126 | ················return 0; |
127 | ········} |
128 | |
129 | ········/// <summary> |
130 | ········/// See <see cref="IProvider">IProvider interface</see>. |
131 | ········/// </summary> |
132 | ········public virtual string Wildcard |
133 | ········{ |
134 | ············get { return "%"; } |
135 | ········} |
136 | |
137 | ········/// <summary> |
138 | ········/// See <see cref="IProvider">IProvider interface</see>. |
139 | ········/// </summary> |
140 | ········public virtual bool UseNamedParams |
141 | ········{ |
142 | ············get { return false; } |
143 | ········} |
144 | |
145 | |
146 | ········/// <summary> |
147 | ········/// See <see cref="IProvider">IProvider interface</see>. |
148 | ········/// </summary> |
149 | ········public virtual string NamedParamPrefix |
150 | ········{ |
151 | ············get { return string.Empty; } |
152 | ········} |
153 | |
154 | ········/// <summary> |
155 | ········/// See <see cref="IProvider">IProvider interface</see>. |
156 | ········/// </summary> |
157 | ········public virtual bool UseStoredProcedure |
158 | ········{ |
159 | ············get { return false; } |
160 | ········} |
161 | |
162 | ···· |
163 | ········/// <summary> |
164 | ········/// See <see cref="IProvider">IProvider interface</see>. |
165 | ········/// </summary> |
166 | ········public virtual string GetNamedParameter(string plainParameterName) |
167 | ········{ |
168 | ············return plainParameterName; |
169 | ········} |
170 | ···· |
171 | ········/// <summary> |
172 | ········/// See <see cref="IProvider">IProvider interface</see>. |
173 | ········/// </summary> |
174 | ········public virtual string GetQuotedName(string plainName) |
175 | ········{ |
176 | ············return plainName; |
177 | ········} |
178 | |
179 | ········/// <summary> |
180 | ········/// See <see cref="IProvider">IProvider interface</see>. |
181 | ········/// </summary> |
182 | ········public virtual string GetSqlLiteral(object o) |
183 | ········{ |
184 | ············if (o == null) |
185 | ················return "NULL"; |
186 | if ( o is string || o is Guid) |
187 | ················return "'" + o.ToString() + "'"; |
188 | |
189 | ············if (o is byte[]) |
190 | ············{ |
191 | ················StringBuilder sb = new StringBuilder(((byte[])o).Length * 2 + 2); |
192 | ················sb.Append('\''); |
193 | ················foreach (byte b in (byte[])o) |
194 | ················{ |
195 | ····················sb.Append(b.ToString("X2")); |
196 | ················} |
197 | ················sb.Append('\''); |
198 | ················return sb.ToString(); |
199 | ············} |
200 | |
201 | ············var ci = CultureInfo.InvariantCulture; |
202 | |
203 | ············if (o is DateTime dt) |
204 | ················return "'" + dt.ToString( "yyyy-MM-dd HH:mm:ss" ) + "'"; |
205 | ············if (o is double d) |
206 | ················return d.ToString( ci ); |
207 | ············if (o is float f) |
208 | ················return f.ToString( ci ); |
209 | ············if (o is decimal dc) |
210 | ················return dc.ToString( ci ); |
211 | |
212 | ············return o.ToString(); |
213 | ········} |
214 | |
215 | |
216 | ········/// <summary> |
217 | ········/// See <see cref="IProvider">IProvider interface</see>. |
218 | ········/// </summary> |
219 | ········public virtual bool SupportsLastInsertedId |
220 | ········{ |
221 | ············get {return false;} |
222 | ········} |
223 | |
224 | ········/// <summary> |
225 | ········/// See <see cref="IProvider">IProvider interface</see>. |
226 | ········/// </summary> |
227 | ········public virtual string GetLastInsertedId(string tableName, string columnName) |
228 | ········{ |
229 | ············return null; |
230 | ········} |
231 | |
232 | ········/// <summary> |
233 | ········/// See <see cref="IProvider">IProvider interface</see>. |
234 | ········/// </summary> |
235 | ········public virtual bool SupportsBulkCommands |
236 | ········{ |
237 | ············get { return false; } |
238 | ········} |
239 | ········ |
240 | |
241 | ········/// <summary> |
242 | ········/// See <see cref="IProvider">IProvider interface</see>. |
243 | ········/// </summary> |
244 | ········public virtual string GenerateBulkCommand(string[] commands) |
245 | ········{ |
246 | ············return null; |
247 | ········} |
248 | |
249 | |
250 | ········/// <summary> |
251 | ········/// See <see cref="IProvider">IProvider interface</see>. |
252 | ········/// </summary> |
253 | ········public virtual int MaxBulkCommandLength |
254 | ········{ |
255 | ············get { return 0; } |
256 | ········} |
257 | |
258 | |
259 | ········/// <summary> |
260 | ········/// See <see cref="IProvider">IProvider interface</see>. |
261 | ········/// </summary> |
262 | ········public abstract string[] TypeNames { get; } |
263 | |
264 | ········/// <summary> |
265 | ········/// See <see cref="IProvider">IProvider interface</see>. |
266 | ········/// </summary> |
267 | ········public string[] GetTableNames (IDbConnection conn) |
268 | ········{ |
269 | ············return GetTableNames(conn, null); |
270 | ········} |
271 | |
272 | ········/// <summary> |
273 | ········/// See <see cref="IProvider">IProvider interface</see>. |
274 | ········/// </summary> |
275 | ········public abstract string[] GetTableNames(IDbConnection conn, string owner); |
276 | |
277 | |
278 | ········/// <summary> |
279 | ········/// Generates a DataSet with exactly the same structure elements as the database. |
280 | ········/// It maps all tables, columns, primary keys and foreign key constraints of the database |
281 | ········/// to the DataSet. |
282 | ········/// </summary> |
283 | ········/// <remarks> |
284 | ········/// This implementation fetches only the tables and columns. |
285 | ········/// </remarks> |
286 | ········public virtual DataSet GetDatabaseStructure( IDbConnection conn, string ownerName ) |
287 | ········{ |
288 | ············bool wasOpen = false; |
289 | ············if (conn.State == ConnectionState.Open) |
290 | ················wasOpen = true; |
291 | ············else |
292 | ················conn.Open(); |
293 | |
294 | ············DataSet ds = new DataSet(); |
295 | ············foreach(string tableName in this.GetTableNames(conn, ownerName)) |
296 | ············{ |
297 | ················string sql; |
298 | |
299 | ················if ( ownerName != null && ownerName.Trim() != "" ) |
300 | ················{ |
301 | ····················sql = "SELECT * FROM " + this.GetQuotedName( ownerName ) + "." + this.GetQuotedName( tableName ); |
302 | ················} |
303 | ················else |
304 | ················{ |
305 | ····················sql = "SELECT * FROM " + this.GetQuotedName( tableName ); |
306 | ················} |
307 | |
308 | ················IDbCommand cmd = this.NewSqlCommand( conn ); |
309 | ················cmd.CommandText = sql; |
310 | ················IDataAdapter da = this.NewDataAdapter( cmd, null, null, null ); |
311 | |
312 | ················da.FillSchema( ds, SchemaType.Source ); |
313 | ················ds.Tables[ds.Tables.Count - 1].TableName = tableName; |
314 | ············} |
315 | |
316 | ············if (!wasOpen) |
317 | ················conn.Close(); |
318 | ············return ds; |
319 | ········} |
320 | |
321 | |
322 | ········/// <summary> |
323 | ········/// See <see cref="IProvider">IProvider interface</see>. |
324 | ········/// </summary> |
325 | ········public abstract string Name { get; } |
326 | |
327 | ········/// <summary> |
328 | ········/// See <see cref="IProvider">IProvider interface</see>. |
329 | ········/// </summary> |
330 | ········public virtual bool SupportsInsertBatch |
331 | ········{ |
332 | ············get { return false; } |
333 | ········} |
334 | |
335 | ········/// <summary> |
336 | ········/// See <see cref="IProvider">IProvider interface</see>. |
337 | ········/// </summary> |
338 | ········public virtual void RegisterRowUpdateHandler(IRowUpdateListener handler) |
339 | ········{ |
340 | ········} |
341 | |
342 | ········/// <summary> |
343 | ········/// See <see cref="IProvider">IProvider interface</see>. |
344 | ········/// </summary> |
345 | ········public abstract bool SupportsNativeGuidType { get; } |
346 | |
347 | ········/// <summary> |
348 | ········/// Fetch limits are used for paging. If the database supports paging, it provides an addition to OrderBy which |
349 | ········/// allows to specify a count of rows to skip and a maximum count of rows to take. |
350 | ········/// </summary> |
351 | ········public virtual bool SupportsFetchLimit |
352 | ········{ |
353 | ············get { return true; } |
354 | ········} |
355 | |
356 | ········/// <summary> |
357 | ········/// Fetch limits are used for paging. If the database supports paging, it provides an addition to OrderBy which |
358 | ········/// allows to specify a count of rows to skip and a maximum count of rows to take. |
359 | ········/// </summary> |
360 | ········/// <param name="skip"></param> |
361 | ········/// <param name="take"></param> |
362 | ········/// <returns>A string, which is concatenated to the OrderBy clause</returns> |
363 | ········public virtual string FetchLimit( int skip, int take ) |
364 | ········{ |
365 | ············if (skip == 0 && take == 0) |
366 | ················return string.Empty; |
367 | ············// Standard Sql implementation |
368 | ············string fetch = String.Empty; |
369 | ············if (take != 0) |
370 | ················fetch = String.Format( " FETCH NEXT {0} ROWS ONLY", take ); |
371 | ············return String.Format("OFFSET {0} ROWS{1}", skip, fetch); |
372 | ········} |
373 | |
374 | ········/// <summary> |
375 | ········/// See <see cref="IProvider">IProvider interface</see>. |
376 | ········/// </summary> |
377 | ········public virtual string CreateDatabase(string databaseName, string connectionString, object additionalData = null) |
378 | ········{ |
379 | ············if (databaseName == null) |
380 | ················throw new ArgumentException( nameof( databaseName ) ); |
381 | ············if (connectionString == null) |
382 | ················throw new ArgumentException( nameof( connectionString ) ); |
383 | |
384 | ············string dbName = this.GetQuotedName(databaseName); |
385 | ············try |
386 | ············{ |
387 | ················IDbConnection conn = this.NewConnection(connectionString); |
388 | ················IDbCommand cmd = this.NewSqlCommand(conn); |
389 | ················cmd.CommandText = "CREATE DATABASE " + dbName; |
390 | ················bool wasOpen = true; |
391 | ················if (conn.State == ConnectionState.Closed) |
392 | ················{ |
393 | ····················conn.Open(); |
394 | ····················wasOpen = false; |
395 | ················} |
396 | ················cmd.ExecuteNonQuery(); |
397 | ················if (!wasOpen) |
398 | ····················conn.Close(); |
399 | ············} |
400 | ············catch (Exception ex) |
401 | ············{ |
402 | ················throw new NDOException(19, "Error while attempting to create a database: Exception Type: " + ex.GetType().Name + " Message: " + ex.Message); |
403 | ············} |
404 | |
405 | ············return string.Empty; |
406 | ········} |
407 | |
408 | |
409 | ········#endregion |
410 | |
411 | ········/// <summary> |
412 | ········/// Called by the providers to get the generic argument type of a Nullable. |
413 | ········/// </summary> |
414 | ········/// <param name="t">The type to convert.</param> |
415 | ········/// <returns>If t is a Nullable, the generic argument type is returned. Else t is returned.</returns> |
416 | ········public Type ConvertNullableType(Type t) |
417 | ········{ |
418 | ············if (t.IsGenericParameter) |
419 | ················return typeof(string); |
420 | ············if (t.FullName.StartsWith("System.Nullable`1")) |
421 | ················t = t.GetGenericArguments()[0]; |
422 | ············if (t.IsEnum) |
423 | ················return Enum.GetUnderlyingType(t); |
424 | ············return t; |
425 | ········} |
426 | |
427 | ········/// <summary> |
428 | ········/// Gets the string representation of the provider specific parameter type. |
429 | ········/// </summary> |
430 | ········/// <param name="parameter">An IDbDataParameter implementation.</param> |
431 | ········/// <returns>The string Representation of the parameter.</returns> |
432 | ········/// <remarks> |
433 | ········/// Each ADO.NET implementation uses it's own parameter types, e.g. SqlDbType for SqlParameter. |
434 | ········/// We need the names of this parameters to support the Loggin. |
435 | ········/// </remarks> |
436 | ········public virtual string GetDbTypeString( IDbDataParameter parameter ) |
437 | ········{ |
438 | ············return parameter.DbType.ToString(); |
439 | ········} |
440 | ····} |
441 | } |
442 |