Skip to content

Commit ff2617a

Browse files
committed
Melhorias em RefreshSQLLists e ConfigHelper
Adiciona comentários detalhados e melhora a estrutura do código em `RefreshSQLLists.cs`, incluindo tratamento de exceções e logs para rastreamento de erros. Implementa carregamento preguiçoso no `ConfigHelper.cs`, priorizando configurações específicas de lista e aprimorando a validação de campos obrigatórios. Novas classes para mapeamento de colunas e configurações de lista foram introduzidas para melhor organização do código.
1 parent 0553a64 commit ff2617a

2 files changed

Lines changed: 53 additions & 16 deletions

File tree

‎SPOtoSQL-Snapshots/ConsoleApp1/Sqlserver/RefreshSQLLists.cs‎

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,44 +5,54 @@
55

66
namespace Bring.Sqlserver
77
{
8+
/// <summary>
9+
/// Provides functionality to synchronize SharePoint lists into SQL Server.
10+
/// </summary>
811
internal class RefreshSQLLists
912
{
10-
// Method to initiate the update process from SharePoint to SQL Server
13+
/// <summary>
14+
/// Initiates the update process from SharePoint to SQL Server for all configured lists.
15+
/// </summary>
16+
/// <param name="daily">Indicates whether to perform a daily incremental update or a full current-time refresh.</param>
1117
public static void SPOtoSQLUpdate(bool daily)
1218
{
1319
Console.WriteLine("SPOtoSQLUpdate: Starting SPO to SQL update. Daily: " + daily);
1420

1521
try
1622
{
17-
// Retrieve SharePoint credentials from the configuration file
23+
// Load SharePoint credentials from configuration (secure storage recommended)
1824
var (username, password) = ConfigurationReader.GetSharePointCredentials();
19-
// Create a SharePoint user object with the retrieved credentials
2025
Console.WriteLine($"SPOtoSQLUpdate: Username: {username} Password: {password}");
26+
27+
// Establish SharePoint user context
2128
SPOUser user;
2229
try
2330
{
2431
user = new SPOUser(username, password);
2532
}
2633
catch (Exception ex)
2734
{
35+
// Fail fast if authentication cannot be created
2836
Console.WriteLine("SPOtoSQLUpdate: ERROR - Failed to create SPOUser.");
2937
Console.WriteLine("Exception: " + ex.Message);
3038
Console.WriteLine("Stack Trace: " + ex.StackTrace);
3139
return;
3240
}
3341

34-
// Iterate through all keys in the AppSettings section of the configuration file
42+
// Iterate through each SharePoint list configured in AppSettings
3543
foreach (string allKey in ConfigurationManager.AppSettings.AllKeys)
3644
{
3745
string listName = allKey;
3846
string ctxURL = ConfigurationManager.AppSettings[allKey];
3947
Console.WriteLine($"SPOtoSQLUpdate: Processing list: {listName} with URL: {ctxURL}");
4048
try
4149
{
50+
// Delegate to RefreshListsSQL for per-list processing
4251
RefreshSQLLists.RefreshListsSQL(listName, ctxURL, user, daily);
4352
}
4453
catch (Exception ex)
4554
{
55+
// Log and continue on individual list errors
4656
Console.WriteLine($"SPOtoSQLUpdate: ERROR - Exception while updating list '{listName}'.");
4757
Console.WriteLine("Exception: " + ex.Message);
4858
Console.WriteLine("Stack Trace: " + ex.StackTrace);
@@ -51,6 +61,7 @@ public static void SPOtoSQLUpdate(bool daily)
5161
}
5262
catch (Exception ex)
5363
{
64+
// Catch-all for any unexpected failure in the orchestration
5465
Console.WriteLine("SPOtoSQLUpdate: FATAL ERROR - Exception during SPO to SQL update process.");
5566
Console.WriteLine("Exception: " + ex.Message);
5667
Console.WriteLine("Stack Trace: " + ex.StackTrace);
@@ -59,37 +70,48 @@ public static void SPOtoSQLUpdate(bool daily)
5970
Console.WriteLine("SPOtoSQLUpdate: SPO to SQL update completed.");
6071
}
6172

62-
// Method to handle the update process for a specific SharePoint list to SQL Server
73+
/// <summary>
74+
/// Processes a specific SharePoint list: initializes context, builds SQL interaction, and performs the data transfer.
75+
/// </summary>
76+
/// <param name="listName">The name/key of the SharePoint list.</param>
77+
/// <param name="ctxURL">The site URL or context for the SharePoint list.</param>
78+
/// <param name="user">Authenticated SharePoint user context.</param>
79+
/// <param name="daily">Flag indicating whether a daily incremental or full refresh should be executed.</param>
6380
public static void RefreshListsSQL(string listName, string ctxURL, SPOUser user, bool daily)
6481
{
6582
try
6683
{
6784
Console.WriteLine($"RefreshListsSQL: Initializing SPO list for: {listName}");
6885

86+
// Initialize SharePoint list object
6987
SPOList spoList = null;
7088
try
7189
{
72-
spoList = new SPOList();
73-
spoList.Site = ctxURL;
74-
spoList.SPOUser = user;
75-
spoList.Name = listName;
90+
spoList = new SPOList
91+
{
92+
Site = ctxURL,
93+
SPOUser = user,
94+
Name = listName
95+
};
7696

7797
Console.WriteLine("RefreshListsSQL: SPOList initialized:");
7898
Console.WriteLine($" Site: {spoList.Site}");
7999
Console.WriteLine($" Name: {spoList.Name}");
80100
}
81101
catch (Exception ex)
82102
{
103+
// Log initialization failure and abort this list's update
83104
Console.WriteLine($"RefreshListsSQL: ERROR - Failed to initialize SPOList for '{listName}'.");
84105
Console.WriteLine("Exception: " + ex.Message);
85106
Console.WriteLine("Stack Trace: " + ex.StackTrace);
86107
return;
87108
}
88109

110+
// Prepare SQL interaction based on the SharePoint list schema
89111
SQLInteraction sqlInteraction = null;
90112
try
91113
{
92-
sqlInteraction = new SQLInteraction()
114+
sqlInteraction = new SQLInteraction
93115
{
94116
List = spoList
95117
};
@@ -99,12 +121,14 @@ public static void RefreshListsSQL(string listName, string ctxURL, SPOUser user,
99121
}
100122
catch (Exception ex)
101123
{
124+
// Log and abort if building SQL commands fails
102125
Console.WriteLine($"RefreshListsSQL: ERROR - Failed to build SQLInteraction for '{listName}'.");
103126
Console.WriteLine("Exception: " + ex.Message);
104127
Console.WriteLine("Stack Trace: " + ex.StackTrace);
105128
return;
106129
}
107130

131+
// Perform the actual data transfer based on the mode (daily vs. full)
108132
try
109133
{
110134
if (daily)
@@ -120,6 +144,7 @@ public static void RefreshListsSQL(string listName, string ctxURL, SPOUser user,
120144
}
121145
catch (Exception ex)
122146
{
147+
// Log any exceptions during the update process
123148
Console.WriteLine($"RefreshListsSQL: ERROR - Exception during update for '{listName}'.");
124149
Console.WriteLine("Exception: " + ex.Message);
125150
Console.WriteLine("Stack Trace: " + ex.StackTrace);
@@ -130,9 +155,10 @@ public static void RefreshListsSQL(string listName, string ctxURL, SPOUser user,
130155
}
131156
catch (Exception ex)
132157
{
158+
// Catch-all for any unforeseen errors in the list-specific workflow
133159
Console.WriteLine($"RefreshListsSQL: FATAL ERROR updating list '{listName}': {ex.Message}");
134160
Console.WriteLine("Stack Trace: " + ex.StackTrace);
135161
}
136162
}
137163
}
138-
}
164+
}

‎SPOtoSQL-Snapshots/ConsoleApp1/XmlConfig/ConfigHelper.cs‎

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public class ConfigurationReader
2424
/// <exception cref="Exception">Thrown when the configuration file cannot be loaded.</exception>
2525
private static void LoadConfig()
2626
{
27+
// Lazy loading pattern - only load once
2728
if (_xmlDoc == null)
2829
{
2930
try
@@ -52,17 +53,19 @@ public static Dictionary<string, ColumnMapping> GetSelectedColumns(string listNa
5253

5354
try
5455
{
55-
// Primeiro verifica configurações específicas da lista
56+
// List-specific configurations take precedence over global settings
5657
if (!string.IsNullOrEmpty(listName))
5758
{
5859
var listConfigs = GetListConfigurations();
5960
if (listConfigs != null && listConfigs.TryGetValue(listName, out var listConfig))
6061
{
62+
// Skip ignored lists entirely
6163
if (listConfig.Ignore)
6264
{
6365
Console.WriteLine($"List {listName} is configured to be ignored.");
6466
return null;
6567
}
68+
// Use list-specific column configuration if available
6669
if (listConfig.Columns != null)
6770
{
6871
Console.WriteLine($"Using specific configuration for list: {listName}");
@@ -71,15 +74,17 @@ public static Dictionary<string, ColumnMapping> GetSelectedColumns(string listNa
7174
}
7275
}
7376

74-
// Se não encontrar configuração específica, usa as configurações globais
77+
// Fall back to global column configuration
7578
var columnNodes = _xmlDoc.SelectNodes("//Configuration/ReplicationConfiguration/SelectColumns/column");
7679

80+
// No specific columns configured = include all columns
7781
if (columnNodes == null || columnNodes.Count == 0)
7882
{
7983
Console.WriteLine("No specific columns configured. All columns will be included.");
8084
return null;
8185
}
8286

87+
// Build case-insensitive column mappings dictionary
8388
var columnMappings = new Dictionary<string, ColumnMapping>(StringComparer.OrdinalIgnoreCase);
8489

8590
foreach (XmlNode node in columnNodes)
@@ -93,7 +98,7 @@ public static Dictionary<string, ColumnMapping> GetSelectedColumns(string listNa
9398
var mapping = new ColumnMapping
9499
{
95100
Source = sourceAttr.Value,
96-
Destination = destAttr?.Value ?? sourceAttr.Value,
101+
Destination = destAttr?.Value ?? sourceAttr.Value, // Default to source name if no destination
97102
Ignore = ignoreAttr != null && bool.Parse(ignoreAttr.Value)
98103
};
99104

@@ -257,6 +262,7 @@ public static IEnumerable<SharePointListConfig> GetSharePointListConfigurations(
257262
Disabled = GetNodeValueBool(listNode, "Disabled", false)
258263
};
259264

265+
// Only add valid configurations
260266
if (IsValidListConfig(config))
261267
{
262268
configurations.Add(config);
@@ -298,6 +304,7 @@ private static bool GetNodeValueBool(XmlNode parentNode, string nodeName, bool d
298304
/// </summary>
299305
private static bool IsValidListConfig(SharePointListConfig config)
300306
{
307+
// All three fields are required for proper replication
301308
if (string.IsNullOrEmpty(config.SiteUrl))
302309
{
303310
Console.WriteLine("Invalid configuration: SiteUrl is required.");
@@ -329,6 +336,7 @@ public static Dictionary<string, ListConfiguration> GetListConfigurations()
329336
if (listNodes == null || listNodes.Count == 0)
330337
return null;
331338

339+
// Case-insensitive dictionary for list name lookups
332340
var listConfigs = new Dictionary<string, ListConfiguration>(StringComparer.OrdinalIgnoreCase);
333341

334342
foreach (XmlNode listNode in listNodes)
@@ -344,7 +352,7 @@ public static Dictionary<string, ListConfiguration> GetListConfigurations()
344352
Name = nameAttr.Value,
345353
Context = contextAttr?.Value,
346354
Ignore = ignoreAttr != null && bool.Parse(ignoreAttr.Value),
347-
Columns = GetListColumns(listNode)
355+
Columns = GetListColumns(listNode) // Get list-specific column mappings
348356
};
349357

350358
listConfigs[listConfig.Name] = listConfig;
@@ -362,6 +370,7 @@ public static Dictionary<string, ListConfiguration> GetListConfigurations()
362370

363371
private static Dictionary<string, ColumnMapping> GetListColumns(XmlNode listNode)
364372
{
373+
// Use relative XPath to find columns within this specific list
365374
var columnNodes = listNode.SelectNodes(".//Columns/column");
366375
if (columnNodes == null || columnNodes.Count == 0)
367376
return null;
@@ -379,7 +388,7 @@ private static Dictionary<string, ColumnMapping> GetListColumns(XmlNode listNode
379388
var mapping = new ColumnMapping
380389
{
381390
Source = sourceAttr.Value,
382-
Destination = destAttr?.Value ?? sourceAttr.Value,
391+
Destination = destAttr?.Value ?? sourceAttr.Value, // Default to source if no destination specified
383392
Ignore = ignoreAttr != null && bool.Parse(ignoreAttr.Value)
384393
};
385394

@@ -403,13 +412,15 @@ public class SharePointListConfig
403412
public bool Disabled { get; set; }
404413
}
405414

415+
// Represents mapping between source and destination columns with ignore capability
406416
public class ColumnMapping
407417
{
408418
public string Source { get; set; }
409419
public string Destination { get; set; }
410420
public bool Ignore { get; set; }
411421
}
412422

423+
// List-specific configuration that can override global settings
413424
public class ListConfiguration
414425
{
415426
public string Name { get; set; }

0 commit comments

Comments
 (0)