I am writing a program that updates bonds in an external system that I have database access to.
The program is run in a 8 minute interval.
Bonds are stored in a table called Debentur
.
Bonds need to be calculated if they are new or it's calculation method is changed. The calculation method is stored in the column CalledIn
with possible values 1(active) and null(not active).
- How do you like my method of finding what is changed?
- In my opinion it is not obvious what the class
CalculateClaimsBondsChangedCommand
is not doing. It is finding changes, updating them and then inserting the changes so they won't be updated in the next update. Do you have any suggestions for improvement?
- My repository
DebenturChangesRepository
has a lot of code duplication which I have not yet refactored, how would you refactor it?
- Anything else that could be imporved?
public class CalculateClaimsBondsChangedCommand : ICalculateCommand
{
private readonly IDebenturChangesRepository debenturChangesRepository;
private readonly IClaimsCalculatorService claimsCalculatorService;
public CalculateClaimsBondsChangedCommand(
IDebenturChangesRepository debenturChangesRepository,
IClaimsCalculatorService claimsCalculatorService)
{
if (debenturChangesRepository == null) throw new ArgumentNullException("debenturChangesRepository");
if (claimsCalculatorService == null) throw new ArgumentNullException("claimsCalculatorService");
this.debenturChangesRepository = debenturChangesRepository;
this.claimsCalculatorService = claimsCalculatorService;
}
public void Execute()
{
var newDebenturs = debenturChangesRepository.CreateForNewDebenturs();
var changedDebenturs = debenturChangesRepository.CreateForChangedCalledIn();
claimsCalculatorService.CalculateClaims(newDebenturs.Concat(changedDebenturs).Select(d => d.ClaimNo));
foreach (var debentur in newDebenturs)
{
debenturChangesRepository.InsertDebenturChange(debentur);
}
foreach (var debentur in changedDebenturs)
{
debenturChangesRepository.UpdateDebenturChange(debentur);
}
}
}
public class DebenturChangesRepository : IDebenturChangesRepository
{
private readonly string connectionString;
public DebenturChangesRepository(string connectionString)
{
if (connectionString == null) throw new ArgumentNullException("connectionString");
this.connectionString = connectionString;
}
public List<DebenturChange> CreateForNewDebenturs()
{
var sql = "Select ClaimNo, CalledIn " +
"From Debentur " +
"Where ClaimNo Not In (Select ClaimNo From DebenturChange) ";
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
var command = connection.CreateCommand();
command.CommandText = sql;
using (var reader = command.ExecuteReader())
{
return GetDebentursFromReader(reader);
}
}
}
public List<DebenturChange> CreateForChangedCalledIn()
{
var sql = "Select d.ClaimNo, d.CalledIn " +
"From Debentur d join DebenturChange c on d.ClaimNo = c.ClaimNo " +
"Where IsNull(d.CalledIn, 0) <> IsNull(c.CalledIn, 0) ";
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
var command = connection.CreateCommand();
command.CommandText = sql;
using (var reader = command.ExecuteReader())
{
return GetDebentursFromReader(reader);
}
}
}
private List<DebenturChange> GetDebentursFromReader(IDataReader reader)
{
var debenturs = new List<DebenturChange>();
while (reader.Read())
{
debenturs.Add(ParseDebenturChange(reader));
}
return debenturs;
}
private DebenturChange ParseDebenturChange(IDataReader reader)
{
return new DebenturChange()
{
ClaimNo = (string)reader["ClaimNo"],
CalledIn = ParseColumnToNullableInt(reader["CalledIn"])
};
}
private int? ParseColumnToNullableInt(object o)
{
if (o == DBNull.Value) return null;
return Convert.ToInt32(o);
}
public void InsertDebenturChange(DebenturChange debenturChange)
{
var sql = "Insert Into DebenturChange (ClaimNo, CalledIn) " +
"Values (@ClaimNo, @CalledIn)";
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
var command = connection.CreateCommand();
command.CommandText = sql;
command.Parameters.AddWithValue("ClaimNo", debenturChange.ClaimNo);
command.Parameters.AddWithValue("CalledIn", ParseNullableIntToColumn(debenturChange.CalledIn));
command.ExecuteNonQuery();
}
}
public void UpdateDebenturChange(DebenturChange debenturChange)
{
var sql = "Update DebenturChange " +
"Set CalledIn = @CalledIn " +
"Where ClaimNo = @ClaimNo";
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
var command = connection.CreateCommand();
command.CommandText = sql;
command.Parameters.AddWithValue("ClaimNo", debenturChange.ClaimNo);
command.Parameters.AddWithValue("CalledIn", ParseNullableIntToColumn(debenturChange.CalledIn));
command.ExecuteNonQuery();
}
}
private object ParseNullableIntToColumn(int? value)
{
if (value == null) return DBNull.Value;
return value.Value;
}
}