///<inheritdoc/> public override void RunVersionScripts( IDbConnection connection, IDbTransaction transaction, List <string> dbVersions, string workingPath, string targetVersion, NonTransactionalContext nonTransactionalContext, List <KeyValuePair <string, string> > tokenKeyPairs = null, string bulkSeparator = null, string metaSchemaName = null, string metaTableName = null, int?commandTimeout = null, int?bulkBatchSize = null, string appliedByTool = null, string appliedByToolVersion = null, string environmentCode = null ) { //excludes all versions already executed var versionDirectories = _directoryService.GetDirectories(workingPath, "v*.*") .Where(v => !dbVersions.Contains(new DirectoryInfo(v).Name)) .ToList(); //exclude all versions greater than the target version if (!string.IsNullOrEmpty(targetVersion)) { versionDirectories.RemoveAll(v => { var cv = new LocalVersion(new DirectoryInfo(v).Name); var tv = new LocalVersion(targetVersion); return(string.Compare(cv.SemVersion, tv.SemVersion) == 1); }); } //execute all sql scripts in the version folders if (versionDirectories.Any()) { versionDirectories.Sort(); versionDirectories.ForEach(versionDirectory => { var versionName = new DirectoryInfo(versionDirectory).Name; //run scripts in all sub-directories var scriptSubDirectories = _directoryService.GetAllDirectories(versionDirectory, "*").ToList(); scriptSubDirectories.Sort(); scriptSubDirectories.ForEach(scriptSubDirectory => { //run all scripts in the current version folder RunSqlScripts(connection, transaction, nonTransactionalContext, versionName, workingPath, scriptSubDirectory, metaSchemaName, metaTableName, tokenKeyPairs, commandTimeout, environmentCode); //import csv files into tables of the the same filename as the csv RunBulkImport(connection, transaction, workingPath, scriptSubDirectory, bulkSeparator, bulkBatchSize, commandTimeout, environmentCode); }); //run all scripts in the current version folder RunSqlScripts(connection, transaction, nonTransactionalContext, versionName, workingPath, versionDirectory, metaSchemaName, metaTableName, tokenKeyPairs, commandTimeout, environmentCode); //import csv files into tables of the the same filename as the csv RunBulkImport(connection, transaction, workingPath, versionDirectory, bulkSeparator, bulkBatchSize, commandTimeout, environmentCode); //update db version _configurationDataService.InsertVersion(connection, transaction, versionName, metaSchemaName: metaSchemaName, metaTableName: metaTableName, commandTimeout: commandTimeout, appliedByTool: appliedByTool, appliedByToolVersion: appliedByToolVersion); _traceService.Info($"Completed migration to version {versionDirectory}"); }); } else { var connectionInfo = _dataService.GetConnectionInfo(); _traceService.Info($"Target database is updated. No migration step executed at {connectionInfo.Database} on {connectionInfo.DataSource}."); } }
private void RunVersionScripts( IDbConnection connection, IDbTransaction transaction, List <string> dbVersions, string workingPath, string targetVersion, List <KeyValuePair <string, string> > tokenKeyPairs = null, string delimiter = null, string schemaName = null, string tableName = null, int?commandTimeout = null, int?batchSize = null, string appliedByTool = null, string appliedByToolVersion = null, string environmentCode = null ) { //excludes all versions already executed var versionDirectories = _directoryService.GetDirectories(workingPath, "v*.*") .Where(v => !dbVersions.Contains(new DirectoryInfo(v).Name)) .ToList(); //exclude all versions greater than the target version if (!string.IsNullOrEmpty(targetVersion)) { versionDirectories.RemoveAll(v => { var cv = new LocalVersion(new DirectoryInfo(v).Name); var tv = new LocalVersion(targetVersion); return(string.Compare(cv.SemVersion, tv.SemVersion) == 1); }); } //execute all sql scripts in the version folders if (versionDirectories.Any()) { versionDirectories.Sort(); versionDirectories.ForEach(versionDirectory => { try { //run scripts in all sub-directories List <string> scriptSubDirectories = null; //check for transaction directory bool isExplicitTransactionDefined = false; string transactionDirectory = Path.Combine(versionDirectory, "_transaction"); if (_directoryService.Exists(transactionDirectory)) { if (_dataService.IsAtomicDDLSupported) { throw new YuniqlMigrationException(@$ "The version directory " "{versionDirectory}" " can't contain " "_transaction" " subdirectory for selected target platform, because the whole migration is already running in single transaction."); } if (_directoryService.GetDirectories(versionDirectory, "*").Count() > 1) { throw new YuniqlMigrationException(@$ "The version directory " "{versionDirectory}" " containing " "_transaction" " subdirectory can't contain other subdirectories"); } else if (_directoryService.GetFiles(versionDirectory, "*.*").Count() > 0) { throw new YuniqlMigrationException(@$ "The version directory " "{versionDirectory}" " containing " "_transaction" " subdirectory can't contain files"); } isExplicitTransactionDefined = true; scriptSubDirectories = _directoryService.GetAllDirectories(transactionDirectory, "*").ToList(); } else { scriptSubDirectories = _directoryService.GetAllDirectories(versionDirectory, "*").ToList(); } if (isExplicitTransactionDefined) { string versionName = new DirectoryInfo(versionDirectory).Name; //run scripts within a single transaction _traceService.Info(@$ "The " "_transaction" " directory has been detected and therefore " "{versionName}" " version scripts will run in single transaction. The rollback will not be reliable in case the version scripts contain commands causing implicit commit (e.g. DDL)!"); using (var transaction = connection.BeginTransaction()) { try { RunVersionScriptsInternal(scriptSubDirectories, versionDirectory); transaction.Commit(); _traceService.Info(@$ "Target database has been commited after running " "{versionName}" " version scripts."); } catch (Exception) { _traceService.Error(@$ "Target database will be rolled back to the state before running " "{versionName}" " version scripts."); transaction.Rollback(); throw; } } } else //run scripts without transaction { RunVersionScriptsInternal(scriptSubDirectories, versionDirectory); } } catch (Exception) { throw; } }); } else { var connectionInfo = _dataService.GetConnectionInfo(); _traceService.Info($"Target database is updated. No migration step executed at {connectionInfo.Database} on {connectionInfo.DataSource}."); } void RunVersionScriptsInternal(List <string> scriptSubDirectories, string versionDirectory) { scriptSubDirectories.Sort(); scriptSubDirectories.ForEach(scriptSubDirectory => { //run all scripts in the current version folder RunSqlScripts(connection, transaction, workingPath, scriptSubDirectory, tokenKeyPairs, commandTimeout, environmentCode); //import csv files into tables of the the same filename as the csv RunBulkImport(connection, transaction, workingPath, scriptSubDirectory, delimiter, batchSize, commandTimeout, environmentCode); }); //run all scripts in the current version folder RunSqlScripts(connection, transaction, workingPath, versionDirectory, tokenKeyPairs, commandTimeout, environmentCode); //import csv files into tables of the the same filename as the csv RunBulkImport(connection, transaction, workingPath, versionDirectory, delimiter, batchSize, commandTimeout, environmentCode); //update db version var versionName = new DirectoryInfo(versionDirectory).Name; _configurationDataService.InsertVersion(connection, transaction, versionName, schemaName: schemaName, tableName: tableName, commandTimeout: commandTimeout, appliedByTool: appliedByTool, appliedByToolVersion: appliedByToolVersion); _traceService.Info($"Completed migration to version {versionDirectory}"); } }