public void Reload(ProjectConfigItem projectConfig)
        {
            projectConfig.ThrowIfNull(nameof(projectConfig));

            using (ArtifactExtractor _currentArtifactExtractor = _artifactExtractorFactory.Create(projectConfig))
            {
                using (var dbCommands = _dbCommandsFactory.CreateDBCommand(projectConfig.DBConnectionInfo))
                {
                    IncrementalScriptFilesComparer = _scriptFilesComparerFactory.CreateScriptFilesComparer <IncrementalScriptFileType>(dbCommands, projectConfig.IncrementalScriptsFolderPath);
                    ScriptFilesComparers[IncrementalScriptFilesComparer.ScriptFileType.FileTypeCode] = IncrementalScriptFilesComparer;

                    RepeatableScriptFilesComparer = _scriptFilesComparerFactory.CreateScriptFilesComparer <RepeatableScriptFileType>(dbCommands, projectConfig.RepeatableScriptsFolderPath);
                    ScriptFilesComparers[RepeatableScriptFilesComparer.ScriptFileType.FileTypeCode] = RepeatableScriptFilesComparer;

                    if (projectConfig.DevEnvironment)
                    {
                        DevDummyDataScriptFilesComparer = _scriptFilesComparerFactory.CreateScriptFilesComparer <DevDummyDataScriptFileType>(dbCommands, projectConfig.DevDummyDataScriptsFolderPath);
                        ScriptFilesComparers[DevDummyDataScriptFilesComparer.ScriptFileType.FileTypeCode] = DevDummyDataScriptFilesComparer;
                    }
                    else
                    {
                        DevDummyDataScriptFilesComparer = null;
                    }
                }
            }
        }
        public override void Execute(DBVersionsProcessContext processContext)
        {
            processContext.ThrowIfNull(nameof(processContext));

            using (var dbCommands = _dbCommandsFactory.CreateDBCommand(processContext.ProjectConfig.DBConnectionInfo))
            {
                DataSet dsExecutionHistory = dbCommands.GetScriptsExecutionHistoryTableStructureFromDB();

                DataTable dbScriptsExecutionHistoryTable      = dsExecutionHistory.Tables[DBCommandsConsts.DBScriptsExecutionHistoryFullTableName];
                DataTable dbScriptsExecutionHistoryFilesTable = dsExecutionHistory.Tables[DBCommandsConsts.DBScriptsExecutionHistoryFilesFullTableName];

                processContext.EndProcessDateTime = DateTime.Now;

                DataRow executionHistoryRow = dbScriptsExecutionHistoryTable.NewRow();

                executionHistoryRow["DBScriptsExecutionHistoryID"] = 0;

                executionHistoryRow["StartProcessDateTime"] = processContext.StartProcessDateTime;
                executionHistoryRow["ExecutionTypeName"]    = processContext.ProcessDefinition.EngineTypeName;
                executionHistoryRow["EndProcessDateTime"]   = processContext.EndProcessDateTime;
                executionHistoryRow["ProcessDurationInMs"]  = processContext.ProcessDurationInMs;
                executionHistoryRow["NumOfScriptFiles"]     = processContext.ExecutedFiles.Count;
                executionHistoryRow["DBBackupFileFullPath"] = processContext.DBBackupFileFullPath;
                executionHistoryRow["IsVirtualExecution"]   = processContext.IsVirtualExecution;

                dbScriptsExecutionHistoryTable.Rows.Add(executionHistoryRow);
                dbCommands.UpdateScriptsExecutionHistoryTableToDB(dbScriptsExecutionHistoryTable);


                foreach (var executedFiles in processContext.ExecutedFiles)
                {
                    DataRow newFileRow = dbScriptsExecutionHistoryFilesTable.NewRow();

                    newFileRow["DBScriptsExecutionHistoryID"] = 0;
                    newFileRow["ExecutedDateTime"]            = DateTime.Now;
                    newFileRow["Filename"]                 = executedFiles.Filename;
                    newFileRow["FileFullPath"]             = executedFiles.FileFullPath;
                    newFileRow["ScriptFileType"]           = executedFiles.ScriptFileType.FileTypeCode;
                    newFileRow["IsVirtualExecution"]       = processContext.IsVirtualExecution;
                    newFileRow["ComputedFileHash"]         = executedFiles.ComputedHash;
                    newFileRow["ComputedFileHashDateTime"] = executedFiles.ComputedHashDateTime;


                    dbScriptsExecutionHistoryFilesTable.Rows.Add(newFileRow);
                }


                int currDBScriptsExecutionHistoryID = Convert.ToInt32(executionHistoryRow["DBScriptsExecutionHistoryID"], CultureInfo.InvariantCulture);

                foreach (DataRow fileRow in dbScriptsExecutionHistoryFilesTable.Rows)
                {
                    fileRow["DBScriptsExecutionHistoryID"] = currDBScriptsExecutionHistoryID;
                }

                dbCommands.UpdateScriptsExecutionHistoryFilesTableToDB(dbScriptsExecutionHistoryFilesTable);
            }
        }
