コード例 #1
0
        public override void AddRootQuery(HqlProjectionQuery query, QueryBuilderArgs args)
        {
            base.AddRootQuery(query, args);

            var from = query.Froms[0];             // added by base.AddRootQuery

            // join report/report part object, because may have criteria or projections on this object
            from.Joins.Add(HqlConstants.JoinReportPart);
            from.Joins.Add(HqlConstants.JoinReport);

            // check if we need to apply the "most recent step" condition
            // this is essentially a workaround to avoid showing duplicates in some worklist results
            // we can only apply this workaround when there is exactly one ps class specified
            // fortunately, there are no use cases yet where more than one ps class is specified
            // that require the workaround
            if (args.ProcedureStepClasses.Length == 1)
            {
                var psClass = CollectionUtils.FirstElement(args.ProcedureStepClasses);
                if (psClass == typeof(PublicationStep))
                {
                    query.Conditions.Add(ConditionMostRecentPublicationStep);
                }
                if (psClass == typeof(TranscriptionStep))
                {
                    query.Conditions.Add(ConditionMostRecentTranscriptionStep);
                }
            }
        }
コード例 #2
0
        /// <summary>
        /// Adds criteria to the query (the 'where' clause).
        /// </summary>
        /// <param name="query"></param>
        /// <param name="args"></param>
        public virtual void AddCriteria(HqlProjectionQuery query, QueryBuilderArgs args)
        {
            QueryBuilderHelpers.AddCriteriaToQuery(HqlConstants.WorklistItemQualifier, args.Criteria, query, RemapHqlExpression);

            // modify the query to workaround some NHibernate bugs
            QueryBuilderHelpers.NHibernateBugWorkaround(query.Froms[0], query.Conditions, a => a);
        }
コード例 #3
0
        public override void AddRootQuery(HqlProjectionQuery query, QueryBuilderArgs args)
        {
            base.AddRootQuery(query, args);

            var from = query.Froms[0];                  // this would be added by the base.AddWorklistRootQuery call

            // join protocol object, because may have criteria on this object
            from.Joins.Add(HqlConstants.JoinProtocol);

            // check if we need to apply the "most recent step" condition
            // this is essentially a workaround to avoid showing duplicates in some worklist results
            // we can only apply this workaround when there is exactly one ps class specified
            // fortunately, there are no use cases yet where more than one ps class is specified
            // that require the workaround
            if (args.ProcedureStepClasses.Length == 1)
            {
                var psClass = CollectionUtils.FirstElement(args.ProcedureStepClasses);
                // the proc step class may be set to the more general "ProtocolProcedureStep" so
                // we need to check for both
                if (psClass == typeof(ProtocolAssignmentStep) || psClass == typeof(ProtocolProcedureStep))
                {
                    // when querying for Rejected protocols, only show the most recent ProtocolAssignmentStep
                    // There may be many ProtocolAssignmentStep if a protocol is rejected, resubmitted and rejected again.
                    // For rejected protocols, the condition "pr.Status not in ('RJ')" is always false.  So the max(EndTime) condition is used
                    // For non-rejected protocols, the first condition is always true, and the max(EndTime) condition is never used.
                    query.Conditions.Add(ConditionMostRecentProtocolAssignmentStepIfRejected);
                }
            }
        }
コード例 #4
0
        /// <summary>
        /// Builds a worklist item query, including the ordering and paging directives.
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        private HqlProjectionQuery BuildWorklistQuery(QueryBuilderArgs args)
        {
            var query = new HqlProjectionQuery();

            this.WorklistItemQueryBuilder.AddRootQuery(query, args);
            this.WorklistItemQueryBuilder.AddConstrainPatientProfile(query, args);
            this.WorklistItemQueryBuilder.AddCriteria(query, args);

            if (args is WorklistQueryArgs)
            {
                this.WorklistItemQueryBuilder.AddFilters(query, (WorklistQueryArgs)args);
            }

            if (args.CountQuery)
            {
                this.WorklistItemQueryBuilder.AddCountProjection(query, args);
            }
            else
            {
                this.WorklistItemQueryBuilder.AddOrdering(query, args);
                this.WorklistItemQueryBuilder.AddItemProjection(query, args);
                this.WorklistItemQueryBuilder.AddPagingRestriction(query, args);
            }

            return(query);
        }
