public void Can_Create_Document_Table()
        {
            using (var scope = ScopeProvider.CreateScope())
            {
                var helper = new DatabaseSchemaCreator(scope.Database, Mock.Of <ILogger>());

                helper.CreateTable <NodeDto>();
                helper.CreateTable <ContentTypeDto>();
                helper.CreateTable <ContentDto>();
                helper.CreateTable <TemplateDto>();
                helper.CreateTable <DocumentDto>();

                scope.Complete();
            }
        }
        public void Can_Create_PropertyData_Table()
        {
            using (var scope = ScopeProvider.CreateScope())
            {
                var helper = new DatabaseSchemaCreator(scope.Database, _loggerFactory.CreateLogger <DatabaseSchemaCreator>(), _loggerFactory, UmbracoVersion, EventAggregator);

                helper.CreateTable <NodeDto>();
                helper.CreateTable <ContentTypeDto>();
                helper.CreateTable <DataTypeDto>();
                helper.CreateTable <PropertyTypeGroupDto>();
                helper.CreateTable <PropertyTypeDto>();
                helper.CreateTable <PropertyDataDto>();

                scope.Complete();
            }
        }
Example #3
0
        public void Can_Create_PropertyData_Table()
        {
            using (var scope = ScopeProvider.CreateScope())
            {
                var helper = new DatabaseSchemaCreator(scope.Database, Mock.Of <ILogger>());

                helper.CreateTable <NodeDto>();
                helper.CreateTable <ContentTypeDto>();
                helper.CreateTable <DataTypeDto>();
                helper.CreateTable <PropertyTypeGroupDto>();
                helper.CreateTable <PropertyTypeDto>();
                helper.CreateTable <PropertyDataDto>();

                scope.Complete();
            }
        }
        /// <summary>
        /// Returns the <see cref="DatabaseSchemaResult"/> for the database
        /// </summary>
        /// <param name="database"></param>
        /// <param name="logger"></param>
        /// <returns></returns>
        public static DatabaseSchemaResult ValidateSchema(this IUmbracoDatabase database, ILogger logger)
        {
            if (database is null)
            {
                throw new ArgumentNullException(nameof(database));
            }
            if (logger is null)
            {
                throw new ArgumentNullException(nameof(logger));
            }

            var dbSchema = new DatabaseSchemaCreator(database, logger);
            var databaseSchemaValidationResult = dbSchema.ValidateSchema();

            return(databaseSchemaValidationResult);
        }
Example #5
0
        private void RebuildSchemaFirstTime(TestDbMeta meta)
        {
            _databaseFactory.Configure(meta.ConnectionString, Constants.DatabaseProviders.SqlServer);

            using (var database = (UmbracoDatabase)_databaseFactory.CreateDatabase())
            {
                database.LogCommands = true;

                using (NPoco.ITransaction transaction = database.GetTransaction())
                {
                    var schemaCreator = new DatabaseSchemaCreator(database, _loggerFactory.CreateLogger <DatabaseSchemaCreator>(), _loggerFactory, new UmbracoVersion(), Mock.Of <IEventAggregator>());
                    schemaCreator.InitializeDatabaseSchema();

                    transaction.Complete();

                    _cachedDatabaseInitCommands = database.Commands.ToArray();
                }
            }
        }
    public void DatabaseSchemaCreation_Produces_DatabaseSchemaResult_With_Zero_Errors()
    {
        DatabaseSchemaResult result;

        using (ScopeProvider.CreateScope(autoComplete: true))
        {
            var schema = new DatabaseSchemaCreator(
                ScopeAccessor.AmbientScope.Database,
                LoggerFactory.CreateLogger <DatabaseSchemaCreator>(),
                LoggerFactory,
                UmbracoVersion,
                EventAggregator,
                Mock.Of <IOptionsMonitor <InstallDefaultDataSettings> >(x =>
                                                                        x.CurrentValue == new InstallDefaultDataSettings()));
            schema.InitializeDatabaseSchema();
            result = schema.ValidateSchema(DatabaseSchemaCreator._orderedTables);
        }

        // Assert
        Assert.That(result.Errors.Count, Is.EqualTo(0));
    }
