Example #1
0
 public EntityApp Build(DbFirstConfig config)
 {
     _config = config;
       _app = new EntityApp();
       var log = _app.ActivationLog;
       _dbSettings = new DbSettings(_config.Driver, DbOptions.Default, _config.ConnectionString);
       _dbSettings.SetSchemas(_config.Schemas);
       var modelLoader = _config.Driver.CreateDbModelLoader(_dbSettings, log);
       _dbModel = modelLoader.LoadModel();
       Util.Check(_dbModel.Tables.Count() > 0, "No tables found in the database. Code generation aborted.");
       // Prepare type generator
       _tempNamespace = "_dummy_" + _callCount++; // artificial unique namespace for dummy interface types
       // Construct model setup and model
       GenerateModulesAndAreas();
       _entityModel = new EntityModel(_app);
       EntityModelBuilder.SetModel(_app, _entityModel);
       _entityModel.ClassesAssembly = new EntityClassesAssembly();
       //generate entities and members
       GenerateEntities();
       SetupPrimaryKeys();
       GenerateReferenceMembers();
       CreateIndexes();
       SetupKeyMembers();
       return _app;
 }
Example #2
0
        // constructors
        public Database(EntityApp app, DbSettings settings)
        {
            _app = app;
              Settings = settings;
              _driver = Settings.ModelConfig.Driver;
              _entityModel = app.Model;
              _timeService = _app.TimeService;
              //Set list of all schemas
              var allSchemas = app.Areas.Select(a => settings.ModelConfig.GetSchema(a));
              settings.SetSchemas(allSchemas);

              //Check if model is shared
              bool modelIsShared = Settings.ModelConfig.Options.IsSet(DbOptions.ShareDbModel);
              lock (_lock) { //we need lock to prevent collision on shared model
              if (modelIsShared)
            DbModel = Settings.ModelConfig.SharedDbModel;
              if (DbModel == null) {
            var dbmBuilder = new DbModelBuilder(app.Model, settings.ModelConfig, app.ActivationLog);
            DbModel = dbmBuilder.Build();
            if (modelIsShared)
              Settings.ModelConfig.SharedDbModel = DbModel;
              }
            }//lock

              //Save
        }
Example #3
0
 public static DbSettings CreateDbSettings(DbServerType serverType, string connectionString = null)
 {
     var driver = CreateDriver(serverType, connectionString);
       var options = GetDefaultOptions(serverType);
       var dbStt = new DbSettings(driver, options, connectionString);
       return dbStt;
 }
Example #4
0
 public static void DropSchemaObjects(string schema)
 {
     if (Driver == null)
     SetupForTestExplorerMode();
       //SQLite and SqlCe do not support schemas so we effectively wipe out database for each test
       var dbSettings = new DbSettings(Driver, DbOptions, ConnectionString);
       dbSettings.SetSchemas(new[] { schema });
       TestUtil.DropSchemaObjects(dbSettings);
 }
Example #5
0
 public static DbModel LoadDbModel(string schema, MemoryLog log)
 {
     if (Driver == null)
     SetupForTestExplorerMode();
       var dbSettings = new DbSettings(Driver, DbOptions, ConnectionString);
       dbSettings.SetSchemas(new[] { schema });
       var loader = Driver.CreateDbModelLoader(dbSettings, log);
       var dbModel = loader.LoadModel();
       if (log.HasErrors())
     Util.Throw("Model loading errors: \r\n" + log.GetAllAsText());
       return dbModel;
 }
