Esempio n. 1
0
 /// <summary>
 /// Obsolete the act
 /// </summary>
 /// <param name="context"></param>
 internal Act ObsoleteCoreProperties(LocalDataContext context, Act data)
 {
     data.StatusConceptKey = StatusKeys.Obsolete;
     return(base.ObsoleteInternal(context, data));
 }
Esempio n. 2
0
        /// <summary>
        /// From the model instance
        /// </summary>
        public override object FromModelInstance(EntityAddressComponent modelInstance, LocalDataContext context)
        {
            modelInstance.Key = modelInstance.Key ?? Guid.NewGuid();
            var retVal = new DbEntityAddressComponent()
            {
                AddressUuid       = modelInstance.SourceEntityKey?.ToByteArray(),
                ComponentTypeUuid = modelInstance.ComponentTypeKey?.ToByteArray(),
                Uuid = modelInstance.Key?.ToByteArray()
            };

            // Address component already exists?
            byte[] existingKey = null;
            if (String.IsNullOrEmpty(modelInstance.Value))
            {
                return(retVal);
            }
            if (!this.m_addressValueIds.TryGetValue(modelInstance.Value, out existingKey))
            {
                var existing = context.Connection.Table <DbAddressValue>().Where(o => o.Value == modelInstance.Value).Take(1).FirstOrDefault();
                if (existing != null && existing.Key != retVal.Key)
                {
                    retVal.ValueUuid = existing.Uuid;
                }
                else if (!String.IsNullOrEmpty(modelInstance.Value))
                {
                    retVal.ValueUuid = Guid.NewGuid().ToByteArray();
                    context.Connection.Insert(new DbAddressValue()
                    {
                        Uuid  = retVal.ValueUuid,
                        Value = modelInstance.Value
                    });
                }
                lock (this.m_addressValueIds)
                    if (!this.m_addressValueIds.ContainsKey(modelInstance.Value))
                    {
                        this.m_addressValueIds.Add(modelInstance.Value, retVal.ValueUuid);
                    }
            }
            else
            {
                retVal.ValueUuid = existingKey;
            }

            return(retVal);
        }
 /// <summary>
 /// Get from source
 /// </summary>
 public IEnumerable GetFromSource(LocalDataContext context, Guid id, decimal?versionSequenceId)
 {
     return(this.Query(context, o => o.SourceEntityKey == id));
 }
Esempio n. 4
0
        /// <summary>
        /// Insert the specified entity into the data context
        /// </summary>
        internal Entity InsertCoreProperties(LocalDataContext context, Entity data)
        {
            // Ensure FK exists
            if (data.ClassConcept != null)
            {
                data.ClassConcept = data.ClassConcept.EnsureExists(context);
            }
            if (data.DeterminerConcept != null)
            {
                data.DeterminerConcept = data.DeterminerConcept.EnsureExists(context);
            }
            if (data.StatusConcept != null)
            {
                data.StatusConcept = data.StatusConcept.EnsureExists(context);
            }
            if (data.TypeConcept != null)
            {
                data.TypeConcept = data.TypeConcept.EnsureExists(context);
            }
            if (data.Template != null)
            {
                data.Template = data.Template.EnsureExists(context);
            }

            data.ClassConceptKey      = data.ClassConcept?.Key ?? data.ClassConceptKey;
            data.DeterminerConceptKey = data.DeterminerConcept?.Key ?? data.DeterminerConceptKey;
            data.StatusConceptKey     = data.StatusConcept?.Key ?? data.StatusConceptKey;
            data.TypeConceptKey       = data.TypeConcept?.Key ?? data.TypeConceptKey;
            data.TemplateKey          = data.Template?.Key ?? data.TemplateKey;
            data.StatusConceptKey     = data.StatusConceptKey.GetValueOrDefault() == Guid.Empty ? StatusKeys.New : data.StatusConceptKey;

            var retVal = base.InsertInternal(context, data);

            // Identifiers
            if (data.Identifiers != null)
            {
                // Validate unique values for IDs
                var    uniqueIds = data.Identifiers.Where(o => o.AuthorityKey.HasValue).Where(o => ApplicationContext.Current.GetService <IDataPersistenceService <AssigningAuthority> >().Get(o.AuthorityKey.Value)?.IsUnique == true);
                byte[] entId     = data.Key.Value.ToByteArray();

                foreach (var itm in uniqueIds)
                {
                    byte[] authId = itm.Authority.Key.Value.ToByteArray();
                    if (context.Connection.Table <DbEntityIdentifier>().Count(o => o.SourceUuid != entId && o.AuthorityUuid == authId && o.Value == itm.Value) > 0)
                    {
                        throw new DuplicateKeyException(itm.Value);
                    }
                }

                base.UpdateAssociatedItems <EntityIdentifier, Entity>(
                    new List <EntityIdentifier>(),
                    data.Identifiers,
                    retVal.Key,
                    context);
            }

            // Relationships
            if (data.Relationships != null)
            {
                data.Relationships.RemoveAll(o => o.IsEmpty());
                base.UpdateAssociatedItems <EntityRelationship, Entity>(
                    new List <EntityRelationship>(),
                    data.Relationships.Where(o => o.SourceEntityKey == null || o.SourceEntityKey == data.Key || o.TargetEntityKey == data.Key || !o.TargetEntityKey.HasValue).Distinct(new EntityRelationshipPersistenceService.Comparer()).ToList(),
                    retVal.Key,
                    context);
            }

            // Telecoms
            if (data.Telecoms != null)
            {
                base.UpdateAssociatedItems <EntityTelecomAddress, Entity>(
                    new List <EntityTelecomAddress>(),
                    data.Telecoms,
                    retVal.Key,
                    context);
            }

            // Extensions
            if (data.Extensions != null)
            {
                base.UpdateAssociatedItems <EntityExtension, Entity>(
                    new List <EntityExtension>(),
                    data.Extensions,
                    retVal.Key,
                    context);
            }

            // Names
            if (data.Names != null)
            {
                base.UpdateAssociatedItems <EntityName, Entity>(
                    new List <EntityName>(),
                    data.Names,
                    retVal.Key,
                    context);
            }

            // Addresses
            if (data.Addresses != null)
            {
                base.UpdateAssociatedItems <EntityAddress, Entity>(
                    new List <EntityAddress>(),
                    data.Addresses,
                    retVal.Key,
                    context);
            }

            // Notes
            if (data.Notes != null)
            {
                base.UpdateAssociatedItems <EntityNote, Entity>(
                    new List <EntityNote>(),
                    data.Notes,
                    retVal.Key,
                    context);
            }

            // Tags
            if (data.Tags != null)
            {
                base.UpdateAssociatedItems <EntityTag, Entity>(
                    new List <EntityTag>(),
                    data.Tags,
                    retVal.Key,
                    context);
            }

            // Participations = The source is not the patient so we don't touch
            //if (data.Participations != null)
            //    foreach (var itm in data.Participations)
            //    {
            //        itm.PlayerEntityKey = retVal.Key;
            //        itm.EnsureExists(context);
            //    }
            return(retVal);
        }
