コード例 #1
0
        /// <summary>
        /// Render the object
        /// </summary>
        public void Render(XElement element, XmlWriter writer, IRenderContext context)
        {
            var resourceType = new ModelSerializationBinder().BindToType(String.Empty, element.Attribute("resource")?.Value);

            if (resourceType == null)
            {
                writer.WriteStartElement("span");
                writer.WriteAttributeString("style", "color:red");
                writer.WriteString($"{element.Attribute("resource")?.Value} not valid");
                writer.WriteEndElement();
            }
            else
            {
                var render     = element.Attribute("render")?.Value;
                var identifier = ReportViewUtil.GetValue(context, element.Value);
                if (identifier != null)
                {
                    var dpType    = typeof(IDataPersistenceService <>).MakeGenericType(resourceType);
                    var dpService = ApplicationServiceContext.Current.GetService(dpType) as IDataPersistenceService;
                    var key       = identifier is Guid || identifier is Guid? ? (Guid)identifier : Guid.Parse(identifier.ToString());
                    var instance  = dpService.Get(key);

                    if (instance == null)
                    {
                        writer.WriteComment($"{resourceType.Name}/{key} not found");
                    }
                    else if (!String.IsNullOrEmpty(render))
                    {
                        var selKey = $"{resourceType.Name}.{render}";
                        if (!this.m_selectors.TryGetValue(selKey, out Delegate selDelegate))
                        {
                            selDelegate = QueryExpressionParser.BuildPropertySelector(resourceType, render).Compile();
                            this.m_selectors.TryAdd(selKey, selDelegate);
                        }
                        writer.WriteString(selDelegate.DynamicInvoke(instance)?.ToString());
                    }
                    else
                    {
                        writer.WriteString(instance?.ToString());
                    }
                }
            }
        }