Example #6
0
    public void TestMultiTenant() {
      // Multi-tenant test is available only for MS SQL Server.
      if (SetupHelper.ServerType != DbServerType.MsSql)
        return;
      const string Books2 = "VitaBooks2";
      var app = SetupHelper.BooksApp; 
      var connString2 = SetupHelper.ConnectionString.Replace("VitaBooks", Books2);
      var mainDbStt = SetupHelper.DbSettings; 
      var dbSettings2 = new DbSettings(mainDbStt.ModelConfig,  connString2, upgradeMode: DbUpgradeMode.Always, dataSourceName: Books2);
      Vita.UnitTests.Common.TestUtil.DropSchemaObjects(dbSettings2);
      app.ConnectTo(dbSettings2);

      //read from new store
      var ctx1 = new OperationContext(app); // DataSourceName=Default
      // The second context will point to another database
      var ctx2 = new OperationContext(app);
      ctx2.DataSourceName = Books2;
      var session = ctx2.OpenSession();
      var books = session.EntitySet<IBook>().ToList();
      Assert.AreEqual(0, books.Count, "Expected no books in new store");
      //Let's create a pub and a book in VitaBooks2
      var newPub = session.NewPublisher("VBooks");
      var newBook = session.NewBook(BookEdition.Hardcover, BookCategory.Programming, "Voodoo Programming", "Voodoo science in code", newPub, DateTime.Now, 10m);
      session.SaveChanges(); 

      //check we inserted them in VitaBooks2
      session = ctx2.OpenSession();
      var pubCopy = session.EntitySet<IPublisher>().FirstOrDefault(p => p.Name == newPub.Name);
      Assert.IsNotNull(pubCopy, "Publisher not found in VitaBooks2");
      var bookCopy = session.EntitySet<IBook>().FirstOrDefault(b => b.Title == newBook.Title);
      Assert.IsNotNull(bookCopy, "Book not found.");

      //Check that it does not exist in 'main' VitaBooks database
      session = ctx1.OpenSession(); //open session in VitaBooks
      var pub = session.EntitySet<IPublisher>().FirstOrDefault(p => p.Name == newPub.Name);
      Assert.IsNull(pub, "Publisher should not exist in VitaBooks");
      var book = session.EntitySet<IBook>().FirstOrDefault(b => b.Title == newBook.Title);
      Assert.IsNull(book, "Book should not exist in VitaBooks.");

      //Verify both data sources share the DbModel object
      var dsService = app.DataAccess;
      var ds1 = dsService.GetDataSource(ctx1);
      var ds2 = dsService.GetDataSource(ctx2);
      Assert.IsNotNull(ds1, "Default data source not found.");
      Assert.IsNotNull(ds2, "Books2 data source not found.");
      Assert.AreEqual(ds1.Database.DbModel, ds2.Database.DbModel, "Db models are not shared.");
    }
Example #7
0
 public static List<DbUpgradeScript> CompareDatabaseSchemas(DbFirstConfig config, Type modelType)
 {
     var entApp = Activator.CreateInstance(modelType) as EntityApp;
       entApp.Init();
       // important - do not use DbOptions.AutoIndexForeignKeys - which is recommended for MS SQL, but is not helpful here.
       // This will create a bunch of extra indexes on FKs in entities schema and result in extra differences with original schema.
       //  We ignore stored procs
       var dbOptions = DbOptions.Default & ~DbOptions.AutoIndexForeignKeys;
       var dbSettings = new DbSettings(config.Driver, dbOptions, config.ConnectionString,
                               upgradeMode: DbUpgradeMode.Always,
                               upgradeOptions : DbUpgradeOptions.UpdateTables | DbUpgradeOptions.UpdateIndexes
                               );
       dbSettings.SetSchemas(config.Schemas);
       var db = new Database(entApp, dbSettings);
       var ds = new DataSource("main", db);
       var upgradeMgr = new DbUpgradeManager(ds);
       var upgradeInfo = upgradeMgr.BuildUpgradeInfo();
       return upgradeInfo.AllScripts;
 }