Esempio n. 5
0
 /// <summary>
 /// Obsoleted status key
 /// </summary>
 protected override Entity ObsoleteInternal(LocalDataContext context, Entity data)
 {
     data.StatusConceptKey = StatusKeys.Obsolete;
     return(base.ObsoleteInternal(context, data));
 }
        /// <summary>
        /// Insert concept
        /// </summary>
        protected override Concept InsertInternal(LocalDataContext context, Concept data)
        {
            // Ensure exists
            if (data.Class != null)
            {
                data.Class = data.Class?.EnsureExists(context);
            }
            if (data.StatusConcept != null)
            {
                data.StatusConcept?.EnsureExists(context);
            }
            data.ClassKey         = data.Class?.Key ?? data.ClassKey;
            data.StatusConceptKey = data.StatusConcept?.Key ?? data.StatusConceptKey;

            data.StatusConceptKey = data.StatusConceptKey ?? StatusKeys.Active;
            data.ClassKey         = data.ClassKey ?? ConceptClassKeys.Other;


            // Persist
            var retVal = base.InsertInternal(context, data);

            // Concept names
            if (retVal.ConceptNames != null)
            {
                base.UpdateAssociatedItems <ConceptName, Concept>(
                    new List <ConceptName>(),
                    retVal.ConceptNames,
                    data.Key.Value,
                    context
                    );
            }

            if (retVal.ConceptSetsXml != null)
            {
                foreach (var r in retVal.ConceptSetsXml)
                {
                    // HACK: SQL lite has decided that there is no such function as "ToByteArray()"
                    var conceptSetUuid = r.ToByteArray();
                    var conceptUuid    = retVal.Key.Value.ToByteArray();

                    if (context.Connection.Table <DbConceptSetConceptAssociation>().Where(o => o.ConceptSetUuid == conceptSetUuid &&
                                                                                          o.ConceptUuid == conceptUuid).Any())
                    {
                        continue;
                    }
                    else
                    {
                        // HACK: SQL lite has decided that there is no such function as "ToByteArray()"
                        var key = Guid.NewGuid().ToByteArray();
                        context.Connection.Insert(new DbConceptSetConceptAssociation()
                        {
                            Uuid           = key,
                            ConceptSetUuid = conceptSetUuid,
                            ConceptUuid    = conceptUuid
                        });
                    }
                }
            }

            return(retVal);
        }
Esempio n. 7
0
 /// <summary>
 /// Conversion based on type
 /// </summary>
 protected override Entity CacheConvert(DbIdentified dataInstance, LocalDataContext context)
 {
     return(this.DoCacheConvert(dataInstance, context));
 }
        /// <summary>
        /// Updates the manufactured material
        /// </summary>
        protected override ManufacturedMaterial UpdateInternal(LocalDataContext context, ManufacturedMaterial data)
        {
            var updated = this.m_materialPersister.Update(context, data);

            return(base.UpdateInternal(context, data));
        }
        /// <summary>
        /// Obsolete the specified manufactured material
        /// </summary>
        protected override ManufacturedMaterial ObsoleteInternal(LocalDataContext context, ManufacturedMaterial data)
        {
            var obsoleted = this.m_materialPersister.Obsolete(context, data);

            return(data);
        }
        /// <summary>
        /// Obsolete the object
        /// </summary>
        protected override TModel ObsoleteInternal(LocalDataContext context, TModel data)
        {
            var retVal = this.m_entityPersister.Obsolete(context, data);

            return(data);
        }
        /// <summary>
        /// Insert the specified manufactured material
        /// </summary>
        protected override ManufacturedMaterial InsertInternal(LocalDataContext context, ManufacturedMaterial data)
        {
            var retVal = this.m_materialPersister.Insert(context, data);

            return(base.InsertInternal(context, data));
        }
 /// <summary>
 /// Do cache convert
 /// </summary>
 protected override TModel CacheConvert(DbIdentified o, LocalDataContext context)
 {
     return((TModel)this.m_entityPersister.DoCacheConvert(o, context));
 }
Esempio n. 13
0
        /// <summary>
        /// Cache convert an act version
        /// </summary>
        protected override Act CacheConvert(DbIdentified dataInstance, LocalDataContext context)
        {
            if (dataInstance == null)
            {
                return(null);
            }
            DbAct dbAct  = dataInstance as DbAct;
            Act   retVal = null;
            IDataCachingService cache = ApplicationContext.Current.GetService <IDataCachingService>();

            if (dbAct != null)
            {
                switch (new Guid(dbAct.ClassConceptUuid).ToString().ToUpper())
                {
                case ControlAct:
                    retVal = cache?.GetCacheItem <ControlAct>(dbAct.Key);
                    break;

                case SubstanceAdministration:
                    retVal = cache?.GetCacheItem <SubstanceAdministration>(dbAct.Key);
                    break;

                case Observation:
                    var dbObs = context.Connection.Table <DbObservation>().Where(o => o.Uuid == dbAct.Uuid).FirstOrDefault();
                    if (dbObs != null)
                    {
                        switch (dbObs.ValueType)
                        {
                        case "ST":
                            retVal = cache?.GetCacheItem <TextObservation>(dbAct.Key);
                            break;

                        case "CD":
                            retVal = cache?.GetCacheItem <CodedObservation>(dbAct.Key);
                            break;

                        case "PQ":
                            retVal = cache?.GetCacheItem <QuantityObservation>(dbAct.Key);
                            break;
                        }
                    }
                    break;

                case Encounter:
                    retVal = cache?.GetCacheItem <PatientEncounter>(dbAct.Key);
                    break;

                case Condition:
                default:
                    retVal = cache?.GetCacheItem <Act>(dbAct.Key);
                    break;
                }
            }
            else if (dataInstance is DbControlAct)
            {
                retVal = cache?.GetCacheItem <ControlAct>(dataInstance.Key);
            }
            else if (dataInstance is DbSubstanceAdministration)
            {
                retVal = cache?.GetCacheItem <SubstanceAdministration>(dataInstance.Key);
            }
            else if (dataInstance is DbTextObservation)
            {
                retVal = cache?.GetCacheItem <TextObservation>(dataInstance.Key);
            }
            else if (dataInstance is DbCodedObservation)
            {
                retVal = cache?.GetCacheItem <CodedObservation>(dataInstance.Key);
            }
            else if (dataInstance is DbQuantityObservation)
            {
                retVal = cache?.GetCacheItem <QuantityObservation>(dataInstance.Key);
            }
            else if (dataInstance is DbPatientEncounter)
            {
                retVal = cache?.GetCacheItem <PatientEncounter>(dataInstance.Key);
            }

            // Return cache value
            if (retVal != null)
            {
                if (retVal.LoadState < context.DelayLoadMode)
                {
                    retVal.LoadAssociations(context,
                                            // Exclude
                                            nameof(OpenIZ.Core.Model.Acts.Act.Extensions),
                                            nameof(OpenIZ.Core.Model.Acts.Act.Tags),
                                            nameof(OpenIZ.Core.Model.Acts.Act.Identifiers),
                                            nameof(OpenIZ.Core.Model.Acts.Act.Notes),
                                            nameof(OpenIZ.Core.Model.Acts.Act.Policies)
                                            );
                }
                return(retVal);
            }
            else
            {
                return(base.CacheConvert(dataInstance, context));
            }
        }
