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 |