Search only matches prefixes rather than any substring
Test: make RunSettingsRoboTests Change-Id: I4da7e4c75c461fad96dedf5277ddba02e067928d Bug: 34688403
This commit is contained in:
@@ -141,9 +141,7 @@ public class DatabaseResultLoader extends AsyncLoader<List<SearchResult>> {
|
|||||||
|
|
||||||
private List<SearchResult> query(String[] matchColumns, int baseRank) {
|
private List<SearchResult> query(String[] matchColumns, int baseRank) {
|
||||||
final String whereClause = buildWhereClause(matchColumns);
|
final String whereClause = buildWhereClause(matchColumns);
|
||||||
final String[] selection = new String[matchColumns.length];
|
final String[] selection = buildQuerySelection(matchColumns.length * 2);
|
||||||
final String query = "%" + mQueryText + "%";
|
|
||||||
Arrays.fill(selection, query);
|
|
||||||
|
|
||||||
final Cursor resultCursor = mDatabase.query(TABLE_PREFS_INDEX, SELECT_COLUMNS, whereClause,
|
final Cursor resultCursor = mDatabase.query(TABLE_PREFS_INDEX, SELECT_COLUMNS, whereClause,
|
||||||
selection, null, null, null);
|
selection, null, null, null);
|
||||||
@@ -169,6 +167,8 @@ public class DatabaseResultLoader extends AsyncLoader<List<SearchResult>> {
|
|||||||
StringBuilder sb = new StringBuilder(" (");
|
StringBuilder sb = new StringBuilder(" (");
|
||||||
final int count = matchColumns.length;
|
final int count = matchColumns.length;
|
||||||
for (int n = 0; n < count; n++) {
|
for (int n = 0; n < count; n++) {
|
||||||
|
sb.append(matchColumns[n]);
|
||||||
|
sb.append(" like ? OR ");
|
||||||
sb.append(matchColumns[n]);
|
sb.append(matchColumns[n]);
|
||||||
sb.append(" like ?");
|
sb.append(" like ?");
|
||||||
if (n < count - 1) {
|
if (n < count - 1) {
|
||||||
@@ -178,4 +178,23 @@ public class DatabaseResultLoader extends AsyncLoader<List<SearchResult>> {
|
|||||||
sb.append(") AND enabled = 1");
|
sb.append(") AND enabled = 1");
|
||||||
return sb.toString();
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -144,6 +144,62 @@ public class DatabaseResultLoaderTest {
|
|||||||
assertThat(loader.loadInBackground().size()).isEqualTo(1);
|
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) {
|
private void insertSpecialCase(String specialCase) {
|
||||||
String normalized = DatabaseIndexingUtils.normalizeHyphen(specialCase);
|
String normalized = DatabaseIndexingUtils.normalizeHyphen(specialCase);
|
||||||
normalized = DatabaseIndexingUtils.normalizeString(normalized);
|
normalized = DatabaseIndexingUtils.normalizeString(normalized);
|
||||||
@@ -184,11 +240,11 @@ public class DatabaseResultLoaderTest {
|
|||||||
values.put(IndexDatabaseHelper.IndexColumns.DATA_TITLE, "alpha_title");
|
values.put(IndexDatabaseHelper.IndexColumns.DATA_TITLE, "alpha_title");
|
||||||
values.put(IndexDatabaseHelper.IndexColumns.DATA_TITLE_NORMALIZED, "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, "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, "alpha_summary");
|
||||||
values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF_NORMALIZED, "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_ENTRIES, "alpha entries");
|
||||||
values.put(IndexDatabaseHelper.IndexColumns.DATA_KEYWORDS, "alpha_keywords");
|
values.put(IndexDatabaseHelper.IndexColumns.DATA_KEYWORDS, "alpha keywords");
|
||||||
values.put(IndexDatabaseHelper.IndexColumns.CLASS_NAME,
|
values.put(IndexDatabaseHelper.IndexColumns.CLASS_NAME,
|
||||||
"com.android.settings.gestures.GestureSettings");
|
"com.android.settings.gestures.GestureSettings");
|
||||||
values.put(IndexDatabaseHelper.IndexColumns.SCREEN_TITLE, "Moves");
|
values.put(IndexDatabaseHelper.IndexColumns.SCREEN_TITLE, "Moves");
|
||||||
@@ -211,11 +267,11 @@ public class DatabaseResultLoaderTest {
|
|||||||
values.put(IndexDatabaseHelper.IndexColumns.DATA_TITLE, "bravo_title");
|
values.put(IndexDatabaseHelper.IndexColumns.DATA_TITLE, "bravo_title");
|
||||||
values.put(IndexDatabaseHelper.IndexColumns.DATA_TITLE_NORMALIZED, "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, "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, "bravo_summary");
|
||||||
values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF_NORMALIZED, "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_ENTRIES, "bravo entries");
|
||||||
values.put(IndexDatabaseHelper.IndexColumns.DATA_KEYWORDS, "bravo_keywords");
|
values.put(IndexDatabaseHelper.IndexColumns.DATA_KEYWORDS, "bravo keywords");
|
||||||
values.put(IndexDatabaseHelper.IndexColumns.CLASS_NAME,
|
values.put(IndexDatabaseHelper.IndexColumns.CLASS_NAME,
|
||||||
"com.android.settings.gestures.GestureSettings");
|
"com.android.settings.gestures.GestureSettings");
|
||||||
values.put(IndexDatabaseHelper.IndexColumns.SCREEN_TITLE, "Moves");
|
values.put(IndexDatabaseHelper.IndexColumns.SCREEN_TITLE, "Moves");
|
||||||
@@ -237,11 +293,11 @@ public class DatabaseResultLoaderTest {
|
|||||||
values.put(IndexDatabaseHelper.IndexColumns.DATA_TITLE, "charlie_title");
|
values.put(IndexDatabaseHelper.IndexColumns.DATA_TITLE, "charlie_title");
|
||||||
values.put(IndexDatabaseHelper.IndexColumns.DATA_TITLE_NORMALIZED, "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, "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, "charlie_summary");
|
||||||
values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF_NORMALIZED, "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_ENTRIES, "charlie entries");
|
||||||
values.put(IndexDatabaseHelper.IndexColumns.DATA_KEYWORDS, "charlie_keywords");
|
values.put(IndexDatabaseHelper.IndexColumns.DATA_KEYWORDS, "charlie keywords");
|
||||||
values.put(IndexDatabaseHelper.IndexColumns.CLASS_NAME,
|
values.put(IndexDatabaseHelper.IndexColumns.CLASS_NAME,
|
||||||
"com.android.settings.gestures.GestureSettings");
|
"com.android.settings.gestures.GestureSettings");
|
||||||
values.put(IndexDatabaseHelper.IndexColumns.SCREEN_TITLE, "Moves");
|
values.put(IndexDatabaseHelper.IndexColumns.SCREEN_TITLE, "Moves");
|
||||||
|
Reference in New Issue
Block a user