Loading src/com/android/settings/search2/DatabaseResultLoader.java +22 −3 Original line number Diff line number Diff line Loading @@ -142,9 +142,7 @@ public class DatabaseResultLoader extends AsyncLoader<List<SearchResult>> { private List<SearchResult> query(String[] matchColumns, int baseRank) { final String whereClause = buildWhereClause(matchColumns); final String[] selection = new String[matchColumns.length]; final String query = "%" + mQueryText + "%"; Arrays.fill(selection, query); final String[] selection = buildQuerySelection(matchColumns.length * 2); final Cursor resultCursor = mDatabase.query(TABLE_PREFS_INDEX, SELECT_COLUMNS, whereClause, selection, null, null, null); Loading Loading @@ -173,6 +171,8 @@ public class DatabaseResultLoader extends AsyncLoader<List<SearchResult>> { StringBuilder sb = new StringBuilder(" ("); final int count = matchColumns.length; for (int n = 0; n < count; n++) { sb.append(matchColumns[n]); sb.append(" like ? OR "); sb.append(matchColumns[n]); sb.append(" like ?"); if (n < count - 1) { Loading @@ -182,4 +182,23 @@ public class DatabaseResultLoader extends AsyncLoader<List<SearchResult>> { sb.append(") AND enabled = 1"); return sb.toString(); } /** * Fills out the selection array to match the query as the prefix of a word. * * @param size is twice the number of columns to be matched. The first match is for the prefix * of the first word in the column. The second match is for any subsequent word * prefix match. */ private String[] buildQuerySelection(int size) { String[] selection = new String[size]; final String query = mQueryText + "%"; final String subStringQuery = "% " + mQueryText + "%"; for(int i = 0; i < (size - 1); i += 2) { selection[i] = query; selection[i + 1] = subStringQuery; } return selection; } } tests/robotests/src/com/android/settings/search/DatabaseResultLoaderTest.java +68 −12 Original line number Diff line number Diff line Loading @@ -144,6 +144,62 @@ public class DatabaseResultLoaderTest { assertThat(loader.loadInBackground().size()).isEqualTo(1); } @Test public void testSpecialCasePrefix_MatchesPrefixOfEntry() { insertSpecialCase("Photos"); loader = new DatabaseResultLoader(mContext, "pho"); assertThat(loader.loadInBackground().size()).isEqualTo(1); } @Test public void testSpecialCasePrefix_DoesNotMatchNonPrefixSubstring() { insertSpecialCase("Photos"); loader = new DatabaseResultLoader(mContext, "hot"); assertThat(loader.loadInBackground().size()).isEqualTo(0); } @Test public void testSpecialCaseMultiWordPrefix_MatchesPrefixOfEntry() { insertSpecialCase("Apps Notifications"); loader = new DatabaseResultLoader(mContext, "Apps"); assertThat(loader.loadInBackground().size()).isEqualTo(1); } @Test public void testSpecialCaseMultiWordPrefix_MatchesSecondWordPrefixOfEntry() { insertSpecialCase("Apps Notifications"); loader = new DatabaseResultLoader(mContext, "Not"); assertThat(loader.loadInBackground().size()).isEqualTo(1); } @Test public void testSpecialCaseMultiWordPrefix_DoesNotMatchMatchesPrefixOfFirstEntry() { insertSpecialCase("Apps Notifications"); loader = new DatabaseResultLoader(mContext, "pp"); assertThat(loader.loadInBackground().size()).isEqualTo(0); } @Test public void testSpecialCaseMultiWordPrefix_DoesNotMatchMatchesPrefixOfSecondEntry() { insertSpecialCase("Apps Notifications"); loader = new DatabaseResultLoader(mContext, "tion"); assertThat(loader.loadInBackground().size()).isEqualTo(0); } @Test public void testSpecialCaseMultiWordPrefixWithSpecial_MatchesPrefixOfEntry() { insertSpecialCase("Apps & Notifications"); loader = new DatabaseResultLoader(mContext, "App"); assertThat(loader.loadInBackground().size()).isEqualTo(1); } @Test public void testSpecialCaseMultiWordPrefixWithSpecial_MatchesPrefixOfSecondEntry() { insertSpecialCase("Apps & Notifications"); loader = new DatabaseResultLoader(mContext, "No"); assertThat(loader.loadInBackground().size()).isEqualTo(1); } private void insertSpecialCase(String specialCase) { String normalized = DatabaseIndexingUtils.normalizeHyphen(specialCase); normalized = DatabaseIndexingUtils.normalizeString(normalized); Loading Loading @@ -184,11 +240,11 @@ public class DatabaseResultLoaderTest { values.put(IndexDatabaseHelper.IndexColumns.DATA_TITLE, "alpha_title"); values.put(IndexDatabaseHelper.IndexColumns.DATA_TITLE_NORMALIZED, "alpha title"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON, "alpha_summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON_NORMALIZED, "alpha_summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON_NORMALIZED, "alpha summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF, "alpha_summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF_NORMALIZED, "alpha_summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_ENTRIES, "alpha_entries"); values.put(IndexDatabaseHelper.IndexColumns.DATA_KEYWORDS, "alpha_keywords"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF_NORMALIZED, "alpha summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_ENTRIES, "alpha entries"); values.put(IndexDatabaseHelper.IndexColumns.DATA_KEYWORDS, "alpha keywords"); values.put(IndexDatabaseHelper.IndexColumns.CLASS_NAME, "com.android.settings.gestures.GestureSettings"); values.put(IndexDatabaseHelper.IndexColumns.SCREEN_TITLE, "Moves"); Loading @@ -211,11 +267,11 @@ public class DatabaseResultLoaderTest { values.put(IndexDatabaseHelper.IndexColumns.DATA_TITLE, "bravo_title"); values.put(IndexDatabaseHelper.IndexColumns.DATA_TITLE_NORMALIZED, "bravo title"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON, "bravo_summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON_NORMALIZED, "bravo_summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON_NORMALIZED, "bravo summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF, "bravo_summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF_NORMALIZED, "bravo_summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_ENTRIES, "bravo_entries"); values.put(IndexDatabaseHelper.IndexColumns.DATA_KEYWORDS, "bravo_keywords"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF_NORMALIZED, "bravo summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_ENTRIES, "bravo entries"); values.put(IndexDatabaseHelper.IndexColumns.DATA_KEYWORDS, "bravo keywords"); values.put(IndexDatabaseHelper.IndexColumns.CLASS_NAME, "com.android.settings.gestures.GestureSettings"); values.put(IndexDatabaseHelper.IndexColumns.SCREEN_TITLE, "Moves"); Loading @@ -237,11 +293,11 @@ public class DatabaseResultLoaderTest { values.put(IndexDatabaseHelper.IndexColumns.DATA_TITLE, "charlie_title"); values.put(IndexDatabaseHelper.IndexColumns.DATA_TITLE_NORMALIZED, "charlie title"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON, "charlie_summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON_NORMALIZED, "charlie_summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON_NORMALIZED, "charlie summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF, "charlie_summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF_NORMALIZED, "charlie_summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_ENTRIES, "charlie_entries"); values.put(IndexDatabaseHelper.IndexColumns.DATA_KEYWORDS, "charlie_keywords"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF_NORMALIZED, "charlie summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_ENTRIES, "charlie entries"); values.put(IndexDatabaseHelper.IndexColumns.DATA_KEYWORDS, "charlie keywords"); values.put(IndexDatabaseHelper.IndexColumns.CLASS_NAME, "com.android.settings.gestures.GestureSettings"); values.put(IndexDatabaseHelper.IndexColumns.SCREEN_TITLE, "Moves"); Loading Loading
src/com/android/settings/search2/DatabaseResultLoader.java +22 −3 Original line number Diff line number Diff line Loading @@ -142,9 +142,7 @@ public class DatabaseResultLoader extends AsyncLoader<List<SearchResult>> { private List<SearchResult> query(String[] matchColumns, int baseRank) { final String whereClause = buildWhereClause(matchColumns); final String[] selection = new String[matchColumns.length]; final String query = "%" + mQueryText + "%"; Arrays.fill(selection, query); final String[] selection = buildQuerySelection(matchColumns.length * 2); final Cursor resultCursor = mDatabase.query(TABLE_PREFS_INDEX, SELECT_COLUMNS, whereClause, selection, null, null, null); Loading Loading @@ -173,6 +171,8 @@ public class DatabaseResultLoader extends AsyncLoader<List<SearchResult>> { StringBuilder sb = new StringBuilder(" ("); final int count = matchColumns.length; for (int n = 0; n < count; n++) { sb.append(matchColumns[n]); sb.append(" like ? OR "); sb.append(matchColumns[n]); sb.append(" like ?"); if (n < count - 1) { Loading @@ -182,4 +182,23 @@ public class DatabaseResultLoader extends AsyncLoader<List<SearchResult>> { sb.append(") AND enabled = 1"); return sb.toString(); } /** * Fills out the selection array to match the query as the prefix of a word. * * @param size is twice the number of columns to be matched. The first match is for the prefix * of the first word in the column. The second match is for any subsequent word * prefix match. */ private String[] buildQuerySelection(int size) { String[] selection = new String[size]; final String query = mQueryText + "%"; final String subStringQuery = "% " + mQueryText + "%"; for(int i = 0; i < (size - 1); i += 2) { selection[i] = query; selection[i + 1] = subStringQuery; } return selection; } }
tests/robotests/src/com/android/settings/search/DatabaseResultLoaderTest.java +68 −12 Original line number Diff line number Diff line Loading @@ -144,6 +144,62 @@ public class DatabaseResultLoaderTest { assertThat(loader.loadInBackground().size()).isEqualTo(1); } @Test public void testSpecialCasePrefix_MatchesPrefixOfEntry() { insertSpecialCase("Photos"); loader = new DatabaseResultLoader(mContext, "pho"); assertThat(loader.loadInBackground().size()).isEqualTo(1); } @Test public void testSpecialCasePrefix_DoesNotMatchNonPrefixSubstring() { insertSpecialCase("Photos"); loader = new DatabaseResultLoader(mContext, "hot"); assertThat(loader.loadInBackground().size()).isEqualTo(0); } @Test public void testSpecialCaseMultiWordPrefix_MatchesPrefixOfEntry() { insertSpecialCase("Apps Notifications"); loader = new DatabaseResultLoader(mContext, "Apps"); assertThat(loader.loadInBackground().size()).isEqualTo(1); } @Test public void testSpecialCaseMultiWordPrefix_MatchesSecondWordPrefixOfEntry() { insertSpecialCase("Apps Notifications"); loader = new DatabaseResultLoader(mContext, "Not"); assertThat(loader.loadInBackground().size()).isEqualTo(1); } @Test public void testSpecialCaseMultiWordPrefix_DoesNotMatchMatchesPrefixOfFirstEntry() { insertSpecialCase("Apps Notifications"); loader = new DatabaseResultLoader(mContext, "pp"); assertThat(loader.loadInBackground().size()).isEqualTo(0); } @Test public void testSpecialCaseMultiWordPrefix_DoesNotMatchMatchesPrefixOfSecondEntry() { insertSpecialCase("Apps Notifications"); loader = new DatabaseResultLoader(mContext, "tion"); assertThat(loader.loadInBackground().size()).isEqualTo(0); } @Test public void testSpecialCaseMultiWordPrefixWithSpecial_MatchesPrefixOfEntry() { insertSpecialCase("Apps & Notifications"); loader = new DatabaseResultLoader(mContext, "App"); assertThat(loader.loadInBackground().size()).isEqualTo(1); } @Test public void testSpecialCaseMultiWordPrefixWithSpecial_MatchesPrefixOfSecondEntry() { insertSpecialCase("Apps & Notifications"); loader = new DatabaseResultLoader(mContext, "No"); assertThat(loader.loadInBackground().size()).isEqualTo(1); } private void insertSpecialCase(String specialCase) { String normalized = DatabaseIndexingUtils.normalizeHyphen(specialCase); normalized = DatabaseIndexingUtils.normalizeString(normalized); Loading Loading @@ -184,11 +240,11 @@ public class DatabaseResultLoaderTest { values.put(IndexDatabaseHelper.IndexColumns.DATA_TITLE, "alpha_title"); values.put(IndexDatabaseHelper.IndexColumns.DATA_TITLE_NORMALIZED, "alpha title"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON, "alpha_summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON_NORMALIZED, "alpha_summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON_NORMALIZED, "alpha summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF, "alpha_summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF_NORMALIZED, "alpha_summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_ENTRIES, "alpha_entries"); values.put(IndexDatabaseHelper.IndexColumns.DATA_KEYWORDS, "alpha_keywords"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF_NORMALIZED, "alpha summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_ENTRIES, "alpha entries"); values.put(IndexDatabaseHelper.IndexColumns.DATA_KEYWORDS, "alpha keywords"); values.put(IndexDatabaseHelper.IndexColumns.CLASS_NAME, "com.android.settings.gestures.GestureSettings"); values.put(IndexDatabaseHelper.IndexColumns.SCREEN_TITLE, "Moves"); Loading @@ -211,11 +267,11 @@ public class DatabaseResultLoaderTest { values.put(IndexDatabaseHelper.IndexColumns.DATA_TITLE, "bravo_title"); values.put(IndexDatabaseHelper.IndexColumns.DATA_TITLE_NORMALIZED, "bravo title"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON, "bravo_summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON_NORMALIZED, "bravo_summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON_NORMALIZED, "bravo summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF, "bravo_summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF_NORMALIZED, "bravo_summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_ENTRIES, "bravo_entries"); values.put(IndexDatabaseHelper.IndexColumns.DATA_KEYWORDS, "bravo_keywords"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF_NORMALIZED, "bravo summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_ENTRIES, "bravo entries"); values.put(IndexDatabaseHelper.IndexColumns.DATA_KEYWORDS, "bravo keywords"); values.put(IndexDatabaseHelper.IndexColumns.CLASS_NAME, "com.android.settings.gestures.GestureSettings"); values.put(IndexDatabaseHelper.IndexColumns.SCREEN_TITLE, "Moves"); Loading @@ -237,11 +293,11 @@ public class DatabaseResultLoaderTest { values.put(IndexDatabaseHelper.IndexColumns.DATA_TITLE, "charlie_title"); values.put(IndexDatabaseHelper.IndexColumns.DATA_TITLE_NORMALIZED, "charlie title"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON, "charlie_summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON_NORMALIZED, "charlie_summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON_NORMALIZED, "charlie summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF, "charlie_summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF_NORMALIZED, "charlie_summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_ENTRIES, "charlie_entries"); values.put(IndexDatabaseHelper.IndexColumns.DATA_KEYWORDS, "charlie_keywords"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF_NORMALIZED, "charlie summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_ENTRIES, "charlie entries"); values.put(IndexDatabaseHelper.IndexColumns.DATA_KEYWORDS, "charlie keywords"); values.put(IndexDatabaseHelper.IndexColumns.CLASS_NAME, "com.android.settings.gestures.GestureSettings"); values.put(IndexDatabaseHelper.IndexColumns.SCREEN_TITLE, "Moves"); Loading