using System; using System.Collections.Generic; using FluentNHibernate.Cfg; using FluentNHibernate.Cfg.Db; using NHibernate; using NHibernate.Cfg; using NHibernate.Tool.hbm2ddl; using log4net; using TracingDB.Entities; namespace TracingDB { public static class DB { static readonly ILog log = LogManager.GetLogger(typeof(DB)); /// /// Current session factory for the last used connection string or null /// public static ISessionFactory SessionFactory; public static ISession Session; /// 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 } } } /// /// 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') /// /// A database session public static ISessionFactory CreateSessionFactory(bool createDB) { FluentConfiguration cfg = Fluently .Configure() .Database(MySQLConfiguration.Standard.ConnectionString(connectionString)) .Mappings(m => m.FluentMappings.AddFromAssemblyOf()); if (createDB) { return cfg.ExposeConfiguration(BuildSchemaCreate).BuildSessionFactory(); } else { return cfg.ExposeConfiguration(BuildSchema).BuildSessionFactory(); } } public delegate void BuildSchemaDlgt(Configuration config); public static void BuildSchema(Configuration config) { /// This NHibernate tool takes a configuration (with mapping info in) /// and exports a database schema from it new SchemaExport(config).SetOutputFile("db_schema"); } static void BuildSchemaCreate(Configuration config) { /// This NHibernate tool takes a configuration (with mapping info in) /// and exports a database schema from it new SchemaExport(config).Create(true, true); } /// Create a NHibernate session for the given database public static ISession CreateSession(string connectionString) { ConnectionString = connectionString; /// Clears session factory on connction string change if (SessionFactory == null) SessionFactory = CreateSessionFactory(); return SessionFactory.OpenSession(); } /// /// Create an empty 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(string connectionString) { ConnectionString = connectionString; ISessionFactory sessionFactory = CreateSessionFactory(true); if (sessionFactory == null) return false; /// Populate the database using (var session = sessionFactory.OpenSession()) { //using (var transaction = session.BeginTransaction()) //{ // var part1 = new Part("flow tube", CodeType.UniqueNr, CodeForm.QRCode, 0); // session.SaveOrUpdate(part1); // transaction.Commit(); //} } return true; } public static IList FindWMParts(ISession session, string pcbNumber) { IList foundParts = new List(); /// initially empty if (string.IsNullOrEmpty(pcbNumber)) return foundParts; /// return an empty list try { /// Get all already existing reference records with Code == pcbNumber, referenceRecords[0] will be the most recent one var referenceRecords = session.QueryOver() .Where(rr => (rr.Code == pcbNumber)) .OrderBy(rr => rr.TimeStamp).Desc .List(); if (referenceRecords.Count == 0) return foundParts; /// Returns an empty list if no such ref. record found foundParts.Add(new WMPart(referenceRecords[0])); Entities.Process process = referenceRecords[0].Process; /// foreach (var refR in referenceRecords) { if (process != refR.Process) { continue; /// skip records obtained by another process } IList relatedRecords = session .QueryOver() .Where(x => (x.ReferenceRecord == refR)) .List(); foreach (var relR in relatedRecords) { foundParts.Add(new WMPart(relR)); foreach (var ws in process.Worksteps) { if (ws.ReferencePart == relR.Part) { FindWMPartsRecursively(process, ws.ReferencePart, relR.Code, session, ref foundParts); } } } } } catch { } return foundParts; } static void FindWMPartsRecursively(Entities.Process process, Entities.Part refPart, string code, ISession session, ref IList foundParts) { IList referenceRecords = session .QueryOver() .Where(x => (x.Workstep.ReferencePart == refPart)) .Where(x => (x.Code == code)) .OrderBy(x => x.TimeStamp).Desc .List(); if (referenceRecords.Count == 0) return; foreach (var refR in referenceRecords) { IList relatedRecords = session .QueryOver() .Where(x => (x.ReferenceRecord == refR)) .List(); foreach (var relR in relatedRecords) { foundParts.Add(new WMPart(relR)); foreach (var ws in process.Worksteps) { if (ws.ReferencePart == relR.Part) { FindWMPartsRecursively(process, ws.ReferencePart, relR.Code, session, ref foundParts); } } } } } public static bool RegisterWorkplace(ISession session, string workplace, string user, string ipAddress, string processName, string workstepName, DateTime valiUntil) { try { IList wpRegs = session .QueryOver() .Where(x => (x.Workplace == workplace)) .List(); if (wpRegs.Count == 0) { Entities.WorkplaceRegistration wpReg = new Entities.WorkplaceRegistration(workplace, user, ipAddress, processName, workstepName); wpRegs.Add(wpReg); session.SaveOrUpdate(wpReg); log.InfoFormat("RegisterWorkplace(., {0}, {1}, ...) successful (new)", workplace, user); return true; } else if (wpRegs.Count == 1) { Entities.WorkplaceRegistration wpReg = wpRegs[0]; wpReg.Active = true; wpReg.TimeStamp = DateTime.Now; wpReg.ValidUntil = DateTime.Now + new TimeSpan(8, 0, 0); wpReg.UserName = user; wpReg.IPAddress = ipAddress; wpReg.ProcessName = processName; wpReg.WorkstepName = workstepName; session.SaveOrUpdate(wpReg); log.InfoFormat("RegisterWorkplace(., {0}, {1}, ...) successful", workplace, user); return true; } else { log.ErrorFormat("RegisterWorkplace(., {0}, {1}, ...) failed", workplace, user); return false; } } catch (Exception e) { log.ErrorFormat("RegisterWorkplace(., {0}, {1}, ...) exception: {2}", workplace, user, e.Message); return false; } } public static bool UnregisterWorkplace(ISession session, string workplace) { try { IList wpRegs = session .QueryOver() .Where(x => (x.Workplace == workplace)) .List(); if (wpRegs.Count == 1) { Entities.WorkplaceRegistration wpReg = wpRegs[0]; wpReg.Active = false; wpReg.TimeStamp = DateTime.Now; session.SaveOrUpdate(wpReg); log.InfoFormat("UnregisterWorkplace(., {0}) successful", workplace); return true; } else { log.ErrorFormat("UnregisterWorkplace(., {0}) failed", workplace); return false; } } catch (Exception e) { log.ErrorFormat("UnregisterWorkplace(., {0}) exception: {1}", workplace, e.Message); return false; } } } }