public void SqlScriptParserErrorComment()
        {
            using (ShimsContext.Create())
              {
            int i = 0;
            System.IO.Fakes.ShimStreamReader.ConstructorStringEncoding = (@this, path, encoding) => { };
            System.IO.Fakes.ShimStreamReader.AllInstances.ReadLine = delegate { return i++ == 0 ? "*//*" : null; };

            // Начало теста.
            SqlScriptParser parser = new SqlScriptParser(@"C:\Test.sql");
              }
        }
        protected override ActionResult DoWorkDeferred()
        {
            ActionResult result = ActionResult.Success;

              // Получаем и десериализуем данные.
              ActionRunSqlScriptWorkerSavedData[] data = Session.
            GetService<ISessionSerializeCustomActionDataExtension>().DeserializeCustomActionData<ActionRunSqlScriptWorkerSavedData[]>(GetType().Name);
              if (data == null || data.Length == 0)
            return ActionResult.Success;

              DatabaseInfo[] databases = GetDatabases();

              foreach (DatabaseInfo database in databases)
              {
            // Для каждой базы данных для разных Worker будем использовать
            // только одно соединение. Это нужно для оптимизации подключения
            // и необходимо для работы с однопользовательским режимом, чтобы
            // в моменыт подключение/отключения не подсоединился какой-нибудь
            // другой процесс MS SQL (фоновый или пользователя).
            ISqlWorkerConnection connection;
            SqlWorkerBase connectioWorker = Factory.CreateSqlCreateConnectionWorker(database.Server, database.Name,
              AuthenticationType.Windows, "", "", out connection);

            RunSqlScriptBefore(database.Server, database.Name, connection);

            try
            {
              // Каждый скрипт выполняем для каждой базы.
              foreach (ActionRunSqlScriptWorkerSavedData d in data.Where(v => v.Server == database.Server && v.Database == database.Name).OrderBy(v => v.Sequence))
              {
            // Для отображения в UI.
            // При отмене инсталляции, может выскочить исключение InstallCanceledException
            // при вызове Session.Message(). Если это случилось, обработаем его в блоке catch.
            UpdateActionDescription(d.Name, database.Name);

            if (!File.Exists(d.Path))
              throw new FileNotFoundException();

            // Читаем полностью скрипт, разбивая его на подскрипты.
            SqlScriptParser parser = new SqlScriptParser(d.Path);

            SqlWorkerBase worker = Factory.CreateSqlRunScriptWorker(connection, parser, OnSqlWorkerProgress);
            worker.Execute();
              }
            }
            catch (Exception ex)
            {
              if (ex is InstallCanceledException)
            result = ActionResult.UserExit;
              // Если произошел сбой, вызываем специальный метод.
              RunSqlScriptFault(database.Server, database.Name, connection, ex);
            }

            RunSqlScriptAfter(database.Server, database.Name, connection);

            // Закрываем соединение.
            connectioWorker.Execute();
              }

              // Удаляем файл.
              foreach (string d in data.Select(v => v.Path).Distinct())
            File.Delete(d);

              return result;
        }
        public void SqlScriptParserSuccessful()
        {
            using (ShimsContext.Create())
              {
            int i = 0; // Текущий указатель на считываемую строку.
            System.IO.Fakes.ShimStreamReader.ConstructorStringEncoding = (@this, path, encoding) => { };
            System.IO.Fakes.ShimStreamReader.AllInstances.ReadLine = delegate
            {
              string[] str = query.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
              return str.Length > i ? str[i++] : null;
            };

            // Начало теста.
            SqlScriptParser parser = new SqlScriptParser(@"C:\Test.sql");
            Assert.AreEqual(expected.Length, parser.Queries.Length);
            for (int j = 0; j < expected.Length; j++)
              Assert.AreEqual(expected[j], parser.Queries[j]);
              }
        }