コード例 #5
0
ファイル: WorklistBroker.cs プロジェクト: hksonngan/Xian
        private static HqlProjectionQuery GetBaseQuery()
        {
            var query = new HqlProjectionQuery(new HqlFrom("Worklist", "w"));

            query.Selects.Add(new HqlSelect("w"));
            query.SelectDistinct = true;
            return(query);
        }
コード例 #6
0
ファイル: WorklistBroker.cs プロジェクト: hksonngan/Xian
        private static void AddClassConditions(HqlProjectionQuery query, IEnumerable <string> worklistClassNames)
        {
            var classOr = new HqlOr();

            foreach (var className in worklistClassNames)
            {
                classOr.Conditions.Add(new HqlCondition("w.class = " + className));
            }
            query.Conditions.Add(classOr);
        }
コード例 #7
0
ファイル: WorklistBroker.cs プロジェクト: hksonngan/Xian
        private static void AddStaffGroupConditions(HqlProjectionQuery query, StaffGroup staffGroup)
        {
            query.Froms.Add(new HqlFrom("StaffGroup", "sg"));
            query.Conditions.Add(new HqlCondition("sg = ?", staffGroup));

            var staffGroupOr = new HqlOr();

            staffGroupOr.Conditions.Add(new HqlCondition("sg in elements(w.GroupSubscribers)"));
            query.Conditions.Add(staffGroupOr);
        }
コード例 #8
0
ファイル: WorklistBroker.cs プロジェクト: hksonngan/Xian
        private static void AddStaffConditions(HqlProjectionQuery query, Staff staff)
        {
            query.Froms.Add(new HqlFrom("Staff", "s"));
            query.Conditions.Add(new HqlCondition("s = ?", staff));

            var staffOr = new HqlOr();

            staffOr.Conditions.Add(new HqlCondition("s in elements(w.StaffSubscribers)"));
            staffOr.Conditions.Add(new HqlCondition("s in (select elements(sg.Members) from StaffGroup sg where sg in elements(w.GroupSubscribers))"));

            query.Conditions.Add(staffOr);
        }
コード例 #9
0
ファイル: OrderBroker.cs プロジェクト: hksonngan/Xian
        private static HqlProjectionQuery GetBaseResultRecipientQuery(OrderSearchCriteria orderSearchCriteria, ResultRecipientSearchCriteria recipientSearchCriteria)
        {
            var hqlFrom = new HqlFrom(typeof(Order).Name, "o");

            hqlFrom.Joins.Add(new HqlJoin("o.ResultRecipients", "rr"));

            var query = new HqlProjectionQuery(hqlFrom);

            query.Conditions.AddRange(HqlCondition.FromSearchCriteria("rr", recipientSearchCriteria));
            query.Conditions.AddRange(HqlCondition.FromSearchCriteria("o", orderSearchCriteria));
            return(query);
        }
コード例 #10
0
        private static HqlProjectionQuery GetBaseVisitPractitionerQuery(VisitSearchCriteria visitSearchCriteria, VisitPractitionerSearchCriteria practitionerSearchCriteria)
        {
            var hqlFrom = new HqlFrom(typeof(Visit).Name, "v");

            hqlFrom.Joins.Add(new HqlJoin("v.Practitioners", "vp"));

            var query = new HqlProjectionQuery(hqlFrom);

            query.Conditions.AddRange(HqlCondition.FromSearchCriteria("vp", practitionerSearchCriteria));
            query.Conditions.AddRange(HqlCondition.FromSearchCriteria("v", visitSearchCriteria));
            return(query);
        }
