### Eclipse Workspace Patch 1.0 #P openmrs-trunk Index: src/api/org/openmrs/api/db/hibernate/HibernatePersonDAO.java =================================================================== --- src/api/org/openmrs/api/db/hibernate/HibernatePersonDAO.java (revision 6872) +++ src/api/org/openmrs/api/db/hibernate/HibernatePersonDAO.java (working copy) @@ -93,8 +93,8 @@ if (names.length == 1) { q += "("; q += " soundex(pname.givenName) = soundex(:n1)"; - q += " or soundex(pname.middleName) = soundex(:n2)"; - q += " or soundex(pname.familyName) = soundex(:n3) "; + q += " or soundex(pname.middleName) = soundex(:n1)"; + q += " or soundex(pname.familyName) = soundex(:n1) "; q += ")"; } else if (names.length == 2) { q += "("; @@ -107,15 +107,15 @@ q += " + "; q += " case"; q += " when pname.middleName is null then 1"; - q += " when soundex(pname.middleName) = soundex(:n3) then 2"; - q += " when soundex(pname.middleName) = soundex(:n4) then 4"; + q += " when soundex(pname.middleName) = soundex(:n1) then 2"; + q += " when soundex(pname.middleName) = soundex(:n2) then 4"; q += " else 0 "; q += " end"; q += " +"; q += " case"; q += " when pname.familyName is null then 1"; - q += " when soundex(pname.familyName) = soundex(:n5) then 2"; - q += " when soundex(pname.familyName) = soundex(:n6) then 4"; + q += " when soundex(pname.familyName) = soundex(:n1) then 2"; + q += " when soundex(pname.familyName) = soundex(:n2) then 4"; q += " else 0 "; q += " end"; q += ") between 6 and 7"; @@ -131,22 +131,59 @@ q += " + "; q += " case"; q += " when pname.middleName is null then 0"; - q += " when soundex(pname.middleName) = soundex(:n4) then 2"; - q += " when soundex(pname.middleName) = soundex(:n5) then 3"; - q += " when soundex(pname.middleName) = soundex(:n6) then 1"; + q += " when soundex(pname.middleName) = soundex(:n1) then 2"; + q += " when soundex(pname.middleName) = soundex(:n2) then 3"; + q += " when soundex(pname.middleName) = soundex(:n3) then 1"; q += " else 0"; q += " end"; q += " +"; q += " case"; q += " when pname.familyName is null then 0"; - q += " when soundex(pname.familyName) = soundex(:n7) then 1"; - q += " when soundex(pname.familyName) = soundex(:n8) then 2"; - q += " when soundex(pname.familyName) = soundex(:n9) then 3"; + q += " when soundex(pname.familyName) = soundex(:n1) then 1"; + q += " when soundex(pname.familyName) = soundex(:n2) then 2"; + q += " when soundex(pname.familyName) = soundex(:n3) then 3"; q += " else 0"; q += " end"; q += ") >= 5"; - } else - throw new DAOException("Too many names to compare effectively."); + } else { + + // This is simply an alternative method of name matching which scales better + // for large names, although it is hard to imagine getting names with more than + // six or so tokens. This can be easily updated to attain more desirable + // results; it is just a working alternative to throwing an exception. + + q += "("; + q += " case"; + q += " when pname.givenName is null then 0"; + q += " when soundex(pname.givenName) = soundex(:n1) then " + (names.length); + q += " when soundex(pname.givenName) = soundex(:n2) then " + (names.length - 1); + for (int i = 2; i < names.length; i++) { + q += " when soundex(pname.givenName) = soundex(:n" + (i+1) + ") then 1"; + } + q += " else 0"; + q += " end"; + q += ")"; + q += "+"; +// q += "("; +// q += " case"; +// q += " when pname.middleName is null then 0"; +// q += " when soundex(pname.middleName) = soundex(:nX) then " + 1); +// q += " else 0"; +// q += " end"; +// q += ")"; +// q += "+"; + q += "("; + q += " case"; + q += " when pname.familyName is null then 0"; + q += " when soundex(pname.familyName) = soundex(:r1) then " + (names.length); + q += " when soundex(pname.familyName) = soundex(:r2) then " + (names.length - 1); + for (int i = 0; i < names.length - 2; i++) { + q += " when soundex(pname.familyName) = soundex(:n" + (i+1) + ") then 1"; + } + q += " else 0"; + q += " end"; + q += ") > " + names.length / 2; + } String birthdayMatch = " (year(p.birthdate) between " + (birthyear - 1) + " and " + (birthyear + 1) + " or p.birthdate is null) "; @@ -161,19 +198,17 @@ q += " and " + genderMatch; } - q += " order by pname.givenName asc, "; - q += "pname.middleName asc, "; - q += "pname.familyName asc"; + q += " order by pname.givenName asc,"; + q += " pname.middleName asc,"; + q += " pname.familyName asc"; Query query = sessionFactory.getCurrentSession().createQuery(q); - int count = 1; - for (int i = 0; i < 3; i++) { - for (int nameIndex = 0; nameIndex < names.length; nameIndex++) { - query.setString("n" + count, names[nameIndex]); - count++; - } + for (int nameIndex = 0; nameIndex < names.length; nameIndex++) { + query.setString("n" + (nameIndex + 1), names[nameIndex]); } + query.setString("r1", names[names.length-1]); + query.setString("r2", names[names.length-2]); if (q.contains(":gender")) query.setString("gender", gender);