Esempio n. 14
0
 /// <summary>
 /// Obsolete
 /// </summary>
 protected override Act ObsoleteInternal(LocalDataContext context, Act data)
 {
     return(this.ObsoleteCoreProperties(context, data));
 }
Esempio n. 15
0
 /// <summary>
 /// Connot query bundles
 /// </summary>
 protected override IEnumerable <Bundle> QueryInternal(LocalDataContext context, string storedQueryName, IDictionary <string, object> parms, int offset, int count, out int totalResults, Guid queryId, bool countResults)
 {
     totalResults = 0;
     return(new List <Bundle>());
 }
Esempio n. 16
0
        /// <summary>
        /// Load specified associations
        /// </summary>
        public static void LoadAssociations <TModel>(this TModel me, LocalDataContext context, params string[] excludeProperties) where TModel : IIdentifiedEntity
        {
            //using (context.LockConnection())
            //{
            if (me == null)
            {
                throw new ArgumentNullException(nameof(me));
            }
            else if (me.LoadState == LoadState.FullLoad ||
                     context.DelayLoadMode == LoadState.PartialLoad && context.LoadAssociations == null)
            {
                return;
            }
            else if (context.Connection.IsInTransaction)
            {
                return;
            }

#if DEBUG
            /*
             * Me neez all the timez
             *
             * /\_/\
             * >^.^<.---.
             * _'-`-'     )\
             * (6--\ |--\ (`.`-.
             *   --'  --'  ``-'
             */
            Stopwatch sw = new Stopwatch();
            sw.Start();
#endif

            // Cache get classification property - thiz makez us fasters
            PropertyInfo classProperty = null;
            if (!s_classificationProperties.TryGetValue(typeof(TModel), out classProperty))
            {
                classProperty = typeof(TModel).GetRuntimeProperty(typeof(TModel).GetTypeInfo().GetCustomAttribute <ClassifierAttribute>()?.ClassifierProperty ?? "____XXX");
                if (classProperty != null)
                {
                    classProperty = typeof(TModel).GetRuntimeProperty(classProperty.GetCustomAttribute <SerializationReferenceAttribute>()?.RedirectProperty ?? classProperty.Name);
                }
                lock (s_lockObject)
                    if (!s_classificationProperties.ContainsKey(typeof(TModel)))
                    {
                        s_classificationProperties.Add(typeof(TModel), classProperty);
                    }
            }

            // Classification property?
            String classValue = classProperty?.GetValue(me)?.ToString();

            // Cache the props so future kitties can call it
            IEnumerable <PropertyInfo> properties = null;
            var propertyCacheKey = $"{me.GetType()}.FullName[{classValue}]";
            if (!s_runtimeProperties.TryGetValue(propertyCacheKey, out properties))
            {
                lock (s_runtimeProperties)
                {
                    properties = me.GetType().GetRuntimeProperties().Where(o => o.GetCustomAttribute <DataIgnoreAttribute>() == null && o.GetCustomAttributes <AutoLoadAttribute>().Any(p => p.ClassCode == classValue || p.ClassCode == null) && typeof(IdentifiedData).GetTypeInfo().IsAssignableFrom(o.PropertyType.StripGeneric().GetTypeInfo())).ToList();

                    if (!s_runtimeProperties.ContainsKey(propertyCacheKey))
                    {
                        s_runtimeProperties.Add(propertyCacheKey, properties);
                    }
                }
            }

            // Load fast or lean mode only root associations which will appear on the wire
            if (context.LoadAssociations != null)
            {
                var loadAssociations = context.LoadAssociations.Where(o => o.StartsWith(me.GetType().GetTypeInfo().GetCustomAttribute <XmlTypeAttribute>()?.TypeName))
                                       .Select(la => la.Contains(".") ? la.Substring(la.IndexOf(".") + 1) : la).ToArray();
                if (loadAssociations.Length == 0)
                {
                    return;
                }
                properties = properties.Where(p => loadAssociations.Any(la => la == p.Name)).ToList();
            }

            // Iterate over the properties and load the properties
            foreach (var pi in properties)
            {
                if (excludeProperties?.Contains(pi.Name) == true)
                {
                    continue;
                }
                // Map model type to domain
                var adoPersister = LocalPersistenceService.GetPersister(pi.PropertyType.StripGeneric());

                // Loading associations, so what is the associated type?
                if (typeof(IList).GetTypeInfo().IsAssignableFrom(pi.PropertyType.GetTypeInfo()) &&
                    adoPersister is ILocalAssociativePersistenceService &&
                    me.Key.HasValue) // List so we select from the assoc table where we are the master table
                {
                    // Is there not a value?
                    var assocPersister = adoPersister as ILocalAssociativePersistenceService;

                    // We want to que   ry based on our PK and version if applicable
                    decimal?versionSequence = (me as IVersionedEntity)?.VersionSequence;
                    var     assoc           = assocPersister.GetFromSource(context, me.Key.Value, versionSequence);

                    ConstructorInfo ci = null;
                    if (!m_constructors.TryGetValue(pi.PropertyType, out ci))
                    {
                        var type = pi.PropertyType.StripGeneric();
                        while (type != typeof(Object) && ci == null)
                        {
                            ci   = pi.PropertyType.GetTypeInfo().DeclaredConstructors.FirstOrDefault(o => o.GetParameters().Length == 1 && o.GetParameters()[0].ParameterType == typeof(IEnumerable <>).MakeGenericType(type));
                            type = type.GetTypeInfo().BaseType;
                        }
                        if (ci != null)
                        {
                            lock (s_lockObject)
                                if (!m_constructors.ContainsKey(pi.PropertyType))
                                {
                                    m_constructors.Add(pi.PropertyType, ci);
                                }
                        }
                        else
                        {
                            throw new InvalidOperationException($"This is odd, you seem to have a list with no constructor -> {pi.PropertyType}");
                        }
                    }

                    //var listValue = Activator.CreateInstance(pi.PropertyType, assoc);
                    var listValue = ci.Invoke(new object[] { assoc });
                    pi.SetValue(me, listValue);
                }
                else if (typeof(IIdentifiedEntity).GetTypeInfo().IsAssignableFrom(pi.PropertyType.GetTypeInfo())) // Single
                {
                    // Single property, we want to execute a get on the key property
                    var redirectAtt = pi.GetCustomAttribute <SerializationReferenceAttribute>();
                    if (redirectAtt == null)
                    {
                        continue; // cannot get key property
                    }
                    // We want to issue a query
                    var keyProperty = pi.DeclaringType.GetRuntimeProperty(redirectAtt.RedirectProperty);
                    var keyValue    = keyProperty?.GetValue(me);
                    if (keyValue == null ||
                        Guid.Empty.Equals(keyValue))
                    {
                        continue; // No key specified
                    }
                    // This is kinda messy.. maybe iz to be changez
                    object value = null;
                    if (!context.Data.TryGetValue(keyValue.ToString(), out value))
                    {
                        value = adoPersister.Get(context, (Guid)keyValue);
                        context.AddData(keyValue.ToString(), value);
                    }
                    pi.SetValue(me, value);
                }
            }
#if DEBUG
            sw.Stop();
            s_tracer.TraceVerbose("Load associations for {0} took {1} ms", me, sw.ElapsedMilliseconds);
#endif

            me.LoadState = excludeProperties.Length > 0 ? LoadState.PartialLoad : LoadState.FullLoad;

            ApplicationContext.Current.GetService <IDataCachingService>()?.Add(me as IdentifiedData);
            //}
        }