コード例 #11
0
        public IList <PublicationStep> FindUnprocessedSteps(int failedItemRetryDelay, SearchResultPage page)
        {
            var query = new HqlProjectionQuery(new HqlFrom(typeof(PublicationStep).Name, "ps"));

            query.Conditions.Add(new HqlCondition("ps.State = ?", ActivityStatus.SC));
            query.Conditions.Add(new HqlCondition("ps.Scheduling.Performer.Staff is not null"));
            query.Conditions.Add(new HqlCondition("ps.Scheduling.StartTime < ?", Platform.Time));
            query.Conditions.Add(new HqlCondition("(ps.LastFailureTime is null or ps.LastFailureTime < ?)", Platform.Time.AddSeconds(-failedItemRetryDelay)));
            query.Sorts.Add(new HqlSort("ps.Scheduling.StartTime", true, 0));
            query.Page = page;
            return(ExecuteHql <PublicationStep>(query));
        }
コード例 #12
0
        protected List <OrderNoteboxItem> DoQuery(HqlProjectionQuery query)
        {
            var list    = ExecuteHql <object[]>(query);
            var results = new List <NoteboxItem>();

            foreach (var tuple in list)
            {
                var item = (NoteboxItem)Activator.CreateInstance(typeof(NoteboxItem), tuple);
                results.Add(item);
            }

            return(BuildOrderNoteboxItems(results));
        }
コード例 #13
0
        public IList <ModalityProcedureStep> Find(ModalityProcedureStepSearchCriteria mpsCriteria, ProcedureSearchCriteria procedureCriteria)
        {
            var hqlFrom = new HqlFrom(typeof(ModalityProcedureStep).Name, "mps");

            hqlFrom.Joins.Add(new HqlJoin("mps.Procedure", "rp", HqlJoinMode.Inner, true));

            var query = new HqlProjectionQuery(hqlFrom);

            query.Conditions.AddRange(HqlCondition.FromSearchCriteria("mps", mpsCriteria));
            query.Conditions.AddRange(HqlCondition.FromSearchCriteria("rp", procedureCriteria));

            return(ExecuteHql <ModalityProcedureStep>(query));
        }
コード例 #14
0
        private List <OrderNoteboxItem> BuildOrderNoteboxItems(List <NoteboxItem> inboxItems)
        {
            if (inboxItems.Count == 0)
            {
                return(new List <OrderNoteboxItem>());
            }

            // Get all the patients for all the items
            var patients        = CollectionUtils.Unique(CollectionUtils.Map <NoteboxItem, Patient>(inboxItems, item => item.Patient));
            var patientQuery    = new HqlProjectionQuery(new HqlFrom(typeof(PatientProfile).Name, "pp"));
            var patientCriteria = new PatientProfileSearchCriteria();

            patientCriteria.Patient.In(patients);
            patientQuery.Conditions.AddRange(HqlCondition.FromSearchCriteria("pp", patientCriteria));
            var profiles = ExecuteHql <PatientProfile>(patientQuery);

            // Have to manually get the postings (and later their recipients) to work around a Hibernate fetch="subselect" issue.
            // The subselect somehow removed the "top(100)" and "order by" clause.  Making the query slow.
            // Load all the postings for all the notes.  There may be more than one postings per orderNote.
            // Therefore it is inappropriate to just use the postings in the base query.
            var notes           = CollectionUtils.Unique(CollectionUtils.Map <NoteboxItem, Note>(inboxItems, item => item.Note));
            var postingQuery    = new HqlProjectionQuery(new HqlFrom(typeof(NotePosting).Name, "np"));
            var postingCriteria = new NotePostingSearchCriteria();

            postingCriteria.Note.In(notes);
            postingQuery.Conditions.AddRange(HqlCondition.FromSearchCriteria("np", postingCriteria));
            postingQuery.Froms[0].Joins.Add(new HqlJoin("np.Recipient", null, HqlJoinMode.Left, true));
            var postings = ExecuteHql <NotePosting>(postingQuery);

            // Build order notebox items
            var orderNoteboxItems = CollectionUtils.Map(inboxItems,
                                                        delegate(NoteboxItem item)
            {
                // Find the appropriate patient profile based on OrderingFacility
                var profile = CollectionUtils.SelectFirst(profiles,
                                                          pp => pp.Patient.Equals(item.Patient) &&
                                                          pp.Mrn.AssigningAuthority.Code.Equals(item.OrderingFacilityInformationAuthority.Code));

                // Find all the recipients
                var postingsForThisNote = CollectionUtils.Select(postings, np => np.Note.Equals(item.Note));
                var recipients          = CollectionUtils.Map <NotePosting, object>(postingsForThisNote,
                                                                                    posting => posting is StaffNotePosting
                                                        ? (object)((StaffNotePosting)posting).Recipient
                                                        : (object)((GroupNotePosting)posting).Recipient);

                return(new OrderNoteboxItem(item.Note, item.Order, item.Patient, profile, item.Author, recipients,
                                            item.DiagnosticServiceName, item.NotePostingAcknowledged));
            });

            return(orderNoteboxItems);
        }