Example #7
0
        public void StandaloneTest()
        {
            IFactory factory = null;

            // clear
            foreach (var file in Directory.GetFiles(Path.Combine(IOHelper.MapPath("~/App_Data")), "NuCache.*"))
            {
                File.Delete(file);
            }

            // settings
            // reset the current version to 0.0.0, clear connection strings
            ConfigurationManager.AppSettings[Constants.AppSettings.ConfigurationStatus] = "";
            // FIXME: we need a better management of settings here (and, true config files?)

            // create the very basic and essential things we need
            var logger          = new ConsoleLogger();
            var profiler        = new LogProfiler(logger);
            var profilingLogger = new ProfilingLogger(logger, profiler);
            var appCaches       = new AppCaches(); // FIXME: has HttpRuntime stuff?
            var databaseFactory = new UmbracoDatabaseFactory(logger, new Lazy <IMapperCollection>(() => factory.GetInstance <IMapperCollection>()));
            var typeLoader      = new TypeLoader(appCaches.RuntimeCache, IOHelper.MapPath("~/App_Data/TEMP"), profilingLogger);
            var mainDom         = new SimpleMainDom();
            var runtimeState    = new RuntimeState(logger, null, null, new Lazy <IMainDom>(() => mainDom), new Lazy <IServerRegistrar>(() => factory.GetInstance <IServerRegistrar>()));

            // create the register and the composition
            var register    = RegisterFactory.Create();
            var composition = new Composition(register, typeLoader, profilingLogger, runtimeState);

            composition.RegisterEssentials(logger, profiler, profilingLogger, mainDom, appCaches, databaseFactory, typeLoader, runtimeState);

            // create the core runtime and have it compose itself
            var coreRuntime = new CoreRuntime();

            coreRuntime.Compose(composition);

            // determine actual runtime level
            runtimeState.DetermineRuntimeLevel(databaseFactory, logger);
            Console.WriteLine(runtimeState.Level);
            // going to be Install BUT we want to force components to be there (nucache etc)
            runtimeState.Level = RuntimeLevel.Run;

            var composerTypes = typeLoader.GetTypes <IComposer>()                                              // all of them
                                .Where(x => !x.FullName.StartsWith("Umbraco.Tests."))                          // exclude test components
                                .Where(x => x != typeof(WebInitialComposer) && x != typeof(WebFinalComposer)); // exclude web runtime
            var composers = new Composers(composition, composerTypes, Enumerable.Empty <Attribute>(), profilingLogger);

            composers.Compose();

            // must registers stuff that WebRuntimeComponent would register otherwise
            // FIXME: UmbracoContext creates a snapshot that it does not register with the accessor
            //  and so, we have to use the UmbracoContextPublishedSnapshotAccessor
            //  the UmbracoContext does not know about the accessor
            //  else that would be a catch-22 where they both know about each other?
            //composition.Register<IPublishedSnapshotAccessor, TestPublishedSnapshotAccessor>(Lifetime.Singleton);
            composition.Register <IPublishedSnapshotAccessor, UmbracoContextPublishedSnapshotAccessor>(Lifetime.Singleton);
            composition.Register <IUmbracoContextAccessor, TestUmbracoContextAccessor>(Lifetime.Singleton);
            composition.Register <IVariationContextAccessor, TestVariationContextAccessor>(Lifetime.Singleton);
            composition.Register <IDefaultCultureAccessor, TestDefaultCultureAccessor>(Lifetime.Singleton);
            composition.Register <ISiteDomainHelper>(_ => Mock.Of <ISiteDomainHelper>(), Lifetime.Singleton);
            composition.Register(_ => Mock.Of <IImageUrlGenerator>(), Lifetime.Singleton);
            composition.RegisterUnique(f => new DistributedCache());
            composition.WithCollectionBuilder <UrlProviderCollectionBuilder>().Append <DefaultUrlProvider>();
            composition.RegisterUnique <IDistributedCacheBinder, DistributedCacheBinder>();
            composition.RegisterUnique <IExamineManager>(f => ExamineManager.Instance);
            composition.RegisterUnique <IUmbracoContextFactory, UmbracoContextFactory>();
            composition.RegisterUnique <IMacroRenderer, MacroRenderer>();
            composition.RegisterUnique <MediaUrlProviderCollection>(_ => new MediaUrlProviderCollection(Enumerable.Empty <IMediaUrlProvider>()));

            // initialize some components only/individually
            composition.WithCollectionBuilder <ComponentCollectionBuilder>()
            .Clear()
            .Append <DistributedCacheBinderComponent>();

            // configure
            composition.Configs.Add(SettingsForTests.GetDefaultGlobalSettings);
            composition.Configs.Add(SettingsForTests.GetDefaultUmbracoSettings);

            // create and register the factory
            Current.Factory = factory = composition.CreateFactory();

            // instantiate and initialize components
            var components = factory.GetInstance <ComponentCollection>();

            // do stuff
            Console.WriteLine(runtimeState.Level);

            // install
            if (true || runtimeState.Level == RuntimeLevel.Install)
            {
                var path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
                var file = databaseFactory.Configured ? Path.Combine(path, "UmbracoNPocoTests.sdf") : Path.Combine(path, "Umbraco.sdf");
                if (File.Exists(file))
                {
                    File.Delete(file);
                }

                // create the database file
                // databaseBuilder.ConfigureEmbeddedDatabaseConnection() can do it too,
                // but then it wants to write the connection string to web.config = bad
                var connectionString = databaseFactory.Configured ? databaseFactory.ConnectionString : "Data Source=|DataDirectory|\\Umbraco.sdf;Flush Interval=1;";
                using (var engine = new SqlCeEngine(connectionString))
                {
                    engine.CreateDatabase();
                }

                //var databaseBuilder = factory.GetInstance<DatabaseBuilder>();
                //databaseFactory.Configure(DatabaseBuilder.EmbeddedDatabaseConnectionString, Constants.DbProviderNames.SqlCe);
                //databaseBuilder.CreateDatabaseSchemaAndData();

                if (!databaseFactory.Configured)
                {
                    databaseFactory.Configure(DatabaseBuilder.EmbeddedDatabaseConnectionString, Constants.DbProviderNames.SqlCe);
                }

                var scopeProvider = factory.GetInstance <IScopeProvider>();
                using (var scope = scopeProvider.CreateScope())
                {
                    var creator = new DatabaseSchemaCreator(scope.Database, logger);
                    creator.InitializeDatabaseSchema();
                    scope.Complete();
                }
            }

            // done installing
            runtimeState.Level = RuntimeLevel.Run;

            components.Initialize();

            // instantiate to register events
            // should be done by Initialize?
            // should we invoke Initialize?
            _ = factory.GetInstance <IPublishedSnapshotService>();

            // at that point, Umbraco can run!
            // though, we probably still need to figure out what depends on HttpContext...
            var contentService = factory.GetInstance <IContentService>();
            var content        = contentService.GetById(1234);

            Assert.IsNull(content);

            // create a document type and a document
            var contentType = new ContentType(-1)
            {
                Alias = "ctype", Name = "ctype"
            };

            factory.GetInstance <IContentTypeService>().Save(contentType);
            content = new Content("test", -1, contentType);
            contentService.Save(content);

            // assert that it is possible to get the document back
            content = contentService.GetById(content.Id);
            Assert.IsNotNull(content);
            Assert.AreEqual("test", content.Name);

            // need an UmbracoCOntext to access the cache
            // FIXME: not exactly pretty, should not depend on HttpContext
            var httpContext             = Mock.Of <HttpContextBase>();
            var umbracoContextFactory   = factory.GetInstance <IUmbracoContextFactory>();
            var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(httpContext);
            var umbracoContext          = umbracoContextReference.UmbracoContext;

            // assert that there is no published document
            var pcontent = umbracoContext.Content.GetById(content.Id);

            Assert.IsNull(pcontent);

            // but a draft document
            pcontent = umbracoContext.Content.GetById(true, content.Id);
            Assert.IsNotNull(pcontent);
            Assert.AreEqual("test", pcontent.Name());
            Assert.IsTrue(pcontent.IsDraft());

            // no published URL
            Assert.AreEqual("#", pcontent.Url());

            // now publish the document + make some unpublished changes
            contentService.SaveAndPublish(content);
            content.Name = "testx";
            contentService.Save(content);

            // assert that snapshot has been updated and there is now a published document
            pcontent = umbracoContext.Content.GetById(content.Id);
            Assert.IsNotNull(pcontent);
            Assert.AreEqual("test", pcontent.Name());
            Assert.IsFalse(pcontent.IsDraft());

            // but the URL is the published one - no draft URL
            Assert.AreEqual("/test/", pcontent.Url());

            // and also an updated draft document
            pcontent = umbracoContext.Content.GetById(true, content.Id);
            Assert.IsNotNull(pcontent);
            Assert.AreEqual("testx", pcontent.Name());
            Assert.IsTrue(pcontent.IsDraft());

            // and the published document has a URL
            Assert.AreEqual("/test/", pcontent.Url());

            umbracoContextReference.Dispose();
            mainDom.Stop();
            components.Terminate();

            // exit!
        }
