Skip to content

Commit 53ffcf2

Browse files
committed
Moved Fetcher to DB from core as its fetching from DB
1 parent fe058b0 commit 53ffcf2

2 files changed

Lines changed: 200 additions & 0 deletions

File tree

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
using System.Reflection;
2+
3+
namespace DbSyncKit.DB.Comparer
4+
{
5+
/// <summary>
6+
/// Compares instances of data contracts based on specified properties, which can be either key or comparable properties.
7+
/// </summary>
8+
public class PropertyEqualityComparer<T> : IEqualityComparer<T>
9+
{
10+
/// <summary>
11+
/// Gets the array of <see cref="PropertyInfo"/> objects representing properties used for equality comparison.
12+
/// These properties can serve as either key or comparable properties.
13+
/// </summary>
14+
public readonly PropertyInfo[] properties;
15+
16+
/// <summary>
17+
/// Initializes a new instance of the <see cref="PropertyEqualityComparer{T}"/> class.
18+
/// </summary>
19+
/// <param name="Properties">An array of <see cref="PropertyInfo"/> objects representing properties used for equality comparison. These can be either key or comparable properties.</param>
20+
public PropertyEqualityComparer(PropertyInfo[] Properties)
21+
{
22+
properties = Properties;
23+
}
24+
25+
/// <summary>
26+
/// Determines whether two instances of the data contract are equal based on the specified properties.
27+
/// </summary>
28+
/// <param name="x">The first instance to compare.</param>
29+
/// <param name="y">The second instance to compare.</param>
30+
/// <returns><c>true</c> if the instances are equal; otherwise, <c>false</c>.</returns>
31+
public bool Equals(T? x, T? y)
32+
{
33+
return properties.All(prop => Equals(prop.GetValue(x), prop.GetValue(y)));
34+
}
35+
36+
/// <summary>
37+
/// Returns a hash code for the specified instance of the data contract based on the specified properties.
38+
/// </summary>
39+
/// <param name="obj">The instance for which to get the hash code.</param>
40+
/// <returns>A hash code for the specified instance.</returns>
41+
public int GetHashCode(T obj)
42+
{
43+
unchecked
44+
{
45+
int hash = 17;
46+
47+
foreach (var prop in properties)
48+
{
49+
var value = prop.GetValue(obj);
50+
hash = hash ^ ((value?.GetHashCode() ?? 0) + 23);
51+
}
52+
53+
return hash;
54+
}
55+
}
56+
}
57+
58+
}