コード例 #2
0
        /// <summary>
        /// Send query to master target
        /// </summary>
        private List <Patient> SendQuery(NameValueCollection originalQuery, int count, out int totalResults)
        {
            // Map reverse
            var parmMap = s_map.Map.FirstOrDefault(o => o.Trigger == "Q22");
            List <KeyValuePair <Hl7QueryParameterMapProperty, object> > parameters = new List <KeyValuePair <Hl7QueryParameterMapProperty, object> >();

            foreach (var kv in originalQuery)
            {
                var rmap = parmMap.Parameters.Find(o => o.ModelName == kv.Key);
                if (rmap == null)
                {
                    // Is the value a UUID? If so, it may be an identifier we can use
                    if (Guid.TryParse(kv.Value.First(), out Guid uuid))
                    {
                        // What is the type of this property
                        var property = QueryExpressionParser.BuildPropertySelector <Patient>(kv.Key);
                        if (property == null)
                        {
                            throw new InvalidOperationException($"{kv.Key} is not valid on Patient");
                        }
                        // Is there a classifier? We need it for querying a guaranteed unique property
                        var preferred = property.Body.Type.GetCustomAttribute <ClassifierAttribute>()?.ClassifierProperty;
                        if (String.IsNullOrEmpty(preferred))
                        {
                            throw new InvalidOperationException($"{property.Body.Type} does not have a ClassifierAttribute");
                        }
                        var idp = typeof(IDataPersistenceService <>).MakeGenericType(property.Body.Type);
                        var ids = ApplicationServiceContext.Current.GetService(idp) as IDataPersistenceService;
                        if (ids == null)
                        {
                            throw new InvalidOperationException($"{idp} not found");
                        }
                        var value = ids.Get(uuid);
                        var match = property.Body.Type.GetProperty(preferred).GetValue(value);
                        preferred = property.Body.Type.GetProperty(preferred).GetSerializationName();

                        // Get the parmaeter map for this classifier
                        rmap = parmMap.Parameters.Find(o => o.ModelName == $"{kv.Key}.{preferred}");
                        if (rmap != null)
                        {
                            parameters.Add(new KeyValuePair <Hl7QueryParameterMapProperty, object>(rmap, match));
                        }
                        else
                        {
                            continue;
                        }
                    }
                    else
                    {
                        continue;
                    }
                }
                else
                {
                    parameters.Add(new KeyValuePair <Hl7QueryParameterMapProperty, object>(rmap, kv.Value));
                }
            }

            if (parameters.Count == 0)
            {
                parameters.Add(new KeyValuePair <Hl7QueryParameterMapProperty, object>(parmMap.Parameters.FirstOrDefault(o => o.Hl7Name == "@PID.33"), DateTime.MinValue.AddDays(10)));
            }


            // Construct the basic QBP_Q22
            QBP_Q21 queryRequest = new QBP_Q21();
            var     endpoint     = this.Configuration.Endpoints.First();

            queryRequest.MSH.SetDefault(endpoint.ReceivingDevice, endpoint.ReceivingFacility, endpoint.SecurityToken);
            queryRequest.MSH.MessageType.MessageStructure.Value = "QBP_Q21";
            queryRequest.MSH.MessageType.TriggerEvent.Value     = "Q22";
            queryRequest.MSH.MessageType.MessageCode.Value      = "QBP";

            queryRequest.GetSFT(0).SetDefault();
            queryRequest.RCP.QuantityLimitedRequest.Units.Identifier.Value = "RD";
            queryRequest.RCP.QuantityLimitedRequest.Quantity.Value         = (count).ToString();
            queryRequest.QPD.MessageQueryName.Identifier.Value             = "Q22";
            queryRequest.QPD.MessageQueryName.Text.Value = "Find Candidates";
            queryRequest.QPD.MessageQueryName.NameOfCodingSystem.Value = "HL7";

            Terser tser = new Terser(queryRequest);

            int q = 0;

            foreach (var qp in parameters)
            {
                List <String> filter = qp.Value as List <String> ?? new List <String>()
                {
                    qp.Value.ToString()
                };
                foreach (var val in filter)
                {
                    Terser.Set(queryRequest.QPD, 3, q, 1, 1, qp.Key.Hl7Name);
                    string dval = val;
                    while (new String[] { "<", ">", "!", "=", "~" }.Any(o => dval.StartsWith(o)))
                    {
                        dval = dval.Substring(1);
                    }

                    switch (qp.Key.ParameterType)
                    {
                    case "date":
                        var dt = DateTime.Parse(dval);
                        switch (dval.Length)
                        {
                        case 4:
                            Terser.Set(queryRequest.QPD, 3, q, 2, 1, dt.Year.ToString());
                            break;

                        case 7:
                            Terser.Set(queryRequest.QPD, 3, q, 2, 1, dt.ToString("yyyyMM"));
                            break;

                        case 10:
                            Terser.Set(queryRequest.QPD, 3, q, 2, 1, dt.ToString("yyyyMMdd"));
                            break;

                        default:
                            Terser.Set(queryRequest.QPD, 3, q, 2, 1, dt.ToString("yyyyMMddHHmmss.fffzzzz").Replace(":", ""));
                            break;
                        }
                        break;

                    default:
                        Terser.Set(queryRequest.QPD, 3, q, 2, 1, dval);
                        break;
                    }
                    q++;
                }
            }

            // TODO: Send the query and then maps results
            try
            {
                RSP_K21 response = endpoint.GetSender().SendAndReceive(queryRequest) as RSP_K21;
                // Iterate and create responses
                totalResults = Int32.Parse(response.QAK.HitCount.Value ?? response.QUERY_RESPONSERepetitionsUsed.ToString());
                List <Patient> overr = new List <Patient>();
                // Query response
                for (int i = 0; i < response.QUERY_RESPONSERepetitionsUsed; i++)
                {
                    var ar = response.GetQUERY_RESPONSE(i);
                    // Create patient
                    Bundle patientData = MessageUtils.Parse(ar);
                    patientData.Reconstitute();

                    // Does this patient "really" exist?
                    if (!ar.PID.GetPatientIdentifierList().Any(o => o.AssigningAuthority.NamespaceID.Value == this.m_configuration.LocalAuthority.DomainName) &&
                        !this.m_retrieveHacks.ContainsKey(patientData.Item.OfType <Patient>().First().Key.Value))
                    {
                        var key     = this.m_retrieveHacks.FirstOrDefault(o => o.Value.Any(x => x.Value == ar.PID.GetPatientIdentifierList()[0].IDNumber.Value));
                        var patient = patientData.Item.OfType <Patient>().First();

                        if (key.Key != Guid.Empty)
                        {
                            patient.Key = key.Key;
                        }
                        else
                        {
                            this.m_retrieveHacks.Add(patient.Key.Value, patient.Identifiers);
                        }
                    }

                    // Now we extract the patient
                    var pat = patientData.Item.OfType <Patient>().First();
                    pat.VersionKey = pat.Key;
                    overr.Add(pat);
                }
                return(overr);
            }
            catch (Exception ex)
            {
                totalResults = 0;
                this.m_tracer.TraceEvent(EventLevel.Error, "Error dispatching HL7 query {0}", ex);
                throw new HL7ProcessingException("Error dispatching HL7 query", null, null, 0, 0, ex);
            }
        }