Example #8
0
 // We cannot use regular access thru EntitySession - db info/version loads at the very start of connecting to db;
 // the entity app is not ready yet (schema not updated, etc).
 public DbVersionInfo LoadDbInfo(DbSettings settings, string appName, Vita.Data.Driver.DbModelLoader loader)
 {
     var thisSchema = settings.ModelConfig.GetSchema(this.Area);
       if (!loader.TableExists(thisSchema, "DbInfo"))
     return null;
       var dbInfoTableName = settings.Driver.GetFullName(thisSchema, "DbInfo");
       var dbModuleInfoTableName = settings.Driver.GetFullName(thisSchema, "DbModuleInfo");
       try {
     var dbInfo = new DbVersionInfo();
     var sql = string.Format("SELECT * FROM {0};", dbInfoTableName);
     var dt = loader.ExecuteSelect(sql);
     var appRow = dt.Rows.FindRow("AppName", appName);
     if (appRow != null) {
       dbInfo.InstanceType = (DbInstanceType)appRow.GetAsInt("InstanceType");
       var strVersion = appRow.GetAsString("Version");
       Version dbVersion;
       if (Version.TryParse(strVersion, out dbVersion))
     dbInfo.Version = dbVersion;
       // 'Values' column appears in v 1.1
       if (dt.Columns.Contains("Values")) {
     var strValues = appRow.GetAsString("Values");
     DeserializeValues(dbInfo, strValues);
       }
     } //if appRow
     //Read modules
     sql = string.Format("SELECT * FROM {0};", dbModuleInfoTableName);
     dt = loader.ExecuteSelect(sql);
     foreach(DataRow row in dt.Rows) {
       var moduleName = row.GetAsString("ModuleName");
       var schema = row.GetAsString("Schema");
       var strModuleVersion = row.GetAsString("Version");
       Version v;
       if (!Version.TryParse(strModuleVersion, out v))
     v = null;
       dbInfo.Modules.Add(new ModuleDbVersionInfo(schema, moduleName, v));
     }
     return dbInfo;
       } catch (Exception ex) {
     Trace.WriteLine("Failed to load DbInfo record:  " + ex.ToLogString());
     //Debugger.Break();
     return null;
       }
 }
Example #9
0
        public void TestGetSchema()
        {
            if(SetupHelper.Driver == null)
            SetupHelper.SetupForTestExplorerMode();
              _fileName = "_schemas_" + SetupHelper.ServerType + ".log";
              System.IO.File.Delete(_fileName);
              WriteLine("--------------------------------------------------------------------------------------------------");
              WriteLine("Server type: " + SetupHelper.ServerType + Environment.NewLine);
              var dbStt = new DbSettings(SetupHelper.Driver, SetupHelper.DbOptions, SetupHelper.ConnectionString);
              var conn = dbStt.ModelConfig.Driver.CreateConnection(SetupHelper.ConnectionString);

              //get col list
              var colList = GetCollectionNames(conn);

              //Report each collection
              foreach(var colName in colList) {
            WriteLine("Collection: " + colName);
            var dt = GetCollection(conn, colName);
            WriteLine("Columns: " + GetColumnNames(dt));

              }
        }
Example #10
0
 public bool GenerateScripts(XmlDocument xmlConfig)
 {
     const string header =
     @"-- DDL Scripts generated by VITA DB Tool.
     -- Generated on: {0}
     -- Target database: {1}
     -- Executed by user {2} on machine {3}.
     ";
       _config = new DbUpdateConfig(xmlConfig);
       Util.Check(File.Exists(_config.AssemblyPath), "Assembly file '{0}' not found.", _config.AssemblyPath);
       var asm = Assembly.LoadFrom(_config.AssemblyPath);
       var appType = asm.GetType(_config.AppClassName);
       Util.Check(appType != null, "Type {0} not found in target assembly.");
       // Using NonPublic flag to allow internal constructor;
       // EntityApp must have a parameterless constructor, but it may be made internal, to hide from regular code
       var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
       var appObj = Activator.CreateInstance(appType, flags, null, null, null);
       Util.Check(appObj != null, "Failed to create instance of class {0}.", _config.AppClassName);
       var entApp = appObj as EntityApp;
       Util.Check(entApp != null, "The target instance of class {0} is not an EntityApp instance.", _config.AppClassName);
       entApp.Init();
       var dbSettings = new DbSettings(_config.Driver, _config.DbOptions, _config.ConnectionString,
            upgradeMode: DbUpgradeMode.Always, upgradeOptions: _config.ModelUpdateOptions);
       var schemas = entApp.Areas.Select(a => a.Name).ToList();
       dbSettings.SetSchemas(schemas);
       var db = new Database(entApp, dbSettings);
       var ds = new DataSource(null, db);
       var updateMgr = new DbUpgradeManager(ds);
       var upgrades = updateMgr.BuildUpgradeInfo();
       var ddl = string.Join(_config.Driver.DDLSeparator, upgrades.AllScripts.Select(scr => scr.Sql));
       if (string.IsNullOrEmpty(ddl))
     ddl = "-- (No changes detected)";
       var text = string.Format(header, DateTime.Now.ToString("s"), _config.ConnectionString, Environment.UserName, Environment.MachineName) + ddl;
       File.WriteAllText(_config.OutputPath, text);
       _feedback.WriteLine(" Generated {0} scripts.", upgrades.AllScripts.Count);
       _feedback.WriteLine(" DDL scripts are saved to '{0}'", _config.OutputPath);
       return true;
 }
