//******************************************************************************************************
// 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 Eclipse Public License -v 1.0 (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/eclipse-1.0.php
//
// 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 System.ComponentModel;
namespace Database
{
#region [ TableProgressEventHandler ]
///
/// Initializes a new instance of the class.
///
///
///
///
///
public class TableProgressEventHandler : EventArgs
{
#region [ Members ]
//Variables declaration
public string TableName;
public bool Executed;
public int CurrentTable;
public int TotalTables;
#endregion
#region [ Constructors ]
///
/// Default constructor
///
public TableProgressEventHandler()
: this(default(string), default(bool), default(int), default(int))
{
}
///
/// Constructor with parameters
///
/// Table is currently in progress for migration
/// Status of table execution
/// Current index of table count
/// Total tables need to be processed
public TableProgressEventHandler(string tableName, bool executed, int currentTable, int totalTables)
{
TableName = tableName;
Executed = executed;
CurrentTable = currentTable;
TotalTables = totalTables;
}
#endregion
}
#endregion
#region [ RowProgressEventHandler ]
///
/// Initializes a new instance of the class.
///
///
///
///
public class RowProgressEventHandler : EventArgs
{
#region [ Members ]
//Variables Declaration
public string TableName;
public int CurrentRow;
public int TotalRows;
#endregion
#region [ Constructors ]
///
/// Default constructor
///
public RowProgressEventHandler()
: this(default(string), default(int), default(int))
{
}
///
/// Constructor with parameters
///
/// Table name for which rows are in progress
/// Current index of row
/// Total rows in table
public RowProgressEventHandler(string tableName, int currentRow, int totalRows)
{
TableName = tableName;
CurrentRow = currentRow;
TotalRows = totalRows;
}
#endregion
}
#endregion
#region [ OverallProgressEventHandler ]
///
/// Initializes a new instance of the class.
///
///
///
public class OverallProgressEventHandler : EventArgs
{
#region [ Members ]
//Variables Declaration
public int Current;
public int Total;
#endregion
#region [ Constructors ]
///
/// Default constructor
///
public OverallProgressEventHandler()
: this(default(int), default(int))
{
}
///
/// Constructor with parameters
///
/// Currenct Index of overall progress
/// Total Table of overall progress
public OverallProgressEventHandler(int current, int total)
{
Current = current;
Total = total;
}
#endregion
}
#endregion
#region [ OverallProgressEventHandler ]
///
/// Initializes a new instance of the class.
///
///
///
public class SqlFailureEventHandler : EventArgs
{
#region [ Members ]
//Variables Declaration
public string Sql;
public Exception Ex;
#endregion
#region [ Constructors ]
///
/// Default constructor
///
public SqlFailureEventHandler()
: this(default(string), default(Exception))
{
}
///
/// Constructor with parameters
///
/// sql statement that executed
/// Exception occured while executing a sql statement
public SqlFailureEventHandler(string sql, Exception ex)
{
Sql = sql;
Ex = ex;
}
#endregion
}
#endregion
#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 ISite ComponentSite;
protected Schema schFrom;
protected Schema schTo;
///
/// Implemetor can use this variable to track overall progress
///
protected long intOverallProgress;
///
/// This is initialized to the overall total number of records to be processed
///
protected long intOverallTotal;
///
/// Defines interval for reporting row progress
///
private int intRowReportInterval;
///
/// Timeout value for Sql operation
///
protected int intTimeout;
///
/// Tables value
///
protected Tables colTables;
///
/// Flag to check Referencial Integrity
///
protected bool flgUseFromSchemaRI;
///
/// List of exclude tables
///
private readonly List m_excludedTables = new List();
// Events
public event EventHandler> TableProgress;
public event EventHandler> RowProgress; //.RowProgress;
public event EventHandler> OverallProgress;
public event EventHandler> SqlFailure;
// Delegates
public delegate void TableProgressEventHandler(string TableName, bool Executed, int CurrentTable, int TotalTables);
public delegate void RowProgressEventHandler(string TableName, int CurrentRow, int TotalRows);
public delegate void OverallProgressEventHandler(int Current, int Total);
public delegate void SqlFailureEventHandler(string Sql, Exception ex);
#endregion
#region [ Constructors ]
///
/// Default Constructor
///
public BulkDataOperationBase()
{
intRowReportInterval = 5;
intTimeout = 120;
flgUseFromSchemaRI = true;
}
///
/// Constructor with parameters
///
/// Source database connection string
/// Destination database connection string
public BulkDataOperationBase(string FromConnectString, string ToConnectString)
: this()
{
schFrom = new Schema(FromConnectString, TableType.Table, false, false);
schTo = new Schema(ToConnectString, TableType.Table, false, false);
}
///
/// Constructor with parameters
///
/// Source Schema
/// Destination Schema
public BulkDataOperationBase(Schema FromSchema, Schema ToSchema)
: this()
{
schFrom = FromSchema;
schTo = ToSchema;
}
#endregion
//protected override void Finalize()
//{
// Dispose(true);
//}
#region [ Properties ]
///
/// Get or Set Source schema
///
[Browsable(true), Category("Configuration"), Description("Source schema definition.")]
public virtual Schema FromSchema
{
get
{
return schFrom;
}
set
{
schFrom = value;
if ((ComponentSite != null))
if (ComponentSite.DesignMode)
schFrom.ImmediateClose = false;
}
}
///
/// Get or Set destination schema
///
[Browsable(true), Category("Configuration"), Description("Destination schema definition.")]
public virtual Schema ToSchema
{
get
{
return schTo;
}
set
{
schTo = value;
if ((ComponentSite != null))
if (ComponentSite.DesignMode)
schTo.ImmediateClose = false;
}
}
///
/// Get or Set number of rows to process before raising progress events
///
[Browsable(true), Category("Configuration"), Description("Number of rows to process before raising progress events."), DefaultValue(5)]
public virtual int RowReportInterval
{
get
{
return intRowReportInterval;
}
set
{
intRowReportInterval = value;
}
}
///
/// Get or Set Maximum number of seconds to wait when processing a Sql command before timing out.
///
[Browsable(true), Category("Configuration"), Description("Maximum number of seconds to wait when processing a Sql command before timing out."), DefaultValue(120)]
public virtual int Timeout
{
get
{
return intTimeout;
}
set
{
intTimeout = value;
}
}
///
/// Get or Set - use referential integrity information from source/to destination database during data processing
///
[Browsable(true), Category("Configuration"), Description("Set to True to use referential integrity information from source database during data processing, set to False to use destination database."), DefaultValue(true)]
public virtual bool UseFromSchemaReferentialIntegrity
{
get
{
return flgUseFromSchemaRI;
}
set
{
flgUseFromSchemaRI = value;
}
}
///
/// These are the tables that were found in both source and dest to be used for data operation...
///
[Browsable(false)]
public virtual Tables WorkTables
{
get
{
return colTables;
}
}
///
/// 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 destinaction schema
///
public virtual void Close()
{
if ((schFrom != null))
schFrom.Close();
if ((schTo != null))
schTo.Close();
schFrom = null;
schTo = null;
GC.SuppressFinalize(this);
}
///
/// Dispose
///
void IDisposable.Dispose()
{
Close();
}
///
/// Analyze data schema before data processing
///
public virtual void Analyze()
{
//Table tbl;// = default(Table);
Table tblLookup;// = default(Table);
schFrom.ImmediateClose = false;
schFrom.Analyze();
schTo.ImmediateClose = false;
schTo.Analyze();
m_excludedTables.Sort();
colTables = new Tables(schFrom);
// We preprocess which tables we are going to access for data operation...
foreach (Table tbl in schFrom.Tables)
{
// Bypass excluded tables
if (m_excludedTables.BinarySearch(tbl.MapName) < 0)
{
// Lookup table name in destination datasource by map name
tblLookup = schTo.Tables.FindByMapName(tbl.MapName);
if ((tblLookup != null))
{
intOverallTotal += tbl.RowCount;
// If user requested to use referential integrity of destination tables then
// we use process priority of those tables instead...
if (!flgUseFromSchemaRI)
tbl.Priority = tblLookup.Priority;
tbl.Process = true;
colTables.Add(tbl);
}
}
}
}
public abstract void Execute();
//Derived classes can't directly raise base class events, hence the following...
///
/// 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 RaiseEvent_TableProgress(string TableName, bool Executed, int CurrentTable, int TotalTables)
{
if (TableProgress != null)
{
TableProgress(this, new TableProgressEventHandler(TableName, Executed, CurrentTable, TotalTables));
//TableProgress(this, new TableProgressEventHandler(this,)); //(eventhandler(new EventArgs{TableName, Executed, CurrentTable, TotalTables});
}
}
///
/// Raise an event while chage 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 RaiseEvent_RowProgress(string TableName, int CurrentRow, int TotalRows)
{
if (RowProgress != null)
{
RowProgress(this, new RowProgressEventHandler(TableName, CurrentRow, TotalRows));
//RowProgress(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 RaiseEvent_OverallProgress(int Current, int Total)
{
if (OverallProgress != null)
{
OverallProgress(this, new OverallProgressEventHandler(Current, Total));
//OverallProgress(Current, Total);
}
}
///
/// Raise an event if sql statement fail
///
/// sql statement information
/// exception information
protected virtual void RaiseEvent_SqlFailure(string Sql, Exception ex)
{
if (SqlFailure != null)
{
SqlFailure(this, new SqlFailureEventHandler(Sql, ex));
//SqlFailure(Sql, ex);
}
}
#endregion
}
}