Downloads Documentation Community Contribute Demo






Show Sidebar
Login | Register

Changeset 5289

Show
Ignore:
Timestamp:
08/15/08 11:32:45 (3 months ago)
Author:
jegg
Message:

in patientmatching module, updated OpenMRS reader with new method of generating HQL queries

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • openmrs-modules/patientmatching/src/org/regenstrief/linkage/io/OrderedOpenMRSReader.java

    r5267 r5289  
    182182                List<Object> ret = null; 
    183183                String query_text = new String(); 
    184                 // need to see if demographic refers to a data model table value, or an attribute 
    185                 if(demographic.contains(".")){ 
    186                        // need to query the table name before the . for the field 
    187                        String[] object_field = demographic.split("\\."); 
    188                        String object_name = object_field[0]
    189                        String field = object_field[object_field.length - 1]
    190                        for(int i = 1; i < object_field.length - 1; i++){ 
    191                                object_name += "." + object_field[i]
    192                        } 
    193                         
    194                        query_text = "SELECT DISTINCT o." + field + " FROM " + object_name + " o where o." + field + " IS NOT NULL"
    195                        Query q = sessionFactory.getCurrentSession().createQuery(query_text); 
    196                        ret = q.list(); 
    197                 } else
    198                         if(demographic.indexOf(ATTRIBUTE_PREFIX) != -1){ 
    199                                // need to look at attribute type first to get the right query 
    200                                 String attr = stripType(demographic); 
    201                                 PersonAttributeType pat = Context.getPersonService().getPersonAttributeType(attr); 
     184                 
     185                List<String> demographics = new ArrayList<String>(); 
     186                demographics.add(demographic); 
     187                 
     188                String select_clause = getSelectDistinctValuesClause(demographics)
     189                String from_clause = getFromClause(demographics)
     190                String where_clause = getValuesWhereClause(demographics); 
     191                query_text = select_clause + " " + from_clause + " " + where_clause
     192                log.warn("getting values for " + demographic + " using query of:  " + query_text); 
     193                 
     194                Query q = sessionFactory.getCurrentSession().createQuery(query_text)
     195                 
     196                // if list of demographics includes attributes or identifiers, need to set types in query text from method 
     197                for(int i = 0; i < demographics.size(); i++)
     198                        String dem = demographics.get(i); 
     199                        if(dem.indexOf(ATTRIBUTE_PREFIX) != -1){ 
     200                                // set o<i>.type equal to pat 
     201                                PersonAttributeType pat = Context.getPersonService().getPersonAttributeTypeByName(stripType(demographic)); 
    202202                                if(pat != null){ 
    203                                         // HQL query to get all values 
    204                                         // something like  
    205                                         // select distinct value from person_attribute where person_attribute_type_id = <id> 
    206                                         query_text = "SELECT DISTINCT p.value FROM PersonAttribute p WHERE p.attributeType = :type AND p.value IS NOT NULL"; 
    207                                         Query q = sessionFactory.getCurrentSession().createQuery(query_text); 
    208                                         q.setParameter("type", pat); 
    209                                         ret = q.list(); 
    210                                 } 
    211                         } else if(demographic.indexOf(IDENT_PREFIX) != -1){ 
    212                                 // need to look at identifier types first to get right query 
    213                                 String ident = stripType(demographic); 
    214                                 PatientIdentifierType pit = Context.getPatientService().getPatientIdentifierType(ident); 
     203                                        q.setParameter("val" + i, pat); 
     204                                } 
     205                        } else if(dem.indexOf(IDENT_PREFIX) != -1){ 
     206                                // everything we need to query for is in PatientIdentifier 
     207                                PatientIdentifierType pit = Context.getPatientService().getPatientIdentifierTypeByName(stripType(demographic)); 
    215208                                if(pit != null){ 
    216                                         // HQL query to get all values 
    217                                         query_text = "SELECT DISTINCT p.identifier FROM PatientIdentifier p WHERE p.identifierType = :type AND p.identifier IS NOT NULL"; 
    218                                         Query q = sessionFactory.getCurrentSession().createQuery(query_text); 
    219                                         q.setParameter("type", pit); 
    220                                         ret = q.list(); 
    221                                 } 
    222                         } 
    223                          
    224                 } 
     209                                        q.setParameter("val" + i, pit); 
     210                                } 
     211                        } 
     212                } 
     213                 
     214                ret = q.list(); 
    225215                 
    226216                return ret; 
     
    247237                List<Integer> ret = null; 
    248238                String query_text = new String(); 
    249                 // get patient IDs using HQL that have this value for 
    250                 // this demographic 
     239                 
     240                List<String> demographics = new ArrayList<String>(); 
     241                List<Object> values = new ArrayList<Object>(); 
     242                demographics.add(demographic); 
     243                values.add(value); 
     244                 
     245                String select_clause = getSelectIDsClause(demographics); 
     246                String from_clause = getFromClause(demographics); 
     247                String where_clause = this.getIDsWhereClause(demographics); 
     248                query_text = select_clause + " " + from_clause + " " + where_clause; 
     249                log.warn("getting ID for values " + values + " using query of:  " + query_text); 
     250                 
     251                Query q = sessionFactory.getCurrentSession().createQuery(query_text); 
     252                 
     253                // if list of demographics includes attributes or identifiers, need to set types in query text from method 
     254                for(int i = 0; i < values.size(); i++){ 
     255                        q.setParameter("val" + i, values.get(i)); 
     256                } 
     257                 
     258                ret = q.list(); 
     259                 
     260                return ret; 
     261        } 
     262         
     263        /** 
     264         * Method returns a string with the select clause of the HQL query used to get 
     265         * the distinct values for the demographics 
     266         *  
     267         * @param demographics 
     268         * @return 
     269         */ 
     270        private String getSelectDistinctValuesClause(List<String> demographics){ 
     271                String clause = "SELECT DISTINCT("; 
     272                for(int i = 0; i < demographics.size(); i++){ 
     273                        String demographic = demographics.get(i); 
     274                        if(i > 0){ 
     275                                clause += ", "; 
     276                        } 
     277                         
     278                        if(demographic.contains(".")){ 
     279                                // only need to know the field name of the object 
     280                                clause += "o" + i + "." + getFieldName(demographic); 
     281                        } else { 
     282                                if(demographic.indexOf(ATTRIBUTE_PREFIX) != -1){ 
     283                                        // attribute values are stored in PersonAttribute.value 
     284                                        clause += "o" + i + ".value"; 
     285                                } else if(demographic.indexOf(IDENT_PREFIX) != -1){ 
     286                                        // identifier values are stored in PatientIdentifier.identifier 
     287                                        clause += "o" + i + ".identifier"; 
     288                                } 
     289                                 
     290                        } 
     291                } 
     292                 
     293                clause += ")"; 
     294                return clause; 
     295        } 
     296         
     297        private String getSelectIDsClause(List<String> demographics){ 
     298                return "SELECT p.patientId"; 
     299        } 
     300         
     301        /** 
     302         * Method returns a From clause that contains the objects the HQL query will need to use 
     303         *  
     304         * @param demographics 
     305         * @return 
     306         */ 
     307        private String getFromClause(List<String> demographics){ 
     308                String clause = "FROM Patient p, "; 
     309                for(int i = 0; i < demographics.size(); i++){ 
     310                        String demographic = demographics.get(i); 
     311                        if(i > 0){ 
     312                                clause += ", "; 
     313                        } 
     314                         
     315                        if(demographic.contains(".")){ 
     316                                // only need to know object name to query from 
     317                                clause += getObjectName(demographic)  + " o" + i; 
     318                        } else { 
     319                                if(demographic.indexOf(ATTRIBUTE_PREFIX) != -1){ 
     320                                        // everything we need to query for is in PersonAttribute objects 
     321                                        clause += "PersonAttribute o" + i; 
     322                                } else if(demographic.indexOf(IDENT_PREFIX) != -1){ 
     323                                        // everything we need to query for is in PatientIdentifier 
     324                                        clause += "PatientIdentifier o" + i; 
     325                                } 
     326                                 
     327                        } 
     328                } 
     329                 
     330                return clause; 
     331        } 
     332         
     333        private String getIDsWhereClause(List<String> demographics){ 
     334                String clause = "WHERE "; 
     335                 
     336                // need to add code relating demographic to Patient objects, since select clause 
     337                // explicitly asks for p.patientId 
     338                clause += getPatientRelation(0, demographics.get(0)) + " AND "; 
     339                 
     340                for(int i = 0; i < demographics.size(); i++){ 
     341                        String demographic = demographics.get(i); 
     342                        if(i > 0){ 
     343                                clause += " AND "; 
     344                                 
     345                                // need to add code to relate objects when there are multiple ones 
     346                                // something like PersonAddress.person = PersonAttribute.person 
     347                                // depends on the particular demographics what it will be 
     348                                 
     349                        } 
     350                         
     351                        if(demographic.contains(".")){ 
     352                                // only need to know object name to query from 
     353                                clause += "o" + i + "." + getFieldName(demographic)  + " = :val" + i; 
     354                        } else { 
     355                                if(demographic.indexOf(ATTRIBUTE_PREFIX) != -1){ 
     356                                        // everything we need to query for is in PersonAttribute objects 
     357                                        PersonAttributeType pat = Context.getPersonService().getPersonAttributeTypeByName(stripType(demographic)); 
     358                                        if(pat != null){ 
     359                                                clause += "o" + i + ".value = :val" + i; 
     360                                        } 
     361                                } else if(demographic.indexOf(IDENT_PREFIX) != -1){ 
     362                                        // everything we need to query for is in PatientIdentifier 
     363                                        PatientIdentifierType pit = Context.getPatientService().getPatientIdentifierTypeByName(stripType(demographic)); 
     364                                        if(pit != null){ 
     365                                                clause += "o" + i + ".identifier = :val" + i; 
     366                                        } 
     367                                } 
     368                                 
     369                        } 
     370                } 
     371                 
     372                return clause; 
     373        } 
     374         
     375        private String getValuesWhereClause(List<String> demographics){ 
     376                String clause = "WHERE "; 
     377                for(int i = 0; i < demographics.size(); i++){ 
     378                        String demographic = demographics.get(i); 
     379                        if(i > 0){ 
     380                                clause += " AND "; 
     381                                 
     382                                // need to add code to relate objects when there are multiple ones 
     383                                // something like PersonAddress.person = PersonAttribute.person 
     384                                // depends on the particular demographics what it will be 
     385                        } 
     386                         
     387                        if(demographic.contains(".")){ 
     388                                // only need to know object name to query from 
     389                                clause += "o" + i + "." + getFieldName(demographic)  + " IS NOT NULL"; 
     390                        } else { 
     391                                if(demographic.indexOf(ATTRIBUTE_PREFIX) != -1){ 
     392                                        // everything we need to query for is in PersonAttribute objects 
     393                                        PersonAttributeType pat = Context.getPersonService().getPersonAttributeTypeByName(stripType(demographic)); 
     394                                        if(pat != null){ 
     395                                                clause += "o" + i + ".value IS NOT NULL AND o" + i + ".attributeType = :val" + i; 
     396                                        } 
     397                                } else if(demographic.indexOf(IDENT_PREFIX) != -1){ 
     398                                        // everything we need to query for is in PatientIdentifier 
     399                                        PatientIdentifierType pit = Context.getPatientService().getPatientIdentifierTypeByName(stripType(demographic)); 
     400                                        if(pit != null){ 
     401                                                clause += "o" + i + ".identifier IS NOT NULL AND o" + i + ".identifierType = :val" + i; 
     402                                        } 
     403                                } 
     404                                 
     405                        } 
     406                } 
     407                 
     408                return clause; 
     409        } 
     410         
     411        /** 
     412         * Method returns the portion in the WHERE clause that relates the given demographic to the 
     413         * Patient objects.  We need this since we only want Patient IDs (not Users or Persons) and 
     414         * when querying for IDs using multiple values, we want the results to be for the same person 
     415         *  
     416         * @param suffix        position of the given demographic within the list of demographics and values 
     417         * @param demographic   the demographic that needs linked to Patient 
     418         * @return      a String that can be place in an HQL WHERE clause that will specify equivalence of Patient and demographic 
     419         */ 
     420        private String getPatientRelation(int suffix, String demographic){ 
    251421                if(demographic.contains(".")){ 
    252                         // need to query the table name before the . for the field 
    253                         String[] object_field = demographic.split("\\."); 
    254                         String object_name = object_field[0]; 
    255                         String field = object_field[object_field.length - 1]; 
    256                         for(int i = 1; i < object_field.length - 1; i++){ 
    257                                 object_name += "." + object_field[i]; 
    258                         } 
    259                          
    260                         query_text = "SELECT o FROM " + object_name + " o WHERE " + field + " =:value"; 
    261                         Query q = sessionFactory.getCurrentSession().createQuery(query_text); 
    262                         q.setParameter("value", value); 
    263                         ret = getIDs(q.list()); 
    264                          
     422                        // load class given by demographic and examine what fields it has 
     423                        String type = getObjectName(demographic); 
     424                        if(type.equals("Patient") || type.equals("org.openmrs.Patient")){ 
     425                                return "p = o" + suffix; 
     426                        } else { 
     427                                try{ 
     428                                        Class c = Class.forName(type); 
     429                                        Method[] methods = c.getMethods(); 
     430                                        for(int i = 0; i < methods.length; i++){ 
     431                                                if(methods[i].getName().equals("getPerson")){ 
     432                                                        return "p = o" + suffix + ".person"; 
     433                                                } 
     434                                        } 
     435                                } 
     436                                catch(ClassNotFoundException cnfe){ 
     437                                        return ""; 
     438                                } 
     439                        } 
    265440                } else { 
     441                        // if it's attribute or identifier, then it'll have a Person or Patient field 
    266442                        if(demographic.indexOf(ATTRIBUTE_PREFIX) != -1){ 
    267                                 // need to look at attribute type first to get the right query 
    268                                 String attr = stripType(demographic); 
    269                                 PersonAttributeType pat = Context.getPersonService().getPersonAttributeType(attr); 
    270                                 if(pat != null){ 
    271                                         // HQL query to get all values 
    272                                         // something like  
    273                                         // select distinct value from person_attribute where person_attribute_type_id = <id> 
    274                                         int id = pat.getPersonAttributeTypeId(); 
    275                                         query_text = "SELECT DISTINCT p FROM PersonAttribute p WHERE p.value = :value"; 
    276                                         Query q = sessionFactory.getCurrentSession().createQuery(query_text); 
    277                                         q.setParameter("value", value); 
    278                                         ret = getIDs(q.list()); 
    279                                 } 
     443                                return "p = o" + suffix + ".person"; 
    280444                        } else if(demographic.indexOf(IDENT_PREFIX) != -1){ 
    281                                 // need to look at identifier types first to get right query 
    282                                 String ident = stripType(demographic); 
    283                                 PatientIdentifierType pit = Context.getPatientService().getPatientIdentifierType(ident); 
    284                                 if(pit != null){ 
    285                                         // HQL query to get all values 
    286                                         int id = pit.getPatientIdentifierTypeId(); 
    287                                         query_text = "SELECT DISTINCT p FROM PatientIdentifier p WHERE p.identifier = :value"; 
    288                                         Query q = sessionFactory.getCurrentSession().createQuery(query_text); 
    289                                         q.setParameter("value", value); 
    290                                         ret = getIDs(q.list()); 
    291                                 } 
    292                         } 
    293                          
    294                 } 
    295                  
    296                 return ret; 
     445                                return "p = o" + suffix + ".patient"; 
     446                        } 
     447                } 
     448         
     449        return ""; 
     450        } 
     451         
     452        /** 
     453         * Method returns the field name of a demographic using the convention for specifying an object's 
     454         * field.  For example, if the demographic is "org.openmrs.Patient.gender", this this method would return 
     455         * "gender" 
     456         *  
     457         * @param demographic 
     458         * @return      the last field of the demographic when split on "." 
     459         */ 
     460        private String getFieldName(String demographic){ 
     461                String[] object_field = demographic.split("\\."); 
     462                String field = object_field[object_field.length - 1]; 
     463                return field; 
     464        } 
     465         
     466        /** 
     467         * Method returns the object name of a demographic using the convention for specifying an object's 
     468         * field as a demographic.  For example, if the demographic is "org.openmrs.Patient.gender", this this method would return 
     469         * "org.openmrs.Patient" 
     470         *  
     471         * @param demographic 
     472         * @return      all but the last element when the demographic is split on "." 
     473         */ 
     474        private String getObjectName(String demographic){ 
     475                String[] object_field = demographic.split("\\."); 
     476                String object_name = object_field[0]; 
     477                for(int i = 1; i < object_field.length - 1; i++){ 
     478                        object_name += "." + object_field[i]; 
     479                } 
     480                 
     481                return object_name; 
    297482        } 
    298483