//****************************************************************************************************** // BulkDataOperationBase.cs - Gbtc // // Copyright © 2012, Grid Protection Alliance. All Rights Reserved. // // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See // the NOTICE file distributed with this work for additional information regarding copyright ownership. // The GPA licenses this file to you under the MIT License (MIT), the "License"; you may // not use this file except in compliance with the License. You may obtain a copy of the License at: // // http://www.opensource.org/licenses/MIT // // Unless agreed to in writing, the subject software distributed under the License is distributed on an // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the // License for the specific language governing permissions and limitations. // // Code Modification History: // ---------------------------------------------------------------------------------------------------- // 06/28/2010 - J. Ritchie Carroll // Generated original version of source code. // 08/21/2008 - Mihir Brahmbhatt // Converted to C# extensions. // 09/27/2010 - Mihir Brahmbhatt // Edited code comments. // 12/20/2012 - Starlynn Danyelle Gilliam // Modified Header. // //****************************************************************************************************** using System; using System.Collections.Generic; using GSF; namespace DataMigrationUtility { #region [ IBulkDataOperation ] /// /// This is the common interface for any bulk data operation /// public interface IBulkDataOperation { /// /// Get the status information of table progress /// event EventHandler> TableProgress; /// /// Get the information of Row progress of table /// event EventHandler> RowProgress; /// /// Get the information of overall progress of Migration utility /// event EventHandler> OverallProgress; /// /// Get the information of exception while processing SQL statement /// event EventHandler> SQLFailure; /// /// Get the work table information /// Tables WorkTables { get; } /// /// From schema information /// Schema FromSchema { get; set; } /// /// To Schema information /// Schema ToSchema { get; set; } /// /// Get the row report interval information /// int RowReportInterval { get; set; } /// /// Get or set time out for SQL statement /// int Timeout { get; set; } /// /// Execute a method of object /// void Execute(); /// /// Close the object connection /// void Close(); } #endregion /// /// This class defines a common set of functionality that any bulk data operation implementation can use /// public abstract class BulkDataOperationBase : IBulkDataOperation, IDisposable { #region [ Members ] // Fields - Variables Declaration protected Schema m_fromSchema; protected Schema m_toSchema; /// /// Implementer can use this variable to track overall progress /// protected long m_overallProgress; /// /// This is initialized to the overall total number of records to be processed /// protected long m_overallTotal; /// /// Defines interval for reporting row progress /// private int m_rowReportInterval; /// /// Timeout value for SQL operation /// protected int m_timeout; /// /// Tables value /// protected Tables m_tableCollection; /// /// Flag to check referential integrity /// protected bool m_useFromSchemaRI; /// /// List of exclude tables /// private readonly List m_excludedTables = new List(); // Events /// /// Get the status information of table progress /// public event EventHandler> TableProgress; /// /// Get the information of Row progress of table /// public event EventHandler> RowProgress; /// /// Get the information of overall progress of Migration utility /// public event EventHandler> OverallProgress; /// /// Get the information of exception while processing SQL statement /// public event EventHandler> SQLFailure; #endregion #region [ Constructors ] /// /// Default Constructor /// protected BulkDataOperationBase() { m_rowReportInterval = 5; m_timeout = 120; m_useFromSchemaRI = true; } /// /// Constructor with parameters /// /// Source database connection string /// Destination database connection string protected BulkDataOperationBase(string fromConnectString, string toConnectString) : this() { m_fromSchema = new Schema(fromConnectString, TableType.Table, false, false); m_toSchema = new Schema(toConnectString, TableType.Table, false, false); } /// /// Constructor with parameters /// /// Source Schema /// Destination Schema protected BulkDataOperationBase(Schema fromSchema, Schema toSchema) : this() { m_fromSchema = fromSchema; m_toSchema = toSchema; } #endregion #region [ Properties ] /// /// Get or set Source schema /// public virtual Schema FromSchema { get { return m_fromSchema; } set { m_fromSchema = value; } } /// /// Get or set destination schema /// public virtual Schema ToSchema { get { return m_toSchema; } set { m_toSchema = value; } } /// /// Get or set number of rows to process before raising progress events /// public virtual int RowReportInterval { get { return m_rowReportInterval; } set { m_rowReportInterval = value; } } /// /// Get or set Maximum number of seconds to wait when processing a SQL command before timing out. /// public virtual int Timeout { get { return m_timeout; } set { m_timeout = value; } } /// /// Get or set - use referential integrity information from source/to destination database during data processing /// public virtual bool UseFromSchemaReferentialIntegrity { get { return m_useFromSchemaRI; } set { m_useFromSchemaRI = value; } } /// /// These are the tables that were found in both source and destination to be used for data operation... /// public virtual Tables WorkTables { get { return m_tableCollection; } } /// /// Get list of tables to be excluded during data processing /// public List ExcludedTables { get { return m_excludedTables; } } #endregion #region [ Methods ] /// /// Dispose /// /// protected virtual void Dispose(bool disposing) { Close(); } /// /// Close source and destination schema /// public virtual void Close() { if ((object)m_fromSchema != null) m_fromSchema.Close(); if ((object)m_toSchema != null) m_toSchema.Close(); m_fromSchema = null; m_toSchema = null; GC.SuppressFinalize(this); } /// /// Dispose /// void IDisposable.Dispose() { Close(); } /// /// Analyze data schema before data processing /// public virtual void Analyze() { Table lookupTable; m_fromSchema.ImmediateClose = false; m_fromSchema.Analyze(); m_toSchema.ImmediateClose = false; m_toSchema.Analyze(); m_excludedTables.Sort(); m_tableCollection = new Tables(m_fromSchema); // We preprocess which tables we are going to access for data operation... foreach (Table table in m_fromSchema.Tables) { // Bypass excluded tables if (m_excludedTables.BinarySearch(table.MapName) < 0) { // Lookup table name in destination data source by map name lookupTable = m_toSchema.Tables.FindByMapName(table.MapName); if ((object)lookupTable != null) { // If user requested to use referential integrity of destination tables then // we use process priority of those tables instead... if (!m_useFromSchemaRI) table.Priority = lookupTable.Priority; table.Process = true; m_tableCollection.Add(table); } } } } public abstract void Execute(); /// /// Raise an event if table change in data processing /// /// Table name in data processing /// Status of data processing on table /// current table index in data processing /// total table count in data processing protected virtual void OnTableProgress(string TableName, bool Executed, int CurrentTable, int TotalTables) { if ((object)TableProgress != null) TableProgress(this, new EventArgs(TableName, Executed, CurrentTable, TotalTables)); } /// /// Raise an event while change row in data processing /// /// Table name in data processing /// current row index in data processing /// total rows needs to be process in data processing protected virtual void OnRowProgress(string TableName, int CurrentRow, int TotalRows) { if ((object)RowProgress != null) RowProgress(this, new EventArgs(TableName, CurrentRow, TotalRows)); } /// /// Raise an event to show overall progress of data processing /// /// Current index of tables in data processing /// Total table count in data processing protected virtual void OnOverallProgress(int Current, int Total) { if ((object)OverallProgress != null) OverallProgress(this, new EventArgs(Current, Total)); } /// /// Raise an event if SQL statement fail /// /// SQL statement information /// exception information protected virtual void OnSQLFailure(string SQL, Exception ex) { if ((object)SQLFailure != null) SQLFailure(this, new EventArgs(SQL, ex)); } #endregion } }