コード例 #3
0
ファイル: DataCmdlet.cs プロジェクト: santedb/santedb-server
        // [PolicyPermission(System.Security.Permissions.SecurityAction.Demand, PolicyId = PermissionPolicyIdentifiers.CreateDevice)]
        internal static void QueryData(HdsiQueryParameters parms)
        {
            if (String.IsNullOrEmpty(parms.ResourceType))
            {
                throw new ArgumentNullException("Require --resourceType or -r");
            }

            // Get the type
            var type = new ModelSerializationBinder().BindToType(null, parms.ResourceType);

            if (type == null)
            {
                throw new InvalidOperationException($"Cannot find reosurce type {parms.ResourceType}");
            }

            if (!parms.AsDataSet)
            {
                Console.WriteLine("Type: {0}", type);
            }

            // Build the parameter list
            NameValueCollection nvc = new NameValueCollection();

            if (parms.Filter != null)
            {
                foreach (var kv in parms.Filter)
                {
                    var f = kv.Split('=');
                    nvc.Add(f[0], f[1]);
                }
            }

            Int32.TryParse(parms.Offset ?? "0", out int offset);
            Int32.TryParse(parms.Count ?? "25", out int count);

            if (parms.Display == null)
            {
                parms.Display = new System.Collections.Specialized.StringCollection()
                {
                    "id", "ToString"
                }
            }
            ;

            // Get the specified lambda expression
            var builderMethod  = typeof(QueryExpressionParser).GetGenericMethod(nameof(QueryExpressionParser.BuildLinqExpression), new Type[] { type }, new Type[] { typeof(NameValueCollection) });
            var linqExpression = builderMethod.Invoke(null, new object[] { nvc });

            if (!parms.AsDataSet)
            {
                Console.WriteLine("Filter: {0}", linqExpression);
            }

            // Fetch results

            var queryMethod = m_client.GetType().GetGenericMethod(nameof(HdsiServiceClient.Query), new Type[] { type }, new Type[] { linqExpression.GetType(), typeof(int), typeof(int?), typeof(String[]), typeof(Guid?), typeof(ModelSort <>).MakeGenericType(type).MakeArrayType() });
            var result      = queryMethod.Invoke(m_client, new object[] { linqExpression, offset, count, parms.Expand?.OfType <String>().ToArray(), null, null }) as Bundle;


            if (!parms.AsDataSet)
            {
                Console.WriteLine("Result: {0} .. {1} of {2}", result.Offset, result.Item.Count, result.TotalResults);
                var displayCols = parms.Display.OfType <String>().Select(o =>
                {
                    return((Expression <Func <IdentifiedData, Object> >)(col => o == "ToString" ? col.ToString() : QueryExpressionParser.BuildPropertySelector(type, o, true).Compile().DynamicInvoke(col)));
                }).ToArray();

                DisplayUtil.TablePrint <IdentifiedData>(result.Item, parms.Display.OfType <String>().ToArray(), parms.Display.OfType <String>().Select(o => 40).ToArray(), displayCols);
            }
            else
            {
                Dataset ds = new Dataset($"sdbac Dataset for {type} filter {nvc}");

                Delegate displaySelector = null;
                if (parms.Display.Count > 0)
                {
                    displaySelector = QueryExpressionParser.BuildPropertySelector(type, parms.Display.OfType <String>().FirstOrDefault(), true).Compile();
                }

                foreach (var itm in result.Item)
                {
                    ds.Action.Add(new DataUpdate()
                    {
                        InsertIfNotExists = true,
                        IgnoreErrors      = true,
                        Element           = (IdentifiedData)(displaySelector != null ? displaySelector.DynamicInvoke(itm) : itm)
                    });
                }

                m_xsz.Serialize(Console.Out, ds);
            }
        }
    }