コード例 #15
0
        public IList <ConfigurationDocument> Find(ConfigurationDocumentSearchCriteria documentCriteria, ConfigurationDocumentBodySearchCriteria bodyCriteria, SearchResultPage page)
        {
            var hqlFrom = new HqlFrom(typeof(ConfigurationDocument).Name, "doc");

            hqlFrom.Joins.Add(new HqlJoin("doc.Body", "body"));

            var query = new HqlProjectionQuery(hqlFrom);

            query.Selects.Add(new HqlSelect("doc"));
            query.Conditions.AddRange(HqlCondition.FromSearchCriteria("doc", documentCriteria));
            query.Conditions.AddRange(HqlCondition.FromSearchCriteria("body", bodyCriteria));
            query.Page = page;

            return(ExecuteHql <ConfigurationDocument>(query));
        }
コード例 #16
0
        /// <summary>
        /// Adds the specified ordering to the specified query, pre-pending the specified qualifier.
        /// </summary>
        /// <param name="qualifier"></param>
        /// <param name="query"></param>
        /// <param name="criteria"></param>
        /// <param name="remapHqlExprFunction"></param>
        /// <remarks>
        /// All HQL dot expressions are passed through the <paramref name="remapHqlExprFunction"/>, allowing the expression
        /// to be modified prior to be added to the query.
        /// </remarks>
        public static void AddOrderingToQuery(string qualifier, HqlProjectionQuery query, WorklistItemSearchCriteria[] criteria,
                                              Converter <string, string> remapHqlExprFunction)
        {
            // use the sorting information from the first WorklistItemSearchCriteria object only
            // (the assumption is that they are all identical)
            var c = CollectionUtils.FirstElement(criteria);

            if (c == null)
            {
                return;
            }

            var sorts = HqlSort.FromSearchCriteria(qualifier, c, remapHqlExprFunction);

            query.Sorts.AddRange(sorts);
        }
コード例 #17
0
        /// <summary>
        /// Builds a query that searches for patient items.
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        private HqlProjectionQuery BuildPatientSearchQuery(QueryBuilderArgs args)
        {
            var query = new HqlProjectionQuery();

            _patientQueryBuilder.AddRootQuery(query, null);
            _patientQueryBuilder.AddCriteria(query, args);

            if (args.CountQuery)
            {
                _patientQueryBuilder.AddCountProjection(query, args);
            }
            else
            {
                _patientQueryBuilder.AddItemProjection(query, args);
            }
            return(query);
        }
コード例 #18
0
ファイル: WorklistBroker.cs プロジェクト: hksonngan/Xian
        public IList <Worklist> Find(string name, bool includeUserDefinedWorklists, IEnumerable <string> worklistClassNames, SearchResultPage page)
        {
            HqlProjectionQuery query = GetBaseQuery();

            if (!string.IsNullOrEmpty(name))
            {
                query.Conditions.Add(new HqlCondition("w.Name like ?", string.Format("%{0}%", name)));
            }

            if (!includeUserDefinedWorklists)
            {
                query.Conditions.Add(new HqlCondition("(w.Owner.Staff is null and w.Owner.Group is null)"));
            }

            AddClassConditions(query, worklistClassNames);
            query.Page = page;

            return(ExecuteHql <Worklist>(query));
        }
