-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSqlBatchOperation.cs
121 lines (107 loc) · 3.3 KB
/
SqlBatchOperation.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Sitecore.Configuration;
using Sitecore.Data.DataProviders.Sql;
using Sitecore.Diagnostics;
using Sitecore.Diagnostics.PerformanceCounters;
namespace Sc.LinkDatabase
{
public interface IBatchOperation
{
int Index { get; }
}
public class SqlBatchOperation : IBatchOperation
{
private const int MaxParametersInSqlRequest = 2100;
private readonly object _lock = new object();
private SqlDataApi DataApi { get; }
private readonly StringBuilder _sqlStatements = new StringBuilder();
private readonly List<object> _sqlParameters = new List<object>();
private int _index;
public int Index
{
get => _index;
set
{
lock (_lock)
{
_index = value;
}
}
}
public SqlBatchOperation(SqlDataApi dataApi)
{
DataApi = dataApi;
}
public void AddSqlBatchCommand(ISqlBatchCommand command)
{
int totalParameters;
lock (_lock)
{
totalParameters = _sqlParameters.Count + command.QueryParameters.Count();
}
if (totalParameters > MaxParametersInSqlRequest)
FlushBatches();
lock (_lock)
{
_sqlStatements.AppendLine(command.QueryStatement);
_sqlParameters.AddRange(command.QueryParameters);
_index ++;
}
}
public void FlushBatches()
{
try
{
string sql;
object[] parameters;
lock (_lock)
{
sql = _sqlStatements.ToString();
parameters = _sqlParameters.ToArray();
}
// Don't execute empty statement list
if (string.IsNullOrWhiteSpace(sql))
return;
LogSqlOperation(sql, parameters);
Factory.GetRetryer().ExecuteNoResult(() =>
{
DataApi.Execute(sql, parameters);
});
DataCount.LinksDataUpdated.IncrementBy(_index);
DataCount.DataPhysicalWrites.Increment();
}
finally
{
ResetBatches();
}
}
private void ResetBatches()
{
lock (_lock)
{
_sqlStatements.Clear();
_sqlParameters.Clear();
_index = 0;
}
}
private void LogSqlOperation(string sql, IEnumerable<object> parameters)
{
if (!Log.IsDebugEnabled)
return;
var sw = new StringWriter();
sw.WriteLine("Performing LinkDatabase batch operation:");
sw.WriteLine("SQL statement:");
sw.WriteLine(sql);
sw.WriteLine("SQL Parameters:");
var p = parameters.ToList();
for (int i = 0; i < p.Count; i += 2)
{
sw.WriteLine("\t{0}: {1}", p[i], p[i+1]);
}
Log.Debug(sw.ToString(), nameof(SqlBatchOperation));
}
}
}