Esempio n. 17
0
        /// <summary>
        /// Bundles are special, they may be written on the current connection
        /// or in memory
        /// </summary>
        public override Bundle Insert(Bundle data)
        {
            // first, are we just doing a normal insert?
            if (data.Item.Count <= 250)
            {
                return(base.Insert(data));
            }
            else
            { // It is cheaper to open a mem-db and let other threads access the main db for the time being
                base.FireInserting(new DataPersistencePreEventArgs <Bundle>(data));

                // Memory connection
                using (var memConnection = new Data.Connection.WriteableSQLiteConnection(ApplicationContext.Current.GetService <ISQLitePlatform>(), ":memory:", SQLiteOpenFlags.ReadWrite))
                {
                    try
                    {
                        ApplicationContext.Current.SetProgress(Strings.locale_prepareBundle, 0.5f);
                        // We want to apply the initial schema
                        new OpenIZ.Mobile.Core.Configuration.Data.Migrations.InitialCatalog().Install(memConnection, true);


                        // Copy the name component and address component values
                        if (ApplicationContext.Current.GetCurrentContextSecurityKey() == null)
                        {
                            memConnection.Execute($"ATTACH DATABASE '{ApplicationContext.Current.Configuration.GetConnectionString("openIzData").Value}' AS file_db KEY ''");
                        }
                        else
                        {
                            memConnection.Execute($"ATTACH DATABASE '{ApplicationContext.Current.Configuration.GetConnectionString("openIzData").Value}' AS file_db KEY X'{BitConverter.ToString(ApplicationContext.Current.GetCurrentContextSecurityKey()).Replace("-", "")}'");
                        }

                        try
                        {
                            memConnection.BeginTransaction();

                            //// Names & Address
                            memConnection.Execute($"INSERT OR REPLACE INTO phonetic_value SELECT * FROM file_db.phonetic_value");
                            memConnection.Execute($"INSERT OR REPLACE INTO entity_addr_val SELECT * FROM file_db.entity_addr_val");

                            //foreach (var itm in memConnection.Query<String>("SELECT NAME FROM SQLITE_MASTER WHERE TYPE = 'index' AND SQL IS NOT NULL"))
                            //    memConnection.Execute(String.Format("DROP INDEX {0};", itm));
                            memConnection.Commit();
                        }
                        catch
                        {
                            memConnection.Rollback();
                            throw;
                        }

                        memConnection.Execute("DETACH DATABASE file_db");

                        // We insert in the memcontext now
                        using (var memContext = new LocalDataContext(memConnection))
                            this.InsertInternal(memContext, data);

                        var columnMapping = memConnection.TableMappings.Where(o => o.MappedType.Namespace.StartsWith("OpenIZ")).ToList();

                        // Now we attach our local file based DB by requesting a lock so nobody else touches it!
                        using (var fileContext = this.CreateConnection())
                            using (fileContext.LockConnection())
                            {
                                if (ApplicationContext.Current.GetCurrentContextSecurityKey() == null)
                                {
                                    memConnection.Execute($"ATTACH DATABASE '{ApplicationContext.Current.Configuration.GetConnectionString("openIzData").Value}' AS file_db KEY ''");
                                }
                                else
                                {
                                    memConnection.Execute($"ATTACH DATABASE '{ApplicationContext.Current.Configuration.GetConnectionString("openIzData").Value}' AS file_db KEY X'{BitConverter.ToString(ApplicationContext.Current.GetCurrentContextSecurityKey()).Replace("-", "")}'");
                                }

                                try
                                {
                                    memConnection.BeginTransaction();

                                    // Copy copy!!!
                                    int i = 0;
                                    foreach (var tbl in columnMapping)
                                    {
                                        var colNames = String.Join(",", tbl.Columns.Select(o => o.Name).ToArray());
                                        memConnection.Execute($"INSERT OR REPLACE INTO file_db.{tbl.TableName} ({colNames}) SELECT {colNames} FROM {tbl.TableName}");
                                        ApplicationContext.Current.SetProgress(Strings.locale_committing, (float)i++ / columnMapping.Count);
                                    }
                                    ApplicationContext.Current.SetProgress(Strings.locale_committing, 1.0f);

                                    memConnection.Commit();
                                }
                                catch
                                {
                                    memConnection.Rollback();
                                    throw;
                                }
                            }
                    }
                    catch (Exception e)
                    {
                        this.m_tracer.TraceError("Error inserting bundle: {0}", e);
                        return(base.Insert(data)); // Attempt to do a slow insert
                        // TODO: Figure out why the copy command sometimes is missing UUIDs
                        //throw new LocalPersistenceException(Synchronization.Model.DataOperationType.Insert, data, e);
                    }
                }

                base.FireInserted(new DataPersistenceEventArgs <Bundle>(data));
                return(data);
            }
        }