コード例 #19
0
        /// <summary>
        /// Builds a query that searches for worklist items.
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        protected HqlProjectionQuery BuildWorklistSearchQuery(QueryBuilderArgs args)
        {
            var query = new HqlProjectionQuery();

            this.WorklistItemQueryBuilder.AddRootQuery(query, args);
            this.WorklistItemQueryBuilder.AddConstrainPatientProfile(query, args);
            this.WorklistItemQueryBuilder.AddCriteria(query, args);
            this.WorklistItemQueryBuilder.AddActiveProcedureStepConstraint(query, args);

            if (args.CountQuery)
            {
                this.WorklistItemQueryBuilder.AddCountProjection(query, args);
            }
            else
            {
                this.WorklistItemQueryBuilder.AddItemProjection(query, args);
            }

            return(query);
        }
コード例 #20
0
ファイル: WorklistBroker.cs プロジェクト: hksonngan/Xian
        public int Count(WorklistOwner owner)
        {
            var query = new HqlProjectionQuery(new HqlFrom("Worklist", "w"));

            query.Selects.Add(new HqlSelect("count(*)"));

            if (owner.IsStaffOwner)
            {
                query.Conditions.Add(new HqlCondition("w.Owner.Staff = ?", owner.Staff));
            }
            else if (owner.IsGroupOwner)
            {
                query.Conditions.Add(new HqlCondition("w.Owner.Group = ?", owner.Group));
            }
            else if (owner.IsAdminOwner)
            {
                query.Conditions.Add(new HqlCondition("(w.Owner.Staff is null and w.Owner.Group is null)"));
            }

            return((int)ExecuteHqlUnique <long>(query));
        }
コード例 #21
0
        /// <summary>
        /// Establishes the root query (the 'from' clause and any 'join' clauses).
        /// </summary>
        /// <param name="query"></param>
        /// <param name="args"></param>
        public override void AddRootQuery(HqlProjectionQuery query, QueryBuilderArgs args)
        {
            var procedureStepClasses = args.ProcedureStepClasses;

            // if we have 1 procedure step class, we can say "from x"
            // otherwise we need to say "from ProcedureStep where ps.class = ..."
            if (procedureStepClasses.Length == 1)
            {
                var procStepClass = CollectionUtils.FirstElement(procedureStepClasses);
                query.Froms.Add(new HqlFrom(procStepClass.Name, "ps", WorklistJoins));
            }
            else
            {
                // either 0 or > 1 classes were specified
                query.Froms.Add(new HqlFrom(typeof(ProcedureStep).Name, "ps", WorklistJoins));
                if (procedureStepClasses.Length > 1)
                {
                    query.Conditions.Add(HqlCondition.IsOfClass("ps", procedureStepClasses));
                }
            }
        }
コード例 #22
0
        public IList <TEntity> Find(TSearchCriteria[] criteria, SearchResultPage page, EntityFindOptions options)
        {
            var query = new HqlProjectionQuery(new HqlFrom(typeof(TEntity).Name, "x"))
            {
                Page = page, Cacheable = options.Cache
            };

            // add fetch joins
            foreach (var fetchJoin in GetDefaultFetchJoins())
            {
                query.Froms[0].Joins.Add(new HqlJoin("x." + fetchJoin, null, HqlJoinMode.Inner, true));
            }

            // apply lock hint
            if (options.LockForUpdate)
            {
                query.SetLockMode("x", LockMode.Upgrade);
            }

            var or = new HqlOr();

            foreach (var c in criteria)
            {
                var and = new HqlAnd(HqlCondition.FromSearchCriteria("x", c));
                if (and.Conditions.Count > 0)
                {
                    or.Conditions.Add(and);
                }

                query.Sorts.AddRange(HqlSort.FromSearchCriteria("x", c));
            }

            if (or.Conditions.Count > 0)
            {
                query.Conditions.Add(or);
            }


            return(ExecuteHql <TEntity>(query, options.Defer));
        }
