Exemple #1
0
        /// <summary>
        /// Load schema for the specified item
        /// </summary>
        private DatamartSchema LoadSchema(DataContext context, Guid id)
        {
            DatamartSchema retVal = null;

            var dbsc = context.FirstOrDefault <AdhocSchema>(o => o.SchemaId == id);

            if (dbsc == null)
            {
                return(null);
            }

            retVal = new DatamartSchema()
            {
                Id   = dbsc.SchemaId,
                Name = dbsc.Name
            };

            // Stored queries
            retVal.Queries = context.Query <AdhocQuery>(o => o.SchemaId == id).Select(o =>
                                                                                      new DatamartStoredQuery()
            {
                Id         = o.QueryId,
                Name       = o.Name,
                Properties = this.LoadProperties(context, o.QueryId)
            }).ToList();

            // properties
            retVal.Properties = this.LoadProperties(context, id);

            // TODO: load schema
            return(retVal);
        }
Exemple #2
0
        /// <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;
                    }
                }
            }
        }
Exemple #3
0
        /// <summary>
        /// Load schema for the specified item
        /// </summary>
        private DatamartSchema LoadSchema(Guid id)
        {
            DatamartSchema retVal = null;

            lock (this.m_lock)
            {
                using (var dbc = this.CreateCommand(null, "SELECT * FROM dw_schemas WHERE uuid = ?", id.ToByteArray()))
                    using (var rdr = dbc.ExecuteReader())
                        if (rdr.Read())
                        {
                            retVal = new DatamartSchema()
                            {
                                Id   = id,
                                Name = (string)rdr["name"]
                            };
                        }
                        else
                        {
                            return(null);
                        }

                // Queries
                using (var dbc = this.CreateCommand(null, "SELECT * FROM dw_st_query WHERE schema_id = ?", retVal.Id))
                    using (var rdr = dbc.ExecuteReader())
                        while (rdr.Read())
                        {
                            retVal.Queries.Add(new DatamartStoredQuery()
                            {
                                Id   = new Guid((byte[])rdr["uuid"]),
                                Name = rdr["name"].ToString()
                            });
                        }
            }

            retVal.Properties = this.LoadProperties(id);
            foreach (var itm in retVal.Queries)
            {
                itm.Properties = this.LoadProperties(itm.Id);
            }

            // TODO: load schema
            return(retVal);
        }