src/Fetcher/DataContractFetcher.cs

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
using DbSyncKit.DB.Comparer;
2+
using DbSyncKit.DB.Factory;
3+
using DbSyncKit.DB.Interface;
4+
5+
namespace DbSyncKit.DB.Fetcher
6+
{
7+
/// <summary>
8+
/// Represents a callback function for filtering a list of data entities of type T.
9+
/// </summary>
10+
/// <typeparam name="T">The type of data entities to filter.</typeparam>
11+
/// <param name="data">The list of data entities to filter.</param>
12+
/// <returns>A filtered list of data entities.</returns>
13+
/// <remarks>
14+
/// This delegate defines a callback function that takes a list of data entities as input,
15+
/// performs filtering operations on the data, and returns the filtered list.
16+
/// </remarks>
17+
public delegate List<T> FilterCallback<T>(List<T> data);
18+
19+
/// <summary>
20+
/// Utility class for fetching data from a database using data contracts.
21+
/// </summary>
22+
public class DataContractFetcher
23+
{
24+
#region Properties
25+
26+
/// <summary>
27+
/// Gets the query generator factory instance used for creating query generators.
28+
/// </summary>
29+
private readonly QueryGeneratorFactory Factory;
30+
31+
/// <summary>
32+
/// Gets or sets the QueryGenerationManager instance for generating queries for the destination database.
33+
/// </summary>
34+
/// <remarks>
35+
/// This property is set by the <see cref="RetrieveDataFromDatabases{T}(IDatabase, IDatabase, string, List{string}, PropertyEqualityComparer{T}, FilterCallback{T}?, out HashSet{T}, out HashSet{T})"/> method.
36+
/// It allows the reuse of the QueryGenerationManager instance when the source and destination databases share the same provider.
37+
/// </remarks>
38+
public IQueryGenerator? DestinationQueryGenerationManager { get; private set; }
39+
40+
#endregion
41+
42+
#region Constructor
43+
44+
/// <summary>
45+
/// Initializes a new instance of the <see cref="DataContractFetcher"/> class with a custom query generator factory.
46+
/// </summary>
47+
/// <param name="factory">The custom query generator factory instance.</param>
48+
public DataContractFetcher(QueryGeneratorFactory factory)
49+
{
50+
Factory = factory;
51+
}
52+
53+
#endregion
54+
55+
#region Methods
56+
57+
/// <summary>
58+
/// Retrieves data from source and destination databases for a specified table and column list, using a specified data contract type.
59+
/// </summary>
60+
/// <typeparam name="T">The type of data entities to retrieve.</typeparam>
61+
/// <param name="source">The source database.</param>
62+
/// <param name="destination">The destination database.</param>
63+
/// <param name="tableName">The name of the table from which to retrieve data.</param>
64+
/// <param name="ColumnList">A list of column names to retrieve from the table.</param>
65+
/// <param name="ComparablePropertyEqualityComparer">An equality comparer for identifying properties used in data comparison.</param>
66+
/// <param name="filterCallback">A callback function for filtering the retrieved data.</param>
67+
/// <param name="sourceList">An output parameter that receives the retrieved data from the source database.</param>
68+
/// <param name="destinationList">An output parameter that receives the retrieved data from the destination database.</param>
69+
/// <remarks>
70+
/// The method uses a QueryGenerationManager to generate queries for retrieving data based on the specified table and columns.
71+
/// If the providers of the source and destination databases differ, a new QueryGenerationManager is created for the destination database.
72+
/// The retrieved data can be optionally filtered using the provided filter callback function.
73+
/// </remarks>
74+
public void RetrieveDataFromDatabases<T>(
75+
IDatabase source,
76+
IDatabase destination,
77+
string tableName,
78+
List<string> ColumnList,
79+
PropertyEqualityComparer<T> ComparablePropertyEqualityComparer,
80+
FilterCallback<T>? filterCallback,
81+
out HashSet<T> sourceList,
82+
out HashSet<T> destinationList)
83+
{
84+
var sourceQueryGenerationManager = new QueryGenerationManager(Factory.GetQueryGenerator(source.Provider));
85+
sourceList = GetDataFromDatabase<T>(tableName, source, sourceQueryGenerationManager, ColumnList, ComparablePropertyEqualityComparer, filterCallback);
86+
87+
if (source.Provider != destination.Provider)
88+
{
89+
sourceQueryGenerationManager.Dispose();
90+
DestinationQueryGenerationManager = new QueryGenerationManager(Factory.GetQueryGenerator(destination.Provider));
91+
}
92+
else
93+
{
94+
DestinationQueryGenerationManager = sourceQueryGenerationManager;
95+
}
96+
97+
destinationList = GetDataFromDatabase<T>(tableName, destination, DestinationQueryGenerationManager, ColumnList, ComparablePropertyEqualityComparer, filterCallback);
98+
}
99+
100+
/// <summary>
101+
/// Retrieves data from a database for a specified table, columns, and data contract type.
102+
/// </summary>
103+
/// <typeparam name="T">The type of data entities to retrieve.</typeparam>
104+
/// <param name="tableName">The name of the table from which to retrieve data.</param>
105+
/// <param name="connection">The database connection.</param>
106+
/// <param name="manager">The query generation manager for creating the SELECT query.</param>
107+
/// <param name="columns">A list of column names to retrieve from the table.</param>
108+
/// <param name="ComparablePropertyEqualityComparer">An equality comparer for identifying properties used in data comparison.</param>
109+
/// <param name="filterCallback">A callback function for filtering the retrieved data.</param>
110+
/// <returns>
111+
/// A HashSet of data entities of type T retrieved from the specified table and columns in the database.
112+
/// </returns>
113+
/// <remarks>
114+
/// The method generates a SELECT query using the provided query generation manager and executes it using a DatabaseManager.
115+
/// The resulting data is converted to a HashSet using the specified property equality comparer for data comparison.
116+
/// The retrieved data can be optionally filtered using the provided filter callback function.
117+
/// </remarks>
118+
public HashSet<T> GetDataFromDatabase<T>(
119+
string tableName,
120+
IDatabase connection,
121+
IQueryGenerator manager,
122+
List<string> columns,
123+
PropertyEqualityComparer<T> ComparablePropertyEqualityComparer,
124+
FilterCallback<T>? filterCallback)
125+
{
126+
var query = manager.GenerateSelectQuery<T>(tableName, columns, string.Empty);
127+
128+
using var DBManager = new DatabaseManager<IDatabase>(connection);
129+
130+
var data = DBManager.ExecuteQuery<T>(query, tableName);
131+
132+
if (filterCallback != null)
133+
{
134+
data = filterCallback(data);
135+
}
136+
137+
return data.ToHashSet(ComparablePropertyEqualityComparer);
138+
}
139+
140+
#endregion
141+
}
142+
}

0 commit comments

Comments
 (0)