Esempio n. 18
0
        /// <summary>
        /// Try get by classifier
        /// </summary>
        public static IIdentifiedEntity TryGetExisting(this IIdentifiedEntity me, LocalDataContext context, bool forceDbSearch = false)
        {
            // Is there a classifier?
            var idpInstance = LocalPersistenceService.GetPersister(me.GetType()) as ILocalPersistenceService;

            if (idpInstance == null)
            {
                return(null);
            }
            //if (me.Key?.ToString() == "e4d3350b-b0f5-45c1-80ba-49e3844cbcc8")
            //    System.Diagnostics.Debugger.Break();

            IIdentifiedEntity existing = null;

            if (me.Key != null)
            {
                existing = context.TryGetCacheItem(me.Key.Value);
            }
            if (existing != null)
            {
                return(existing);
            }
            else if (!context.Connection.IsInTransaction)
            {
                existing = context.TryGetData(me.Key.Value.ToString()) as IdentifiedData;
            }
            else if (me.Key.HasValue)
            {
                existing = context.FindTransactedItem(me.Key.Value);
            }

            if (forceDbSearch && me.Key.HasValue)
            {
                ApplicationContext.Current.GetService <IDataCachingService>().Remove(me.Key.Value);
            }

            // Is the key not null?
            if (me.Key != Guid.Empty && me.Key != null && existing == null)
            {
                existing = idpInstance.Get(context, me.Key.Value) as IIdentifiedEntity;
            }

            var classAtt = me.GetType().GetTypeInfo().GetCustomAttribute <KeyLookupAttribute>();

            if (classAtt != null && existing == null)
            {
                // Get the domain type
                var dataType = LocalPersistenceService.Mapper.MapModelType(me.GetType());
                var tableMap = TableMapping.Get(dataType);

                // Get the classifier attribute value
                var    classProperty   = me.GetType().GetRuntimeProperty(classAtt.UniqueProperty);
                object classifierValue = classProperty.GetValue(me); // Get the classifier

                // Is the classifier a UUID'd item?
                if (classifierValue is IIdentifiedEntity)
                {
                    classifierValue = (classifierValue as IIdentifiedEntity).Key.Value;
                    classProperty   = me.GetType().GetRuntimeProperty(classProperty.GetCustomAttribute <SerializationReferenceAttribute>()?.RedirectProperty ?? classProperty.Name);
                }

                // Column
                var column = tableMap.GetColumn(LocalPersistenceService.Mapper.MapModelProperty(me.GetType(), dataType, classProperty));
                // Now we want to query
                SqlStatement stmt = new SqlStatement().SelectFrom(dataType)
                                    .Where($"{column.Name} = ?", classifierValue).Build();

                var mapping    = context.Connection.GetMapping(dataType);
                var dataObject = context.Connection.Query(mapping, stmt.SQL, stmt.Arguments.ToArray()).FirstOrDefault();
                if (dataObject != null)
                {
                    existing = idpInstance.ToModelInstance(dataObject, context) as IIdentifiedEntity;
                }
            }

            if (existing != null && me.Key.HasValue)
            {
                context.AddData(me.Key.Value.ToString(), existing);
            }

            return(existing);
        }
Esempio n. 19
0
        /// <summary>
        /// Create an appropriate entity based on the class code
        /// </summary>
        public override Entity ToModelInstance(object dataInstance, LocalDataContext context)
        {
            // Alright first, which type am I mapping to?
            var dbEntity = dataInstance as DbEntity;

            if (dbEntity != null)
            {
                switch (new Guid(dbEntity.ClassConceptUuid).ToString().ToUpper())
                {
                case Device:
                    return(new DeviceEntityPersistenceService().ToModelInstance(dataInstance, context));

                case NonLivingSubject:
                    return(new ApplicationEntityPersistenceService().ToModelInstance(dataInstance, context));

                case Person:
                    return(new PersonPersistenceService().ToModelInstance(dataInstance, context));

                case Patient:
                    return(new PatientPersistenceService().ToModelInstance(dataInstance, context));

                case Provider:
                    return(new ProviderPersistenceService().ToModelInstance(dataInstance, context));

                case Place:
                case CityOrTown:
                case Country:
                case CountyOrParish:
                case State:
                case ServiceDeliveryLocation:
                    return(new PlacePersistenceService().ToModelInstance(dataInstance, context));

                case Organization:
                    return(new OrganizationPersistenceService().ToModelInstance(dataInstance, context));

                case Material:
                    return(new MaterialPersistenceService().ToModelInstance(dataInstance, context));

                case ManufacturedMaterial:
                    return(new ManufacturedMaterialPersistenceService().ToModelInstance(dataInstance, context));

                default:
                    return(this.ToModelInstance <Entity>(dbEntity, context));
                }
            }
            else if (dataInstance is DbDeviceEntity)
            {
                return(new DeviceEntityPersistenceService().ToModelInstance(dataInstance, context));
            }
            else if (dataInstance is DbApplicationEntity)
            {
                return(new ApplicationEntityPersistenceService().ToModelInstance(dataInstance, context));
            }
            else if (dataInstance is DbPerson)
            {
                return(new PersonPersistenceService().ToModelInstance(dataInstance, context));
            }
            else if (dataInstance is DbPatient)
            {
                return(new PatientPersistenceService().ToModelInstance(dataInstance, context));
            }
            else if (dataInstance is DbProvider)
            {
                return(new ProviderPersistenceService().ToModelInstance(dataInstance, context));
            }
            else if (dataInstance is DbPlace)
            {
                return(new PlacePersistenceService().ToModelInstance(dataInstance, context));
            }
            else if (dataInstance is DbOrganization)
            {
                return(new OrganizationPersistenceService().ToModelInstance(dataInstance, context));
            }
            else if (dataInstance is DbMaterial)
            {
                return(new MaterialPersistenceService().ToModelInstance(dataInstance, context));
            }
            else if (dataInstance is DbManufacturedMaterial)
            {
                return(new ManufacturedMaterialPersistenceService().ToModelInstance(dataInstance, context));
            }
            else
            {
                return(null);
            }
        }
        /// <summary>
        /// Convert the specified object to a model instance
        /// </summary>
        public override TextObservation ToModelInstance(DbTextObservation dataInstance, DbAct actInstance, DbObservation obsInstance, LocalDataContext context)
        {
            var retVal = base.ToModelInstance(dataInstance, actInstance, obsInstance, context);

            retVal.Value = dataInstance.Value;
            return(retVal);
        }