Exemple #4
0
        public static int Careplan(string[] argv)
        {
            var parms = new ParameterParser <CareplanParameters>().Parse(argv);

            ApplicationContext.Current.Start();
            ApplicationServiceContext.Current = ApplicationContext.Current;
            AuthenticationContext.Current     = new AuthenticationContext(AuthenticationContext.SystemPrincipal);
            EntitySource.Current = new EntitySource(new PersistenceServiceEntitySource());
            var warehouseService = ApplicationContext.Current.GetService <IAdHocDatawarehouseService>();
            var planService      = ApplicationContext.Current.GetService <ICarePlanService>();

            if (warehouseService == null)
            {
                throw new InvalidOperationException("Ad-hoc data warehouse service is not registered");
            }
            if (planService == null)
            {
                throw new InvalidOperationException("Missing care plan service");
            }

            // Warehouse service
            foreach (var cp in planService.Protocols)
            {
                Console.WriteLine("Loaded {0}...", cp.Name);
            }

            // Deploy schema?
            var dataMart = warehouseService.GetDatamart("oizcp");

            if (dataMart == null)
            {
                if (parms.Create)
                {
                    Console.WriteLine("Datamart for care plan service doesn't exist, will have to create it...");
                    dataMart = warehouseService.CreateDatamart("oizcp", DatamartSchema.Load(typeof(Warehouse).Assembly.GetManifestResourceStream("OizDevTool.Resources.CarePlanWarehouseSchema.xml")));
                }
                else
                {
                    throw new InvalidOperationException("Warehouse schema does not exist!");
                }
            }

            // Truncate?
            if (parms.Truncate)
            {
                warehouseService.Truncate(dataMart.Id);
            }

            // Now we want to calculate

            var patientPersistence = ApplicationContext.Current.GetService <IStoredQueryDataPersistenceService <Patient> >();
            var lastRefresh        = DateTime.Parse(parms.Since ?? "0001-01-01");

            // Should we calculate?

            var            warehousePatients = warehouseService.StoredQuery(dataMart.Id, "consistency", new { });
            Guid           queryId = Guid.NewGuid();
            int            tr = 1, ofs = 0, calc = 0, tq = 0;
            WaitThreadPool wtp = new WaitThreadPool(Environment.ProcessorCount * 2);
            DateTime       start = DateTime.Now;

            // Type filters
            List <Guid> typeFilter = new List <Guid>();

            if (parms.ActTypes?.Count > 0)
            {
                var cpcr = ApplicationContext.Current.GetService <IConceptRepositoryService>();
                foreach (var itm in parms.ActTypes)
                {
                    typeFilter.Add(cpcr.GetConcept(itm).Key.Value);
                }
            }

            while (ofs < tr)
            {
                var prodPatients = patientPersistence.Query(o => o.StatusConcept.Mnemonic != "OBSOLETE" && o.ModifiedOn > lastRefresh, queryId, ofs, 100, AuthenticationContext.SystemPrincipal, out tr);
                ofs += 100;

                foreach (var p in prodPatients.Where(o => !warehousePatients.Any(w => w.patient_id == o.Key)))
                {
                    tq++;
                    wtp.QueueUserWorkItem(state =>
                    {
                        AuthenticationContext.Current = new AuthenticationContext(AuthenticationContext.SystemPrincipal);

                        Patient pState = (Patient)state;

                        List <dynamic> warehousePlan = new List <dynamic>();

                        Interlocked.Increment(ref calc);
                        lock (parms)
                        {
                            var ips            = (((double)(DateTime.Now - start).Ticks / calc) * (tq - calc));
                            Console.CursorLeft = 0;
                            Console.Write("    Calculating care plan {0}/{1} <<Scan: {4} ({5:0%})>> ({2:0%}) [ETA: {3}] {6:0.##} R/S ", calc, tq, (float)calc / tq, new TimeSpan((long)ips).ToString("hh'h 'mm'm 'ss's'"), ofs, (float)ofs / tr, ((double)calc / (double)(DateTime.Now - start).TotalSeconds));
                        }

                        var data = p; //  ApplicationContext.Current.GetService<IDataPersistenceService<Patient>>().Get(p.Key.Value);

                        // First, we want a copy of the warehouse
                        var existing = warehouseService.AdhocQuery(dataMart.Id, new
                        {
                            patient_id = data.Key.Value
                        });
                        warehouseService.Delete(dataMart.Id, new { patient_id = data.Key.Value });
                        var careplanService = ApplicationContext.Current.GetService <ICarePlanService>();

                        // Now calculate the care plan...
                        var carePlan = careplanService.CreateCarePlan(data, false, new Dictionary <String, Object>()
                        {
                            { "isBackground", true }
                        });
                        warehousePlan.AddRange(carePlan.Action.Select(o => new
                        {
                            creation_date = DateTime.Now,
                            patient_id    = data.Key.Value,
                            location_id   = data.Relationships.FirstOrDefault(r => r.RelationshipTypeKey == EntityRelationshipTypeKeys.DedicatedServiceDeliveryLocation || r.RelationshipType?.Mnemonic == "DedicatedServiceDeliveryLocation")?.TargetEntityKey.Value,
                            act_id        = o.Key.Value,
                            class_id      = o.ClassConceptKey.Value,
                            type_id       = o.TypeConceptKey.Value,
                            protocol_id   = o.Protocols.FirstOrDefault()?.ProtocolKey,
                            min_date      = o.StartTime?.DateTime.Date,
                            max_date      = o.StopTime?.DateTime.Date,
                            act_date      = o.ActTime.DateTime.Date,
                            product_id    = o.Participations?.FirstOrDefault(r => r.ParticipationRoleKey == ActParticipationKey.Product || r.ParticipationRole?.Mnemonic == "Product")?.PlayerEntityKey.Value,
                            sequence_id   = o.Protocols.FirstOrDefault()?.Sequence,
                            dose_seq      = (o as SubstanceAdministration)?.SequenceId,
                            fulfilled     = false
                        }));

                        var fulfillCalc = data.LoadCollection <ActParticipation>("Participations");
                        if (typeFilter.Count > 0)
                        {
                            fulfillCalc = fulfillCalc.Where(o => typeFilter.Contains(o.LoadProperty <Act>("Act").TypeConceptKey ?? Guid.Empty));
                        }

                        // Are there care plan items existing that dont exist in the calculated care plan, if so that means that the patient has completed steps and we need to indicate that
                        if (existing.Any(o => !o.fulfilled)) // != true is needed because it can be null.
                        {
                            var fulfilled = existing.Where(o => !warehousePlan.Any(pl => pl.protocol_id == o.protocol_id && pl.sequence_id == o.sequence_id));
                            warehousePlan.AddRange(fulfilled.Select(o => new
                            {
                                creation_date = o.creation_date,
                                patient_id    = o.patient_id,
                                location_id   = o.location_id,
                                act_id        = data.LoadCollection <ActParticipation>("Participations").FirstOrDefault(ap => ap.LoadProperty <Act>("Act").LoadCollection <ActProtocol>("Protocols").Any(pr => pr.ProtocolKey == o.protocol_id && pr.Sequence == o.sequence_id))?.Key ?? o.act_id,
                                class_id      = o.class_id,
                                type_id       = o.type_id,
                                protocol_id   = o.protocol_id,
                                min_date      = o.min_date,
                                max_date      = o.max_date,
                                act_date      = o.act_date,
                                product_id    = o.product_id,
                                sequence_id   = o.sequence_id,
                                dose_seq      = o.dose_seq,
                                fulfilled     = true
                            }));
                        }
                        else if (
                            !parms.NoFulfill &&
                            fulfillCalc.Any()) // not calculated anything but there are steps previously done, this is a little more complex
                        {
                            // When something is not yet calculated what we have to do is strip away each act done as part of the protocol and re-calculate when that action was supposed to occur
                            // For example: We calculate PCV we strip away PCV2 and re-run the plan to get the proposal of PCV3 then strip away PCV1 and re-run the plan to get the proposal of PCV2
                            var acts = fulfillCalc.Select(o => o.LoadProperty <Act>("Act"));
                            foreach (var itm in acts.GroupBy(o => o.LoadCollection <ActProtocol>("Protocols").FirstOrDefault()?.ProtocolKey ?? Guid.Empty))
                            {
                                var steps                   = itm.OrderByDescending(o => o.LoadCollection <ActProtocol>("Protocols").FirstOrDefault()?.Sequence);
                                var patientClone            = data.Clone() as Patient;
                                patientClone.Participations = new List <ActParticipation>(data.Participations);
                                foreach (var s in steps)
                                {
                                    patientClone.Participations.RemoveAll(o => o.ActKey == s.Key);
                                    // Run protocol
                                    IEnumerable <Act> candidate;
                                    if (itm.Key == Guid.Empty) // There is no protocol identifier
                                    {
                                        var tempPlan = careplanService.CreateCarePlan(patientClone, false, new Dictionary <String, Object>()
                                        {
                                            { "isBackground", true }, { "ignoreEntry", true }
                                        });
                                        if (tempPlan.Action.Count == 0)
                                        {
                                            continue;
                                        }
                                        candidate = tempPlan.Action.OfType <SubstanceAdministration>().Where(o => o.SequenceId == (s as SubstanceAdministration)?.SequenceId &&
                                                                                                             o.Participations.FirstOrDefault(pt => pt.ParticipationRoleKey == ActParticipationKey.Product).PlayerEntityKey == s.Participations.FirstOrDefault(pt => pt.ParticipationRoleKey == ActParticipationKey.Product).PlayerEntityKey);
                                        if (candidate.Count() != 1)
                                        {
                                            continue;
                                        }
                                    }
                                    else
                                    {
                                        var tempPlan = careplanService.CreateCarePlan(patientClone, false, new Dictionary <String, Object>()
                                        {
                                            { "isBackground", true }, { "ignoreEntry", true }
                                        }, itm.Key);
                                        if (tempPlan.Action.Count == 0)
                                        {
                                            continue;
                                        }
                                        candidate = tempPlan.Action.Where(o => o.Protocols.FirstOrDefault().Sequence == s.Protocols.FirstOrDefault().Sequence);
                                        if (candidate.Count() != 1)
                                        {
                                            candidate = tempPlan.Action.OfType <SubstanceAdministration>().Where(o => o.SequenceId == (s as SubstanceAdministration)?.SequenceId);
                                            if (candidate.Count() != 1)
                                            {
                                                continue;
                                            }
                                        }
                                    }

                                    var planned = candidate.FirstOrDefault();

                                    warehousePlan.Add(new
                                    {
                                        creation_date = DateTime.Now,
                                        patient_id    = data.Key.Value,
                                        location_id   = data.Relationships.FirstOrDefault(r => r.RelationshipTypeKey == EntityRelationshipTypeKeys.DedicatedServiceDeliveryLocation || r.RelationshipType?.Mnemonic == "DedicatedServiceDeliveryLocation")?.TargetEntityKey.Value,
                                        act_id        = s.Key,
                                        class_id      = planned.ClassConceptKey.Value,
                                        type_id       = planned.TypeConceptKey.Value,
                                        protocol_id   = itm.Key,
                                        min_date      = planned.StartTime?.DateTime.Date,
                                        max_date      = planned.StopTime?.DateTime.Date,
                                        act_date      = planned.ActTime.DateTime.Date,
                                        product_id    = planned.Participations?.FirstOrDefault(r => r.ParticipationRoleKey == ActParticipationKey.Product || r.ParticipationRole?.Mnemonic == "Product")?.PlayerEntityKey.Value,
                                        sequence_id   = planned.Protocols.FirstOrDefault()?.Sequence,
                                        dose_seq      = (planned as SubstanceAdministration)?.SequenceId,
                                        fulfilled     = true
                                    });
                                }
                            }
                        }

                        // Insert plans
                        warehouseService.Add(dataMart.Id, warehousePlan);
                    }, p);
                }
            }

            wtp.WaitOne();

            return(0);
        }