Example #11
0
 public static EntityApp ActivateApp(EntityApp app, bool updateSchema = true, bool dropUnknownTables = false)
 {
     DeleteLocalLogFile();
       app.LogPath = LogFilePath;
       //If driver is not set, it means we are running from Test Explorer in VS. Use ServerTypeForTestExplorer
       if(Driver == null)
     SetupForTestExplorerMode();
       try {
     app.Init();
     var upgradeMode = updateSchema ? DbUpgradeMode.Always : DbUpgradeMode.Never;
     var upgradeOptions = DbUpgradeOptions.Default;
     if(dropUnknownTables)
       upgradeOptions |= DbUpgradeOptions.DropUnknownObjects;
     var dbSettings = new DbSettings(Driver, DbOptions, ConnectionString, upgradeMode: upgradeMode, upgradeOptions: upgradeOptions);
     app.ConnectTo(dbSettings);
     return app;
       } catch (StartupFailureException sx) {
     //Unit test framework shows only ex message, not details; let's write specifics into debug output - it will be shown in test failure report
     Debug.WriteLine("EntityApp init exception: ");
     Debug.WriteLine(sx.Log);
     throw;
       }
 }
Example #12
0
 public static BooksEntityApp CreateConfigureBooksApp()
 {
     // set up application
       var protectedSection = (NameValueCollection)ConfigurationManager.GetSection("protected");
       var cryptoKey = protectedSection["LoginInfoCryptoKey"];
       var booksApp = new BooksEntityApp(cryptoKey);
       booksApp.Init();
       var connString = protectedSection["MsSqlConnectionString"];
       var logConnString = protectedSection["MsSqlLogConnectionString"];
       var driver = MsSqlDbDriver.Create(connString);
       var dbOptions = MsSqlDbDriver.DefaultMsSqlDbOptions;
       var logDbSettings = new DbSettings(driver, dbOptions, logConnString);
       booksApp.LoggingApp.ConnectTo(logDbSettings);
       var dbSettings = new DbSettings(driver, dbOptions, connString, upgradeMode: DbUpgradeMode.Always);
       booksApp.ConnectTo(dbSettings);
       //Web Api
       WebHelper.ConfigureWebApi(GlobalConfiguration.Configuration, booksApp, logLevel: Entities.Services.LogLevel.Details);
       /*
       var hc = GlobalConfiguration.Configuration;
       var webH = hc.MessageHandlers.First(h => h is WebCallContextHandler);
       hc.MessageHandlers.Remove(webH);
       */
       return booksApp;
 }
Example #13
0
 public override DbModelUpdater CreateDbModelUpdater(DbSettings settings)
 {
     return new MySqlDbModelUpdater(settings);
 }
Example #14
0
 public override DbModelLoader CreateDbModelLoader(DbSettings settings, MemoryLog log)
 {
     return new MySqlDbModelLoader(settings, log);
 }
