Поставщик настраиваемых сценариев dbup - необходимо добавить значение к именам сценариев журнала - PullRequest
0 голосов
/ 16 июня 2020

Я создаю пользовательский ScriptProvider, реализующий интерфейс IScriptProvider в dbup, и я могу получить список скриптов с помощью метода GetScripts() и вернуть объект SqlScript. Я хотел бы сначала скомпилировать объект, а затем, прежде чем возвращать его, изменить имя каждого скрипта, добавив текущий выпуск к имени файла, который вставляется в таблицу журнала.

Насколько я понимаю, это должно быть выполнимым, поскольку содержимое сценария уже добавлено к объекту SqlScript при его заполнении, похоже, что изменение имени в этот момент ни на что не повлияет.

Проблема, с которой я столкнулся заключается в том, что свойство Name объекта SqlScript доступно только для чтения, поэтому я не могу изменить его напрямую, как хотелось бы.

Как я могу обойти это, или есть другой способ, которым я мог бы скомпилируйте сценарии для выполнения и ведения журнала, а затем перед записью имен сценариев в таблицу журнала добавьте значение к имени сценария.

Например, Script001 становится Release 1.0.0 - Script001.

Мне также нужно было бы удалить это значение при чтении ранее выполненных скриптов, чтобы убедиться, что они соответствуют фактическим именам файлов и не получают выполняется снова.

ОБНОВЛЕНИЕ

namespace DbUpManifest
{
public class DeploymentManifestScriptProvider : IScriptProvider
{
    readonly string directoryPath;
    readonly string basePath;
    readonly Func<string, bool> filter;
    readonly Encoding encoding;
    readonly FileSystemScriptOptions options;
    public string Release;
    public List<string> FileList;        


    public DeploymentManifestScriptProvider(string basePath, string directoryPath, FileSystemScriptOptions options) 
    {
        if (options == null)
            throw new ArgumentNullException("options");
        this.options = options;
        this.directoryPath = directoryPath;
        this.basePath = basePath;
    }

    private List<string> SerializeJsonFile()
    {
        Manifest manifest;
        var files = new List<string>();

        using (StreamReader file = File.OpenText(directoryPath))
        {
            JsonSerializer serializer = new JsonSerializer();
            manifest = (Manifest)serializer.Deserialize(file, typeof(Manifest));
        }

        Release = manifest.Release.ToString();

        foreach (var item in manifest.Scripts)
        {
            string thisItem;
            if(Debugger.IsAttached)
            {
                thisItem = string.Concat(basePath, @"Deployment Scripts\vNext\", item);
            }
            else
            {
                thisItem = string.Concat(basePath, @"Deployment Scripts\", Release, @"\", item);
            }

            FileAttributes attr = File.GetAttributes(thisItem);

            foreach (var scriptExtension in options.Extensions)
            {
                if ((attr & FileAttributes.Directory) == FileAttributes.Directory)
                {
                    files.AddRange(Directory.GetFiles(thisItem, scriptExtension, ShouldSearchSubDirectories()));
                }
                else
                {
                    files.Add(thisItem.ToString());
                }
            }
        }


        foreach (var item in manifest.StoredProcedures)
        {
            string thisItem = string.Concat(basePath, "Stored Procedures", "\\", item);

            FileAttributes attr = File.GetAttributes(thisItem);

            foreach (var scriptExtension in options.Extensions)
            {
                 files.Add(thisItem.ToString());
            }
        }

        return files;
    }        

    public IEnumerable<SqlScript> GetScripts(IConnectionManager connectionManager)
    {
        List<string> scripts = SerializeJsonFile();

        var outputFiles = scripts.Select(x => SqlScript.FromFile(x))
           .OrderBy(x => x.Name)
           .ToList();

        return outputFiles;
    }

    SearchOption ShouldSearchSubDirectories()
    {
        return options.IncludeSubDirectories ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
    }
}

}

Я попытался изменить это, чтобы добавить выпуск к имени файла, но затем он ошибки, говорящие, что он не может найти файл, потому что физический файл фактически не назван с добавленной строкой.

var outputFiles = scripts.Select(x => SqlScript.FromFile(String.Concat(Release," - ", x)))
       .OrderBy(x => x.Name)
       .ToList();

В конечном итоге я хочу иметь файл манифеста, который запускает сценарии развертывания как сценарии типа «запускать один раз», а затем я хочу поддерживать единую версию таких вещей, как сохраненные процессы и представления, и иметь манифест файл определяет, какие из этих сценариев запускаются при каждом развертывании, поэтому мы не отбрасываем и воссоздаем каждую сохраненную версию pro c, что мы сейчас и делаем.

Проблема в том, что у меня есть выбор либо использовать NullJournal и ничего не записывать в БД, либо сохраненные процессы не будут выполняться более одного раза, потому что они всегда будут называться одинаковыми.

Попытка придумать другие способы выполнения это тоже, но пока у меня ничего нет.

В идеальном мире я бы хотел, чтобы физический файл dbo.StoredProcedure.sql регистрировался как Release 1.0.0 - dbo.StoredProcedure.sql. Таким образом, если этот spro c изменится в будущем, он будет выполнен и сохранен как Release 2.0.0 - dbo.StoredProcedure.sql или какой-либо другой выпуск, в котором он находится. Но физический файл всегда представляет собой только один файл с тем же именем во времени / выпусках.

...