Exemple #5
0
        /// <summary>
        /// Truncate the existing care plan database
        /// </summary>
        public void Truncate()
        {
            try
            {
                if (this.m_actCarePlanPromise.Count == 0)
                {
                    // Deploy schema?
                    this.m_dataMart = this.m_warehouseService.GetDatamart("oizcp");
                    if (this.m_dataMart != null)
                    {
                        this.m_warehouseService.DeleteDatamart(this.m_dataMart.Id);
                    }

                    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
                {
                    throw new InvalidOperationException(Strings.err_already_computing_careplan);
                }
            }
            catch (Exception e)
            {
                this.m_tracer.TraceError("Error truncating care plan: {0}", e);
                this.m_resetEvent.Set();
                throw;
            }
        }
Exemple #6
0
        /// <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);
        }
Exemple #7
0
        /// <summary>
        /// Create properties for the specified container
        /// </summary>
        private void CreateProperties(DataContext context, String pathName, DatamartSchema schema, IDatamartSchemaPropertyContainer container)
        {
            List <SqlStatement> indexes = new List <SqlStatement>();

            // Create the property container table
            SqlStatement createSql = context.CreateSqlStatement("CREATE TABLE ")
                                     .Append(pathName)
                                     .Append("(")
                                     .Append("uuid UUID NOT NULL PRIMARY KEY DEFAULT uuid_generate_v4(),");

            if (container is DatamartSchemaProperty)
            {
                createSql = createSql.Append("entity_uuid UUID NOT NULL, ");
            }

            // Create the specified dm_<<name>>_table
            foreach (var itm in (container ?? schema).Properties)
            {
                itm.Id = itm.Id == default(Guid) ? Guid.NewGuid() : itm.Id;

                // Insert
                context.Insert(new AdhocProperty()
                {
                    Attributes  = (int)itm.Attributes,
                    TypeId      = (int)itm.Type,
                    ContainerId = (container as DatamartSchemaProperty)?.Id,
                    SchemaId    = schema.Id,
                    Name        = itm.Name,
                    PropertyId  = itm.Id
                });

                if (itm.Properties?.Count > 0)
                {
                    this.CreateProperties(context, String.Format("{0}_{1}", pathName, itm.Name), schema, itm);
                }

                // get datatype
                var typeString = context.GetDataType(itm.Type);;

                // Add property to the table
                if (!String.IsNullOrEmpty(typeString))
                {
                    String attributeString = "";
                    if (itm.Attributes.HasFlag(SchemaPropertyAttributes.NotNull))
                    {
                        attributeString += "NOT NULL ";
                    }
                    if (itm.Attributes.HasFlag(SchemaPropertyAttributes.Unique))
                    {
                        attributeString += "UNIQUE ";
                    }
                    createSql = createSql.Append($"{itm.Name} {typeString} {attributeString}");

                    // HACK:
                    createSql.Append(",");
                    if (itm.Attributes.HasFlag(SchemaPropertyAttributes.Indexed))
                    {
                        indexes.Add(context.CreateSqlStatement($"CREATE INDEX {pathName}_{itm.Name}_idx ON {pathName}({itm.Name})"));
                    }
                }
            }

            createSql.RemoveLast();
            createSql = createSql.Append(")");

            // Now execute SQL create statement
            if (!(container is DatamartStoredQuery))
            {
                context.ExecuteNonQuery(createSql);
                foreach (var idx in indexes)
                {
                    context.ExecuteNonQuery(idx);
                }
            }
        }
Exemple #8
0
        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;
                }
            }
        }