Example #15
0
        public static void InitImpl()
        {
            if(BooksApp != null)
            return;
              LogFilePath = ConfigurationManager.AppSettings["LogFilePath"];
              DeleteLocalLogFile();

              var protectedSection = (NameValueCollection)ConfigurationManager.GetSection("protected");
              var loginCryptoKey = protectedSection["LoginInfoCryptoKey"];
              var connString = protectedSection["MsSqlConnectionString"];
              var logConnString = protectedSection["MsSqlLogConnectionString"];

              BooksApp = new BooksEntityApp(loginCryptoKey);
              //Add mock email/sms service
              NotificationListener = new NotificationListener(BooksApp, blockAll: true);
              //Set magic captcha in login settings, so we can pass captcha in unit tests
              var loginStt = BooksApp.GetConfig<Vita.Modules.Login.LoginModuleSettings>();
              loginStt.MagicCaptcha = "Magic";
              BooksApp.Init();
              //connect to database
              var driver = MsSqlDbDriver.Create(connString);
              var dbOptions = MsSqlDbDriver.DefaultMsSqlDbOptions;
              var dbSettings = new DbSettings(driver, dbOptions, connString, upgradeMode: DbUpgradeMode.Always); // schemas);
              var resetDb = ConfigurationManager.AppSettings["ResetDatabase"] == "true";
              if(resetDb)
            Vita.UnitTests.Common.TestUtil.DropSchemaObjects(dbSettings);
              BooksApp.ConnectTo(dbSettings);
              var logDbSettings = new DbSettings(driver, dbOptions, logConnString);
              BooksApp.LoggingApp.ConnectTo(logDbSettings);
              BooksApp.LoggingApp.LogPath = LogFilePath;
              TestUtil.DeleteAllData(BooksApp, exceptEntities: new [] {typeof(IDbInfo), typeof(IDbModuleInfo)});
              TestUtil.DeleteAllData(BooksApp.LoggingApp);

              SampleDataGenerator.CreateUnitTestData(BooksApp);
              var serviceUrl = ConfigurationManager.AppSettings["ServiceUrl"];
              StartService(serviceUrl);
              Client = new WebApiClient(serviceUrl);
              Client.InnerHandler.AllowAutoRedirect = false; //we need it for Redirect test
        }
Example #16
0
        public static void InitApp()
        {
            Util.Check(!_initFailed, "App initialization failed. Cannot run tests. See other tests output for failure details.");
              if(BooksApp != null)
            return;
              try {
            //force randomization of schema update SQLs, to test that they will put in correct order anyway
            DbModelUpdater.Test_RandomizeInitialSchemaUpdatesOrder = true;
            //Check if Reset was called; if Driver is null, we are running in Test Explorer mode
            if(Driver == null)
              SetupForTestExplorerMode();
            //Reset Db and drop schema objects
            var resetDb = ConfigurationManager.AppSettings["ResetDatabase"] == "true";
            if(resetDb)
              Vita.UnitTests.Common.TestUtil.DropSchemaObjects(DbSettings);
            //Setup model, initialize Books module, create database model, update schema -------------------------------------------------
            BooksApp = new BooksEntityApp(LoginCryptoKey);
            BooksApp.LogPath = LogFilePath;
            BooksApp.ActivationLogPath = ActivationLogFilePath;
            BooksApp.CacheSettings.CacheEnabled = CacheEnabled;
            NotificationListener = new NotificationListener(BooksApp, blockAll: true);   //SmtpMock for testing password reset and other processes
            BooksApp.Init();
            //Now connect the main app
            BooksApp.ConnectTo(DbSettings);
            //if we have logging app as a separate app - we need to connect it too.
            // NOTE: good pracice to connect LoggingApp before we connect the main app, so it can log main database update scripts
            // but it should work anyway.
            var logDbSettings = new DbSettings(Driver, DbSettings.ModelConfig.Options, LogConnectionString);
            BooksApp.LoggingApp.ConnectTo(logDbSettings);

            Thread.Yield();
            CreateSampleData();

              } catch(ClientFaultException cfx) {
            Debug.WriteLine("Validation errors: \r\n" + cfx.ToString());
            throw;
              } catch(Exception sx) {
            _initFailed = true;
            //Unit test framework shows only ex message, not details; let's write specifics into debug output - it will be shown in test failure report
            Debug.WriteLine("app init encountered errors: ");
            Debug.WriteLine(sx.ToLogString());
            throw;
              }
        }
