public ProviderSiteRepository(IGetOpenConnection getOpenConnection, IMapper mapper, ILogService logger, IConfigurationService configurationService) { _getOpenConnection = getOpenConnection; _mapper = mapper; _logger = logger; _configurationService = configurationService; }
public ChangesOnlySnapshotSyncContext(ILogService log, IGetOpenConnection sourceDatabase, IGetOpenConnection targetDatabase) : base(log, sourceDatabase, targetDatabase) { var lastSyncVersion = _targetDatabase.Query <long?>($"SELECT LastSyncVersion FROM Sync.SyncParams").Single(); if (lastSyncVersion == null) { throw new FullScanRequiredException(); } _lastSyncVersion = lastSyncVersion.Value; _log.Info($"LastSyncVersion={_lastSyncVersion}"); try { _sourceConnection = _sourceDatabase.GetOpenConnection(); _sourceConnection.Execute("SET TRANSACTION ISOLATION LEVEL SNAPSHOT"); _sourceTransaction = _sourceConnection.BeginTransaction(); _nextSyncVersion = _sourceConnection.Query <long>($"SELECT CHANGE_TRACKING_CURRENT_VERSION()", transaction: _sourceTransaction, buffered: false).Single(); _log.Info($"NextSyncVersion={_nextSyncVersion}"); } catch (Exception) { Dispose(); throw; } }
public void SetUpFixture() { _connection = new GetOpenConnectionFromConnectionString(DatabaseConfigurationProvider.Instance.TargetConnectionString); _dateTimeService = new Mock <IDateTimeService>(); _currentUserService = new Mock <ICurrentUserService>(); }
public void SetUp() { _connection = new GetOpenConnectionFromConnectionString( DatabaseConfigurationProvider.Instance.TargetConnectionString); _providerReadRepository = new ProviderRepository(_connection, _mapper, _logger.Object); _providerWriteRepository = new ProviderRepository(_connection, _mapper, _logger.Object); }
public void SetUpFixture() { _connection = new GetOpenConnectionFromConnectionString( DatabaseConfigurationProvider.Instance.TargetConnectionString); _employerReadRepository = new EmployerRepository(_connection, _mapper); _employerWriteRepository = new EmployerRepository(_connection, _mapper); }
public void SetUpFixture() { _connection = new GetOpenConnectionFromConnectionString(DatabaseConfigurationProvider.Instance.TargetConnectionString); _logger = new Mock <ILogService>(); _repoUnderTest = new AgencyUserRepository(_connection, _mapper, _logger.Object); }
public AuditMigrationProcessor(SyncRepository syncRepository, IGetOpenConnection targetDatabase, IConfigurationService configurationService, ILogService logService) { _logService = logService; _syncRepository = syncRepository; _auditRepository = new AuditRepository(configurationService, logService); _candidateRepository = new CandidateRepository(targetDatabase); _applicationRepository = new ApplicationRepository(targetDatabase); }
public void SetUp() { _connection = new GetOpenConnectionFromConnectionString( DatabaseConfigurationProvider.Instance.TargetConnectionString); var logger = new Mock <ILogService>(); _repository = new ProviderUserRepository( _connection, _mapper, logger.Object); }
public VacancyRepository(IGetOpenConnection getOpenConnection, IMapper mapper, IDateTimeService dateTimeService, ILogService logger, ICurrentUserService currentUserService, IConfigurationService configurationService) { _getOpenConnection = getOpenConnection; _mapper = mapper; _dateTimeService = dateTimeService; _logger = logger; _currentUserService = currentUserService; _configurationService = configurationService; }
/// <summary> /// Insert a new record containing data from the specified object. The primary key in the specified record must be zero. /// Very similar to Dapper.Contrib.SqlMapperExtensions Insert method except: /// <list type="bullet"> /// <item><description>It manages (obtains, opens, closes and returns) the database connection itself</description></item> /// <item><description>Transient errors are automatically retried</description></item> /// <item><description>Transactions are not supported (in order to support retries)</description></item> /// <item><description>Table / primary key naming conventions are <EntityName>.<EntityName>Id rather than <EntityName>s.Id</description></item> /// </list> /// </summary> /// <typeparam name="T"></typeparam> /// <param name="goc"></param> /// <param name="entity"></param> /// <param name="commandTimeout"></param> /// <returns>The primary key of the </returns> public static long Insert <T>(this IGetOpenConnection goc, T entity, int?commandTimeout = null) where T : class { // TODO: Log that user did this query return(RetryPolicy.ExecuteAction <long>(() => { using (var conn = goc.GetOpenConnection()) { return conn.Insert <T>(entity, null, commandTimeout); } })); }
/// <summary> /// Peform a mutating query returning the specified type. This may update multiple tables. /// The caller must perform logging of the changes made. /// Very similar to Dapper's IDbConnection.Query except: /// <list type="bullet"> /// <item><description>It manages (obtains, opens, closes and returns) the database connection itself</description></item> /// <item><description>The result is always entirely loaded and returned as an IList ("buffered" cannot be set to false)</description></item> /// <item><description>Transient errors are automatically retried</description></item> /// <item><description>Transactions are not supported (in order to support retries)</description></item> /// </list> /// </summary> /// <typeparam name="T"></typeparam> /// <param name="goc"></param> /// <param name="sql"></param> /// <param name="param"></param> /// <param name="commandTimeout"></param> /// <param name="commandType"></param> /// <returns></returns> public static IList <T> MutatingQuery <T>(this IGetOpenConnection goc, string sql, object param = null, int?commandTimeout = default(int?), CommandType?commandType = default(CommandType?)) { // TODO: Log that user did this query return(RetryPolicy.ExecuteAction <IList <T> >(() => { using (var conn = goc.GetOpenConnection()) { return (IList <T>)conn.Query <T>(sql, param, transaction: null, buffered: true, commandTimeout: commandTimeout, commandType: commandType); } })); }
/// <summary> /// Update the single record with a primary key matching the specified object. /// Very similar to Dapper.Contrib.SqlMapperExtensions Update method except: /// <list type="bullet"> /// <item><description>It manages (obtains, opens, closes and returns) the database connection itself</description></item> /// <item><description>Transient errors are automatically retried</description></item> /// <item><description>Transactions are not supported (in order to support retries)</description></item> /// <item><description>Table / primary key naming conventions are <EntityName>.<EntityName>Id rather than <EntityName>s.Id</description></item> /// <item><description>It only supports updating a single record at a time and may rollback / throw an exception if more than one is affected</description></item> /// </list> /// </summary> /// <typeparam name="T"></typeparam> /// <param name="goc"></param> /// <param name="entity"></param> /// <param name="commandTimeout"></param> /// <returns>true if at least one record was updated, otherwise false</returns> /// <remarks>Consider issuing a custom update if not all columns are changed.</remarks> public static bool UpdateSingle <T>(this IGetOpenConnection goc, T entity, int?commandTimeout = null) where T : class { // TODO: Log that user did this query // TODO: Do in a transaction and check that only one record updated before committing return(RetryPolicy.ExecuteAction <bool>(() => { using (var conn = goc.GetOpenConnection()) { return conn.Update <T>(entity, null, commandTimeout); } })); }
/// <summary> /// Delete the single record with a primary key matching the specified object. /// Very similar to Dapper.Contrib.SqlMapperExtensions Delete method except: /// <list type="bullet"> /// <item><description>It manages (obtains, opens, closes and returns) the database connection itself</description></item> /// <item><description>Transient errors are automatically retried</description></item> /// <item><description>Transactions are not supported (in order to support retries)</description></item> /// <item><description>Table / primary key naming conventions are <EntityName>.<EntityName>Id rather than <EntityName>s.Id</description></item> /// <item><description>It only supports deleting a single record at a time and may rollback / throw an exception if more than one is affected</description></item> /// </list> /// </summary> /// <typeparam name="T"></typeparam> /// <param name="goc"></param> /// <param name="entity"></param> /// <param name="commandTimeout"></param> /// <returns></returns> public static bool DeleteSingle <T>(this IGetOpenConnection goc, T entity, int?commandTimeout = null) where T : class { // TODO: Replace with method that takes primary key (does this have the same design fault as entity framework?) // TODO: Log that user did this query // TODO: Do in a transaction and check that only one record deleted before committing return(RetryPolicy.ExecuteAction <bool>(() => { using (var conn = goc.GetOpenConnection()) { return conn.Delete <T>(entity, null, commandTimeout); } })); }
/// <summary> /// Execute a query that returns multiple datasets. Similar in principal to Dapper's IDbConnection.QueryMultiple except: /// <list type="bullet"> /// <item><description>It manages (obtains, opens, closes and returns) the database connection itself</description></item> /// <item><description>All the results are fully loaded and returned in a Tuple of ILists (Dapper defers loading until GridReader.Read is called)</description></item> /// <item><description>Transient errors are automatically retried</description></item> /// <item><description>Transactions are not supported (in order to support retries)</description></item> /// </list> /// </summary> /// <param name="goc"></param> /// <param name="sql"></param> /// <param name="param"></param> /// <param name="commandTimeout"></param> /// <param name="commandType"></param> /// <returns>An enumerable of the results. This must either be fully iterated or disposed of to avoid a resource leak. Using foreach will automatically dispose. It can only be iterated through once.</returns> /// <remarks>Once the first value has been returned any transient errors will not be retried. Ideally the caller would be carrying out an idempotent operation and would retry from the beginning. /// Transient errors can be detected with "new SqlDatabaseTransientErrorDetectionStrategy().IsTransient(ex)"</remarks> public static Tuple <IList <T1>, IList <T2> > QueryMultiple <T1, T2>(this IGetOpenConnection goc, string sql, object param = null, int?commandTimeout = default(int?), CommandType?commandType = default(CommandType?)) { // TODO: Log that user did this query return(RetryPolicy.ExecuteAction <Tuple <IList <T1>, IList <T2> > >(() => { using (var conn = goc.GetOpenConnection()) { var allResults = conn.QueryMultiple(sql, param, transaction: null, commandTimeout: commandTimeout, commandType: commandType); return new Tuple <IList <T1>, IList <T2> >((IList <T1>)allResults.Read <T1>(), (IList <T2>)allResults.Read <T2>()); } } )); }
public ApplicationUpdater(string collectionName, IConfigurationService configurationService, ILogService logService) { _logService = logService; var configuration = configurationService.Get <MigrateFromFaaToAvmsPlusConfiguration>(); _targetDatabase = new GetOpenConnectionFromConnectionString(configuration.TargetConnectionString); _applicationMappers = new ApplicationMappers(_logService); _vacancyApplicationsRepository = new VacancyApplicationsRepository(collectionName, configurationService, logService); _candidateRepository = new CandidateRepository(_targetDatabase); _destinationApplicationRepository = new ApplicationRepository(_targetDatabase); _destinationApplicationHistoryRepository = new ApplicationHistoryRepository(_targetDatabase, _logService); _schoolAttendedRepository = new SchoolAttendedRepository(_targetDatabase); }
public VacancyApplicationsMigrationProcessor(IVacancyApplicationsUpdater vacancyApplicationsUpdater, IApplicationMappers applicationMappers, IGenericSyncRespository genericSyncRespository, IGetOpenConnection sourceDatabase, IGetOpenConnection targetDatabase, IConfigurationService configurationService, ILogService logService) { _vacancyApplicationsUpdater = vacancyApplicationsUpdater; _applicationMappers = applicationMappers; _genericSyncRespository = genericSyncRespository; _targetDatabase = targetDatabase; _logService = logService; _vacancyRepository = new VacancyRepository(targetDatabase); _candidateRepository = new CandidateRepository(targetDatabase); _sourceApplicationRepository = new ApplicationRepository(sourceDatabase); _sourceApplicationHistoryRepository = new ApplicationHistoryRepository(sourceDatabase, _logService); _sourceSubVacancyRepository = new SubVacancyRepository(sourceDatabase); _destinationApplicationRepository = new ApplicationRepository(targetDatabase); _destinationApplicationHistoryRepository = new ApplicationHistoryRepository(targetDatabase, _logService); _schoolAttendedRepository = new SchoolAttendedRepository(targetDatabase); _destinationSubVacancyRepository = new SubVacancyRepository(targetDatabase); _vacancyApplicationsRepository = new VacancyApplicationsRepository(_vacancyApplicationsUpdater.CollectionName, configurationService, logService); _updateVacancyApplicationsRepository = new UpdateVacancyApplicationsRepository(_vacancyApplicationsUpdater.CollectionName, configurationService, logService); }
public CandidateMigrationProcessor(ICandidateMappers candidateMappers, SyncRepository syncRepository, IGenericSyncRespository genericSyncRespository, IGetOpenConnection targetDatabase, IConfigurationService configurationService, ILogService logService) { _candidateMappers = candidateMappers; _syncRepository = syncRepository; _genericSyncRespository = genericSyncRespository; _targetDatabase = targetDatabase; _logService = logService; _vacancyRepository = new VacancyRepository(targetDatabase); _localAuthorityRepository = new LocalAuthorityRepository(targetDatabase); _candidateRepository = new CandidateRepository(targetDatabase); _schoolAttendedRepository = new SchoolAttendedRepository(targetDatabase); _candidateHistoryRepository = new CandidateHistoryRepository(targetDatabase); _candidateUserRepository = new CandidateUserRepository(configurationService, _logService); _userRepository = new UserRepository(configurationService, logService); var configuration = configurationService.Get <MigrateFromFaaToAvmsPlusConfiguration>(); _anonymiseData = configuration.AnonymiseData; }
/// <summary> /// Execute a query and progressively load the data. Very similar to Dapper's IDbConnection.Query except: /// <list type="bullet"> /// <item><description>It manages (obtains, opens, closes and returns) the database connection itself</description></item> /// <item><description>Data will be progressively loaded as the result is iterated through (i.e. buffered=false in Dapper).</description></item> /// <item><description>Transient errors are automatically retried, up to and including the first row (only)</description></item> /// <item><description>Transactions are not supported (in order to support retries)</description></item> /// </list> /// </summary> /// <typeparam name="T"></typeparam> /// <param name="goc"></param> /// <param name="sql"></param> /// <param name="param"></param> /// <param name="commandTimeout"></param> /// <param name="commandType"></param> /// <returns>An enumerable of the results. This must either be fully iterated or disposed of to avoid a resource leak. Using foreach will automatically dispose. It can only be iterated through once.</returns> /// <remarks>Once the first value has been returned any transient errors will not be retried. Ideally the caller would be carrying out an idempotent operation and would retry from the beginning. /// Transient errors can be detected with "new SqlDatabaseTransientErrorDetectionStrategy().IsTransient(ex)"</remarks> public static IEnumerable <T> QueryProgressive <T>(this IGetOpenConnection goc, string sql, object param = null, int?commandTimeout = default(int?), CommandType?commandType = default(CommandType?)) { // TODO: Log that user did this query IDbConnection conn = null; IEnumerator <T> enumerator = null; try { var hasFirstRecord = RetryPolicy.ExecuteAction <bool>(() => { conn = goc.GetOpenConnection(); var results = conn.Query <T>(sql, param, transaction: null, buffered: false, commandTimeout: commandTimeout, commandType: commandType); enumerator = results.GetEnumerator(); return(enumerator.MoveNext()); }); Debug.Assert(enumerator != null); if (hasFirstRecord) { yield return(enumerator.Current); } while (enumerator.MoveNext()) { yield return(enumerator.Current); } } finally { if (enumerator != null) { enumerator.Dispose(); } if (conn != null) { conn.Dispose(); } } }
public FullTransactionlessSyncContext(ILogService log, IGetOpenConnection sourceDatabase, IGetOpenConnection targetDatabase) : base(log, sourceDatabase, targetDatabase) { /* * ALTER DATABASE LSC_MI_MS_CRM_Staging * SET CHANGE_TRACKING = ON * (CHANGE_RETENTION = 2 DAYS, AUTO_CLEANUP = ON) * * USE LSC_MI_MS_CRM_Staging * EXEC sp_MSforeachtable 'ALTER TABLE ? ENABLE CHANGE_TRACKING' * * GRANT VIEW CHANGE TRACKING ON SCHEMA ::dbo TO MSSQLReadOnly */ var version = _sourceDatabase.Query <long?>($"SELECT CHANGE_TRACKING_CURRENT_VERSION() AS ver").Single(); if (version == null) { throw new FatalException("Change tracking not enabled on source database"); } _nextSyncVersion = version.Value; }
public CandidateUserUpdater(IConfigurationService configurationService, ILogService logService) { _logService = logService; var configuration = configurationService.Get <MigrateFromFaaToAvmsPlusConfiguration>(); _targetDatabase = new GetOpenConnectionFromConnectionString(configuration.TargetConnectionString); _candidateMappers = new CandidateMappers(logService); _candidateUserRepository = new CandidateUserRepository(configurationService, logService); _userRepository = new UserRepository(configurationService, logService); _candidateRepository = new CandidateRepository(_targetDatabase); _schoolAttendedRepository = new SchoolAttendedRepository(_targetDatabase); _candidateHistoryRepository = new CandidateHistoryRepository(_targetDatabase); _applicationRepository = new ApplicationRepository(_targetDatabase); _vacancyLocalAuthorities = new Lazy <IDictionary <string, int> >(() => new VacancyRepository(_targetDatabase).GetAllVacancyLocalAuthorities()); _localAuthorityCountyIds = new Lazy <IDictionary <int, int> >(() => new LocalAuthorityRepository(_targetDatabase).GetLocalAuthorityCountyIds()); _anonymiseData = configuration.AnonymiseData; }
/// <summary> /// Execute a query. Very similar to Dapper's IDbConnection.Query except: /// <list type="bullet"> /// <item><description>It manages (obtains, opens, closes and returns) the database connection itself</description></item> /// <item><description>The result is always entirely loaded and returned as an IList ("buffered" cannot be set to false)</description></item> /// <item><description>Transient errors are automatically retried</description></item> /// <item><description>Transactions are not supported (in order to support retries)</description></item> /// </list> /// </summary> /// <typeparam name="TFirst"></typeparam> /// <typeparam name="TSecond"></typeparam> /// <typeparam name="TReturn"></typeparam> /// <param name="goc"></param> /// <param name="sql"></param> /// <param name="map"></param> /// <param name="param"></param> /// <param name="splitOn"></param> /// <param name="commandTimeout"></param> /// <param name="commandType"></param> /// <returns></returns> public static IList <TReturn> Query <TFirst, TSecond, TReturn>(this IGetOpenConnection goc, string sql, Func <TFirst, TSecond, TReturn> map, object param = null, string splitOn = "Id", int?commandTimeout = default(int?), CommandType?commandType = default(CommandType?)) { // TODO: Log that user did this query return(RetryPolicy.ExecuteAction <IList <TReturn> >(() => { using (var conn = goc.GetOpenConnection()) { try { return (IList <TReturn>) conn.Query <TFirst, TSecond, TReturn>(sql, map, param, transaction: null, buffered: true, commandTimeout: commandTimeout, commandType: commandType, splitOn: splitOn); } catch (Exception ex) { throw ex; } } } )); }
public ReportingRepository(IGetOpenConnection getOpenConnection, ILogService logger) { _getOpenConnection = getOpenConnection; _logger = logger; }
public VacancyRepository(IGetOpenConnection getOpenConnection) { _getOpenConnection = getOpenConnection; }
public VacancyLocationRepository(IGetOpenConnection getOpenConnection, IMapper mapper, ILogService logger) { _getOpenConnection = getOpenConnection; _mapper = mapper; _logger = logger; }
/* * public ApprenticeshipVacancyRepository( * IConfigurationService configurationService, * IMapper mapper, * ILogService logger) * { * var config = configurationService.Get<MongoConfiguration>(); * * Initialise(config.VacancyDb, "apprenticeshipVacancies"); * * _mapper = mapper; * _logger = logger; * } */ public ApprenticeshipVacancyRepository(IGetOpenConnection getOpenConnection, IMapper mapper, ILogService logger) { _getOpenConnection = getOpenConnection; _mapper = mapper; _logger = logger; }
/// <summary> /// Return cached data for the query and associated parameters if available, otherwise query the data and add it to the cache. In the query case /// it is very similar to Dapper's IDbConnection.Query except: /// <list type="bullet"> /// <item><description>It manages (obtains, opens, closes and returns) the database connection itself</description></item> /// <item><description>The result is always entirely loaded and returned as an IList ("buffered" cannot be set to false)</description></item> /// <item><description>Transient errors are automatically retried</description></item> /// <item><description>Transactions are not supported (in order to support retries)</description></item> /// </list> /// </summary> /// <typeparam name="TFirst"></typeparam> /// <typeparam name="TSecond"></typeparam> /// <typeparam name="TReturn"></typeparam> /// <param name="goc"></param> /// <param name="cacheDuration">This is advisory only. It end up being cached for less time (perhaps due to memory limitations) or longer /// (perhaps if the query fails, or is slow).</param> /// <param name="sql"></param> /// <param name="map"></param> /// <param name="param"></param> /// <param name="splitOn"></param> /// <param name="commandTimeout"></param> /// <param name="commandType"></param> /// <returns></returns> /// <remarks>Once the first value has been returned any transient errors will not be retried. Ideally the caller would be carrying out an idempotent operation and would retry from the beginning.</remarks> public static IList <TReturn> QueryCached <TFirst, TSecond, TReturn>(this IGetOpenConnection goc, TimeSpan cacheDuration, string sql, Func <TFirst, TSecond, TReturn> map, object param = null, string splitOn = "Id", int?commandTimeout = default(int?), CommandType?commandType = default(CommandType?)) { // TODO: Implement caching. Consider using older values in case of error / slow response return(goc.Query <TFirst, TSecond, TReturn>(sql, map, param, splitOn, commandTimeout, commandType)); }
/// <summary> /// Return cached data for the query and associated parameters if available, otherwise query the data and add it to the cache. In the query case /// it is very similar to Dapper's IDbConnection.Query except: /// <list type="bullet"> /// <item><description>It manages (obtains, opens, closes and returns) the database connection itself</description></item> /// <item><description>The result is always entirely loaded and returned as an IList ("buffered" cannot be set to false)</description></item> /// <item><description>Transient errors are automatically retried</description></item> /// <item><description>Transactions are not supported (in order to support retries)</description></item> /// </list> /// </summary> /// <typeparam name="T"></typeparam> /// <param name="goc"></param> /// <param name="cacheDuration">This is advisory only. It end up being cached for less time (perhaps due to memory limitations) or longer /// (perhaps if the query fails, or is slow).</param> /// <param name="sql"></param> /// <param name="param"></param> /// <param name="commandTimeout"></param> /// <param name="commandType"></param> /// <returns></returns> /// <remarks>Once the first value has been returned any transient errors will not be retried. Ideally the caller would be carrying out an idempotent operation and would retry from the beginning.</remarks> public static IList <T> QueryCached <T>(this IGetOpenConnection goc, TimeSpan cacheDuration, string sql, object param = null, int?commandTimeout = default(int?), CommandType?commandType = default(CommandType?)) { // TODO: Implement caching. Consider using older values in case of error / slow response return(goc.Query <T>(sql, param, commandTimeout, commandType)); }
public ApiUserRepository(IGetOpenConnection getOpenConnection, IConfigurationService configurationService) { _getOpenConnection = getOpenConnection; _configurationService = configurationService; }
public AgencyUserRepository(IGetOpenConnection getOpenConnection, IMapper mapper, ILogService logger) { _getOpenConnection = getOpenConnection; _mapper = mapper; _logger = logger; }
public CandidateHistoryRepository(IGetOpenConnection getOpenConnection) { _getOpenConnection = getOpenConnection; }