//******************************************************************************************************
// 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
}
}