Example #17
0
        //Prepares for full run with a specified server
        internal static void Reset(TestConfig config)
        {
            if(BooksApp != null)
            BooksApp.Flush();
              Thread.Sleep(100); //to allow log dump of buffered messages
              DeleteLogFiles(); //it will happen only once
              WriteLog("\r\n------------------------ " + config.ToString() + "---------------------------------------------\r\n\r\n");

              ServerType = config.ServerType;
              CacheEnabled = config.EnableCache;
              UseBatchMode = config.UseBatchMode;
              BooksApp = null;
              _initFailed = false;

              var protectedSection = (NameValueCollection)ConfigurationManager.GetSection("protected");
              //Load connection string
              ConnectionString = ReplaceBinFolderToken(protectedSection[ServerType + "ConnectionString"]);
              Util.Check(!string.IsNullOrEmpty(ConnectionString), "Connection string not found for server: {0}.", ServerType);
              LogConnectionString = ReplaceBinFolderToken(protectedSection[ServerType + "LogConnectionString"]);
              LogConnectionString = LogConnectionString ?? ConnectionString;

              LoginCryptoKey = protectedSection["LoginInfoCryptoKey"];
              Driver = ToolHelper.CreateDriver(ServerType, ConnectionString);
              var dbOptions = ToolHelper.GetDefaultOptions(ServerType);

              if (config.UseStoredProcs)
            dbOptions |= DbOptions.UseStoredProcs;
              else
            dbOptions &= ~DbOptions.UseStoredProcs;
              if (config.UseBatchMode)
            dbOptions |= DbOptions.UseBatchMode;
              else
            dbOptions &= ~DbOptions.UseBatchMode;

              // dbOptions |= DbOptions.ForceArraysAsLiterals; -- just to test this flag
              DbSettings = new DbSettings(Driver, dbOptions, ConnectionString, upgradeMode: DbUpgradeMode.Always);
              //Test: remap login schema into login2
              DbSettings.ModelConfig.MapSchema("login", "login2");
        }
Example #18
0
 private bool InitApp() {
   Application.ThreadException += Application_ThreadException;
   try {
     var serviceURl = ConfigurationManager.AppSettings.Get("serviceUrl");
     _app = new OAuthEntityApp(serviceURl);
     _app.Init();
     // Get IOAuthClientService and hook to it's Redirected event - to get notified when user hits "Allow"
     _service = _app.GetService<IOAuthClientService>();
     _service.Redirected += OAuthClientService_Redirected;
     //Setup default encryption channel - we store OAuth data encrypted
     var cryptoKey = ConfigurationManager.AppSettings.Get("CryptoKey");
     var encrService = _app.GetService<Vita.Modules.EncryptedData.IEncryptionService>();
     encrService.AddChannel(HexUtil.HexToByteArray(cryptoKey));
     //Connect to db
     var connString = ConfigurationManager.AppSettings.Get("MsSqlConnectionString");
     if(!CheckConnection(connString))
       return false; 
     var dbSettings = new DbSettings(new MsSqlDbDriver(), MsSqlDbDriver.DefaultMsSqlDbOptions, connString);
     _app.ConnectTo(dbSettings);
     //Start local web server to handle redirects back from OAuth server, after user approves access
     StartWebService(serviceURl);
     // Hook to global error log, to show exception when it happens in Redirect controller
     var errLog = _app.GetService<IErrorLogService>();
     errLog.ErrorLogged += ErrLog_ErrorLogged;
     //Just for ease of debugging this app, update servers definitions in database
     var session = OpenSession();
     Vita.Modules.OAuthClient.OAuthServers.CreateUpdatePopularServers(session);
     session.SaveChanges();
     return true;
   } catch(Exception ex) {
     Log(ex.ToLogString());
     MessageBox.Show(ex.Message, "Error");
     return false; 
   }
 }
Example #19
0
 public SQLiteDbModelLoader(DbSettings settings, MemoryLog log)
     : base(settings, log)
 {
 }