Beispiel #3
0
        public override void Execute(DBVersionsProcessContext processContext)
        {
            processContext.ThrowIfNull(nameof(processContext));

            using (var dbCommands = _dbCommandsFactory.CreateDBCommand(processContext.ProjectConfig.DBConnectionInfo))
            {
                dbCommands.RecreateDBVersionsTables();
            }

            processContext.ScriptFilesState.Reload(processContext.ProjectConfig);
        }
Beispiel #4
0
        public NumOfDBConnections GetNumOfOpenConnection(DBConnectionInfo dbConnectionInfo)
        {
            NumOfDBConnections numOfConnectionsItem = new NumOfDBConnections();

            string masterDBName;

            using (var dbCommands = _dbCommandsFactory.CreateDBCommand(dbConnectionInfo))
            {
                masterDBName = dbCommands.DataBaseName;
            }


            using (var dbCommands = _dbCommandsFactory.CreateDBCommand(dbConnectionInfo))
            {
                numOfConnectionsItem.DBName = dbCommands.DataBaseName;
            }

            using (var dbQueryStatus = _dbCommandsFactory.CreateDBQueryStatus(dbConnectionInfo))
            {
                numOfConnectionsItem.NumOfConnectionsToDB      = dbQueryStatus.GetNumOfOpenConnection(numOfConnectionsItem.DBName);
                numOfConnectionsItem.NumOfConnectionsToAdminDB = dbQueryStatus.GetNumOfOpenConnection(masterDBName);
            }

            return(numOfConnectionsItem);
        }
Beispiel #5
0
        public override void Execute(DBVersionsProcessContext processContext)
        {
            processContext.ThrowIfNull(nameof(processContext));

            if (!processContext.ProjectConfig.DevEnvironment)
            {
                throw new Exception(CoreTextResources.CantDropDBOnDelEnvException);
            }

            using (var dbCommands = _dbCommandsFactory.CreateDBCommand(processContext.ProjectConfig.DBConnectionInfo))
            {
                dbCommands.DropAllDBObject();
            }
        }
