diff --git a/src/Comparer/PropertyEqualityComparer.cs b/src/Comparer/PropertyEqualityComparer.cs
new file mode 100644
index 0000000..e39e29d
--- /dev/null
+++ b/src/Comparer/PropertyEqualityComparer.cs
@@ -0,0 +1,58 @@
+using System.Reflection;
+
+namespace DbSyncKit.DB.Comparer
+{
+ ///
+ /// Compares instances of data contracts based on specified properties, which can be either key or comparable properties.
+ ///
+ public class PropertyEqualityComparer : IEqualityComparer
+ {
+ ///
+ /// Gets the array of objects representing properties used for equality comparison.
+ /// These properties can serve as either key or comparable properties.
+ ///
+ public readonly PropertyInfo[] properties;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// An array of objects representing properties used for equality comparison. These can be either key or comparable properties.
+ public PropertyEqualityComparer(PropertyInfo[] Properties)
+ {
+ properties = Properties;
+ }
+
+ ///
+ /// Determines whether two instances of the data contract are equal based on the specified properties.
+ ///
+ /// The first instance to compare.
+ /// The second instance to compare.
+ /// true if the instances are equal; otherwise, false.
+ public bool Equals(T? x, T? y)
+ {
+ return properties.All(prop => Equals(prop.GetValue(x), prop.GetValue(y)));
+ }
+
+ ///
+ /// Returns a hash code for the specified instance of the data contract based on the specified properties.
+ ///
+ /// The instance for which to get the hash code.
+ /// A hash code for the specified instance.
+ public int GetHashCode(T obj)
+ {
+ unchecked
+ {
+ int hash = 17;
+
+ foreach (var prop in properties)
+ {
+ var value = prop.GetValue(obj);
+ hash = hash ^ ((value?.GetHashCode() ?? 0) + 23);
+ }
+
+ return hash;
+ }
+ }
+ }
+
+}
diff --git a/src/DatabaseManager.cs b/src/DatabaseManager.cs
index 92a2d04..afe7067 100644
--- a/src/DatabaseManager.cs
+++ b/src/DatabaseManager.cs
@@ -28,7 +28,7 @@ public DatabaseManager(T databaseProvider)
/// The SQL query to execute.
/// The name of the table associated with the query.
/// A list of results of type .
- public List ExecuteQuery(string query, string tableName) where TItem : IDataContract
+ public List ExecuteQuery(string query, string tableName)
{
List result = new List();
diff --git a/src/DbSyncKit.DB.csproj b/src/DbSyncKit.DB.csproj
index 4e1305c..afd1d9c 100644
--- a/src/DbSyncKit.DB.csproj
+++ b/src/DbSyncKit.DB.csproj
@@ -5,9 +5,9 @@
enable
enable
True
- 1.2.0.0
- 1.2.0.0
- 1.2.0.0
+ 1.3.0.0
+ 1.3.0.0
+ 1.3.0.0
README.md
https://dbsynckit.rohit-mahajan.in/
https://github.com/RohitM-IN/DbSyncKit
@@ -31,4 +31,8 @@
+
+
+
+
diff --git a/src/Extensions/DataRowExtensions.cs b/src/Extensions/DataRowExtensions.cs
index 03401fe..efb4499 100644
--- a/src/Extensions/DataRowExtensions.cs
+++ b/src/Extensions/DataRowExtensions.cs
@@ -14,9 +14,6 @@ public static class DataRowExtensions
/// The DataRow from which to retrieve the value.
/// The name of the column.
/// The value of the specified column, converted to the specified type.
- ///
- /// This extension method is intended for use with classes that inherit from .
- ///
public static T GetValue(this DataRow row, string columnName)
{
// Check if the DataRow is null
diff --git a/src/Factory/QueryGeneratorFactory.cs b/src/Factory/QueryGeneratorFactory.cs
index f8a0bc9..c20f012 100644
--- a/src/Factory/QueryGeneratorFactory.cs
+++ b/src/Factory/QueryGeneratorFactory.cs
@@ -1,5 +1,6 @@
using DbSyncKit.DB.Enum;
using DbSyncKit.DB.Interface;
+using DbSyncKit.Templates.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
diff --git a/src/Fetcher/DataContractFetcher.cs b/src/Fetcher/DataContractFetcher.cs
new file mode 100644
index 0000000..516be8e
--- /dev/null
+++ b/src/Fetcher/DataContractFetcher.cs
@@ -0,0 +1,144 @@
+using DbSyncKit.DB.Comparer;
+using DbSyncKit.DB.Factory;
+using DbSyncKit.DB.Interface;
+using DbSyncKit.Templates;
+using DbSyncKit.Templates.Interface;
+
+namespace DbSyncKit.DB.Fetcher
+{
+ ///
+ /// Represents a callback function for filtering a list of data entities of type T.
+ ///
+ /// The type of data entities to filter.
+ /// The list of data entities to filter.
+ /// A filtered list of data entities.
+ ///
+ /// This delegate defines a callback function that takes a list of data entities as input,
+ /// performs filtering operations on the data, and returns the filtered list.
+ ///
+ public delegate List FilterCallback(List data);
+
+ ///
+ /// Utility class for fetching data from a database using data contracts.
+ ///
+ public class DataContractFetcher
+ {
+ #region Properties
+
+ ///
+ /// Gets the query generator factory instance used for creating query generators.
+ ///
+ private readonly QueryGeneratorFactory Factory;
+
+ ///
+ /// Gets or sets the QueryGenerationManager instance for generating queries for the destination database.
+ ///
+ ///
+ /// This property is set by the method.
+ /// It allows the reuse of the QueryGenerationManager instance when the source and destination databases share the same provider.
+ ///
+ public IQueryGenerator? DestinationQueryGenerationManager { get; private set; }
+
+ #endregion
+
+ #region Constructor
+
+ ///
+ /// Initializes a new instance of the class with a custom query generator factory.
+ ///
+ /// The custom query generator factory instance.
+ public DataContractFetcher(QueryGeneratorFactory factory)
+ {
+ Factory = factory;
+ }
+
+ #endregion
+
+ #region Methods
+
+ ///
+ /// Retrieves data from source and destination databases for a specified table and column list, using a specified data contract type.
+ ///
+ /// The type of data entities to retrieve.
+ /// The source database.
+ /// The destination database.
+ /// The name of the table from which to retrieve data.
+ /// A list of column names to retrieve from the table.
+ /// An equality comparer for identifying properties used in data comparison.
+ /// A callback function for filtering the retrieved data.
+ /// An output parameter that receives the retrieved data from the source database.
+ /// An output parameter that receives the retrieved data from the destination database.
+ ///
+ /// The method uses a QueryGenerationManager to generate queries for retrieving data based on the specified table and columns.
+ /// If the providers of the source and destination databases differ, a new QueryGenerationManager is created for the destination database.
+ /// The retrieved data can be optionally filtered using the provided filter callback function.
+ ///
+ public void RetrieveDataFromDatabases(
+ IDatabase source,
+ IDatabase destination,
+ string tableName,
+ List ColumnList,
+ PropertyEqualityComparer ComparablePropertyEqualityComparer,
+ FilterCallback? filterCallback,
+ out HashSet sourceList,
+ out HashSet destinationList)
+ {
+ var sourceQueryGenerationManager = new QueryGenerationManager(Factory.GetQueryGenerator(source.Provider));
+ sourceList = GetDataFromDatabase(tableName, source, sourceQueryGenerationManager, ColumnList, ComparablePropertyEqualityComparer, filterCallback);
+
+ if (source.Provider != destination.Provider)
+ {
+ sourceQueryGenerationManager.Dispose();
+ DestinationQueryGenerationManager = new QueryGenerationManager(Factory.GetQueryGenerator(destination.Provider));
+ }
+ else
+ {
+ DestinationQueryGenerationManager = sourceQueryGenerationManager;
+ }
+
+ destinationList = GetDataFromDatabase(tableName, destination, DestinationQueryGenerationManager, ColumnList, ComparablePropertyEqualityComparer, filterCallback);
+ }
+
+ ///
+ /// Retrieves data from a database for a specified table, columns, and data contract type.
+ ///
+ /// The type of data entities to retrieve.
+ /// The name of the table from which to retrieve data.
+ /// The database connection.
+ /// The query generation manager for creating the SELECT query.
+ /// A list of column names to retrieve from the table.
+ /// An equality comparer for identifying properties used in data comparison.
+ /// A callback function for filtering the retrieved data.
+ ///
+ /// A HashSet of data entities of type T retrieved from the specified table and columns in the database.
+ ///
+ ///
+ /// The method generates a SELECT query using the provided query generation manager and executes it using a DatabaseManager.
+ /// The resulting data is converted to a HashSet using the specified property equality comparer for data comparison.
+ /// The retrieved data can be optionally filtered using the provided filter callback function.
+ ///
+ public HashSet GetDataFromDatabase(
+ string tableName,
+ IDatabase connection,
+ IQueryGenerator manager,
+ List columns,
+ PropertyEqualityComparer ComparablePropertyEqualityComparer,
+ FilterCallback? filterCallback)
+ {
+ var query = manager.GenerateSelectQuery(tableName, columns, string.Empty);
+
+ using var DBManager = new DatabaseManager(connection);
+
+ var data = DBManager.ExecuteQuery(query, tableName);
+
+ if (filterCallback != null)
+ {
+ data = filterCallback(data);
+ }
+
+ return data.ToHashSet(ComparablePropertyEqualityComparer);
+ }
+
+ #endregion
+ }
+}
diff --git a/src/Helper/QueryHelper.cs b/src/Helper/QueryHelper.cs
index 186e395..6bff04e 100644
--- a/src/Helper/QueryHelper.cs
+++ b/src/Helper/QueryHelper.cs
@@ -12,9 +12,9 @@ public class QueryHelper
///
/// Gets the table name of a specified type, considering the TableNameAttribute if present.
///
- /// The type for which to get the table name. Must implement .
+ /// The type for which to get the table name.
/// The table name.
- public string GetTableName() where T : IDataContract
+ public string GetTableName()
{
return CacheManager.GetTableName(typeof(T));
}
@@ -22,9 +22,9 @@ public string GetTableName() where T : IDataContract
///
/// Gets the table schema of a specified type, considering the TableSchemaAttribute if present.
///
- /// The type for which to get the table schema. Must implement .
+ /// The type for which to get the table schema.
/// The table schema name or null if not specified.
- public string? GetTableSchema() where T : IDataContract
+ public string? GetTableSchema()
{
return CacheManager.GetTableSchema(typeof(T));
}
@@ -32,9 +32,9 @@ public string GetTableName() where T : IDataContract
///
/// Gets whether the type specifies to generate an INSERT query with ID, considering the GenerateInsertWithIDAttribute if present.
///
- /// The type for which to determine the generation of INSERT query with ID. Must implement .
+ /// The type for which to determine the generation of INSERT query with ID.
/// True if the INSERT query should include ID, otherwise false.
- public bool GetInsertWithID() where T : IDataContract
+ public bool GetInsertWithID()
{
return CacheManager.GetInsertWithID(typeof(T));
}
@@ -44,9 +44,9 @@ public bool GetInsertWithID() where T : IDataContract
/// during insert query generation, considering the GenerateInsertWithIDAttribute if present.
///
/// The type for which to determine the inclusion of identity insert statements.
- /// Must implement .
+ ///
/// true if identity insert statements should be included; otherwise, false.
- public bool GetIncludeIdentityInsert() where T : IDataContract
+ public bool GetIncludeIdentityInsert()
{
return CacheManager.GetIncludeIdentityInsert(typeof(T));
}
@@ -54,10 +54,9 @@ public bool GetIncludeIdentityInsert() where T : IDataContract
///
/// Gets the names of properties marked as key columns for a specified type.
///
- /// The type for which to get the key columns. Must implement .
+ /// The type for which to get the key columns.
/// A list of key column names.
- ///
- public List GetKeyColumns() where T : IDataContract
+ public List GetKeyColumns()
{
return CacheManager.GetKeyColumns(typeof(T));
}
@@ -65,10 +64,9 @@ public List GetKeyColumns() where T : IDataContract
///
/// Gets the names of properties marked as excluded properties for a specified type.
///
- /// The type for which to get the excluded properties. Must implement .
+ /// The type for which to get the excluded properties.
/// A list of excluded property names.
- ///
- public List GetExcludedColumns() where T : IDataContract
+ public List GetExcludedColumns()
{
return CacheManager.GetExcludedColumns(typeof(T));
}
@@ -76,10 +74,9 @@ public List GetExcludedColumns() where T : IDataContract
///
/// Gets the names of all properties for a specified type.
///
- /// The type for which to get all properties. Must implement .
+ /// The type for which to get all properties.
/// A list of all property names.
- ///
- public List GetAllColumns() where T : IDataContract
+ public List GetAllColumns()
{
return CacheManager.GetAllColumns(typeof(T));
}
@@ -87,37 +84,33 @@ public List GetAllColumns() where T : IDataContract
///
/// Retrieves a list of identity columns for a specified data contract type .
///
- /// The type implementing the IDataContract interface.
/// A list containing the names of identity columns for the specified data contract type .
///
/// This method uses reflection to analyze the properties of the specified type and retrieves properties marked with a [Key] attribute, indicating identity columns.
///
- ///
- public List GetIdentityColumns() where T : IDataContract
+ public List GetIdentityColumns()
{
return CacheManager.GetIdentityColumns(typeof(T));
}
///
/// Retrieves an array of objects representing the properties that are used for data comparison
- /// in objects of type . These properties are determined based on the implementation of the
- /// interface.
+ /// in objects of type .
///
/// The type of objects for which to retrieve comparable properties.
/// An array of objects representing the comparable properties of type .
- public PropertyInfo[] GetComparableProperties() where T: IDataContract
+ public PropertyInfo[] GetComparableProperties()
{
return CacheManager.GetComparableProperties(typeof(T));
}
///
/// Retrieves an array of objects representing the properties that are used as key properties
- /// for uniquely identifying objects of type . These key properties are determined based on the
- /// implementation of the interface.
+ /// for uniquely identifying objects of type .
///
/// The type of objects for which to retrieve key properties.
/// An array of objects representing the key properties of type .
- public PropertyInfo[] GetKeyProperties() where T : IDataContract
+ public PropertyInfo[] GetKeyProperties()
{
return CacheManager.GetKeyProperties(typeof(T));
}
diff --git a/src/Interface/IDataContract.cs b/src/Interface/IDataContract.cs
deleted file mode 100644
index 38e17e7..0000000
--- a/src/Interface/IDataContract.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace DbSyncKit.DB.Interface
-{
- ///
- /// Represents an interface for data contracts that require comparison functionality.
- ///
- ///
- /// Implement this interface in data contracts to enable comparison functionality.
- ///
- public interface IDataContract
- {
- }
-}
diff --git a/src/Interface/IQueryGenerator.cs b/src/Interface/IQueryGenerator.cs
deleted file mode 100644
index b400392..0000000
--- a/src/Interface/IQueryGenerator.cs
+++ /dev/null
@@ -1,84 +0,0 @@
-namespace DbSyncKit.DB.Interface
-{
- ///
- /// Defines methods for generating SQL queries and handling query-related operations.
- ///
- public interface IQueryGenerator : IDisposable
- {
- ///
- /// Generates a SELECT query for retrieving data from a database table.
- ///
- /// The type of entity that implements IDataContract.
- /// The name of the database table.
- /// The list of columns to be selected.
- /// The schema name of the database table.
- /// A string representing the generated SELECT query.
- string GenerateSelectQuery(string tableName, List ListOfColumns, string schemaName) where T : IDataContract;
-
- ///
- /// Generates an UPDATE query for updating data in a database table.
- ///
- /// The type of entity that implements IDataContract.
- /// The entity with the updated data.
- /// The list of key columns used for updating.
- /// The list of columns to be excluded from the update.
- /// A dictionary representing the properties and their new values to be updated.
- /// A string representing the generated UPDATE query.
- string GenerateUpdateQuery(T DataContract, List keyColumns, List excludedColumns, (string propName, object propValue)[] editedProperties) where T : IDataContract;
-
- ///
- /// Generates a DELETE query for deleting data from a database table.
- ///
- /// The type of entity that implements IDataContract.
- /// The entity representing the data to be deleted.
- /// The list of key columns used for deletion.
- /// A string representing the generated DELETE query.
- string GenerateDeleteQuery(T entity, List keyColumns) where T : IDataContract;
-
- ///
- /// Generates an INSERT query for inserting data into a database table.
- ///
- /// The type of entity that implements IDataContract.
- /// The entity representing the data to be inserted.
- /// The list of key columns used for insertion.
- /// The list of columns to be excluded from the insertion.
- /// A string representing the generated INSERT query.
- string GenerateInsertQuery(T entity, List keyColumns, List excludedColumns) where T : IDataContract;
-
- ///
- /// Generates a SQL comment.
- ///
- /// The comment text.
- /// A string representing the generated comment.
- string GenerateComment(string comment);
-
- ///
- /// Gets a condition for use in a SQL WHERE clause based on the entity and key columns.
- ///
- /// The type of entity that implements IDataContract.
- /// The entity for which the condition is generated.
- /// The list of key columns used to create the condition.
- /// A string representing the generated condition for a SQL WHERE clause.
- List GetCondition(T entity, List keyColumns) where T : IDataContract;
-
- ///
- /// Escapes special characters in the input to make it SQL-safe.
- ///
- /// The input object or string to be escaped.
- /// The escaped object or string.
- object? EscapeValue(object? input);
-
- ///
- /// Escapes the input column name to be used safely in SQL queries.
- ///
- /// The input column name to be escaped.
- /// The escaped column name.
- string EscapeColumn(string? input);
-
- ///
- /// Generates a SQL batch separator ('GO' statement in SQL Server) used to execute batches of SQL statements.
- ///
- /// A string representing the generated batch separator.
- string GenerateBatchSeparator();
- }
-}
diff --git a/src/QueryGenerationManager.cs b/src/QueryGenerationManager.cs
deleted file mode 100644
index 9f354e8..0000000
--- a/src/QueryGenerationManager.cs
+++ /dev/null
@@ -1,88 +0,0 @@
-using DbSyncKit.DB.Interface;
-
-namespace DbSyncKit.DB
-{
- ///
- /// Manages the generation of SQL queries for data operations by delegating the query generation tasks
- /// to an implementation of the interface.
- ///
- ///
- /// This class acts as a wrapper around an instance of and forwards
- /// query generation requests to the underlying implementation.
- ///
- public class QueryGenerationManager : IQueryGenerator
- {
- private readonly IQueryGenerator _querryGenerator;
-
- ///
- /// The underlying query generator instance used for actual query generation.
- ///
- public QueryGenerationManager(IQueryGenerator querryGenerator)
- {
- _querryGenerator = querryGenerator;
- }
-
- #region Public Methods
- ///
- public string GenerateSelectQuery(string tableName, List listOfColumns, string schemaName) where T : IDataContract
- {
- return _querryGenerator.GenerateSelectQuery(tableName, listOfColumns, schemaName);
- }
-
- ///
- public string GenerateUpdateQuery(T DataContract, List keyColumns, List excludedColumns, (string propName, object propValue)[] editedProperties) where T : IDataContract
- {
- return _querryGenerator.GenerateUpdateQuery(DataContract, keyColumns, excludedColumns, editedProperties);
- }
-
- ///
- public string GenerateDeleteQuery(T entity, List keyColumns) where T : IDataContract
- {
- return _querryGenerator.GenerateDeleteQuery(entity, keyColumns);
- }
-
- ///
- public string GenerateInsertQuery(T entity, List keyColumns, List excludedColumns) where T : IDataContract
- {
- return _querryGenerator.GenerateInsertQuery(entity, keyColumns, excludedColumns);
- }
-
- ///
- public string GenerateComment(string comment)
- {
- return _querryGenerator.GenerateComment(comment);
- }
-
- ///
- public List GetCondition(T entity, List keyColumns) where T : IDataContract
- {
- return _querryGenerator.GetCondition(entity, keyColumns);
- }
-
- ///
- public object? EscapeValue(object? input)
- {
- return _querryGenerator.EscapeValue(input);
- }
-
- ///
- public string EscapeColumn(string? input)
- {
- return _querryGenerator.EscapeColumn(input);
- }
-
- ///
- public string GenerateBatchSeparator()
- {
- return _querryGenerator.GenerateBatchSeparator();
- }
-
- ///
- public void Dispose()
- {
- _querryGenerator.Dispose();
- }
-
- #endregion
- }
-}