| 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)); |
|---|
| 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){ |
|---|
| 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; |
|---|