Example #8
0
        private void DoUnattendedInstall(IUmbracoDatabaseFactory databaseFactory)
        {
            // unattended install is not enabled
            if (RuntimeOptions.InstallUnattended == false)
            {
                return;
            }

            var localVersion = UmbracoVersion.LocalVersion; // the local, files, version
            var codeVersion  = _state.SemanticVersion;      // the executing code version

            // local version and code version is not equal, an unattended install cannot be performed
            if (localVersion != codeVersion)
            {
                return;
            }

            // no connection string set
            if (databaseFactory.Configured == false)
            {
                return;
            }

            // create SQL CE database if not existing and database provider is SQL CE
            if (databaseFactory.ProviderName == Constants.DbProviderNames.SqlCe)
            {
                var dataSource = new SqlCeConnectionStringBuilder(databaseFactory.ConnectionString).DataSource;
                var dbFilePath = dataSource.Replace("|DataDirectory|", AppDomain.CurrentDomain.GetData("DataDirectory").ToString());

                if (File.Exists(dbFilePath) == false)
                {
                    var engine = new SqlCeEngine(databaseFactory.ConnectionString);
                    engine.CreateDatabase();
                }
            }

            var tries   = 5;
            var connect = false;

            for (var i = 0;;)
            {
                connect = databaseFactory.CanConnect;
                if (connect || ++i == tries)
                {
                    break;
                }
                Logger.Debug <CoreRuntime>("Could not immediately connect to database, trying again.");
                Thread.Sleep(1000);
            }

            // could not connect to the database
            if (connect == false)
            {
                return;
            }

            using (var database = databaseFactory.CreateDatabase())
            {
                var hasUmbracoTables = database.IsUmbracoInstalled(Logger);

                // database has umbraco tables, assume Umbraco is already installed
                if (hasUmbracoTables)
                {
                    return;
                }

                // all conditions fulfilled, do the install
                Logger.Info <CoreRuntime>("Starting unattended install.");

                try
                {
                    database.BeginTransaction();
                    var creator = new DatabaseSchemaCreator(database, Logger);
                    creator.InitializeDatabaseSchema();
                    database.CompleteTransaction();

                    // Emit an event that unattended install completed
                    // Then this event can be listened for and create an unattended user
                    UnattendedInstalled?.Invoke(this, new UnattendedInstallEventArgs());

                    Logger.Info <CoreRuntime>("Unattended install completed.");
                }
                catch (Exception ex)
                {
                    Logger.Error <CoreRuntime>(ex, "Error during unattended install.");
                    database.AbortTransaction();

                    throw new UnattendedInstallException(
                              "The database configuration failed with the following message: " + ex.Message
                              + "\n Please check log file for additional information (can be found in '/App_Data/Logs/')");
                }
            }
        }