Esempio n. 21
0
        /// <summary>
        /// Perform the cache convert
        /// </summary>
        internal Entity DoCacheConvert(DbIdentified dataInstance, LocalDataContext context)
        {
            if (dataInstance == null)
            {
                return(null);
            }
            // Alright first, which type am I mapping to?
            var    dbEntity           = dataInstance as DbEntity;
            Entity retVal             = null;
            IDataCachingService cache = ApplicationContext.Current.GetService <IDataCachingService>();

            if (dbEntity != null)
            {
                switch (new Guid(dbEntity.ClassConceptUuid).ToString().ToUpper())
                {
                case Device:
                    retVal = cache?.GetCacheItem <DeviceEntity>(dbEntity.Key);
                    break;

                case NonLivingSubject:
                    retVal = cache?.GetCacheItem <ApplicationEntity>(dbEntity.Key);
                    break;

                case Person:
                    retVal = cache?.GetCacheItem <UserEntity>(dbEntity.Key);
                    if (retVal == null)
                    {
                        retVal = cache?.GetCacheItem <Person>(dbEntity.Key);
                    }
                    break;

                case Patient:
                    retVal = cache?.GetCacheItem <Patient>(dbEntity.Key);
                    break;

                case Provider:
                    retVal = cache?.GetCacheItem <Provider>(dbEntity.Key);

                    break;

                case Place:
                case CityOrTown:
                case Country:
                case CountyOrParish:
                case State:
                case ServiceDeliveryLocation:
                    retVal = cache?.GetCacheItem <Place>(dbEntity.Key);

                    break;

                case Organization:
                    retVal = cache?.GetCacheItem <Organization>(dbEntity.Key);

                    break;

                case Material:
                    retVal = cache?.GetCacheItem <Material>(dbEntity.Key);

                    break;

                case ManufacturedMaterial:
                    retVal = cache?.GetCacheItem <ManufacturedMaterial>(dbEntity.Key);

                    break;

                default:
                    retVal = cache?.GetCacheItem <Entity>(dbEntity.Key);
                    break;
                }
            }
            else if (dataInstance is DbDeviceEntity)
            {
                retVal = cache?.GetCacheItem <DeviceEntity>(dataInstance.Key);
            }
            else if (dataInstance is DbApplicationEntity)
            {
                retVal = cache?.GetCacheItem <ApplicationEntity>(dataInstance.Key);
            }
            else if (dataInstance is DbPerson)
            {
                retVal = cache?.GetCacheItem <UserEntity>(dataInstance.Key);
            }
            else if (dataInstance is DbPatient)
            {
                retVal = cache?.GetCacheItem <Patient>(dataInstance.Key);
            }
            else if (dataInstance is DbProvider)
            {
                retVal = cache?.GetCacheItem <Provider>(dataInstance.Key);
            }
            else if (dataInstance is DbPlace)
            {
                retVal = cache?.GetCacheItem <Place>(dataInstance.Key);
            }
            else if (dataInstance is DbOrganization)
            {
                retVal = cache?.GetCacheItem <Organization>(dataInstance.Key);
            }
            else if (dataInstance is DbMaterial)
            {
                retVal = cache?.GetCacheItem <Material>(dataInstance.Key);
            }
            else if (dataInstance is DbManufacturedMaterial)
            {
                retVal = cache?.GetCacheItem <ManufacturedMaterial>(dataInstance.Key);
            }

            // Return cache value
            if (retVal != null)
            {
                if (retVal.LoadState < context.DelayLoadMode)
                {
                    retVal.LoadAssociations(context,
                                            // Exclude
                                            nameof(OpenIZ.Core.Model.Entities.Entity.Extensions),
                                            nameof(OpenIZ.Core.Model.Entities.Entity.Notes),
                                            nameof(OpenIZ.Core.Model.Entities.Entity.Participations),
                                            nameof(OpenIZ.Core.Model.Entities.Entity.Telecoms),
                                            nameof(OpenIZ.Core.Model.Entities.UserEntity.SecurityUser)
                                            );
                }
                return(retVal);
            }
            else
            {
                return(base.CacheConvert(dataInstance, context));
            }
        }
        /// <summary>
        /// Convert the specified object to a model instance
        /// </summary>
        public override CodedObservation ToModelInstance(DbCodedObservation dataInstance, DbAct actInstance, DbObservation obsInstance, LocalDataContext context)
        {
            var retVal = base.ToModelInstance(dataInstance, actInstance, obsInstance, context);

            if (dataInstance.Value != null)
            {
                retVal.ValueKey = new Guid(dataInstance.Value);
            }
            return(retVal);
        }
Esempio n. 23
0
        /// <summary>
        /// Update the specified entity
        /// </summary>
        internal Entity UpdateCoreProperties(LocalDataContext context, Entity data)
        {
            // Esnure exists
            if (data.ClassConcept != null)
            {
                data.ClassConcept = data.ClassConcept.EnsureExists(context);
            }
            if (data.DeterminerConcept != null)
            {
                data.DeterminerConcept = data.DeterminerConcept.EnsureExists(context);
            }
            if (data.StatusConcept != null)
            {
                data.StatusConcept = data.StatusConcept.EnsureExists(context);
            }
            if (data.TypeConcept != null)
            {
                data.TypeConcept = data.TypeConcept.EnsureExists(context);
            }
            data.ClassConceptKey      = data.ClassConcept?.Key ?? data.ClassConceptKey;
            data.DeterminerConceptKey = data.DeterminerConcept?.Key ?? data.DeterminerConceptKey;
            data.StatusConceptKey     = data.StatusConcept?.Key ?? data.StatusConceptKey;
            data.TypeConceptKey       = data.TypeConcept?.Key ?? data.TypeConceptKey;


            var retVal = base.UpdateInternal(context, data);

            byte[] entityUuid = retVal.Key.Value.ToByteArray();


            // Set appropriate versioning
            retVal.PreviousVersion = new Entity()
            {
                ClassConcept = retVal.ClassConcept,
                Key          = retVal.Key,
                VersionKey   = retVal.PreviousVersionKey,
                CreationTime = (DateTimeOffset)retVal.CreationTime,
                CreatedByKey = retVal.CreatedByKey
            };
            retVal.CreationTime = DateTimeOffset.Now;
            retVal.CreatedByKey = data.CreatedByKey == Guid.Empty || data.CreatedByKey == null?base.CurrentUserUuid(context) : data.CreatedByKey;


            // Identifiers
            if (data.Identifiers != null)
            {
                // Validate unique values for IDs
                if (this.m_uniqueAssigningAuthorites == null)
                {
                    this.m_uniqueAssigningAuthorites = new HashSet <Guid>(context.Connection.Table <DbAssigningAuthority>().Where(o => o.IsUnique).ToArray().Select(o => new Guid(o.Uuid)));
                }

                var    uniqueIds = data.Identifiers.Where(o => o.AuthorityKey.HasValue).Where(o => this.m_uniqueAssigningAuthorites.Contains(o.Authority.Key.Value));
                byte[] entId     = data.Key.Value.ToByteArray();

                foreach (var itm in uniqueIds)
                {
                    byte[] authId = itm.Authority.Key.Value.ToByteArray();
                    if (context.Connection.Table <DbEntityIdentifier>().Count(o => o.SourceUuid != entId && o.AuthorityUuid == authId && o.Value == itm.Value) > 0)
                    {
                        throw new DuplicateKeyException(itm.Value);
                    }
                }

                base.UpdateAssociatedItems <EntityIdentifier, Entity>(
                    context.Connection.Table <DbEntityIdentifier>().Where(o => o.SourceUuid == entityUuid).ToList().Select(o => m_mapper.MapDomainInstance <DbEntityIdentifier, EntityIdentifier>(o)).ToList(),
                    data.Identifiers,
                    retVal.Key,
                    context);
            }

            // Relationships
            if (data.Relationships != null)
            {
                data.Relationships.RemoveAll(o => o.IsEmpty());

                base.UpdateAssociatedItems <EntityRelationship, Entity>(
                    context.Connection.Table <DbEntityRelationship>().Where(o => o.SourceUuid == entityUuid).ToList().Select(o => m_mapper.MapDomainInstance <DbEntityRelationship, EntityRelationship>(o)).ToList(),
                    data.Relationships.Where(o => o.SourceEntityKey == null || o.SourceEntityKey == data.Key || o.TargetEntityKey == data.Key || !o.TargetEntityKey.HasValue).Distinct(new EntityRelationshipPersistenceService.Comparer()).ToList(),
                    retVal.Key,
                    context);
            }

            // Telecoms
            if (data.Telecoms != null)
            {
                base.UpdateAssociatedItems <EntityTelecomAddress, Entity>(
                    context.Connection.Table <DbTelecomAddress>().Where(o => o.SourceUuid == entityUuid).ToList().Select(o => m_mapper.MapDomainInstance <DbTelecomAddress, EntityTelecomAddress>(o)).ToList(),
                    data.Telecoms,
                    retVal.Key,
                    context);
            }

            // Extensions
            if (data.Extensions != null)
            {
                base.UpdateAssociatedItems <EntityExtension, Entity>(
                    context.Connection.Table <DbEntityExtension>().Where(o => o.SourceUuid == entityUuid).ToList().Select(o => m_mapper.MapDomainInstance <DbEntityExtension, EntityExtension>(o)).ToList(),
                    data.Extensions,
                    retVal.Key,
                    context);
            }

            // Names
            if (data.Names != null)
            {
                base.UpdateAssociatedItems <EntityName, Entity>(
                    context.Connection.Table <DbEntityName>().Where(o => o.SourceUuid == entityUuid).ToList().Select(o => m_mapper.MapDomainInstance <DbEntityName, EntityName>(o)).ToList(),
                    data.Names,
                    retVal.Key,
                    context);
            }

            // Addresses
            if (data.Addresses != null)
            {
                base.UpdateAssociatedItems <EntityAddress, Entity>(
                    context.Connection.Table <DbEntityAddress>().Where(o => o.SourceUuid == entityUuid).ToList().Select(o => m_mapper.MapDomainInstance <DbEntityAddress, EntityAddress>(o)).ToList(),
                    data.Addresses,
                    retVal.Key,
                    context);
            }

            // Notes
            if (data.Notes != null)
            {
                base.UpdateAssociatedItems <EntityNote, Entity>(
                    context.Connection.Table <DbEntityNote>().Where(o => o.EntityUuid == entityUuid).ToList().Select(o => m_mapper.MapDomainInstance <DbEntityNote, EntityNote>(o)).ToList(),
                    data.Notes,
                    retVal.Key,
                    context);
            }

            // Tags
            if (data.Tags != null)
            {
                base.UpdateAssociatedItems <EntityTag, Entity>(
                    context.Connection.Table <DbEntityTag>().Where(o => o.SourceUuid == entityUuid).ToList().Select(o => m_mapper.MapDomainInstance <DbEntityTag, EntityTag>(o)).ToList(),
                    data.Tags,
                    retVal.Key,
                    context);
            }

            // Participations - We don't touch as Act > Participation
            //if(data.Participations != null)
            //{
            //    foreach (var itm in data.Participations)
            //    {
            //        itm.PlayerEntityKey = retVal.Key;
            //        itm.Act?.EnsureExists(context);
            //        itm.SourceEntityKey = itm.Act?.Key ?? itm.SourceEntityKey;
            //    }
            //    var existing = context.Table<DbActParticipation>().Where(o => o.EntityUuid == entityUuid).ToList().Select(o => m_mapper.MapDomainInstance<DbActParticipation, ActParticipation>(o)).ToList();
            //    base.UpdateAssociatedItems<ActParticipation, Act>(
            //        existing,
            //        data.Participations,
            //        retVal.Key,
            //        context,
            //        true);
            //}


            return(retVal);
        }
        /// <summary>
        /// Convert the specified object to a model instance
        /// </summary>
        public override QuantityObservation ToModelInstance(DbQuantityObservation dataInstance, DbAct actInstance, DbObservation obsInstance, LocalDataContext context)
        {
            var retVal = base.ToModelInstance(dataInstance, actInstance, obsInstance, context);

            if (dataInstance.UnitOfMeasureUuid != null)
            {
                retVal.UnitOfMeasureKey = new Guid(dataInstance.UnitOfMeasureUuid);
            }
            retVal.Value = dataInstance.Value;
            return(retVal);
        }