コード例 #4
0
        /// <summary>
        /// Perform the block operation
        /// </summary>
        private IEnumerable <T> DoBlock <T>(T input, MatchBlock block, IEnumerable <Guid> ignoreKeys, IRecordMatchingDiagnosticSession collector = null) where T : IdentifiedData
        {
            // Load the persistence service
            int tr = 1;

            try
            {
                collector?.LogStartAction(block);
                // Perpare filter
                var filter = block.Filter;
                NameValueCollection qfilter = new NameValueCollection();
                foreach (var b in filter)
                {
                    bool shouldIncludeExpression = true;
                    if (b.When?.Any() == true) // Only include the filter when the conditions are met
                    {
                        var guardExpression = b.GuardExpression;

                        if (guardExpression == null) // not built
                        {
                            var        parameter = Expression.Parameter(typeof(T));
                            Expression guardBody = null;
                            foreach (var whenClause in b.When)
                            {
                                var selectorExpression = QueryExpressionParser.BuildPropertySelector <T>(whenClause, true);
                                if (guardBody == null)
                                {
                                    guardBody = Expression.MakeBinary(ExpressionType.NotEqual, Expression.Invoke(selectorExpression, parameter), Expression.Constant(null));
                                }
                                else
                                {
                                    guardBody = Expression.MakeBinary(ExpressionType.AndAlso, Expression.Invoke(guardBody, parameter), Expression.MakeBinary(ExpressionType.NotEqual, Expression.Invoke(selectorExpression, parameter), Expression.Constant(null)));
                                }
                            }
                            b.GuardExpression = guardExpression = Expression.Lambda(guardBody, parameter).Compile();
                        }

                        shouldIncludeExpression = (bool)guardExpression.DynamicInvoke(input);
                    }

                    if (shouldIncludeExpression)
                    {
                        var nvc = NameValueCollection.ParseQueryString(b.Expression);
                        // Build the expression
                        foreach (var nv in nvc)
                        {
                            foreach (var val in nv.Value)
                            {
                                qfilter.Add(nv.Key, val);
                            }
                        }
                    }
                }

                // Do we skip when no conditions?
                if (!qfilter.Any())
                {
                    yield break;
                }

                // Add ignore clauses
                if (ignoreKeys?.Any() == true)
                {
                    qfilter.Add("id", ignoreKeys.Select(o => $"!{o}"));
                }
                if (input.Key.HasValue)
                {
                    qfilter.Add("id", $"!{input.Key}");
                }

                // Make LINQ query
                // NOTE: We can't build and store this since input is a closure
                // TODO: Figure out a way to compile this expression once
                var linq = QueryExpressionParser.BuildLinqExpression <T>(qfilter, new Dictionary <string, Func <Object> >()
                {
                    { "input", ((Func <T>)(() => input)) }
                }, safeNullable: true, lazyExpandVariables: false);

                // Add status keys
                if (typeof(IHasState).IsAssignableFrom(typeof(T)))
                {
                    var        stateAccess = Expression.MakeMemberAccess(linq.Parameters[0], typeof(T).GetProperty(nameof(IHasState.StatusConceptKey)));
                    Expression statePart   = null;
                    foreach (var stateKey in StatusKeys.ActiveStates)
                    {
                        if (statePart == null)
                        {
                            statePart = Expression.MakeBinary(ExpressionType.Equal, stateAccess, Expression.Convert(Expression.Constant(stateKey), typeof(Guid?)));
                        }
                        else
                        {
                            statePart = Expression.MakeBinary(ExpressionType.OrElse, Expression.MakeBinary(ExpressionType.Equal, stateAccess, Expression.Convert(Expression.Constant(stateKey), typeof(Guid?))), statePart);
                        }
                    }
                    linq = Expression.Lambda <Func <T, bool> >(Expression.MakeBinary(ExpressionType.AndAlso,
                                                                                     statePart, linq.Body), linq.Parameters[0]);
                }
                this.m_tracer.TraceVerbose("Will execute block query : {0}", linq);

                // Query control variables for iterating result sets
                var batch = block.BatchSize;
                if (batch == 0)
                {
                    batch = 100;
                }

                // Set the authentication context
                using (AuthenticationContext.EnterSystemContext())
                {
                    int ofs = 0;
                    while (ofs < tr)
                    {
                        if (block.UseRawPersistenceLayer)
                        {
                            var persistenceService = ApplicationServiceContext.Current.GetService <IDataPersistenceService <T> >();
                            if (persistenceService == null)
                            {
                                throw new InvalidOperationException($"Cannot find persistence service for {typeof(T).FullName}");
                            }

                            var records = persistenceService.Query(linq, ofs, batch, out tr, AuthenticationContext.SystemPrincipal);
                            collector?.LogSample(linq.ToString(), tr);
                            foreach (var itm in records)
                            {
                                yield return(itm);
                            }
                            ofs += batch;
                        }
                        else
                        {
                            var persistenceService = ApplicationServiceContext.Current.GetService <IRepositoryService <T> >();
                            if (persistenceService == null)
                            {
                                throw new InvalidOperationException($"Cannot find persistence service for {typeof(T).FullName}");
                            }

                            var records = persistenceService.Find(linq, ofs, batch, out tr);
                            collector?.LogSample(linq.ToString(), tr);
                            foreach (var itm in records)
                            {
                                if (itm.Key.HasValue &&
                                    itm.Key != input.Key &&
                                    ignoreKeys?.Contains(itm.Key.Value) != true)
                                {
                                    yield return(itm);
                                }
                            }
                            ofs += batch;
                        }

                        if (ofs > 100)
                        {
                            collector?.LogSample("too-many-results", tr);
                            yield break;
                        }
                    }
                }
            }
            finally
            {
                collector?.LogEndAction();
            }
        }