/// <summary> /// Get the specified data mart /// </summary> public DatamartDefinition GetDatamart(String name) { lock (this.m_lock) { DatamartDefinition retVal = null; using (var cmd = this.CreateCommand(null, "SELECT * FROM dw_datamarts WHERE name = ?", name)) using (var rdr = cmd.ExecuteReader()) if (rdr.Read()) { retVal = new DatamartDefinition() { Id = new Guid((byte[])rdr["uuid"]), Name = (string)rdr["name"], CreationTime = this.m_epoch.AddSeconds((long)rdr["creation_time"]).ToLocalTime(), Schema = new DatamartSchema() { Id = new Guid((byte[])rdr["schema_id"]) } }; } else { return(null); } retVal.Schema = this.LoadSchema(retVal.Schema.Id); return(retVal); } }
/// <summary> /// Create a datamart /// </summary> public DatamartDefinition CreateDatamart(string name, object schema) { this.ThrowIfDisposed(); DatamartSchema dmSchema = schema as DatamartSchema; if (schema is ExpandoObject) { dmSchema = JsonConvert.DeserializeObject <DatamartSchema>(JsonConvert.SerializeObject(schema)); } // Now create / register the data schema lock (this.m_lock) { using (var tx = this.m_connection.BeginTransaction()) { try { this.m_tracer.TraceInfo("Creating datamart {0}", name); // Register the schema dmSchema.Id = dmSchema.Id == default(Guid) ? Guid.NewGuid() : dmSchema.Id; using (var dbc = this.CreateCommand(tx, "INSERT INTO dw_schemas VALUES (?, ?)", dmSchema.Id.ToByteArray(), dmSchema.Name)) dbc.ExecuteNonQuery(); this.CreateProperties(name, tx, dmSchema); // Create mart var retVal = new DatamartDefinition() { Id = Guid.NewGuid(), Name = name, CreationTime = DateTime.Now, Schema = dmSchema }; using (var dbc = this.CreateCommand(tx, "INSERT INTO dw_datamarts VALUES (?, ?, ?, ?)", retVal.Id.ToByteArray(), name, retVal.CreationTime.ToUniversalTime().Subtract(this.m_epoch).TotalSeconds, retVal.Schema.Id)) dbc.ExecuteNonQuery(); foreach (var itm in dmSchema.Queries) { this.CreateStoredQueryInternal(tx, retVal.Id, itm); } tx.Commit(); return(retVal); } catch (Exception e) { this.m_tracer.TraceError("Error creating data mart {0} : {1}", name, e); tx.Rollback(); throw; } } } }
/// <summary> /// Create datamart /// </summary> public DatamartDefinition CreateDatamart(DatamartDefinition definition) { var adhocService = ApplicationServiceContext.Current.GetService <IAdHocDatawarehouseService>(); if (adhocService == null) { throw new InvalidOperationException("Cannot find the adhoc data warehouse service"); } return(adhocService.CreateDatamart(definition.Name, definition.Schema)); }
/// <summary> /// Get the specified data mart /// </summary> public DatamartDefinition GetDatamart(Guid datamartId) { lock (this.m_lock) { try { DatamartDefinition retVal = new DatamartDefinition(); using (var cmd = this.CreateCommand(null, "SELECT * FROM dw_datamarts WHERE uuid = ?", datamartId.ToByteArray())) using (var rdr = cmd.ExecuteReader()) if (rdr.Read()) { retVal = new DatamartDefinition() { Id = new Guid((byte[])rdr["uuid"]), Name = (string)rdr["name"], CreationTime = this.m_epoch.AddSeconds((long)rdr["creation_time"]).ToLocalTime(), Schema = new DatamartSchema() { Id = new Guid((byte[])rdr["schema_id"]) } }; } else { return(retVal); } retVal.Schema = this.LoadSchema(retVal.Schema.Id); return(retVal); } catch (Exception e) { this.m_tracer.TraceError("Error getting data marts: {0}", e); throw; } } }
/// <summary> /// Start the daemon service /// </summary> /// <returns></returns> public bool Start() { this.Starting?.Invoke(this, EventArgs.Empty); this.m_tracer.TraceInfo("Starting care plan manager / warehousing service..."); // Application context has started ApplicationContext.Current.Started += (ao, ae) => ApplicationContext.Current.GetService <IThreadPoolService>().QueueUserWorkItem(xo => { try { ApplicationContext.Current.SetProgress(Strings.locale_start_careplan, 0); // Warehouse service this.m_warehouseService = ApplicationContext.Current.GetService <IAdHocDatawarehouseService>(); foreach (var cp in ApplicationContext.Current.GetService <ICarePlanService>().Protocols) { ApplicationContext.Current.SetProgress(String.Format(Strings.locale_starting, cp.Name), 0); this.m_tracer.TraceInfo("Loaded {0}...", cp.Name); } // Deploy schema? this.m_dataMart = this.m_warehouseService.GetDatamart("oizcp"); if (this.m_dataMart == null) { this.m_tracer.TraceInfo("Datamart for care plan service doesn't exist, will have to create it..."); this.m_dataMart = this.m_warehouseService.CreateDatamart("oizcp", DatamartSchema.Load(typeof(CarePlanManagerService).GetTypeInfo().Assembly.GetManifestResourceStream("OpenIZ.Mobile.Core.Data.Warehouse.CarePlan.CarePlanWarehouseSchema.xml"))); this.m_tracer.TraceVerbose("Datamart {0} created", this.m_dataMart.Id); } //else // prune datamart //{ // this.m_warehouseService.Delete(this.m_dataMart.Id, new // { // max_date = String.Format("<=", DateTime.Now.AddDays(-365)) // }); //} // Stage 2. Ensure consistency with existing patient dataset var patientPersistence = ApplicationContext.Current.GetService <IDataPersistenceService <Patient> >(); var remoteSyncService = ApplicationContext.Current.GetService <ISynchronizationService>(); var queueService = ApplicationContext.Current.GetService <QueueManagerService>(); var lastRefresh = DateTime.Parse(ApplicationContext.Current.Configuration.GetAppSetting("openiz.mobile.core.protocol.plan.lastRun") ?? "0001-01-01"); // Should we ? var patientSync = SynchronizationLog.Current.GetAll().FirstOrDefault(o => o.ResourceType == "Person"); this.RefreshCarePlan(false); remoteSyncService.PullCompleted += (o, e) => { if (!remoteSyncService.IsSynchronizing) { this.m_resetEvent.Set(); } }; // Subscribe to events this.SubscribeEvents(); // We're not connected to the in queueService.QueueExhausted += (o, e) => { int inboundQueueCount = SynchronizationQueue.Inbound.Count(); if (e.Queue == "inbound" && !remoteSyncService.IsSynchronizing && inboundQueueCount == 0) { Guid queryId = Guid.NewGuid(); int tr = 1, ofs = 0; queryId = Guid.NewGuid(); tr = 1; ofs = 0; //this.m_actCarePlanPromise.Clear(); var syncFilter = patientSync?.LastSync ?? new DateTime(1900, 01, 01); while (ofs < tr) { if (tr > 1) { ApplicationContext.Current.SetProgress(Strings.locale_calculateImportedCareplan, ofs / (float)tr); } var prodPatients = patientPersistence.QueryExplicitLoad(p => p.ObsoletionTime == null && p.StatusConcept.Mnemonic != "OBSOLETE" && p.CreationTime >= syncFilter, ofs, 15, out tr, queryId, new String[] { "Patient.Relationships" }); this.QueueWorkItem(prodPatients); ofs += 15; } this.m_isSubscribed = false; this.SubscribeEvents(); } else if (e.Queue == "inbound") { this.m_tracer.TraceWarning("Cannot execute CP yet because inbound={0} & isSync={1}", inboundQueueCount, queueService.IsBusy); } }; } catch (Exception e) { this.m_tracer.TraceError("Could not bind clinical protocols: {0}", e); } }); this.m_running = true; // Polling for the doing of work ApplicationContext.Current.GetService <IThreadPoolService>().QueueNonPooledWorkItem((o) => { try { ISynchronizationService syncService = ApplicationContext.Current.GetService <ISynchronizationService>(); while (this.m_running) { this.m_resetEvent.WaitOne(); // de-queue int promiseCount = this.m_actCarePlanPromise.Count; while (!syncService.IsSynchronizing && SynchronizationQueue.Inbound.Count() == 0 && this.m_actCarePlanPromise.Count > 0) { if (this.m_actCarePlanPromise.Count > promiseCount) { promiseCount = this.m_actCarePlanPromise.Count; } ApplicationContext.Current.SetProgress(String.Format(Strings.locale_calculatingCarePlan, this.m_actCarePlanPromise.Count), (promiseCount - this.m_actCarePlanPromise.Count) / (float)promiseCount); IdentifiedData qitm = null; qitm = this.m_actCarePlanPromise.First(); if (qitm is Patient) { Patient[] patients = null; // Get all patients lock (this.m_lock) { patients = this.m_actCarePlanPromise.OfType <Patient>().Take(5).ToArray(); this.m_actCarePlanPromise.RemoveAll(d => patients.Contains(d)); } this.UpdateCarePlan(patients); // We can also remove all acts that are for a patient //lock (this.m_lock) // this.m_actCarePlanPromise.RemoveAll(i => i is Act && (i as Act).Participations.Any(p => p.PlayerEntityKey == qitm.Key)); } else if (qitm is Act) { // Get all patients var act = this.m_actCarePlanPromise.OfType <Act>().First(); this.UpdateCarePlan(act); //// Remove all acts which are same protocol and same patient lock (this.m_lock) { this.m_actCarePlanPromise.Remove(act); this.m_actCarePlanPromise.RemoveAll(i => i is Act && (i as Act).Protocols.Any(p => (qitm as Act).Protocols.Any(q => q.ProtocolKey == p.ProtocolKey)) && (i as Act).Participations.Any(p => p.PlayerEntityKey == (qitm as Act).Participations.FirstOrDefault(c => c.ParticipationRoleKey == ActParticipationKey.RecordTarget || c.ParticipationRole?.Mnemonic == "RecordTarget").PlayerEntityKey)); } } // Drop everything else in the queue lock (this.m_lock) this.m_actCarePlanPromise.RemoveAll(i => i.Key == qitm.Key); } if (promiseCount > 0 && this.m_actCarePlanPromise.Count == 0) { ApplicationContext.Current.SetProgress(String.Format(Strings.locale_calculatingCarePlan, 0), 1.0f); ApplicationContext.Current.Configuration.SetAppSetting("openiz.mobile.core.protocol.plan.lastRun", DateTime.Now); ApplicationContext.Current.SaveConfiguration(); } this.m_resetEvent.Reset(); } } catch (Exception e) { this.m_tracer.TraceError("Error polling warehouse service: {0}", e); } }, null); this.Started?.Invoke(this, EventArgs.Empty); return(true); }
public DatamartDefinition CreateDatamart(string name, object schema) { this.ThrowIfDisposed(); DatamartSchema dmSchema = schema as DatamartSchema; if (schema is ExpandoObject) { dmSchema = JsonConvert.DeserializeObject <DatamartSchema>(JsonConvert.SerializeObject(schema)); } // Now create / register the data schema using (var context = this.m_configuration.Provider.GetWriteConnection()) { try { context.Open(); context.BeginTransaction(); this.m_tracer.TraceInfo("Creating datamart {0}", name); // Register the schema dmSchema.Id = dmSchema.Id == default(Guid) ? Guid.NewGuid() : dmSchema.Id; context.Insert(new AdhocSchema() { Name = name, SchemaId = dmSchema.Id }); this.CreateProperties(context, name, dmSchema, null); // Create mart var retVal = new DatamartDefinition() { Id = Guid.NewGuid(), Name = name, CreationTime = DateTime.Now, Schema = dmSchema }; context.Insert(new AdhocDatamart() { DatamartId = retVal.Id, Name = name, CreationTime = DateTime.Now, SchemaId = dmSchema.Id }); foreach (var itm in dmSchema.Queries) { this.CreateStoredQueryInternal(context, retVal.Id, itm); } context.Transaction.Commit(); return(retVal); } catch (Exception e) { this.m_tracer.TraceError("Error creating data mart {0} : {1}", name, e); context.Transaction.Rollback(); throw; } } }
/// <summary> /// Creates the datamart. /// </summary> /// <param name="definition">The definition.</param> /// <returns>Returns the created datamart.</returns> public DatamartDefinition CreateDatamart(DatamartDefinition definition) { return(this.Client.Post <DatamartDefinition, DatamartDefinition>("datamart", definition)); }