Beispiel #6
0
        public override void Execute(DBVersionsProcessContext processContext)
        {
            processContext.ThrowIfNull(nameof(processContext));


            using (ArtifactExtractor _currentArtifactExtractor = _artifactExtractorFactory.Create(processContext.ProjectConfig))
            {
                List <ActionStepBase> internalSteps = new List <ActionStepBase>();

                using (var dbCommands = _dbCommandsFactory.CreateDBCommand(processContext.ProjectConfig.DBConnectionInfo))
                {
                    ScriptFileTypeBase       incrementalFileType = ScriptFileTypeBase.Create <IncrementalScriptFileType>();
                    ExecuteScriptsByTypeStep incrementalExecuteScriptsByTypeStep = _executeScriptsByTypeStepFactory.Create(incrementalFileType.FileTypeCode, dbCommands);
                    internalSteps.Add(incrementalExecuteScriptsByTypeStep);


                    string lastIncStriptFilename = GetLastIncFilename(processContext);

                    TargetScripts targetScripts = null;
                    if (processContext.ProcessArgs != null)
                    {
                        targetScripts = (processContext.ProcessArgs as DBVersionsProcessArgs).TargetScripts;
                    }

                    //Comment: We run the repeatable files and ddd files, onlyif we have all the schema on the DB. mean, only if we executed all incremiental files.
                    if (targetScripts.IncScriptFileName.Trim().ToUpperInvariant() == lastIncStriptFilename.Trim().ToUpperInvariant() ||
                        targetScripts.IncScriptFileName.Trim().ToUpperInvariant() == RuntimeScriptFile.TargetLastScriptFileName.Trim().ToUpperInvariant())
                    {
                        ScriptFileTypeBase       repeatableFileType = ScriptFileTypeBase.Create <RepeatableScriptFileType>();
                        ExecuteScriptsByTypeStep repeatableFileTypeExecuteScriptsByTypeStep = _executeScriptsByTypeStepFactory.Create(repeatableFileType.FileTypeCode, dbCommands);
                        internalSteps.Add(repeatableFileTypeExecuteScriptsByTypeStep);


                        if (processContext.ScriptFilesState.DevDummyDataScriptFilesComparer != null)
                        {
                            ScriptFileTypeBase       devDummyDataFileType = ScriptFileTypeBase.Create <DevDummyDataScriptFileType>();
                            ExecuteScriptsByTypeStep devDummyDataFileTypeExecuteScriptsByTypeStep = _executeScriptsByTypeStepFactory.Create(devDummyDataFileType.FileTypeCode, dbCommands);
                            internalSteps.Add(devDummyDataFileTypeExecuteScriptsByTypeStep);
                        }
                    }


                    ExecuteInternalSteps(internalSteps, false);
                }
            }
        }
        public override void Execute(DBVersionsProcessContext processContext)
        {
            processContext.ThrowIfNull(nameof(processContext));


            if (processContext.ScriptFilesState.DevDummyDataScriptFilesComparer != null)
            {
                using (var dbCommands = _dbCommandsFactory.CreateDBCommand(processContext.ProjectConfig.DBConnectionInfo))
                {
                    List <ActionStepBase> internalSteps = new List <ActionStepBase>();

                    (processContext.ProcessDefinition as DBVersionsProcessDefinition).IsVirtualExecution = true;

                    ScriptFileTypeBase       devDummyDataFileType = ScriptFileTypeBase.Create <DevDummyDataScriptFileType>();
                    ExecuteScriptsByTypeStep devDummyDataFileTypeExecuteScriptsByTypeStep = _executeScriptsByTypeStepFactory.Create(devDummyDataFileType.FileTypeCode, dbCommands);
                    internalSteps.Add(devDummyDataFileTypeExecuteScriptsByTypeStep);

                    ExecuteInternalSteps(internalSteps, false);
                }
            }
        }
Beispiel #8
0
        public override string Validate()
        {
            using (var dbCommands = _dbCommandsFactory.CreateDBCommand(_dbConnectionInfo))
            {
                if (!dbCommands.CheckIfTableExist(DBCommandsConsts.DBSchemaName, DBCommandsConsts.DBScriptsExecutionHistoryTableName) &&
                    !dbCommands.CheckIfTableExist(DBCommandsConsts.DBSchemaName, DBCommandsConsts.DBScriptsExecutionHistoryFilesTableName))
                {
                    if (_isDevEnvironment)
                    {
                        if (_scriptFilesState.IncrementalScriptFilesComparer.AllFileSystemScriptFiles.Count == 0 &&
                            _scriptFilesState.RepeatableScriptFilesComparer.AllFileSystemScriptFiles.Count == 0 &&
                            _scriptFilesState.DevDummyDataScriptFilesComparer.AllFileSystemScriptFiles.Count == 0)
                        {
                            _errorInstructionsMessage = CoreTextResources.NewProjectDevEnvInstructionsMessage;
                            return(CoreTextResources.NewProjectDevEnvErrorMessage);
                        }
                    }
                    else
                    {
                        if (_scriptFilesState.IncrementalScriptFilesComparer.AllFileSystemScriptFiles.Count == 0 &&
                            _scriptFilesState.RepeatableScriptFilesComparer.AllFileSystemScriptFiles.Count == 0)
                        {
                            //Comment: this message could be confusing, because it can popup when the user deploy an artifact file, but empty one
                            //TODO: change the following message
                            _errorInstructionsMessage = CoreTextResources.NewProjectDeliveryEnvNoscriptsFilesInstructionsMessage;
                            string errorMsg = CoreTextResources.NewProjectDeliveryEnvNoscriptsFilesEnvErrorMessage;
                            return(errorMsg);
                        }
                        else
                        {
                            _errorInstructionsMessage = CoreTextResources.NewProjectDeliveryEnvInstructionsMessage;
                            return(CoreTextResources.NewProjectDeliveryEnvErrorMessage);
                        }
                    }
                }
            }


            return("");
        }
