private void CreateSettingUpdater_FormClosing(object sender, FormClosingEventArgs e) { if ((e.CloseReason != CloseReason.UserClosing & e.CloseReason != CloseReason.None) || this.DialogResult != DialogResult.OK) { return; } if (errorTracker.Count != 0) { Dialogs.ErrorF(this, errorTracker.ToString()); e.Cancel = true; if (editLink != null) { ItemsInSets.Add(editLink); } return; } DbTypeItem dbItem = (DbTypeItem)cmbDbConectionType.SelectedItem; int?taskId = null; int tid; if (int.TryParse(tbNumberTask.Text, out tid)) { taskId = tid; } // формируем настройку для получения настроек TfsDbLink newLink = editLink ?? new TfsDbLink(); newLink.Name = tbSettingName.Text; newLink.ServerUri = new Uri(tbTfsProject.Text); newLink.ServerPathToSettings = tbSetFileServerFolder.Text + "/" + tbFileNameSet.Text; // Собираем и пакуем настройки накатки var newSet = new UpdateDbSetting(); newSet.ServerPathScripts = tbFolderForScripts.Text; newSet.TypeConnectionFullName = dbItem.ConType.ToString(); newSet.AssemplyWithImplementDbConnection = dbItem.AssembyRawBytes; newSet.ConnectionStringModelDb = tbConnectionString.Text; newSet.ScriptPartBeforeBodyWithTran = tbPartBeforescript.Text.GetNullIfIsNullOrWhiteSpace(); newSet.ScriptPartAfterBodyWithTran = tbPartAfterScript.Text.GetNullIfIsNullOrWhiteSpace(); newSet.ScriptUpdateVer = tbScriptUpdateVer.Text.GetNullIfIsNullOrWhiteSpace(); newSet.FormatBinary = new FormatBinaryData() { Prefix = tbFormatBinPrefix.Text, FormatByte = tbFormatBinFormat.Text }; var encodedSetting = newSet.SerializeAesEncrypt(newLink.ServerPathToSettings); string fileNameSet = tbFileNameSet.Text; try { using (var tfsbl = new TFSRoutineBL()) { var localFileSetPath = Path.Combine(tfsbl.Tempdir, fileNameSet); tfsbl.VersionControl(new Uri(tbTfsProject.Text)); tfsbl.MapTempWorkspace(tbSetFileServerFolder.Text); tfsbl.GetLastFile(fileNameSet); var fileExist = File.Exists(localFileSetPath); if (fileExist && !tfsbl.CheckOut(localFileSetPath)) { throw new Exception("Извлечение настроек неуспешно. Повторите позже"); } // блокируем от изменений if (fileExist && !tfsbl.LockFile(fileNameSet)) { throw new Exception("Производится сохранение настроек другим пользователем."); } // если есть - удаляем if (fileExist) { File.Delete(localFileSetPath); } // записываем новый File.WriteAllBytes(localFileSetPath, encodedSetting); if (!fileExist) { tfsbl.AddFile(localFileSetPath); } List <int> linkedTask = new List <int>(); if (taskId.HasValue) { linkedTask.Add(taskId.Value); } tfsbl.CheckIn("Добавленение настроек версионности", linkedTask); } if (editLink == null) { this.ItemsInSets.Add(newLink); } } catch (Exception ex) { String msg = ex.Expand(); if (ex.GetType().Name == "TargetInvocationException" && ex.InnerException != null) { msg = ex.InnerException.Message; } Dialogs.ErrorF(this, "Сохранение неуспешно" + Environment.NewLine + msg); e.Cancel = true; } }
/// <summary> /// Накатить скрипт /// </summary> /// <param name="tdlink">Настройка связки TFS-DB</param> /// <param name="sqlScript">Тело скрипта</param> /// <param name="comment">Комментарий к заливке</param> /// <returns></returns> public String SaveScript( TfsDbLink tdlink, String sqlScript, String comment, Boolean inTaransaction, List <int> linkedTask) { try { if (comment.IsNullOrWhiteSpace()) { return("Необходимо заполнить комментрарий"); } if (sqlScript.IsNullOrWhiteSpace()) { return("Тело скрипта пустое"); } if (checkSqlScriptOnUSE(sqlScript)) { return("В скрипте используется USE БД."); } if (!linkedTask.Any()) { return("Для накатки необходимо привязать задачу."); } Func <String, String> trimLines = (a) => { a = a.Trim(); var colStr = a.Split(new string[] { Environment.NewLine }, StringSplitOptions.None); for (int i = 0; i < colStr.Length; i++) { colStr[i] = colStr[i].TrimEnd(); } return(colStr.JoinValuesToString(Environment.NewLine, false)); }; // причесываем текстовки sqlScript = trimLines(sqlScript); comment = trimLines(comment); var commentforSQL = "--" + comment.Replace(Environment.NewLine, Environment.NewLine + "--") + Environment.NewLine; UpdateDbSetting upsets = null; bool useSqlConnection = false; using (TFSRoutineBL tfsbl = new TFSRoutineBL()) { // Проверяем переданные соединения с TFS и БД // Проверяем настройки TFS SendStat("Подключаемся к TFS"); tfsbl.VersionControl(tdlink.ServerUri); SendStat("Получение настроек поднятия версии."); var tempfile = Path.Combine(DomainContext.TempPath, Guid.NewGuid().ToString()); tfsbl.DownloadFile(tdlink.ServerPathToSettings, tempfile); try { upsets = File.ReadAllBytes(tempfile).DeserializeAesDecrypt <UpdateDbSetting>(tdlink.ServerPathToSettings); } catch (Exception ex) { String msg = ex.Expand(); if (ex.GetType().Name == "TargetInvocationException" && ex.InnerException != null) { msg = ex.InnerException.Message; } return("Получение файла настроек неуспешно. Exception: " + msg); } if (upsets == null || upsets.ServerPathScripts.IsNullOrWhiteSpace()) { return("Получение файла настроек неуспешно"); } SendStat("Получение типа соединения"); Type conn = typeof(SqlConnection); useSqlConnection = true; if (upsets.TypeConnectionFullName != conn.ToString()) { if (upsets.AssemplyWithImplementDbConnection == null) { return($"В настроках указан тип DbConnection '{upsets.TypeConnectionFullName}', но отсутствует бинарное представление сборки реализации"); } conn = null; Assembly conAss = null; foreach (var asmly in AppDomain.CurrentDomain.GetAssemblies()) { conn = asmly.GetType(upsets.TypeConnectionFullName, false); if (conn != null) { conAss = asmly; break; } } if (conn == null) { conAss = AppDomain.CurrentDomain.Load(upsets.AssemplyWithImplementDbConnection); } conn = conAss.ExportedTypes.FirstOrDefault(x => x.FullName == upsets.TypeConnectionFullName); if (conn == null) { return($"Не удалось найти тип DbConnection '{upsets.TypeConnectionFullName}'"); } useSqlConnection = false; } SendStat("Проверка несохраненных данных в шельве"); if (tfsbl.ExistsShelveset()) { return($"В шельве присутствуют несохраненные изменения"); } SendStat("Подключаемся к БД"); DomainContext.InitConnection(conn, upsets.ConnectionStringModelDb); tfsbl.MapTempWorkspace(upsets.ServerPathScripts); // TODO Проверить скрип на корректность // В частности, отсутствие USE. Ещеб как нить замутить просто проверку, а не выполнение SendStat("Обработка файла версионности"); String VerFileName = "_lastVer.xml"; String PathVerFile = Path.Combine(tfsbl.Tempdir, VerFileName); if (tfsbl.GetLastFile(VerFileName) == 0) { //файла нет if (!File.Exists(PathVerFile)) { // сохраняем новую чистую версию ДБ (new VerDB()).XMLSerialize(PathVerFile); tfsbl.AddFile(PathVerFile); tfsbl.CheckIn("Добавлен файл версионности", linkedTask); } } if (!tfsbl.LockFile(VerFileName)) { return("Производится накатка. Повторите позже"); } if (!tfsbl.CheckOut(PathVerFile)) { return("Извлечение файла текущей версии неуспешно. Повторите позже"); } var CurVerDB = PathVerFile.XMLDeserializeFromFile <VerDB>() ?? new VerDB(); CurVerDB.VersionBD += 1; CurVerDB.DateVersion = new DateTimeOffset(DateTime.Now).DateTime; List <String> scts = new List <string>(); if (useSqlConnection) { scts.AddRange(SplitSqlTExtOnGO(sqlScript)); } else { scts.Add(sqlScript); } SendStat("Накатка скрипта на БД"); DbTransactionScope tran = null; try { if (inTaransaction) { tran = new DbTransactionScope(); } #region накатываем скрипты foreach (var sct in scts) { adapter.ExecScript(sct); } adapter.ExecScript(String.Format(upsets.ScriptUpdateVer, CurVerDB)); #endregion #region формируем файл и чекиним SendStat("Генерация файла скрипта"); var sb = new StringBuilder(); sb.AppendLine(commentforSQL); if (inTaransaction) { sb.AppendLine(upsets.ScriptPartBeforeBodyWithTran); } foreach (var item in scts) { var script = item; if (useSqlConnection) { script = "EXEC('" + script.Replace("'", "''") + "')"; } sb.AppendLine(script); } sb.AppendLine(String.Format(upsets.ScriptUpdateVer, CurVerDB)); if (inTaransaction) { sb.Append(upsets.ScriptPartAfterBodyWithTran); } String FileNameNewVer = Path.Combine(tfsbl.Tempdir, CurVerDB + ".sql"); File.WriteAllText(FileNameNewVer, sb.ToString()); CurVerDB.XMLSerialize(PathVerFile); tfsbl.AddFile(FileNameNewVer); SendStat("Кладем в шельву в TFS"); tfsbl.CreateShelveset(comment, linkedTask); if (tran != null) { tran.Complete(); ((IDisposable)tran).Dispose(); tran = null; } SendStat("Чекин в TFS"); tfsbl.CheckIn(comment, linkedTask); SendStat("Удаление шельвы в TFS"); tfsbl.DeleteShelveset(); SendStat("Готово"); #endregion } catch { throw; } finally { if (tran != null) { ((IDisposable)tran).Dispose(); } } } return(null); } catch (Exception ex) { String msg = ex.Expand(); if (ex.GetType().Name == "TargetInvocationException" && ex.InnerException != null) { msg = ex.InnerException.Message; } return(msg); } }