Esempio n. 25
0
        /// <summary>
        /// To model instance
        /// </summary>
        public virtual TEntityType ToModelInstance <TEntityType>(DbEntity dbInstance, LocalDataContext context) where TEntityType : Entity, new()
        {
            var retVal = m_mapper.MapDomainInstance <DbEntity, TEntityType>(dbInstance, useCache: !context.Connection.IsInTransaction);

            // Has this been updated? If so, minimal information about the previous version is available
            if (dbInstance.UpdatedTime != null)
            {
                retVal.CreationTime    = (DateTimeOffset)dbInstance.UpdatedTime;
                retVal.CreatedByKey    = dbInstance.UpdatedByKey;
                retVal.PreviousVersion = new Entity()
                {
                    ClassConcept      = retVal.ClassConcept,
                    DeterminerConcept = retVal.DeterminerConcept,
                    Key          = dbInstance.Key,
                    VersionKey   = dbInstance.PreviousVersionKey,
                    CreationTime = (DateTimeOffset)dbInstance.CreationTime,
                    CreatedByKey = dbInstance.CreatedByKey
                };
            }


            retVal.LoadAssociations(context,
                                    // Exclude
                                    nameof(OpenIZ.Core.Model.Entities.Entity.Extensions),
                                    nameof(OpenIZ.Core.Model.Entities.Entity.Notes),
                                    nameof(OpenIZ.Core.Model.Entities.Entity.Participations),
                                    nameof(OpenIZ.Core.Model.Entities.Entity.Telecoms),
                                    nameof(OpenIZ.Core.Model.Entities.UserEntity.SecurityUser)
                                    );

            //if (!loadFast)
            //{
            //    foreach (var itm in retVal.Relationships.Where(o => !o.InversionIndicator && o.TargetEntity == null))
            //        itm.TargetEntity = this.CacheConvert(context.Get<DbEntity>(itm.TargetEntityKey.Value.ToByteArray()), context, true);
            //    retVal.Relationships.RemoveAll(o => o.InversionIndicator);
            //    retVal.Relationships.AddRange(
            //        context.Table<DbEntityRelationship>().Where(o => o.TargetUuid == dbInstance.Uuid).ToList().Select(o => new EntityRelationship(new Guid(o.RelationshipTypeUuid), new Guid(o.TargetUuid))
            //        {
            //            SourceEntityKey = new Guid(o.EntityUuid),
            //            InversionIndicator = true
            //        })
            //    );
            //    retVal.Participations = new List<ActParticipation>(context.Table<DbActParticipation>().Where(o => o.EntityUuid == dbInstance.Uuid).ToList().Select(o => new ActParticipation(new Guid(o.ParticipationRoleUuid), retVal)
            //    {
            //        ActKey = new Guid(o.ActUuid),
            //        Key = o.Key
            //    }));
            //}


            return(retVal);
        }
        /// <summary>
        /// Convert a data act and observation instance to an observation
        /// </summary>
        public virtual TObservation ToModelInstance(TDbObservation dataInstance, DbAct actInstance, DbObservation obsInstance, LocalDataContext context)
        {
            var retVal = m_actPersister.ToModelInstance <TObservation>(actInstance, context);

            if (obsInstance.InterpretationConceptUuid != null)
            {
                retVal.InterpretationConceptKey = new Guid(obsInstance.InterpretationConceptUuid);
            }

            return(retVal);
        }