Beispiel #9
0
        public override void Execute(DBVersionsProcessContext processContext)
        {
            processContext.ThrowIfNull(nameof(processContext));

            using (var dbCommands = _dbCommandsFactory.CreateDBCommand(processContext.ProjectConfig.DBConnectionInfo))
            {
                string dbName = dbCommands.DataBaseName;


                string tempFolderForDeploy = Path.Combine(_settings.TempFolderPath, $"Deploy_{dbName}_{DateTime.Now:HH-mm-dd-fff}");
                if (!Directory.Exists(tempFolderForDeploy))
                {
                    Directory.CreateDirectory(tempFolderForDeploy);
                }



                ScriptFileTypeBase incrementalScriptFileType = ScriptFileTypeBase.Create <IncrementalScriptFileType>();

                string incrementalSubFolderToDeploy = Path.Combine(tempFolderForDeploy, incrementalScriptFileType.RelativeFolderName);
                if (!Directory.Exists(incrementalSubFolderToDeploy))
                {
                    Directory.CreateDirectory(incrementalSubFolderToDeploy);
                }

                DirectoryInfo diIncremental = new DirectoryInfo(processContext.ProjectConfig.IncrementalScriptsFolderPath);
                foreach (FileInfo scriptFileToCopy in diIncremental.GetFiles())
                {
                    string targetFilename = Path.Combine(incrementalSubFolderToDeploy, scriptFileToCopy.Name);
                    scriptFileToCopy.CopyTo(targetFilename, true);
                }


                ScriptFileTypeBase repeatableScriptFileType = ScriptFileTypeBase.Create <RepeatableScriptFileType>();

                string repeatableSubFolderToDeploy = Path.Combine(tempFolderForDeploy, repeatableScriptFileType.RelativeFolderName);
                if (!Directory.Exists(repeatableSubFolderToDeploy))
                {
                    Directory.CreateDirectory(repeatableSubFolderToDeploy);
                }

                DirectoryInfo diRepeatable = new DirectoryInfo(processContext.ProjectConfig.RepeatableScriptsFolderPath);
                foreach (FileInfo scriptFileToCopy in diRepeatable.GetFiles())
                {
                    string targetFilename = Path.Combine(repeatableSubFolderToDeploy, scriptFileToCopy.Name);
                    scriptFileToCopy.CopyTo(targetFilename, true);
                }



                if (!Directory.Exists(processContext.ProjectConfig.DeployArtifactFolderPath))
                {
                    Directory.CreateDirectory(processContext.ProjectConfig.DeployArtifactFolderPath);
                }

                string targetFileFullPath = Path.Combine(processContext.ProjectConfig.DeployArtifactFolderPath, $"{dbName}{ArtifactExtractor.ArtifactFilenameExtension}");

                if (File.Exists(targetFileFullPath))
                {
                    File.Delete(targetFileFullPath);
                }

                ZipFile.CreateFromDirectory(tempFolderForDeploy, targetFileFullPath);

                processContext.Results = targetFileFullPath;
            }
        }
        public override void Execute(DBVersionsProcessContext processContext)
        {
            processContext.ThrowIfNull(nameof(processContext));

            string timeStampStr = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss", CultureInfo.InvariantCulture);

            string targetFileName;

            using (var dbCommands = _dbCommandsFactory.CreateDBCommand(processContext.ProjectConfig.DBConnectionInfo))
            {
                targetFileName = $"bu_{ dbCommands.DataBaseName}_{timeStampStr}.bak";
            }

            string targetFileFullPath = Path.Combine(processContext.ProjectConfig.BackupFolderPath, targetFileName);

            FileSystemPathUtils.ResloveFilePath(targetFileFullPath);

            //notificationExecutersProvider.SetStepStartManually(100, "Backup process");

            using (var dbBackupStatusNotifyer = _dbCommandsFactory.CreateDBProcessStatusNotifyer(typeof(DBBackupStatusNotifyer), processContext.ProjectConfig.DBConnectionInfo).AsDisposable())
            {
                //DBProcessStatusNotifyerBase dbBackupStatusNotifyer = _dbProcessStatusNotifyerFactory.Create(, dbQueryStatus.Instance) as DBBackupStatusNotifyer;

                List <ActionStepBase> internalSteps = new List <ActionStepBase>();

                for (int internalStepNumber = 1; internalStepNumber <= 100; internalStepNumber++)
                {
                    ExternalProcessStatusStep externalProcessStatusStep = new ExternalProcessStatusStep(internalStepNumber);
                    internalSteps.Add(externalProcessStatusStep);
                }

                Exception processExpetion = null;


                dbBackupStatusNotifyer.Instance.Start(
                    (precents) =>
                {
                    //notificationExecutersProvider.ForceStepProgress(Convert.ToInt32(precents));

                    foreach (ExternalProcessStatusStep step in internalSteps)
                    {
                        if (!step.IsCompleted)
                        {
                            step.SetProcessState((int)Math.Floor(precents), processExpetion);
                        }
                    }
                });

                Task.Run(() =>
                {
                    try
                    {
                        using (var dbCommands = _dbCommandsFactory.CreateDBCommand(processContext.ProjectConfig.DBConnectionInfo))
                        {
                            using (var dbBackupRestoreCommands = _dbCommandsFactory.CreateDBBackupRestoreCommands(processContext.ProjectConfig.DBConnectionInfo))
                            {
                                dbBackupRestoreCommands.CreateDBBackup(targetFileFullPath, dbCommands.DataBaseName);

                                foreach (ExternalProcessStatusStep step in internalSteps)
                                {
                                    if (!step.IsCompleted)
                                    {
                                        step.SetProcessState(100, processExpetion);
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        processExpetion = ex;
                    }
                });

                ExecuteInternalSteps(internalSteps, false);

                dbBackupStatusNotifyer.Instance.Stop();

                if (processExpetion != null)
                {
                    throw processExpetion; //new Exception("CreateBackupStep", processExpetion);
                }

                processContext.DBBackupFileFullPath = targetFileFullPath;
            }
        }
Beispiel #11
0
        public override void Execute(DBVersionsProcessContext processContext)
        {
            processContext.ThrowIfNull(nameof(processContext));


            //notificationExecutersProvider.SetStepStartManually(100, "Restore process");

            using (var dbRestoreStatusNotifyer = _dbCommandsFactory.CreateDBProcessStatusNotifyer(typeof(DBRestoreStatusNotifyer), processContext.ProjectConfig.DBConnectionInfo).AsDisposable())
            {
                List <ActionStepBase> internalSteps = new List <ActionStepBase>();

                for (int internalStepNumber = 1; internalStepNumber <= 100; internalStepNumber++)
                {
                    ExternalProcessStatusStep externalProcessStatusStep = new ExternalProcessStatusStep(internalStepNumber);
                    internalSteps.Add(externalProcessStatusStep);
                }

                Exception processExpetion = null;


                dbRestoreStatusNotifyer.Instance.Start((precents) =>
                {
                    // notificationExecutersProvider.ForceStepProgress(Convert.ToInt32(precents));

                    foreach (ExternalProcessStatusStep step in internalSteps)
                    {
                        if (!step.IsCompleted)
                        {
                            step.SetProcessState((int)Math.Floor(precents), processExpetion);
                        }
                    }
                });

                Task.Run(() =>
                {
                    try
                    {
                        using (var dbCommands = _dbCommandsFactory.CreateDBCommand(processContext.ProjectConfig.DBConnectionInfo))
                        {
                            using (var dbBackupRestoreCommands = _dbCommandsFactory.CreateDBBackupRestoreCommands(processContext.ProjectConfig.DBConnectionInfo))
                            {
                                dbBackupRestoreCommands.RestoreDBFromBackup(processContext.DBBackupFileFullPath, dbCommands.DataBaseName);

                                foreach (ExternalProcessStatusStep step in internalSteps)
                                {
                                    if (!step.IsCompleted)
                                    {
                                        step.SetProcessState(100, processExpetion);
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        processExpetion = new NotificationProcessException(StepName, ex.Message, CoreTextResources.RestoreDBFailInstructionsMessage, NotificationErrorType.Error, ex);
                    }
                });

                ExecuteInternalSteps(internalSteps, true);

                dbRestoreStatusNotifyer.Instance.Stop();
            }
        }
        public override string Validate()
        {
            using (var dbCommands = _dbCommandsFactory.CreateDBCommand(_dbConnectionInfo))
            {
                if (!dbCommands.CheckIfTableExist(DBCommandsConsts.DBSchemaName, DBCommandsConsts.DBScriptsExecutionHistoryTableName))
                {
                    return(CoreTextResources.TableNotExistErrorMessage.Replace("[TableName]", DBCommandsConsts.DBScriptsExecutionHistoryFullTableName));
                }

                if (!dbCommands.CheckIfTableExist(DBCommandsConsts.DBSchemaName, DBCommandsConsts.DBScriptsExecutionHistoryFilesTableName))
                {
                    return(CoreTextResources.TableNotExistErrorMessage.Replace("[TableName]", DBCommandsConsts.DBScriptsExecutionHistoryFilesTableName));
                }


                DataSet systemTablesSetFromDB = dbCommands.GetScriptsExecutionHistoryTableStructureFromDB();

                DataTable scriptsExecutionHistoryTableFromDB = systemTablesSetFromDB.Tables[DBCommandsConsts.DBScriptsExecutionHistoryFullTableName];

                using (DataTable scriptsExecutionHistoryTableFromStructure = CreateScriptsExecutionHistoryTableStructure())
                {
                    foreach (DataColumn colFromStruct in scriptsExecutionHistoryTableFromStructure.Columns)
                    {
                        if (!scriptsExecutionHistoryTableFromDB.Columns.Contains(colFromStruct.ColumnName))
                        {
                            return(CoreTextResources
                                   .TableMissingColumnErrorMessage
                                   .Replace("[TableName]", DBCommandsConsts.DBScriptsExecutionHistoryFullTableName)
                                   .Replace("[ColumnName]", colFromStruct.ColumnName));
                        }
                        else
                        {
                            DataColumn colFromDB = scriptsExecutionHistoryTableFromDB.Columns[colFromStruct.ColumnName];
                            if (colFromDB.DataType != colFromStruct.DataType)
                            {
                                return(CoreTextResources
                                       .TableColumnIvalidTypeErrorMessage
                                       .Replace("[ColumnName]", colFromStruct.ColumnName)
                                       .Replace("[DBDataType]", colFromDB.DataType.Name)
                                       .Replace("[StructDataType]", colFromStruct.DataType.Name)
                                       .Replace("[TableName]", DBCommandsConsts.DBScriptsExecutionHistoryFullTableName));
                            }
                        }
                    }
                }


                DataTable scriptsExecutionHistoryFilesTableFromDB = systemTablesSetFromDB.Tables[DBCommandsConsts.DBScriptsExecutionHistoryFilesFullTableName];

                using (DataTable scriptsExecutionHistoryFilesTableFromStructure = CreateScriptsExecutionHistoryFilesTableStructure())
                {
                    foreach (DataColumn colFromStruct in scriptsExecutionHistoryFilesTableFromStructure.Columns)
                    {
                        if (!scriptsExecutionHistoryFilesTableFromDB.Columns.Contains(colFromStruct.ColumnName))
                        {
                            return(CoreTextResources
                                   .TableMissingColumnErrorMessage
                                   .Replace("[TableName]", DBCommandsConsts.DBScriptsExecutionHistoryFilesFullTableName)
                                   .Replace("[ColumnName]", colFromStruct.ColumnName));
                        }
                        else
                        {
                            DataColumn colFromDB = scriptsExecutionHistoryFilesTableFromStructure.Columns[colFromStruct.ColumnName];
                            if (colFromDB.DataType != colFromStruct.DataType)
                            {
                                return(CoreTextResources
                                       .TableColumnIvalidTypeErrorMessage
                                       .Replace("[ColumnName]", colFromStruct.ColumnName)
                                       .Replace("[DBDataType]", colFromDB.DataType.Name)
                                       .Replace("[StructDataType]", colFromStruct.DataType.Name)
                                       .Replace("[TableName]", DBCommandsConsts.DBScriptsExecutionHistoryFilesFullTableName));
                            }
                        }
                    }
                }
            }



            return("");
        }