Esempio n. 1
0
        /// <summary>
        /// Update container
        /// </summary>
        public VersionedDomainIdentifier UpdateContainer(System.ComponentModel.IContainer storageData, DataPersistenceMode mode)
        {
            if (m_disposed)
            {
                throw new ObjectDisposedException("DatabasePersistenceService");
            }

            if (storageData == null)
            {
                throw new ArgumentNullException("storageData");
            }

            // Get the persister
            IComponentPersister         persister     = GetPersister(storageData.GetType());
            ISystemConfigurationService configService = ApplicationContext.ConfigurationService;

            if (persister != null)
            {
                IDbTransaction tx   = null;
                IDbConnection  conn = null;
                try
                {
                    conn = DatabasePersistenceService.ConnectionManager.GetConnection();

                    RegistrationEvent hsrEvent = storageData as RegistrationEvent;

                    // Is the record something that we have access to?
                    if (hsrEvent.AlternateIdentifier != null && !hsrEvent.AlternateIdentifier.Domain.Equals(configService.OidRegistrar.GetOid(ClientRegistryOids.REGISTRATION_EVENT).Oid))
                    {
                        throw new ArgumentException(String.Format("The record OID '{0}' cannot be retrieved by this repository, expecting OID '{1}'",
                                                                  hsrEvent.AlternateIdentifier.Domain, configService.OidRegistrar.GetOid(ClientRegistryOids.REGISTRATION_EVENT).Oid));
                    }

                    decimal tryDec         = default(decimal);
                    bool    isDirectUpdate = false;

                    // Is there no event identifier ?
                    if (hsrEvent.AlternateIdentifier != null && !Decimal.TryParse(hsrEvent.AlternateIdentifier.Identifier, out tryDec))
                    {
                        throw new ArgumentException(String.Format("The identifier '{0}' is not a valid identifier for this repository", hsrEvent.AlternateIdentifier.Identifier));
                    }
                    else if (hsrEvent.AlternateIdentifier == null) // The alternate identifier is null ... so we need to look up the registration event to version ... interesting....
                    {
                        this.EnrichRegistrationEvent(conn, tx, hsrEvent);
                    }
                    else
                    {
                        // Get the person name
                        isDirectUpdate = true; // Explicit update
                    }

                    // Validate and duplicate the components that are to be loaded as part of the new version
                    var oldHsrEvent = GetContainer(hsrEvent.AlternateIdentifier, true) as RegistrationEvent; // Get the old container
                    if (oldHsrEvent == null)
                    {
                        throw new MissingPrimaryKeyException(String.Format("Record {1}^^^&{0}&ISO does not exist", hsrEvent.AlternateIdentifier.Domain, hsrEvent.AlternateIdentifier.Identifier));
                    }

                    PersonPersister cp = new PersonPersister();

                    // Validate the old record target
                    Person oldRecordTarget = oldHsrEvent.FindComponent(HealthServiceRecordSiteRoleType.SubjectOf) as Person,
                           newRecordTarget = hsrEvent.FindComponent(HealthServiceRecordSiteRoleType.SubjectOf) as Person;

                    Person verifyRecordTarget = null;
                    if (!isDirectUpdate)
                    {
                        Trace.TraceInformation("Not Direct update, enriching the Patient Data");
                        int idCheck = 0;
                        while (verifyRecordTarget == null || idCheck > newRecordTarget.AlternateIdentifiers.Count)
                        {
                            verifyRecordTarget = cp.GetPerson(conn, null, newRecordTarget.AlternateIdentifiers[idCheck++], true);
                        }

                        if (verifyRecordTarget == null || oldRecordTarget.Id != verifyRecordTarget.Id)
                        {
                            throw new ConstraintException("The update request specifies a different subject than the request currently stored");
                        }
                    }
                    else
                    {
                        verifyRecordTarget = oldRecordTarget;
                    }
                    //newRecordTarget.VersionId = verifyRecordTarget.VersionId;
                    newRecordTarget.Id = verifyRecordTarget.Id;

                    // VAlidate classific
                    if (oldHsrEvent.EventClassifier != hsrEvent.EventClassifier &&
                        (hsrEvent.EventClassifier & RegistrationEventType.Register) == RegistrationEventType.None)
                    {
                        throw new ConstraintException("Record type mis-match between update data and the data already in the persistence store");
                    }

                    if (oldHsrEvent.LanguageCode != hsrEvent.LanguageCode)
                    {
                        throw new ConstraintException("Record language mis-match between update data and data already in persistence store. To change the language use a \"replaces\" relationship rather than an update");
                    }

                    // Are we performing a component update? If so the only two components we want freshened are the CommentOn (for adding comments)
                    // and the ReasonFor | OlderVersionOf comment for change summaries
                    if ((hsrEvent.EventClassifier & RegistrationEventType.ComponentEvent) != 0)
                    {
                        for (int i = hsrEvent.XmlComponents.Count - 1; i >= 0; i--)
                        {
                            if (((hsrEvent.XmlComponents[i].Site as HealthServiceRecordSite).SiteRoleType & (HealthServiceRecordSiteRoleType.CommentOn | HealthServiceRecordSiteRoleType.ReasonFor | HealthServiceRecordSiteRoleType.OlderVersionOf | HealthServiceRecordSiteRoleType.TargetOf)) == 0)
                            {
                                hsrEvent.Remove(hsrEvent.XmlComponents[i]);
                            }
                        }
                    }

                    // Copy over any components that aren't already specified or updated in the new record
                    // Merge the old and new. Sets the update mode appropriately
                    cp.MergePersons(newRecordTarget, oldRecordTarget);

                    // Next we copy this as a replacement of
                    hsrEvent.RemoveAllFromRole(HealthServiceRecordSiteRoleType.SubjectOf);
                    hsrEvent.Add(newRecordTarget, "SUBJ", HealthServiceRecordSiteRoleType.SubjectOf, null);

                    // Begin and update
                    tx = conn.BeginTransaction();

                    var retVal = persister.Persist(conn, tx, storageData as IComponent, true);

                    if (m_configuration.OverridePersistenceMode.HasValue)
                    {
                        mode = m_configuration.OverridePersistenceMode.Value;
                    }

                    if (mode == DataPersistenceMode.Production)
                    {
                        tx.Commit();
                        tx = null;

                        // Mark conflicts if any are outstanding pointing at the old versionj
                        if (this.m_clientRegistryMerge != null)
                        {
                            var existingConflicts = this.m_clientRegistryMerge.GetConflicts(oldHsrEvent.AlternateIdentifier);
                            if (existingConflicts.Count() > 0)
                            {
                                Trace.TraceInformation("Obsoleting existing conlflicts resolved");
                                this.m_clientRegistryMerge.ObsoleteConflicts(oldHsrEvent.AlternateIdentifier);
                            }
                            this.m_threadPool.QueueUserWorkItem(this.MarkConflictsAsync, retVal);
                        }

                        // Notify register
                        if (this.m_notificationService != null)
                        {
                            if (hsrEvent.Mode == RegistrationEventType.Replace)
                            {
                                this.m_notificationService.NotifyDuplicatesResolved(hsrEvent);
                            }
                            else
                            {
                                this.m_notificationService.NotifyUpdate(hsrEvent);
                            }
                        }
                    }
                    else
                    {
                        tx.Rollback();
                    }


                    return(retVal);
                }
                catch (Exception e)
                {
                    if (tx != null)
                    {
                        tx.Rollback();
                    }
                    throw;
                }
                finally
                {
                    if (tx != null)
                    {
                        tx.Dispose();
                    }
                    if (conn != null)
                    {
                        DatabasePersistenceService.ConnectionManager.ReleaseConnection(conn);
                        conn = null;
                    }
                }
            }
            else
            {
                Trace.TraceError("Can't find a persistence handler for type '{0}'", storageData.GetType().Name);
                throw new DataException(String.Format("Can't persist type '{0}'", storageData.GetType().Name));
            }
        }