コード例 #23
0
        private static HqlProjectionQuery GetBaseQuery(INoteboxQueryContext nqc, bool countQuery,
                                                       string entityAlias, Type fromEntityType, HqlSelect[] itemProjection, HqlJoin[] itemJoins)
        {
            var joins = countQuery ? new HqlJoin[] { } : itemJoins;
            var query = new HqlProjectionQuery(new HqlFrom(fromEntityType.Name, entityAlias, joins));

            if (countQuery)
            {
                query.Selects.AddRange(CountProjection);
            }
            else
            {
                query.Selects.AddRange(itemProjection);

                // need this in case orderNote was sent to staff and staffgroup containing same staff
                //query.SelectDistinct = true;

                // add paging if not a count query
                query.Page = nqc.Page;
            }

            return(query);
        }
コード例 #24
0
 /// <summary>
 /// Establishes the root query (the 'from' clause and any 'join' clauses).
 /// </summary>
 /// <param name="query"></param>
 /// <param name="args"></param>
 public override void AddRootQuery(HqlProjectionQuery query, QueryBuilderArgs args)
 {
     query.Froms.Add(DefaultFrom);
 }
コード例 #25
0
ファイル: PatientQueryBuilder.cs プロジェクト: hksonngan/Xian
        /// <summary>
        /// Establishes the root query (the 'from' clause and any 'join' clauses).
        /// </summary>
        /// <param name="query"></param>
        /// <param name="args"></param>
        public override void AddRootQuery(HqlProjectionQuery query, QueryBuilderArgs args)
        {
            query.Froms.Add(DefaultFrom);

            // do not constrain patient profile
        }
コード例 #26
0
 /// <summary>
 /// Adds worklist filters to the query (affects the 'from' clause).
 /// </summary>
 /// <param name="query"></param>
 /// <param name="args"></param>
 public virtual void AddFilters(HqlProjectionQuery query, WorklistQueryArgs args)
 {
     QueryBuilderHelpers.AddCriteriaToQuery(HqlConstants.WorklistItemQualifier, args.FilterCriteria, query, RemapHqlExpression);
 }
コード例 #27
0
 /// <summary>
 /// Constrains the patient profile to match the performing facility.
 /// </summary>
 /// <param name="query"></param>
 /// <param name="args"></param>
 public override void AddConstrainPatientProfile(HqlProjectionQuery query, QueryBuilderArgs args)
 {
     // constrain patient profile to performing facility
     query.Conditions.Add(HqlConstants.ConditionConstrainPatientProfile);
 }
コード例 #28
0
 /// <summary>
 /// Adds the "active procedure step" constraint (affects the 'from' clause).
 /// </summary>
 /// <param name="query"></param>
 /// <param name="args"></param>
 public void AddActiveProcedureStepConstraint(HqlProjectionQuery query, QueryBuilderArgs args)
 {
     query.Conditions.Add(HqlConstants.ConditionActiveProcedureStep);
 }
コード例 #29
0
 /// <summary>
 /// Adds an item projection to the query (the 'select' clause).
 /// </summary>
 /// <param name="query"></param>
 /// <param name="args"></param>
 public virtual void AddItemProjection(HqlProjectionQuery query, QueryBuilderArgs args)
 {
     query.Selects.AddRange(GetWorklistItemSelects(args.Projection));
 }
コード例 #30
0
ファイル: PatientQueryBuilder.cs プロジェクト: hksonngan/Xian
 /// <summary>
 /// Constrains the patient profile to match the performing facility.
 /// </summary>
 /// <param name="query"></param>
 /// <param name="args"></param>
 public override void AddConstrainPatientProfile(HqlProjectionQuery query, QueryBuilderArgs args)
 {
     // calling this method on this class would not make any sense
     throw new InvalidOperationException();
 }