Esempio n. 27
0
        /// <summary>
        /// Get components from source
        /// </summary>
        public IEnumerable GetFromSource(LocalDataContext context, Guid id, decimal?versionSequenceId)
        {
            int tr = 0;

            return(this.QueryInternal(context, o => o.SourceEntityKey == id, 0, -1, out tr, Guid.Empty, false));
        }
Esempio n. 28
0
 /// <summary>
 /// Cannot query for bundles
 /// </summary>
 protected override IEnumerable <Bundle> QueryInternal(LocalDataContext context, Expression <Func <Bundle, bool> > query, int offset, int count, out int totalResults, Guid queryId, bool countResults)
 {
     totalResults = 0;
     return(new List <Bundle>());
 }
Esempio n. 29
0
 /// <summary>
 /// Create from model instance
 /// </summary>
 public override object FromModelInstance(SubstanceAdministration modelInstance, LocalDataContext context)
 {
     modelInstance.Key = modelInstance.Key ?? Guid.NewGuid();
     return(new DbSubstanceAdministration()
     {
         DoseQuantity = modelInstance.DoseQuantity,
         DoseUnitConceptUuid = modelInstance.DoseUnitKey?.ToByteArray(),
         RouteConceptUuid = modelInstance.RouteKey?.ToByteArray(),
         SequenceId = modelInstance.SequenceId,
         SiteConceptUuid = modelInstance.SiteKey?.ToByteArray(),
         Uuid = modelInstance.Key?.ToByteArray()
     });
 }
Esempio n. 30
0
        /// <summary>
        /// Update the specified data
        /// </summary>
        internal Act UpdateCoreProperties(LocalDataContext context, Act data)
        {
            if (data.ClassConcept != null)
            {
                data.ClassConcept = data.ClassConcept.EnsureExists(context);
            }
            if (data.MoodConcept != null)
            {
                data.MoodConcept = data.MoodConcept.EnsureExists(context);
            }
            if (data.ReasonConcept != null)
            {
                data.ReasonConcept = data.ReasonConcept.EnsureExists(context);
            }
            if (data.StatusConcept != null)
            {
                data.StatusConcept = data.StatusConcept.EnsureExists(context);
            }
            if (data.TypeConcept != null)
            {
                data.TypeConcept = data.TypeConcept.EnsureExists(context);
            }

            data.ClassConceptKey  = data.ClassConcept?.Key ?? data.ClassConceptKey;
            data.MoodConceptKey   = data.MoodConcept?.Key ?? data.MoodConceptKey;
            data.ReasonConceptKey = data.ReasonConcept?.Key ?? data.ReasonConceptKey;
            data.StatusConceptKey = data.StatusConcept?.Key ?? data.StatusConceptKey ?? StatusKeys.New;
            //            data.TypeConcept?.EnsureExists(context);

            // Do the update
            var retVal = base.UpdateInternal(context, data);

            // Set appropriate versioning
            retVal.PreviousVersion = new Act()
            {
                ClassConcept = retVal.ClassConcept,
                MoodConcept  = retVal.MoodConcept,
                Key          = retVal.Key,
                VersionKey   = retVal.PreviousVersionKey,
                CreationTime = (DateTimeOffset)retVal.CreationTime,
                CreatedByKey = retVal.CreatedByKey
            };
            retVal.CreationTime = DateTimeOffset.Now;
            retVal.CreatedByKey = data.CreatedByKey == Guid.Empty || data.CreatedByKey == null?base.CurrentUserUuid(context) : data.CreatedByKey;

            var ruuid = retVal.Key.Value.ToByteArray();

            if (retVal.Extensions != null)
            {
                base.UpdateAssociatedItems <ActExtension, Act>(
                    context.Connection.Table <DbActExtension>().Where(a => ruuid == a.SourceUuid).ToList().Select(o => m_mapper.MapDomainInstance <DbActExtension, ActExtension>(o)).ToList(),
                    retVal.Extensions,
                    retVal.Key,
                    context);
            }

            if (retVal.Identifiers != null)
            {
                base.UpdateAssociatedItems <ActIdentifier, Act>(
                    context.Connection.Table <DbActIdentifier>().Where(a => ruuid == a.SourceUuid).ToList().Select(o => m_mapper.MapDomainInstance <DbActIdentifier, ActIdentifier>(o)).ToList(),
                    retVal.Identifiers,
                    retVal.Key,
                    context);
            }

            if (retVal.Notes != null)
            {
                base.UpdateAssociatedItems <ActNote, Act>(
                    context.Connection.Table <DbActNote>().Where(a => ruuid == a.SourceUuid).ToList().Select(o => m_mapper.MapDomainInstance <DbActNote, ActNote>(o)).ToList(),
                    retVal.Notes,
                    retVal.Key,
                    context);
            }

            if (retVal.Participations != null)
            {
                retVal.Participations.RemoveAll(o => o.IsEmpty());

                base.UpdateAssociatedItems <ActParticipation, Act>(
                    context.Connection.Table <DbActParticipation>().Where(a => ruuid == a.ActUuid).ToList().Select(o => m_mapper.MapDomainInstance <DbActParticipation, ActParticipation>(o)).ToList(),
                    retVal.Participations.Distinct(new ActParticipationPersistenceService.Comparer()),
                    retVal.Key,
                    context);
            }

            if (retVal.Relationships != null)
            {
                retVal.Relationships.RemoveAll(o => o.IsEmpty());

                base.UpdateAssociatedItems <ActRelationship, Act>(
                    context.Connection.Table <DbActRelationship>().Where(a => ruuid == a.SourceUuid).ToList().Select(o => m_mapper.MapDomainInstance <DbActRelationship, ActRelationship>(o)).ToList(),
                    retVal.Relationships.Distinct(new ActRelationshipPersistenceService.Comparer()),
                    retVal.Key,
                    context);
            }

            if (retVal.Tags != null)
            {
                base.UpdateAssociatedItems <ActTag, Act>(
                    context.Connection.Table <DbActTag>().Where(a => ruuid == a.SourceUuid).ToList().Select(o => m_mapper.MapDomainInstance <DbActTag, ActTag>(o)).ToList(),
                    retVal.Tags,
                    retVal.Key,
                    context);
            }


            if (retVal.Protocols != null)
            {
                base.UpdateAssociatedItems <ActProtocol, Act>(
                    context.Connection.Table <DbActProtocol>().Where(a => ruuid == a.SourceUuid).ToList().Select(o => m_mapper.MapDomainInstance <DbActProtocol, ActProtocol>(o)).ToList(),
                    retVal.Protocols,
                    retVal.Key,
                    context);
            }

            return(retVal);
        }