/// /// Copyright (c) 2020-2021 Sensus Slovensko a.s. /// using System; using System.Collections.Generic; using FluentNHibernate.Cfg; using FluentNHibernate.Cfg.Db; using NHibernate; using NHibernate.Cfg; using NHibernate.Tool.hbm2ddl; using Common; using SharedDatabase.Entities; namespace SharedDatabase { public static class EventsDB { /// Session factory for all regular sessions, not for CreateEmptyResultsDB(). public static ISessionFactory SessionFactory; /// Connection string for all sessions static string connectionString; /// public static string ConnectionString { get { return connectionString; } set { if (value != connectionString) { connectionString = value; SessionFactory = null; /// Clear SessionFactory on connection string change } } } /// Database type (MySQL or SQLite) for all sessions private static Common.DBType dbType; /// public static Common.DBType DbType { get { return dbType; } set { dbType = value; SessionFactory = null; } } /// /// NHibernate session factory (to create the database session 'SessionFactory') /// /// A database session static ISessionFactory CreateSessionFactory() { return CreateSessionFactory(false); } /// /// NHibernate session factory (to create the database session 'SessionFactory') /// /// true = Create a new DB, false = Regular DB /// A database session public static ISessionFactory CreateSessionFactory(bool createDB) { FluentConfiguration cfg = Fluently.Configure(); switch (dbType) { default: case DBType.MySql: cfg = cfg.Database(MySQLConfiguration.Standard.ConnectionString(connectionString)); break; case DBType.SQLite: cfg = cfg.Database(SQLiteConfiguration.Standard.UsingFile(connectionString)); break; } cfg = cfg.Mappings(m => m.FluentMappings.AddFromAssemblyOf()); if (createDB) { return cfg.ExposeConfiguration(BuildSchemaCreate).BuildSessionFactory(); } else { return cfg.ExposeConfiguration(BuildSchema).BuildSessionFactory(); } } static void BuildSchema(Configuration config) { /// This NHibernate tool takes a configuration with mapping info and exports a database schema new SchemaExport(config).SetOutputFile("db_schema"); } static void BuildSchemaCreate(Configuration config) { /// This NHibernate tool takes a configuration with mapping info and exports a database schema new SchemaExport(config).Create(true, true); } /// Create a NHibernate session for the given database public static ISession CreateSession() { if (string.IsNullOrEmpty(connectionString)) { throw new Exception("Connection string was not specified"); } if (SessionFactory == null) SessionFactory = CreateSessionFactory(); return SessionFactory.OpenSession(); } public static void SaveObject(object obj) { SaveObject(CreateSession(), obj); } /// public static void SaveObject(ISession session, object obj) { using (var transaction = session.BeginTransaction()) { session.SaveOrUpdate(obj); try { transaction.Commit(); } catch { } } } public static void DeleteObject(object obj) { DeleteObject(CreateSession(), obj); } /// public static void DeleteObject(ISession session, object obj) { using (var transaction = session.BeginTransaction()) { session.Delete(obj); transaction.Commit(); } } /// /// Create an empty users database. /// Database contains only the user 'admin' and the control board component 'CB'. /// /// DBType.SQLite or DBType.MySql /// Connection string /// true=success, false=error public static bool CreateEmptyDB() { ISessionFactory sessionFactory = CreateSessionFactory(true); if (sessionFactory == null) return false; /// Populate the database using (var session = sessionFactory.OpenSession()) { using (var transaction = session.BeginTransaction()) { transaction.Commit(); } } return true; } /// /// Shared data (initially empty) /// public static string BenchName = "undefined"; public static IList RecentEvents = null; static IList allSubscribers = null; /// /// Set test bench name used in SharedDatabase.Entities.Event constructors /// public static void SetBenchName(string benchName) { EventsDB.BenchName = benchName; } /// /// Loads shared data from the database /// public static void LoadSubscribers(ISession session) { allSubscribers = session.QueryOver().List(); } /// /// Loads shared data from the database /// public static void LoadRecentEvents(ISession session, string benchName, int days) { RecentEvents = session.QueryOver() .Where(e => (e.Bench == benchName)) .And(e => (e.TimeStamp >= DateTime.Now - new TimeSpan(days, 0, 0, 0))) .List(); } public static void SaveEvent(ISession session, Event evnt, SubscriberGroup groups) { if (allSubscribers == null) return; IList thisEventSubscribers = new List(); foreach (var s in allSubscribers) { if ((s.Groups & (long)groups) != 0) { /// Subscriber 's' belongs to at least one of SubscriberGroup(s) in 'groups' bit field thisEventSubscribers.Add(s); } } evnt.Bench = BenchName; evnt.Subscribers = thisEventSubscribers; session.SaveOrUpdate(evnt); session.Flush(); } } }