/Rhino.Etl.Core/Operations/AbstractDatabaseOperation.cs

http://github.com/ayende/rhino-etl · C# · 157 lines · 98 code · 16 blank · 43 comment · 7 complexity · a0f4be9571812b34e6041197e3cf64a0 MD5 · raw file

  1. using System.Configuration;
  2. namespace Rhino.Etl.Core.Operations
  3. {
  4. using System;
  5. using System.Collections;
  6. using System.Data;
  7. /// <summary>
  8. /// Represent an operation that uses the database can occure during the ETL process
  9. /// </summary>
  10. public abstract class AbstractDatabaseOperation : AbstractOperation
  11. {
  12. private readonly ConnectionStringSettings connectionStringSettings;
  13. private static Hashtable supportedTypes;
  14. ///<summary>
  15. ///The parameter prefix to use when adding parameters
  16. ///</summary>
  17. protected string paramPrefix = "";
  18. /// <summary>
  19. /// Gets the connection string settings.
  20. /// </summary>
  21. /// <value>The connection string settings.</value>
  22. public ConnectionStringSettings ConnectionStringSettings
  23. {
  24. get { return connectionStringSettings; }
  25. }
  26. /// <summary>
  27. /// Gets the name of the connection string.
  28. /// </summary>
  29. /// <value>The name of the connection string.</value>
  30. public string ConnectionStringName
  31. {
  32. get { return connectionStringSettings.Name; }
  33. }
  34. /// <summary>
  35. /// Initializes a new instance of the <see cref="AbstractDatabaseOperation"/> class.
  36. /// </summary>
  37. /// <param name="connectionStringName">Name of the connection string.</param>
  38. protected AbstractDatabaseOperation(string connectionStringName)
  39. {
  40. Guard.Against<ArgumentException>(string.IsNullOrEmpty(connectionStringName),
  41. "Connection string name must have a value");
  42. Guard.Against<ArgumentException>(ConfigurationManager.ConnectionStrings[connectionStringName] == null,
  43. "Cannot resolve connection strings with name: " + connectionStringName);
  44. connectionStringSettings = ConfigurationManager.ConnectionStrings[connectionStringName];
  45. }
  46. /// <summary>
  47. /// Initializes a new instance of the <see cref="AbstractDatabaseOperation"/> class.
  48. /// </summary>
  49. /// <param name="connectionStringSettings">Name of the connection string.</param>
  50. protected AbstractDatabaseOperation(ConnectionStringSettings connectionStringSettings)
  51. {
  52. Guard.Against<ArgumentException>(connectionStringSettings == null,
  53. "connectionStringSettings must resolve to a value");
  54. this.connectionStringSettings = connectionStringSettings;
  55. }
  56. private static void InitializeSupportedTypes()
  57. {
  58. supportedTypes = new Hashtable();
  59. supportedTypes[typeof (byte[])] = typeof (byte[]);
  60. supportedTypes[typeof (Guid)] = typeof (Guid);
  61. supportedTypes[typeof (Object)] = typeof (Object);
  62. supportedTypes[typeof (Boolean)] = typeof (Boolean);
  63. supportedTypes[typeof (SByte)] = typeof (SByte);
  64. supportedTypes[typeof (SByte)] = typeof (SByte);
  65. supportedTypes[typeof (Byte)] = typeof (Byte);
  66. supportedTypes[typeof (Int16)] = typeof (Int16);
  67. supportedTypes[typeof (UInt16)] = typeof (UInt16);
  68. supportedTypes[typeof (Int32)] = typeof (Int32);
  69. supportedTypes[typeof (UInt32)] = typeof (UInt32);
  70. supportedTypes[typeof (Int64)] = typeof (Int64);
  71. supportedTypes[typeof (UInt64)] = typeof (UInt64);
  72. supportedTypes[typeof (Single)] = typeof (Single);
  73. supportedTypes[typeof (Double)] = typeof (Double);
  74. supportedTypes[typeof (Decimal)] = typeof (Decimal);
  75. supportedTypes[typeof (DateTime)] = typeof (DateTime);
  76. supportedTypes[typeof (String)] = typeof (String);
  77. }
  78. private static Hashtable SupportedTypes
  79. {
  80. get
  81. {
  82. if (supportedTypes == null)
  83. {
  84. InitializeSupportedTypes();
  85. }
  86. return supportedTypes;
  87. }
  88. }
  89. /// <summary>
  90. /// Copies the row values to command parameters.
  91. /// </summary>
  92. /// <param name="command">The command.</param>
  93. /// <param name="row">The row.</param>
  94. protected void CopyRowValuesToCommandParameters(IDbCommand command, Row row)
  95. {
  96. foreach (string column in row.Columns)
  97. {
  98. object value = row[column];
  99. if (CanUseAsParameter(value))
  100. AddParameter(command, column, value);
  101. }
  102. }
  103. /// <summary>
  104. /// Adds the parameter the specifed command
  105. /// </summary>
  106. /// <param name="command">The command.</param>
  107. /// <param name="name">The name.</param>
  108. /// <param name="val">The val.</param>
  109. protected void AddParameter(IDbCommand command, string name, object val)
  110. {
  111. IDbDataParameter parameter = command.CreateParameter();
  112. parameter.ParameterName = paramPrefix + name;
  113. parameter.Value = val ?? DBNull.Value;
  114. command.Parameters.Add(parameter);
  115. }
  116. /// <summary>
  117. /// Determines whether this value can be use as a parameter to ADO.Net provider.
  118. /// This perform a simple heuristic
  119. /// </summary>
  120. /// <param name="value">The value.</param>
  121. private static bool CanUseAsParameter(object value)
  122. {
  123. if(value==null)
  124. return true;
  125. return SupportedTypes.ContainsKey(value.GetType());
  126. }
  127. /// <summary>
  128. /// Begins a transaction conditionally based on the UseTransaction property
  129. /// </summary>
  130. /// <param name="connection">The IDbConnection object you are working with</param>
  131. /// <returns>An open IDbTransaction object or null.</returns>
  132. protected IDbTransaction BeginTransaction(IDbConnection connection)
  133. {
  134. if (UseTransaction)
  135. {
  136. return connection.BeginTransaction();
  137. }
  138. return null;
  139. }
  140. }
  141. }