Example #9
0
        private void DoUnattendedInstall(IUmbracoDatabaseFactory databaseFactory)
        {
            // unattended install is not enabled
            if (RuntimeOptions.InstallUnattended == false)
            {
                return;
            }

            var localVersion = UmbracoVersion.LocalVersion; // the local, files, version
            var codeVersion  = _state.SemanticVersion;      // the executing code version

            // local version and code version is not equal, an unattended install cannot be performed
            if (localVersion != codeVersion)
            {
                return;
            }

            // no connection string set
            if (databaseFactory.Configured == false)
            {
                return;
            }

            var tries   = 5;
            var connect = false;

            for (var i = 0;;)
            {
                connect = databaseFactory.CanConnect;
                if (connect || ++i == tries)
                {
                    break;
                }
                Logger.Debug <CoreRuntime>("Could not immediately connect to database, trying again.");
                Thread.Sleep(1000);
            }

            // could not connect to the database
            if (connect == false)
            {
                return;
            }

            using (var database = databaseFactory.CreateDatabase())
            {
                var hasUmbracoTables = database.IsUmbracoInstalled(Logger);

                // database has umbraco tables, assume Umbraco is already installed
                if (hasUmbracoTables)
                {
                    return;
                }

                // all conditions fulfilled, do the install
                Logger.Info <CoreRuntime>("Starting unattended install.");

                try
                {
                    database.BeginTransaction();
                    var creator = new DatabaseSchemaCreator(database, Logger);
                    creator.InitializeDatabaseSchema();
                    database.CompleteTransaction();
                    Logger.Info <CoreRuntime>("Unattended install completed.");
                }
                catch (Exception ex)
                {
                    Logger.Error <CoreRuntime>(ex, "Error during unattended install.");
                    database.AbortTransaction();

                    throw new UnattendedInstallException(
                              "The database configuration failed with the following message: " + ex.Message
                              + "\n Please check log file for additional information (can be found in '/App_Data/Logs/')");
                }
            }
        }
