Merge branch 'fix-511--database-constants-everywhere' into 'master'

Ensure database fields referred to by `Schema.*Table.Cols.*` constants

**This is based on top of !346.** When that is merged, I'll rebase this again and then remove the WIP.

The goal of this is to ensure that all string literals which refer to database columns are replaced with constants from the relevant `Schema.*Table.Cols` interface.

The only exceptions are fields which no longer exist and are referred to in the `DBHelper` class (e.g. the `fdroid_repo` table had an `id` column but that is now `_id`).

This should not change **any** behaviour in the client app, all semantics should stay **exactly** the same.

See merge request !347
This commit is contained in:
Daniel Martí 2016-07-04 12:50:09 +00:00
commit e38624626c
9 changed files with 240 additions and 254 deletions

View File

@ -199,7 +199,7 @@ public class RepoUpdater {
reader.setContentHandler(repoXMLHandler);
reader.parse(new InputSource(indexInputStream));
long timestamp = repoDetailsToSave.getAsLong("timestamp");
long timestamp = repoDetailsToSave.getAsLong(RepoTable.Cols.TIMESTAMP);
if (timestamp < repo.timestamp) {
throw new UpdateException(repo, "index.jar is older that current index! "
+ timestamp + " < " + repo.timestamp);

View File

@ -350,8 +350,8 @@ public class ApkProvider extends FDroidProvider {
appendField("rowid", "apk", "_id");
} else if (field.equals(Cols._COUNT)) {
appendField("COUNT(*) AS " + Cols._COUNT);
} else if (field.equals(Cols._COUNT_DISTINCT_ID)) {
appendField("COUNT(DISTINCT apk.id) AS " + Cols._COUNT_DISTINCT_ID);
} else if (field.equals(Cols._COUNT_DISTINCT)) {
appendField("COUNT(DISTINCT apk." + Cols.PACKAGE_NAME + ") AS " + Cols._COUNT_DISTINCT);
} else {
appendField(field, "apk");
}
@ -360,7 +360,7 @@ public class ApkProvider extends FDroidProvider {
private void addRepoField(String field, String alias) {
if (!repoTableRequired) {
repoTableRequired = true;
leftJoin(RepoTable.NAME, "repo", "apk.repo = repo._id");
leftJoin(RepoTable.NAME, "repo", "apk." + Cols.REPO_ID + " = repo." + RepoTable.Cols._ID);
}
appendField(field, "repo", alias);
}
@ -374,7 +374,7 @@ public class ApkProvider extends FDroidProvider {
}
private QuerySelection querySingle(Uri uri) {
final String selection = " vercode = ? and id = ? ";
final String selection = Cols.VERSION_CODE + " = ? and " + Cols.PACKAGE_NAME + " = ? ";
final String[] args = {
// First (0th) path segment is the word "apk",
// and we are not interested in it.
@ -412,7 +412,7 @@ public class ApkProvider extends FDroidProvider {
if (i != 0) {
sb.append(" OR ");
}
sb.append(" ( id = ? AND vercode = ? ) ");
sb.append(" ( " + Cols.PACKAGE_NAME + " = ? AND " + Cols.VERSION_CODE + " = ? ) ");
}
return new QuerySelection(sb.toString(), args);
}

View File

@ -247,8 +247,8 @@ public class AppProvider extends FDroidProvider {
final String repo = RepoTable.NAME;
return app +
" LEFT JOIN " + apk + " ON ( " + apk + ".id = " + app + ".id ) " +
" LEFT JOIN " + repo + " ON ( " + apk + ".repo = " + repo + "._id )";
" LEFT JOIN " + apk + " ON (" + apk + "." + ApkTable.Cols.PACKAGE_NAME + " = " + app + "." + Cols.PACKAGE_NAME + ") " +
" LEFT JOIN " + repo + " ON (" + apk + "." + ApkTable.Cols.REPO_ID + " = " + repo + "." + RepoTable.Cols._ID + ") ";
}
@Override
@ -259,7 +259,7 @@ public class AppProvider extends FDroidProvider {
@Override
protected String groupBy() {
// If the count field has been requested, then we want to group all rows together.
return countFieldAppended ? null : getTableName() + ".id";
return countFieldAppended ? null : getTableName() + "." + Cols.PACKAGE_NAME;
}
public void addSelection(AppQuerySelection selection) {
@ -276,7 +276,7 @@ public class AppProvider extends FDroidProvider {
join(
InstalledAppTable.NAME,
"installed",
"installed." + InstalledAppTable.Cols.PACKAGE_NAME + " = " + getTableName() + ".id");
"installed." + InstalledAppTable.Cols.PACKAGE_NAME + " = " + getTableName() + "." + Cols.PACKAGE_NAME);
requiresInstalledTable = true;
}
}
@ -286,7 +286,7 @@ public class AppProvider extends FDroidProvider {
leftJoin(
InstalledAppTable.NAME,
"installed",
"installed." + InstalledAppTable.Cols.PACKAGE_NAME + " = " + getTableName() + ".id");
"installed." + InstalledAppTable.Cols.PACKAGE_NAME + " = " + getTableName() + "." + Cols.PACKAGE_NAME);
requiresInstalledTable = true;
}
}
@ -320,7 +320,7 @@ public class AppProvider extends FDroidProvider {
private void appendCountField() {
countFieldAppended = true;
appendField("COUNT( DISTINCT " + getTableName() + ".id ) AS " + Cols._COUNT);
appendField("COUNT( DISTINCT " + getTableName() + "." + Cols.PACKAGE_NAME + " ) AS " + Cols._COUNT);
}
private void addSuggestedApkVersionField() {
@ -335,7 +335,7 @@ public class AppProvider extends FDroidProvider {
leftJoin(
getApkTableName(),
"suggestedApk",
getTableName() + ".suggestedVercode = suggestedApk.vercode AND " + getTableName() + ".id = suggestedApk.id");
getTableName() + "." + Cols.SUGGESTED_VERSION_CODE + " = suggestedApk." + ApkTable.Cols.VERSION_CODE + " AND " + getTableName() + "." + Cols.PACKAGE_NAME + " = suggestedApk." + ApkTable.Cols.PACKAGE_NAME);
}
appendField(fieldName, "suggestedApk", alias);
}
@ -547,15 +547,16 @@ public class AppProvider extends FDroidProvider {
}
private AppQuerySelection queryCanUpdate() {
final String ignoreCurrent = getTableName() + ".ignoreThisUpdate != " + getTableName() + ".suggestedVercode ";
final String ignoreAll = getTableName() + ".ignoreAllUpdates != 1 ";
final String app = getTableName();
final String ignoreCurrent = app + "." + Cols.IGNORE_THISUPDATE + "!= " + app + "." + Cols.SUGGESTED_VERSION_CODE;
final String ignoreAll = app + "." + Cols.IGNORE_ALLUPDATES + " != 1";
final String ignore = " (" + ignoreCurrent + " AND " + ignoreAll + ") ";
final String where = ignore + " AND " + getTableName() + "." + Cols.SUGGESTED_VERSION_CODE + " > installed.versionCode";
final String where = ignore + " AND " + app + "." + Cols.SUGGESTED_VERSION_CODE + " > installed." + InstalledAppTable.Cols.VERSION_CODE;
return new AppQuerySelection(where).requireNaturalInstalledTable();
}
private AppQuerySelection queryRepo(long repoId) {
final String selection = getApkTableName() + ".repo = ? ";
final String selection = getApkTableName() + "." + ApkTable.Cols.REPO_ID + " = ? ";
final String[] args = {String.valueOf(repoId)};
return new AppQuerySelection(selection, args);
}
@ -580,11 +581,12 @@ public class AppProvider extends FDroidProvider {
iKeyword++;
}
final String app = getTableName();
final String[] columns = {
getTableName() + ".id",
getTableName() + ".name",
getTableName() + ".summary",
getTableName() + ".description",
app + "." + Cols.PACKAGE_NAME,
app + "." + Cols.NAME,
app + "." + Cols.SUMMARY,
app + "." + Cols.DESCRIPTION,
};
// Build selection string and fill out keyword arguments
@ -606,7 +608,7 @@ public class AppProvider extends FDroidProvider {
} else {
selection.append(" AND ");
}
selection.append(column).append(" like ?");
selection.append(column).append(" LIKE ?");
selectionKeywords[iKeyword] = keyword;
iKeyword++;
}
@ -616,15 +618,15 @@ public class AppProvider extends FDroidProvider {
}
protected AppQuerySelection querySingle(String packageName) {
final String selection = getTableName() + ".id = ?";
final String selection = getTableName() + "." + Cols.PACKAGE_NAME + " = ?";
final String[] args = {packageName};
return new AppQuerySelection(selection, args);
}
private AppQuerySelection queryIgnored() {
final String table = getTableName();
final String selection = table + ".ignoreAllUpdates = 1 OR " +
table + ".ignoreThisUpdate >= " + table + ".suggestedVercode";
final String selection = table + "." + Cols.IGNORE_ALLUPDATES + " = 1 OR " +
table + "." + Cols.IGNORE_THISUPDATE + " >= " + table + "." + Cols.SUGGESTED_VERSION_CODE;
return new AppQuerySelection(selection);
}
@ -632,19 +634,21 @@ public class AppProvider extends FDroidProvider {
// fdroid_repo will have null fields if the LEFT JOIN didn't resolve, e.g. due to there
// being no apks for the app in the result set. In that case, we can't tell if it is from
// a swap repo or not.
final String selection = " fdroid_repo.isSwap = 0 OR fdroid_repo.isSwap is null ";
final String isSwap = RepoTable.NAME + "." + RepoTable.Cols.IS_SWAP;
final String selection = isSwap + " = 0 OR " + isSwap + " IS NULL";
return new AppQuerySelection(selection);
}
private AppQuerySelection queryNewlyAdded() {
final String selection = getTableName() + ".added > ?";
final String selection = getTableName() + "." + Cols.ADDED + " > ?";
final String[] args = {Utils.formatDate(Preferences.get().calcMaxHistory(), "")};
return new AppQuerySelection(selection, args);
}
private AppQuerySelection queryRecentlyUpdated() {
final String app = getTableName();
final String selection = app + ".added != " + app + ".lastUpdated AND " + app + ".lastUpdated > ?";
final String lastUpdated = app + "." + Cols.LAST_UPDATED;
final String selection = app + "." + Cols.ADDED + " != " + lastUpdated + " AND " + lastUpdated + " > ?";
final String[] args = {Utils.formatDate(Preferences.get().calcMaxHistory(), "")};
return new AppQuerySelection(selection, args);
}
@ -652,11 +656,12 @@ public class AppProvider extends FDroidProvider {
private AppQuerySelection queryCategory(String category) {
// TODO: In the future, add a new table for categories,
// so we can join onto it.
final String app = getTableName();
final String selection =
getTableName() + ".categories = ? OR " + // Only category e.g. "internet"
getTableName() + ".categories LIKE ? OR " + // First category e.g. "internet,%"
getTableName() + ".categories LIKE ? OR " + // Last category e.g. "%,internet"
getTableName() + ".categories LIKE ? "; // One of many categories e.g. "%,internet,%"
app + "." + Cols.CATEGORIES + " = ? OR " + // Only category e.g. "internet"
app + "." + Cols.CATEGORIES + " LIKE ? OR " + // First category e.g. "internet,%"
app + "." + Cols.CATEGORIES + " LIKE ? OR " + // Last category e.g. "%,internet"
app + "." + Cols.CATEGORIES + " LIKE ? "; // One of many categories e.g. "%,internet,%"
final String[] args = {
category,
category + ",%",
@ -667,18 +672,20 @@ public class AppProvider extends FDroidProvider {
}
private AppQuerySelection queryNoApks() {
String selection = "(SELECT COUNT(*) FROM " + getApkTableName() + " WHERE " + getApkTableName() + ".id = " + getTableName() + ".id) = 0";
final String apk = getApkTableName();
final String app = getTableName();
String selection = "(SELECT COUNT(*) FROM " + apk + " WHERE " + apk + "." + ApkTable.Cols.PACKAGE_NAME + " = " + app + "." + Cols.PACKAGE_NAME + ") = 0";
return new AppQuerySelection(selection);
}
static AppQuerySelection queryApps(String packageNames, String idField) {
static AppQuerySelection queryApps(String packageNames, String packageNameField) {
String[] args = packageNames.split(",");
String selection = idField + " IN (" + generateQuestionMarksForInClause(args.length) + ")";
String selection = packageNameField + " IN (" + generateQuestionMarksForInClause(args.length) + ")";
return new AppQuerySelection(selection, args);
}
private AppQuerySelection queryApps(String packageNames) {
return queryApps(packageNames, getTableName() + ".id");
return queryApps(packageNames, getTableName() + "." + Cols.PACKAGE_NAME);
}
@Override
@ -749,13 +756,13 @@ public class AppProvider extends FDroidProvider {
break;
case RECENTLY_UPDATED:
sortOrder = getTableName() + ".lastUpdated DESC";
sortOrder = getTableName() + "." + Cols.LAST_UPDATED + " DESC";
selection = selection.add(queryRecentlyUpdated());
includeSwap = false;
break;
case NEWLY_ADDED:
sortOrder = getTableName() + ".added DESC";
sortOrder = getTableName() + "." + Cols.ADDED + " DESC";
selection = selection.add(queryNewlyAdded());
includeSwap = false;
break;
@ -846,26 +853,18 @@ public class AppProvider extends FDroidProvider {
/**
* For each app, we want to set the isCompatible flag to 1 if any of the apks we know
* about are compatible, and 0 otherwise.
*
* Readable SQL code:
*
* UPDATE fdroid_app SET compatible = (
* SELECT TOTAL( fdroid_apk.compatible ) > 0
* FROM fdroid_apk
* WHERE fdroid_apk.id = fdroid_app.id );
*/
private void updateCompatibleFlags() {
Utils.debugLog(TAG, "Calculating whether apps are compatible, based on whether any of their apks are compatible");
final String apk = getApkTableName();
final String app = getTableName();
String updateSql =
"UPDATE " + app + " SET compatible = ( " +
" SELECT TOTAL( " + apk + ".compatible ) > 0 " +
"UPDATE " + app + " SET " + Cols.IS_COMPATIBLE + " = ( " +
" SELECT TOTAL( " + apk + "." + ApkTable.Cols.IS_COMPATIBLE + ") > 0 " +
" FROM " + apk +
" WHERE " + apk + ".id = " + app + ".id );";
" WHERE " + apk + "." + ApkTable.Cols.PACKAGE_NAME + " = " + app + "." + Cols.PACKAGE_NAME + " );";
db().execSQL(updateSql);
}
@ -875,38 +874,24 @@ public class AppProvider extends FDroidProvider {
* with the closest version code to that, without going over.
* If the app is not compatible at all (i.e. no versions were compatible)
* then we take the highest, otherwise we take the highest compatible version.
*
* Readable SQL code:
*
* UPDATE fdroid_app
* SET suggestedVercode = (
* SELECT MAX(fdroid_apk.vercode)
* FROM fdroid_apk
* WHERE
* fdroid_app.id = fdroid_apk.id AND
* fdroid_apk.vercode <= fdroid_app.upstreamVercode AND
* ( fdroid_app.compatible = 0 OR fdroid_apk.compatible = 1 )
* )
* WHERE upstreamVercode > 0
*/
private void updateSuggestedFromUpstream() {
Utils.debugLog(TAG, "Calculating suggested versions for all apps which specify an upstream version code.");
final String apk = getApkTableName();
final String app = getTableName();
final boolean unstableUpdates = Preferences.get().getUnstableUpdates();
String restrictToStable = unstableUpdates ? "" : (apk + ".vercode <= " + app + ".upstreamVercode AND ");
String restrictToStable = unstableUpdates ? "" : (apk + "." + ApkTable.Cols.VERSION_CODE + " <= " + app + "." + Cols.UPSTREAM_VERSION_CODE + " AND ");
String updateSql =
"UPDATE " + app + " SET suggestedVercode = ( " +
" SELECT MAX( " + apk + ".vercode ) " +
"UPDATE " + app + " SET " + Cols.SUGGESTED_VERSION_CODE + " = ( " +
" SELECT MAX( " + apk + "." + ApkTable.Cols.VERSION_CODE + " ) " +
" FROM " + apk +
" WHERE " +
app + ".id = " + apk + ".id AND " +
app + "." + Cols.PACKAGE_NAME + " = " + apk + "." + ApkTable.Cols.PACKAGE_NAME + " AND " +
restrictToStable +
" ( " + app + ".compatible = 0 OR " + apk + ".compatible = 1 ) ) " +
" WHERE upstreamVercode > 0 ";
" ( " + app + "." + Cols.IS_COMPATIBLE + " = 0 OR " + apk + "." + Cols.IS_COMPATIBLE + " = 1 ) ) " +
" WHERE " + Cols.UPSTREAM_VERSION_CODE + " > 0 ";
db().execSQL(updateSql);
}
@ -918,33 +903,21 @@ public class AppProvider extends FDroidProvider {
* If the suggested version is null, it means that we could not figure it
* out from the upstream vercode. In such a case, fall back to the simpler
* algorithm as if upstreamVercode was 0.
*
* Readable SQL code:
*
* UPDATE fdroid_app SET suggestedVercode = (
* SELECT MAX(fdroid_apk.vercode)
* FROM fdroid_apk
* WHERE
* fdroid_app.id = fdroid_apk.id AND
* ( fdroid_app.compatible = 0 OR fdroid_apk.compatible = 1 )
* )
* WHERE upstreamVercode = 0 OR upstreamVercode IS NULL OR suggestedVercode IS NULL;
*/
private void updateSuggestedFromLatest() {
Utils.debugLog(TAG, "Calculating suggested versions for all apps which don't specify an upstream version code.");
final String apk = getApkTableName();
final String app = getTableName();
String updateSql =
"UPDATE " + app + " SET suggestedVercode = ( " +
" SELECT MAX( " + apk + ".vercode ) " +
"UPDATE " + app + " SET " + Cols.SUGGESTED_VERSION_CODE + " = ( " +
" SELECT MAX( " + apk + "." + ApkTable.Cols.VERSION_CODE + " ) " +
" FROM " + apk +
" WHERE " +
app + ".id = " + apk + ".id AND " +
" ( " + app + ".compatible = 0 OR " + apk + ".compatible = 1 ) ) " +
" WHERE upstreamVercode = 0 OR upstreamVercode IS NULL OR suggestedVercode IS NULL ";
app + "." + Cols.PACKAGE_NAME + " = " + apk + "." + ApkTable.Cols.PACKAGE_NAME + " AND " +
" ( " + app + "." + Cols.IS_COMPATIBLE + " = 0 OR " + apk + "." + ApkTable.Cols.IS_COMPATIBLE + " = 1 ) ) " +
" WHERE " + Cols.UPSTREAM_VERSION_CODE + " = 0 OR " + Cols.UPSTREAM_VERSION_CODE + " IS NULL OR " + Cols.SUGGESTED_VERSION_CODE + " IS NULL ";
db().execSQL(updateSql);
}
@ -958,8 +931,7 @@ public class AppProvider extends FDroidProvider {
final String iconsDir = Utils.getIconsDir(context, 1.0);
final String iconsDirLarge = Utils.getIconsDir(context, 1.5);
String repoVersion = Integer.toString(Repo.VERSION_DENSITY_SPECIFIC_ICONS);
Utils.debugLog(TAG, "Updating icon paths for apps belonging to repos with version >= "
+ repoVersion);
Utils.debugLog(TAG, "Updating icon paths for apps belonging to repos with version >= " + repoVersion);
Utils.debugLog(TAG, "Using icons dir '" + iconsDir + "'");
Utils.debugLog(TAG, "Using large icons dir '" + iconsDirLarge + "'");
String query = getIconUpdateQuery(appTable, apkTable);
@ -986,32 +958,27 @@ public class AppProvider extends FDroidProvider {
// icons directory (bound to the ? as the second parameter
// when executing the query) and the icon path.
"( " +
repo + ".address " +
repo + "." + RepoTable.Cols.ADDRESS +
" || " +
// If the repo has the relevant version, then use a more
// intelligent icons dir, otherwise revert to the default
// one
" CASE WHEN " + repo + ".version >= ? THEN ? ELSE ? END " +
" CASE WHEN " + repo + "." + RepoTable.Cols.VERSION + " >= ? THEN ? ELSE ? END " +
" || " +
app + ".icon " +
app + "." + Cols.ICON +
") " +
" FROM " +
apk +
" JOIN " + repo + " ON (" + repo + "._id = " + apk + ".repo) " +
" JOIN " + repo + " ON (" + repo + "." + RepoTable.Cols._ID + " = " + apk + "." + ApkTable.Cols.REPO_ID + ") " +
" WHERE " +
app + ".id = " + apk + ".id AND " +
apk + ".vercode = " + app + ".suggestedVercode ";
app + "." + Cols.PACKAGE_NAME + " = " + apk + "." + ApkTable.Cols.PACKAGE_NAME + " AND " +
apk + "." + ApkTable.Cols.VERSION_CODE + " = " + app + "." + Cols.SUGGESTED_VERSION_CODE;
return
" UPDATE " + app + " SET " +
" iconUrl = ( " +
iconUrlQuery +
" ), " +
" iconUrlLarge = ( " +
iconUrlQuery +
" ) ";
return "UPDATE " + app + " SET "
+ Cols.ICON_URL + " = ( " + iconUrlQuery + " ), "
+ Cols.ICON_URL_LARGE + " = ( " + iconUrlQuery + " )";
}
}

View File

@ -5,6 +5,7 @@ import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.text.TextUtils;
import android.util.Log;
import org.fdroid.fdroid.R;
@ -24,74 +25,81 @@ class DBHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "fdroid";
private static final String CREATE_TABLE_REPO = "create table "
+ RepoTable.NAME + " (_id integer primary key, "
+ "address text not null, "
+ "name text, description text, inuse integer not null, "
+ "priority integer not null, pubkey text, fingerprint text, "
+ "maxage integer not null default 0, "
+ "version integer not null default 0, "
+ "lastetag text, lastUpdated string,"
+ "isSwap integer boolean default 0,"
+ "username string, password string,"
+ "timestamp integer not null default 0"
+ RepoTable.NAME + " ("
+ RepoTable.Cols._ID + " integer primary key, "
+ RepoTable.Cols.ADDRESS + " text not null, "
+ RepoTable.Cols.NAME + " text, "
+ RepoTable.Cols.DESCRIPTION + " text, "
+ RepoTable.Cols.IN_USE + " integer not null, "
+ RepoTable.Cols.PRIORITY + " integer not null, "
+ RepoTable.Cols.SIGNING_CERT + " text, "
+ RepoTable.Cols.FINGERPRINT + " text, "
+ RepoTable.Cols.MAX_AGE + " integer not null default 0, "
+ RepoTable.Cols.VERSION + " integer not null default 0, "
+ RepoTable.Cols.LAST_ETAG + " text, "
+ RepoTable.Cols.LAST_UPDATED + " string,"
+ RepoTable.Cols.IS_SWAP + " integer boolean default 0,"
+ RepoTable.Cols.USERNAME + " string, "
+ RepoTable.Cols.PASSWORD + " string,"
+ RepoTable.Cols.TIMESTAMP + " integer not null default 0"
+ ");";
private static final String CREATE_TABLE_APK =
"CREATE TABLE " + ApkTable.NAME + " ( "
+ "id text not null, "
+ "version text not null, "
+ "repo integer not null, "
+ "hash text not null, "
+ "vercode int not null,"
+ "apkName text not null, "
+ "size int not null, "
+ "sig string, "
+ "srcname string, "
+ "minSdkVersion integer, "
+ "targetSdkVersion integer, "
+ "maxSdkVersion integer, "
+ "permissions string, "
+ "features string, "
+ "nativecode string, "
+ "hashType string, "
+ "added string, "
+ "compatible int not null, "
+ "incompatibleReasons text, "
+ "primary key(id, vercode)"
+ ApkTable.Cols.PACKAGE_NAME + " text not null, "
+ ApkTable.Cols.VERSION_NAME + " text not null, "
+ ApkTable.Cols.REPO_ID + " integer not null, "
+ ApkTable.Cols.HASH + " text not null, "
+ ApkTable.Cols.VERSION_CODE + " int not null,"
+ ApkTable.Cols.NAME + " text not null, "
+ ApkTable.Cols.SIZE + " int not null, "
+ ApkTable.Cols.SIGNATURE + " string, "
+ ApkTable.Cols.SOURCE_NAME + " string, "
+ ApkTable.Cols.MIN_SDK_VERSION + " integer, "
+ ApkTable.Cols.TARGET_SDK_VERSION + " integer, "
+ ApkTable.Cols.MAX_SDK_VERSION + " integer, "
+ ApkTable.Cols.PERMISSIONS + " string, "
+ ApkTable.Cols.FEATURES + " string, "
+ ApkTable.Cols.NATIVE_CODE + " string, "
+ ApkTable.Cols.HASH_TYPE + " string, "
+ ApkTable.Cols.ADDED_DATE + " string, "
+ ApkTable.Cols.IS_COMPATIBLE + " int not null, "
+ ApkTable.Cols.INCOMPATIBLE_REASONS + " text, "
+ "primary key(" + ApkTable.Cols.PACKAGE_NAME + ", " + ApkTable.Cols.VERSION_CODE + ")"
+ ");";
private static final String CREATE_TABLE_APP = "CREATE TABLE " + AppTable.NAME
+ " ( "
+ "id text not null, "
+ "name text not null, "
+ "summary text not null, "
+ "icon text, "
+ "description text not null, "
+ "license text not null, "
+ "author text, "
+ "email text, "
+ "webURL text, "
+ "trackerURL text, "
+ "sourceURL text, "
+ "changelogURL text, "
+ "suggestedVercode text,"
+ "upstreamVersion text,"
+ "upstreamVercode integer,"
+ "antiFeatures string,"
+ "donateURL string,"
+ "bitcoinAddr string,"
+ "litecoinAddr string,"
+ "flattrID string,"
+ "requirements string,"
+ "categories string,"
+ "added string,"
+ "lastUpdated string,"
+ "compatible int not null,"
+ "ignoreAllUpdates int not null,"
+ "ignoreThisUpdate int not null,"
+ "iconUrl text, "
+ "iconUrlLarge text, "
+ "primary key(id));";
+ AppTable.Cols.PACKAGE_NAME + " text not null, "
+ AppTable.Cols.NAME + " text not null, "
+ AppTable.Cols.SUMMARY + " text not null, "
+ AppTable.Cols.ICON + " text, "
+ AppTable.Cols.DESCRIPTION + " text not null, "
+ AppTable.Cols.LICENSE + " text not null, "
+ AppTable.Cols.AUTHOR + " text, "
+ AppTable.Cols.EMAIL + " text, "
+ AppTable.Cols.WEB_URL + " text, "
+ AppTable.Cols.TRACKER_URL + " text, "
+ AppTable.Cols.SOURCE_URL + " text, "
+ AppTable.Cols.CHANGELOG_URL + " text, "
+ AppTable.Cols.SUGGESTED_VERSION_CODE + " text,"
+ AppTable.Cols.UPSTREAM_VERSION_NAME + " text,"
+ AppTable.Cols.UPSTREAM_VERSION_CODE + " integer,"
+ AppTable.Cols.ANTI_FEATURES + " string,"
+ AppTable.Cols.DONATE_URL + " string,"
+ AppTable.Cols.BITCOIN_ADDR + " string,"
+ AppTable.Cols.LITECOIN_ADDR + " string,"
+ AppTable.Cols.FLATTR_ID + " string,"
+ AppTable.Cols.REQUIREMENTS + " string,"
+ AppTable.Cols.CATEGORIES + " string,"
+ AppTable.Cols.ADDED + " string,"
+ AppTable.Cols.LAST_UPDATED + " string,"
+ AppTable.Cols.IS_COMPATIBLE + " int not null,"
+ AppTable.Cols.IGNORE_ALLUPDATES + " int not null,"
+ AppTable.Cols.IGNORE_THISUPDATE + " int not null,"
+ AppTable.Cols.ICON_URL + " text, "
+ AppTable.Cols.ICON_URL_LARGE + " text, "
+ "primary key(" + AppTable.Cols.PACKAGE_NAME + "));";
private static final String CREATE_TABLE_INSTALLED_APP = "CREATE TABLE " + InstalledAppTable.NAME
+ " ( "
@ -120,9 +128,9 @@ class DBHelper extends SQLiteOpenHelper {
return;
}
Utils.debugLog(TAG, "Populating repo names from the url");
final String[] columns = {"address", "_id"};
final String[] columns = {RepoTable.Cols.ADDRESS, RepoTable.Cols._ID};
Cursor cursor = db.query(RepoTable.NAME, columns,
"name IS NULL OR name = ''", null, null, null, null);
RepoTable.Cols.NAME + " IS NULL OR " + RepoTable.Cols.NAME + " = ''", null, null, null, null);
if (cursor != null) {
if (cursor.getCount() > 0) {
cursor.moveToFirst();
@ -131,10 +139,10 @@ class DBHelper extends SQLiteOpenHelper {
long id = cursor.getInt(1);
ContentValues values = new ContentValues(1);
String name = Repo.addressToName(address);
values.put("name", name);
values.put(RepoTable.Cols.NAME, name);
final String[] args = {Long.toString(id)};
Utils.debugLog(TAG, "Setting repo name to '" + name + "' for repo " + address);
db.update(RepoTable.NAME, values, "_id = ?", args);
db.update(RepoTable.NAME, values, RepoTable.Cols._ID + " = ?", args);
cursor.moveToNext();
}
}
@ -143,11 +151,11 @@ class DBHelper extends SQLiteOpenHelper {
}
private void renameRepoId(SQLiteDatabase db, int oldVersion) {
if (oldVersion >= 36 || columnExists(db, RepoTable.NAME, "_id")) {
if (oldVersion >= 36 || columnExists(db, RepoTable.NAME, RepoTable.Cols._ID)) {
return;
}
Utils.debugLog(TAG, "Renaming " + RepoTable.NAME + ".id to _id");
Utils.debugLog(TAG, "Renaming " + RepoTable.NAME + ".id to " + RepoTable.Cols._ID);
db.beginTransaction();
try {
@ -163,33 +171,44 @@ class DBHelper extends SQLiteOpenHelper {
// statement. Therefore, I've put a copy of CREATE_TABLE_REPO
// here that is the same as it was at DBVersion 36.
String createTableDdl = "create table " + RepoTable.NAME + " ("
+ "_id integer not null primary key, "
+ "address text not null, "
+ "name text, "
+ "description text, "
+ "inuse integer not null, "
+ "priority integer not null, "
+ "pubkey text, "
+ "fingerprint text, "
+ "maxage integer not null default 0, "
+ "version integer not null default 0, "
+ "lastetag text, "
+ "lastUpdated string);";
+ RepoTable.Cols._ID + " integer not null primary key, "
+ RepoTable.Cols.ADDRESS + " text not null, "
+ RepoTable.Cols.NAME + " text, "
+ RepoTable.Cols.DESCRIPTION + " text, "
+ RepoTable.Cols.IN_USE + " integer not null, "
+ RepoTable.Cols.PRIORITY + " integer not null, "
+ RepoTable.Cols.SIGNING_CERT + " text, "
+ RepoTable.Cols.FINGERPRINT + " text, "
+ RepoTable.Cols.MAX_AGE + " integer not null default 0, "
+ RepoTable.Cols.VERSION + " integer not null default 0, "
+ RepoTable.Cols.LAST_ETAG + " text, "
+ RepoTable.Cols.LAST_UPDATED + " string);";
db.execSQL(createTableDdl);
String nonIdFields = "address, name, description, inuse, priority, " +
"pubkey, fingerprint, maxage, version, lastetag, lastUpdated";
String nonIdFields = TextUtils.join(", ", new String[] {
RepoTable.Cols.ADDRESS,
RepoTable.Cols.NAME,
RepoTable.Cols.DESCRIPTION,
RepoTable.Cols.IN_USE,
RepoTable.Cols.PRIORITY,
RepoTable.Cols.SIGNING_CERT,
RepoTable.Cols.FINGERPRINT,
RepoTable.Cols.MAX_AGE,
RepoTable.Cols.VERSION,
RepoTable.Cols.LAST_ETAG,
RepoTable.Cols.LAST_UPDATED,
});
String insertSql = "INSERT INTO " + RepoTable.NAME +
"(_id, " + nonIdFields + " ) " +
"(" + RepoTable.Cols._ID + ", " + nonIdFields + " ) " +
"SELECT id, " + nonIdFields + " FROM " + tempTableName + ";";
db.execSQL(insertSql);
db.execSQL("DROP TABLE " + tempTableName + ";");
db.setTransactionSuccessful();
} catch (Exception e) {
Log.e(TAG, "Error renaming id to _id", e);
Log.e(TAG, "Error renaming id to " + RepoTable.Cols._ID, e);
}
db.endTransaction();
}
@ -308,7 +327,7 @@ class DBHelper extends SQLiteOpenHelper {
}
List<Repo> oldrepos = new ArrayList<>();
Cursor cursor = db.query(RepoTable.NAME,
new String[] {"address", "inuse", "pubkey"},
new String[] {RepoTable.Cols.ADDRESS, RepoTable.Cols.IN_USE, RepoTable.Cols.SIGNING_CERT},
null, null, null, null, null);
if (cursor != null) {
if (cursor.getCount() > 0) {
@ -328,11 +347,11 @@ class DBHelper extends SQLiteOpenHelper {
db.execSQL(CREATE_TABLE_REPO);
for (final Repo repo : oldrepos) {
ContentValues values = new ContentValues();
values.put("address", repo.address);
values.put("inuse", repo.inuse);
values.put("priority", 10);
values.put("pubkey", repo.signingCertificate);
values.put("lastetag", (String) null);
values.put(RepoTable.Cols.ADDRESS, repo.address);
values.put(RepoTable.Cols.IN_USE, repo.inuse);
values.put(RepoTable.Cols.PRIORITY, 10);
values.put(RepoTable.Cols.SIGNING_CERT, repo.signingCertificate);
values.put(RepoTable.Cols.LAST_ETAG, (String) null);
db.insert(RepoTable.NAME, null, values);
}
}
@ -341,9 +360,9 @@ class DBHelper extends SQLiteOpenHelper {
int addressResId, int nameResId, int descriptionResId) {
ContentValues values = new ContentValues();
values.clear();
values.put("name", context.getString(nameResId));
values.put("description", context.getString(descriptionResId));
db.update(RepoTable.NAME, values, "address = ?", new String[] {
values.put(RepoTable.Cols.NAME, context.getString(nameResId));
values.put(RepoTable.Cols.DESCRIPTION, context.getString(descriptionResId));
db.update(RepoTable.NAME, values, RepoTable.Cols.ADDRESS + " = ?", new String[] {
context.getString(addressResId),
});
}
@ -353,16 +372,16 @@ class DBHelper extends SQLiteOpenHelper {
* default repos with values from strings.xml.
*/
private void addNameAndDescriptionToRepo(SQLiteDatabase db, int oldVersion) {
boolean nameExists = columnExists(db, RepoTable.NAME, "name");
boolean descriptionExists = columnExists(db, RepoTable.NAME, "description");
boolean nameExists = columnExists(db, RepoTable.NAME, RepoTable.Cols.NAME);
boolean descriptionExists = columnExists(db, RepoTable.NAME, RepoTable.Cols.DESCRIPTION);
if (oldVersion >= 21 || (nameExists && descriptionExists)) {
return;
}
if (!nameExists) {
db.execSQL("alter table " + RepoTable.NAME + " add column name text");
db.execSQL("alter table " + RepoTable.NAME + " add column " + RepoTable.Cols.NAME + " text");
}
if (!descriptionExists) {
db.execSQL("alter table " + RepoTable.NAME + " add column description text");
db.execSQL("alter table " + RepoTable.NAME + " add column " + RepoTable.Cols.DESCRIPTION + " text");
}
insertNameAndDescription(db, R.string.fdroid_repo_address,
R.string.fdroid_repo_name, R.string.fdroid_repo_description);
@ -383,12 +402,12 @@ class DBHelper extends SQLiteOpenHelper {
if (oldVersion >= 44) {
return;
}
if (!columnExists(db, RepoTable.NAME, "fingerprint")) {
db.execSQL("alter table " + RepoTable.NAME + " add column fingerprint text");
if (!columnExists(db, RepoTable.NAME, RepoTable.Cols.FINGERPRINT)) {
db.execSQL("alter table " + RepoTable.NAME + " add column " + RepoTable.Cols.FINGERPRINT + " text");
}
List<Repo> oldrepos = new ArrayList<>();
Cursor cursor = db.query(RepoTable.NAME,
new String[] {"address", "pubkey"},
new String[] {RepoTable.Cols.ADDRESS, RepoTable.Cols.SIGNING_CERT},
null, null, null, null, null);
if (cursor != null) {
if (cursor.getCount() > 0) {
@ -405,70 +424,70 @@ class DBHelper extends SQLiteOpenHelper {
}
for (final Repo repo : oldrepos) {
ContentValues values = new ContentValues();
values.put("fingerprint", Utils.calcFingerprint(repo.signingCertificate));
db.update(RepoTable.NAME, values, "address = ?", new String[] {repo.address});
values.put(RepoTable.Cols.FINGERPRINT, Utils.calcFingerprint(repo.signingCertificate));
db.update(RepoTable.NAME, values, RepoTable.Cols.ADDRESS + " = ?", new String[] {repo.address});
}
}
private void addMaxAgeToRepo(SQLiteDatabase db, int oldVersion) {
if (oldVersion >= 30 || columnExists(db, RepoTable.NAME, "maxage")) {
if (oldVersion >= 30 || columnExists(db, RepoTable.NAME, RepoTable.Cols.MAX_AGE)) {
return;
}
db.execSQL("alter table " + RepoTable.NAME + " add column maxage integer not null default 0");
db.execSQL("alter table " + RepoTable.NAME + " add column " + RepoTable.Cols.MAX_AGE + " integer not null default 0");
}
private void addVersionToRepo(SQLiteDatabase db, int oldVersion) {
if (oldVersion >= 33 || columnExists(db, RepoTable.NAME, "version")) {
if (oldVersion >= 33 || columnExists(db, RepoTable.NAME, RepoTable.Cols.VERSION)) {
return;
}
db.execSQL("alter table " + RepoTable.NAME + " add column version integer not null default 0");
db.execSQL("alter table " + RepoTable.NAME + " add column " + RepoTable.Cols.VERSION + " integer not null default 0");
}
private void addLastUpdatedToRepo(SQLiteDatabase db, int oldVersion) {
if (oldVersion >= 35 || columnExists(db, RepoTable.NAME, "lastUpdated")) {
if (oldVersion >= 35 || columnExists(db, RepoTable.NAME, RepoTable.Cols.LAST_UPDATED)) {
return;
}
Utils.debugLog(TAG, "Adding lastUpdated column to " + RepoTable.NAME);
db.execSQL("Alter table " + RepoTable.NAME + " add column lastUpdated string");
Utils.debugLog(TAG, "Adding " + RepoTable.Cols.LAST_UPDATED + " column to " + RepoTable.NAME);
db.execSQL("Alter table " + RepoTable.NAME + " add column " + RepoTable.Cols.LAST_UPDATED + " string");
}
private void addIsSwapToRepo(SQLiteDatabase db, int oldVersion) {
if (oldVersion >= 47 || columnExists(db, RepoTable.NAME, "isSwap")) {
if (oldVersion >= 47 || columnExists(db, RepoTable.NAME, RepoTable.Cols.IS_SWAP)) {
return;
}
Utils.debugLog(TAG, "Adding isSwap field to " + RepoTable.NAME + " table in db.");
db.execSQL("alter table " + RepoTable.NAME + " add column isSwap boolean default 0;");
Utils.debugLog(TAG, "Adding " + RepoTable.Cols.IS_SWAP + " field to " + RepoTable.NAME + " table in db.");
db.execSQL("alter table " + RepoTable.NAME + " add column " + RepoTable.Cols.IS_SWAP + " boolean default 0;");
}
private void addCredentialsToRepo(SQLiteDatabase db, int oldVersion) {
if (oldVersion >= 52) {
return;
}
if (!columnExists(db, Schema.RepoTable.NAME, "username")) {
Utils.debugLog(TAG, "Adding username field to " + RepoTable.NAME + " table in db.");
db.execSQL("alter table " + RepoTable.NAME + " add column username string;");
if (!columnExists(db, Schema.RepoTable.NAME, RepoTable.Cols.USERNAME)) {
Utils.debugLog(TAG, "Adding " + RepoTable.Cols.USERNAME + " field to " + RepoTable.NAME + " table in db.");
db.execSQL("alter table " + RepoTable.NAME + " add column " + RepoTable.Cols.USERNAME + " string;");
}
if (!columnExists(db, RepoTable.NAME, "password")) {
Utils.debugLog(TAG, "Adding password field to " + RepoTable.NAME + " table in db.");
db.execSQL("alter table " + RepoTable.NAME + " add column password string;");
if (!columnExists(db, RepoTable.NAME, RepoTable.Cols.PASSWORD)) {
Utils.debugLog(TAG, "Adding " + RepoTable.Cols.PASSWORD + " field to " + RepoTable.NAME + " table in db.");
db.execSQL("alter table " + RepoTable.NAME + " add column " + RepoTable.Cols.PASSWORD + " string;");
}
}
private void addChangelogToApp(SQLiteDatabase db, int oldVersion) {
if (oldVersion >= 48 || columnExists(db, AppTable.NAME, "changelogURL")) {
if (oldVersion >= 48 || columnExists(db, AppTable.NAME, AppTable.Cols.CHANGELOG_URL)) {
return;
}
Utils.debugLog(TAG, "Adding changelogURL column to " + AppTable.NAME);
db.execSQL("alter table " + AppTable.NAME + " add column changelogURL text");
Utils.debugLog(TAG, "Adding " + AppTable.Cols.CHANGELOG_URL + " column to " + AppTable.NAME);
db.execSQL("alter table " + AppTable.NAME + " add column " + AppTable.Cols.CHANGELOG_URL + " text");
}
private void addIconUrlLargeToApp(SQLiteDatabase db, int oldVersion) {
if (oldVersion >= 49 || columnExists(db, AppTable.NAME, "iconUrlLarge")) {
if (oldVersion >= 49 || columnExists(db, AppTable.NAME, AppTable.Cols.ICON_URL_LARGE)) {
return;
}
Utils.debugLog(TAG, "Adding iconUrlLarge columns to " + AppTable.NAME);
db.execSQL("alter table " + AppTable.NAME + " add column iconUrlLarge text");
Utils.debugLog(TAG, "Adding " + AppTable.Cols.ICON_URL_LARGE + " columns to " + AppTable.NAME);
db.execSQL("alter table " + AppTable.NAME + " add column " + AppTable.Cols.ICON_URL_LARGE + " text");
}
private void updateIconUrlLarge(SQLiteDatabase db, int oldVersion) {
@ -484,13 +503,13 @@ class DBHelper extends SQLiteOpenHelper {
if (oldVersion >= 53) {
return;
}
if (!columnExists(db, AppTable.NAME, "author")) {
Utils.debugLog(TAG, "Adding author column to " + AppTable.NAME);
db.execSQL("alter table " + AppTable.NAME + " add column author text");
if (!columnExists(db, AppTable.NAME, AppTable.Cols.AUTHOR)) {
Utils.debugLog(TAG, "Adding " + AppTable.Cols.AUTHOR + " column to " + AppTable.NAME);
db.execSQL("alter table " + AppTable.NAME + " add column " + AppTable.Cols.AUTHOR + " text");
}
if (!columnExists(db, AppTable.NAME, "email")) {
Utils.debugLog(TAG, "Adding email column to " + AppTable.NAME);
db.execSQL("alter table " + AppTable.NAME + " add column email text");
if (!columnExists(db, AppTable.NAME, AppTable.Cols.EMAIL)) {
Utils.debugLog(TAG, "Adding " + AppTable.Cols.EMAIL + " column to " + AppTable.NAME);
db.execSQL("alter table " + AppTable.NAME + " add column " + AppTable.Cols.EMAIL + " text");
}
}
@ -498,7 +517,7 @@ class DBHelper extends SQLiteOpenHelper {
if (oldVersion >= 54) {
return;
}
Utils.debugLog(TAG, "Converting maxSdkVersion value 0 to " + Byte.MAX_VALUE);
Utils.debugLog(TAG, "Converting " + ApkTable.Cols.MAX_SDK_VERSION + " value 0 to " + Byte.MAX_VALUE);
ContentValues values = new ContentValues();
values.put(ApkTable.Cols.MAX_SDK_VERSION, Byte.MAX_VALUE);
db.update(ApkTable.NAME, values, ApkTable.Cols.MAX_SDK_VERSION + " < 1", null);
@ -526,7 +545,7 @@ class DBHelper extends SQLiteOpenHelper {
*/
private void clearRepoEtags(SQLiteDatabase db) {
Utils.debugLog(TAG, "Clearing repo etags, so next update will not be skipped with \"Repos up to date\".");
db.execSQL("update " + RepoTable.NAME + " set lastetag = NULL");
db.execSQL("update " + RepoTable.NAME + " set " + RepoTable.Cols.LAST_ETAG + " = NULL");
}
private void resetTransient(SQLiteDatabase db, int oldVersion) {
@ -548,10 +567,10 @@ class DBHelper extends SQLiteOpenHelper {
private static void createAppApk(SQLiteDatabase db) {
db.execSQL(CREATE_TABLE_APP);
db.execSQL("create index app_id on " + AppTable.NAME + " (id);");
db.execSQL("create index app_id on " + AppTable.NAME + " (" + AppTable.Cols.PACKAGE_NAME + ");");
db.execSQL(CREATE_TABLE_APK);
db.execSQL("create index apk_vercode on " + ApkTable.NAME + " (vercode);");
db.execSQL("create index apk_id on " + ApkTable.NAME + " (id);");
db.execSQL("create index apk_vercode on " + ApkTable.NAME + " (" + ApkTable.Cols.VERSION_CODE + ");");
db.execSQL("create index apk_id on " + ApkTable.NAME + " (" + AppTable.Cols.PACKAGE_NAME + ");");
}
/**

View File

@ -118,11 +118,11 @@ public class InstalledAppProvider extends FDroidProvider {
}
private QuerySelection queryApp(String packageName) {
return new QuerySelection("appId = ?", new String[]{packageName});
return new QuerySelection(Cols.PACKAGE_NAME + " = ?", new String[]{packageName});
}
private QuerySelection querySearch(String query) {
return new QuerySelection("applicationLabel LIKE ?",
return new QuerySelection(Cols.APPLICATION_LABEL + " LIKE ?",
new String[]{"%" + query + "%"});
}

View File

@ -141,8 +141,8 @@ public class RepoProvider extends FDroidProvider {
} else if (!fingerprint.equals(calcedFingerprint)) {
// TODO the UI should represent this error!
Log.e(TAG, "The stored and calculated fingerprints do not match!");
Log.e(TAG, "stored: " + fingerprint);
Log.e(TAG, "calced: " + calcedFingerprint);
Log.e(TAG, "Stored: " + fingerprint);
Log.e(TAG, "Calculated: " + calcedFingerprint);
}
}
} else if (!TextUtils.isEmpty(publicKey)) {
@ -195,7 +195,7 @@ public class RepoProvider extends FDroidProvider {
public static int countAppsForRepo(Context context, long repoId) {
ContentResolver resolver = context.getContentResolver();
final String[] projection = {Schema.ApkTable.Cols._COUNT_DISTINCT_ID};
final String[] projection = {Schema.ApkTable.Cols._COUNT_DISTINCT};
Uri apkUri = ApkProvider.getRepoUri(repoId);
Cursor cursor = resolver.query(apkUri, projection, null, null, null);
int count = 0;
@ -327,14 +327,14 @@ public class RepoProvider extends FDroidProvider {
@Override
public int delete(Uri uri, String where, String[] whereArgs) {
QuerySelection selection = new QuerySelection(where, whereArgs);
switch (MATCHER.match(uri)) {
case CODE_LIST:
// Don't support deleting of multiple repos.
return 0;
case CODE_SINGLE:
where = (where == null ? "" : where + " AND ") +
"_ID = " + uri.getLastPathSegment();
selection.add(Cols._ID + " = ?", new String[] {uri.getLastPathSegment()});
break;
default:
@ -342,7 +342,7 @@ public class RepoProvider extends FDroidProvider {
throw new UnsupportedOperationException("Invalid URI for repo content provider: " + uri);
}
int rowsAffected = db().delete(getTableName(), where, whereArgs);
int rowsAffected = db().delete(getTableName(), selection.getSelection(), selection.getArgs());
Utils.debugLog(TAG, "Deleted repos. Notifying provider change: '" + uri + "'.");
getContext().getContentResolver().notifyChange(uri, null);
return rowsAffected;

View File

@ -80,7 +80,7 @@ public interface Schema {
String NAME = "fdroid_apk";
interface Cols extends BaseColumns {
String _COUNT_DISTINCT_ID = "countDistinct";
String _COUNT_DISTINCT = "countDistinct";
String PACKAGE_NAME = "id";
String VERSION_NAME = "version";

View File

@ -131,9 +131,9 @@ public class TempApkProvider extends ApkProvider {
final SQLiteDatabase db = db();
final String memoryDbName = TempAppProvider.DB;
db.execSQL("CREATE TABLE " + memoryDbName + "." + getTableName() + " AS SELECT * FROM main." + ApkTable.NAME);
db.execSQL("CREATE INDEX IF NOT EXISTS " + memoryDbName + ".apk_vercode on " + getTableName() + " (vercode);");
db.execSQL("CREATE INDEX IF NOT EXISTS " + memoryDbName + ".apk_id on " + getTableName() + " (id);");
db.execSQL("CREATE INDEX IF NOT EXISTS " + memoryDbName + ".apk_compatible ON " + getTableName() + " (compatible);");
db.execSQL("CREATE INDEX IF NOT EXISTS " + memoryDbName + ".apk_vercode on " + getTableName() + " (" + ApkTable.Cols.VERSION_CODE + ");");
db.execSQL("CREATE INDEX IF NOT EXISTS " + memoryDbName + ".apk_id on " + getTableName() + " (" + ApkTable.Cols.PACKAGE_NAME + ");");
db.execSQL("CREATE INDEX IF NOT EXISTS " + memoryDbName + ".apk_compatible ON " + getTableName() + " (" + ApkTable.Cols.IS_COMPATIBLE + ");");
}
}

View File

@ -131,9 +131,9 @@ public class TempAppProvider extends AppProvider {
ensureTempTableDetached(db);
db.execSQL("ATTACH DATABASE ':memory:' AS " + DB);
db.execSQL("CREATE TABLE " + DB + "." + getTableName() + " AS SELECT * FROM main." + AppTable.NAME);
db.execSQL("CREATE INDEX IF NOT EXISTS " + DB + ".app_id ON " + getTableName() + " (id);");
db.execSQL("CREATE INDEX IF NOT EXISTS " + DB + ".app_upstreamVercode ON " + getTableName() + " (upstreamVercode);");
db.execSQL("CREATE INDEX IF NOT EXISTS " + DB + ".app_compatible ON " + getTableName() + " (compatible);");
db.execSQL("CREATE INDEX IF NOT EXISTS " + DB + ".app_id ON " + getTableName() + " (" + AppTable.Cols.PACKAGE_NAME + ");");
db.execSQL("CREATE INDEX IF NOT EXISTS " + DB + ".app_upstreamVercode ON " + getTableName() + " (" + AppTable.Cols.UPSTREAM_VERSION_CODE + ");");
db.execSQL("CREATE INDEX IF NOT EXISTS " + DB + ".app_compatible ON " + getTableName() + " (" + AppTable.Cols.IS_COMPATIBLE + ");");
}
private void commitTable() {