public void Manages_database()
		{
			var settings = new ConnectionSettings("server", "db", true, null, null);
            var scriptDirectory = @"c:\scripts"; 
            var taskAttributes = new TaskAttributes(settings, scriptDirectory);

			var mocks = new MockRepository();
			var taskObserver = mocks.CreateMock<ITaskObserver>();
			var generator = mocks.CreateMock<ILogMessageGenerator>();
			var factory = mocks.CreateMock<IDatabaseActionExecutorFactory>();

			var creator = mocks.CreateMock<IDatabaseActionExecutor>();
			var updater = mocks.CreateMock<IDatabaseActionExecutor>();

			var executors = new IDatabaseActionExecutor[] { creator, updater };

			using (mocks.Record())
			{
				Expect.Call(generator.GetInitialMessage(taskAttributes)).Return("starting...");
				taskObserver.Log("starting...");
				Expect.Call(factory.GetExecutors(RequestedDatabaseAction.Create)).Return(executors);

                creator.Execute(taskAttributes, taskObserver);
                updater.Execute(taskAttributes, taskObserver);
			}

			using (mocks.Playback())
			{
				ISqlDatabaseManager manager = new SqlDatabaseManager(generator, factory);

				manager.Upgrade(taskAttributes, taskObserver);
			}

			mocks.VerifyAll();
		}
	    public void Execute(TaskAttributes taskAttributes, ITaskObserver taskObserver)
		{
            string sql = string.Format("create database [{0}]", taskAttributes.ConnectionSettings.Database);
            _queryExecutor.ExecuteNonQuery(taskAttributes.ConnectionSettings, sql, false);

            _folderExecutor.ExecuteScriptsInFolder(taskAttributes, "ExistingSchema", taskObserver);
		}
		public void Should_not_fail_if_datebase_does_not_exist()
		{
			var settings = new ConnectionSettings("server", "db", true, null, null);
            var taskAttributes = new TaskAttributes(settings, null);

			var mocks = new MockRepository();
			var connectionDropper = mocks.DynamicMock<IDatabaseConnectionDropper>();
			var taskObserver = mocks.CreateMock<ITaskObserver>();
			var queryExecutor = mocks.CreateMock<IQueryExecutor>();

			using (mocks.Record())
			{
                Expect.Call(() => queryExecutor.ExecuteNonQuery(settings, "ALTER DATABASE [db] SET SINGLE_USER WITH ROLLBACK IMMEDIATE drop database [db]", false))
					.Throw(new Exception("foo message"));
				Expect.Call(() => taskObserver.Log("Database 'db' could not be dropped."));
			}

			using (mocks.Playback())
			{
				IDatabaseActionExecutor dropper = new DatabaseDropper(connectionDropper, queryExecutor);
                dropper.Execute(taskAttributes, taskObserver);
			}

			mocks.VerifyAll();
		}
        public bool UpdateDatabase(ConnectionSettings settings, string scriptDirectory, RequestedDatabaseAction action)
        {
            var manager = new SqlDatabaseManager();
            
            var taskAttributes = new TaskAttributes(settings, scriptDirectory)
                                     {
                                         RequestedDatabaseAction = action,
                                     };
            try
            {
                manager.Upgrade(taskAttributes, this);

                foreach (var property in _properties)
                {
                    Log(property.Key +": " + property.Value);
                }
                return true;
            }
            catch (Exception exception)
            {                
                var ex = exception;
                do
                {
                    Log("Failure: " + ex.Message);
                    ex = ex.InnerException;    
                } while (ex!=null);

                //Log(exception.ToString());
                

            }
            return false;
        }
		public void Drops_database()
		{
			var settings = new ConnectionSettings("server", "db", true, null, null);
            var taskAttributes = new TaskAttributes(settings, null);

			var mocks = new MockRepository();
			var connectionDropper = mocks.CreateMock<IDatabaseConnectionDropper>();
			var taskObserver = mocks.CreateMock<ITaskObserver>();
			var queryExecutor = mocks.CreateMock<IQueryExecutor>();
            
			using (mocks.Record())
			{
				connectionDropper.Drop(settings, taskObserver);
                
                queryExecutor.ExecuteNonQuery(settings, "ALTER DATABASE [db] SET SINGLE_USER WITH ROLLBACK IMMEDIATE drop database [db]", false);
			    
			}

			using (mocks.Playback())
			{
				IDatabaseActionExecutor dropper = new DatabaseDropper(connectionDropper, queryExecutor);
				dropper.Execute(taskAttributes, taskObserver);
			}

			mocks.VerifyAll();
		}
		public void Creates_initial_log_message_for_database_drop()
		{
			ILogMessageGenerator generator = new LogMessageGenerator();

			var settings = new ConnectionSettings("server", "db", true, null, null);
            var taskAttributes = new TaskAttributes(settings, "c:\\scripts") {RequestedDatabaseAction = RequestedDatabaseAction.Drop};
			string message = generator.GetInitialMessage(taskAttributes);

			Assert.That(message, Is.EqualTo("Drop db on server\n"));
		}
        public void Creates_initial_log_message_for_database_create_while_skiping_some_files()
        {
            ILogMessageGenerator generator = new LogMessageGenerator();

            var settings = new ConnectionSettings("server", "db", true, null, null);
            var taskAttributes = new TaskAttributes(settings, "c:\\scripts") { SkipFileNameContaining = "_data_"};
            string message = generator.GetInitialMessage(taskAttributes);

            Assert.That(message, Is.EqualTo("Create db on server using scripts from c:\\scripts while skipping file containing _data_\n"));
        }
		public void Creates_initial_log_message_for_database_create()
		{
			ILogMessageGenerator generator = new LogMessageGenerator();

			var settings = new ConnectionSettings("server", "db", true, null, null);
            var taskAttributes = new TaskAttributes(settings, "c:\\scripts");
			string message = generator.GetInitialMessage(taskAttributes);

			Assert.That(message, Is.EqualTo("Create db on server using scripts from c:\\scripts\n"));
		}
	    public void Upgrade(TaskAttributes taskAttributes, ITaskObserver taskObserver)
		{
            string initializationMessage = _logMessageGenerator.GetInitialMessage(taskAttributes);
			taskObserver.Log(initializationMessage);

            IEnumerable<IDatabaseActionExecutor> executors = _actionExecutorFactory.GetExecutors(taskAttributes.RequestedDatabaseAction);

			foreach (IDatabaseActionExecutor executor in executors)
			{
                executor.Execute(taskAttributes, taskObserver);
			}
		}
	    public void Execute(TaskAttributes taskAttributes, ITaskObserver taskObserver)
		{
	               _connectionDropper.Drop(taskAttributes.ConnectionSettings, taskObserver);
			var sql = string.Format("ALTER DATABASE [{0}] SET SINGLE_USER WITH ROLLBACK IMMEDIATE drop database [{0}]", taskAttributes.ConnectionSettings.Database);

			try
			{
                _queryExecutor.ExecuteNonQuery(taskAttributes.ConnectionSettings, sql, false);
			}
			catch(Exception)
			{
				taskObserver.Log(string.Format("Database '{0}' could not be dropped.", taskAttributes.ConnectionSettings.Database));
			}
		}
		public string GetInitialMessage(TaskAttributes taskAttributes)
		{
            var scriptFolder = taskAttributes.RequestedDatabaseAction != RequestedDatabaseAction.Drop
															? string.Format(" using scripts from {0}", taskAttributes.ScriptDirectory)
															: string.Empty;

		    var skipFiles = !string.IsNullOrEmpty(taskAttributes.SkipFileNameContaining)
		                        ? string.Format(" while skipping file containing {0}",taskAttributes.SkipFileNameContaining)
		                        : string.Empty;

            var logMessage = string.Format("{0} {1} on {2}{3}{4}\n", taskAttributes.RequestedDatabaseAction,taskAttributes.ConnectionSettings.Database, taskAttributes.ConnectionSettings.Server, scriptFolder,skipFiles);

			return logMessage;
		}
	    public void ExecuteScriptsInFolder(TaskAttributes taskAttributes, string scriptDirectory, ITaskObserver taskObserver)
		{
            _schemaInitializer.EnsureSchemaCreated(taskAttributes.ConnectionSettings);
            
            var sqlFilenames = _fileLocator.GetSqlFilenames(taskAttributes.ScriptDirectory, scriptDirectory);
            
            var filteredFilenames = _fileFilterService.GetFilteredFilenames(sqlFilenames, taskAttributes.SkipFileNameContaining);
            
			foreach (string sqlFilename in filteredFilenames)
			{
                _scriptExecutor.Execute(sqlFilename, taskAttributes.ConnectionSettings, taskObserver);
			}

            _versioner.VersionDatabase(taskAttributes.ConnectionSettings, taskObserver);
		}
        protected override void ExecuteTask()
		{
			try
			{
			    var manager = new SqlDatabaseManager();
                var settings = new ConnectionSettings(Server, Database, IntegratedAuthentication, Username, Password);
                var taskAttributes = new TaskAttributes(settings, ScriptDirectory.FullName)
                                         {
                                             SkipFileNameContaining = SkipFileNameContaining,
                                             RequestedDatabaseAction = Action,
                                         };

                manager.Upgrade(taskAttributes, this);
			}
			catch
			{
				if (FailOnError)
					throw;
			}
		}
		public void Updates_database()
		{
			var settings = new ConnectionSettings("server", "db", true, null, null);
            var taskAttributes = new TaskAttributes(settings, "c:\\scripts");

			var mocks = new MockRepository();
			var executor = mocks.CreateMock<IScriptFolderExecutor>();
			var taskObserver = mocks.CreateMock<ITaskObserver>();

			using (mocks.Record())
			{
				executor.ExecuteScriptsInFolder(taskAttributes, "Update", taskObserver);
			}

			using (mocks.Playback())
			{
				IDatabaseActionExecutor updater = new DatabaseUpdater(executor);
                updater.Execute(taskAttributes, taskObserver);
			}

			mocks.VerifyAll();
		}
        public void Executes_only_filtereded_scripts_within_a_folder()
        {
            var settings = new ConnectionSettings("server", "db", true, null, null);
            var sqlFiles = new[] { "c:\\scripts\\Update\\001.sql", "c:\\scripts\\Update\\002_data_.sql", "c:\\scripts\\Update\\003.sql" };
            var filteredFiles = new[] { "c:\\scripts\\Update\\001.sql", "c:\\scripts\\Update\\003.sql" };
            var taskAttributes = new TaskAttributes(settings, "c:\\scripts")
            {
                RequestedDatabaseAction = RequestedDatabaseAction.Update,
                SkipFileNameContaining = "_data_"
            };

            var mocks = new MockRepository();
            var initializer = mocks.CreateMock<ISchemaInitializer>();
            var fileLocator = mocks.CreateMock<ISqlFileLocator>();
            var executor = mocks.CreateMock<IChangeScriptExecutor>();
            var versioner = mocks.CreateMock<IDatabaseVersioner>();
            var taskObserver = mocks.CreateMock<ITaskObserver>();
            var fileFilterService = mocks.CreateMock<IFileFilterService>();

            using (mocks.Record())
            {
                initializer.EnsureSchemaCreated(settings);
                Expect.Call(fileLocator.GetSqlFilenames("c:\\scripts", "Update")).Return(sqlFiles);
                Expect.Call(fileFilterService.GetFilteredFilenames(sqlFiles, "_data_")).Return(filteredFiles);
                executor.Execute("c:\\scripts\\Update\\001.sql", settings, taskObserver);
                executor.Execute("c:\\scripts\\Update\\003.sql", settings, taskObserver);
                versioner.VersionDatabase(settings, taskObserver);
            }

            using (mocks.Playback())
            {
                IScriptFolderExecutor folderExecutor = new ScriptFolderExecutor(initializer, fileLocator, executor, versioner, fileFilterService);
                folderExecutor.ExecuteScriptsInFolder(taskAttributes, "Update", taskObserver);
            }

            mocks.VerifyAll();
        }
		public void Creates_database()
		{
			var settings = new ConnectionSettings("server", "db", true, null, null);
            var taskAttributes = new TaskAttributes(settings, "c:\\scripts");

			var mocks = new MockRepository();
			var queryExecutor = mocks.CreateMock<IQueryExecutor>();
			var executor = mocks.CreateMock<IScriptFolderExecutor>();
			var taskObserver = mocks.CreateMock<ITaskObserver>();
			
			using (mocks.Record())
			{
				queryExecutor.ExecuteNonQuery(settings, "create database [db]", false);
				executor.ExecuteScriptsInFolder(taskAttributes, "ExistingSchema", taskObserver);
			}

			using (mocks.Playback())
			{
				IDatabaseActionExecutor creator = new DatabaseCreator(queryExecutor, executor);
				creator.Execute(taskAttributes, taskObserver);
			}

			mocks.VerifyAll();
		}
		public void Execute(TaskAttributes taskAttributes, ITaskObserver taskObserver)
		{
            _folderExecutor.ExecuteScriptsInFolder(taskAttributes, "Update", taskObserver);
		}