Example #10
0
        public Task HandleAsync(RuntimeUnattendedInstallNotification notification, CancellationToken cancellationToken)
        {
            // unattended install is not enabled
            if (_unattendedSettings.Value.InstallUnattended == false)
            {
                return(Task.CompletedTask);
            }

            // no connection string set
            if (_databaseFactory.Configured == false)
            {
                return(Task.CompletedTask);
            }

            _runtimeState.DetermineRuntimeLevel();
            if (_runtimeState.Reason == RuntimeLevelReason.InstallMissingDatabase)
            {
                _dbProviderFactoryCreator.CreateDatabase(_databaseFactory.ProviderName, _databaseFactory.ConnectionString);
            }

            bool connect;

            try
            {
                for (var i = 0; ;)
                {
                    connect = _databaseFactory.CanConnect;
                    if (connect || ++i == 5)
                    {
                        break;
                    }

                    _logger.LogDebug("Could not immediately connect to database, trying again.");

                    Thread.Sleep(1000);
                }
            }
            catch (Exception ex)
            {
                _logger.LogInformation(ex, "Error during unattended install.");

                var innerException = new UnattendedInstallException("Unattended installation failed.", ex);
                _runtimeState.Configure(Core.RuntimeLevel.BootFailed, Core.RuntimeLevelReason.BootFailedOnException, innerException);
                return(Task.CompletedTask);
            }

            // could not connect to the database
            if (connect == false)
            {
                return(Task.CompletedTask);
            }

            IUmbracoDatabase database = null;

            try
            {
                using (database = _databaseFactory.CreateDatabase())
                {
                    var hasUmbracoTables = database.IsUmbracoInstalled();

                    // database has umbraco tables, assume Umbraco is already installed
                    if (hasUmbracoTables)
                    {
                        return(Task.CompletedTask);
                    }

                    // all conditions fulfilled, do the install
                    _logger.LogInformation("Starting unattended install.");

                    database.BeginTransaction();
                    DatabaseSchemaCreator creator = _databaseSchemaCreatorFactory.Create(database);
                    creator.InitializeDatabaseSchema();
                    database.CompleteTransaction();
                    _logger.LogInformation("Unattended install completed.");

                    // Emit an event with EventAggregator that unattended install completed
                    // Then this event can be listened for and create an unattended user
                    _eventAggregator.Publish(new UnattendedInstallNotification());
                }
            }
            catch (Exception ex)
            {
                _logger.LogInformation(ex, "Error during unattended install.");
                database?.AbortTransaction();

                var innerException = new UnattendedInstallException(
                    "The database configuration failed."
                    + "\n Please check log file for additional information (can be found in '/Umbraco/Data/Logs/')",
                    ex);

                _runtimeState.Configure(Core.RuntimeLevel.BootFailed, Core.RuntimeLevelReason.BootFailedOnException, innerException);
            }

            return(Task.CompletedTask);
        }
        public void CreateDatabase() // FIXME: move to DatabaseBuilderTest!
        {
            var path = TestHelper.CurrentAssemblyDirectory;

            AppDomain.CurrentDomain.SetData("DataDirectory", path);

            // delete database file
            // NOTE: using a custom db file for this test since we're re-using the one created with BaseDatabaseFactoryTest
            var filePath = string.Concat(path, "\\DatabaseContextTests.sdf");

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

            // get the connectionstring settings from config
            var settings = ConfigurationManager.ConnectionStrings[Constants.System.UmbracoConnectionName];

            // by default the conn string is: Datasource=|DataDirectory|UmbracoNPocoTests.sdf;Flush Interval=1;
            // replace the SDF file with our own and create the sql ce database
            var connString = settings.ConnectionString.Replace("UmbracoNPocoTests", "DatabaseContextTests");

            using (var engine = new SqlCeEngine(connString))
            {
                engine.CreateDatabase();
            }

            // re-create the database factory and database context with proper connection string
            _databaseFactory = new UmbracoDatabaseFactory(connString, Constants.DbProviderNames.SqlCe, _logger, new Lazy <IMapperCollection>(() => Mock.Of <IMapperCollection>()));

            // test get database type (requires an actual database)
            using (var database = _databaseFactory.CreateDatabase())
            {
                var databaseType = database.DatabaseType;
                Assert.AreEqual(DatabaseType.SQLCe, databaseType);
            }

            // create application context
            //var appCtx = new ApplicationContext(
            //    _databaseFactory,
            //    new ServiceContext(migrationEntryService: Mock.Of<IMigrationEntryService>()),
            //    CacheHelper.CreateDisabledCacheHelper(),
            //    new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>()));

            // create the umbraco database
            DatabaseSchemaCreator schemaHelper;

            using (var database = _databaseFactory.CreateDatabase())
                using (var transaction = database.GetTransaction())
                {
                    schemaHelper = new DatabaseSchemaCreator(database, _logger);
                    schemaHelper.InitializeDatabaseSchema();
                    transaction.Complete();
                }

            var umbracoNodeTable = schemaHelper.TableExists("umbracoNode");
            var umbracoUserTable = schemaHelper.TableExists("umbracoUser");
            var cmsTagsTable     = schemaHelper.TableExists("cmsTags");

            Assert.That(umbracoNodeTable, Is.True);
            Assert.That(umbracoUserTable, Is.True);
            Assert.That(cmsTagsTable, Is.True);
        }