Bug 1025128 - Part 1: Regularize tabs and clients tables. r=nalexander

This patch bumps the browser.db version to 25 and makes
tabs.client_guid a foreign key to client.guid.  It also replaces the
non-standard "rowid" with "_id".

Together, these disambiguate client_guid and guid and fix non-local
client deletion.

--HG--
extra : commitid : 5dSVFfdTJRK
extra : rebase_source : e72fe51e1afd1a94bbc96efcfaa3a302de468043
This commit is contained in:
vivek 2015-10-27 14:44:23 -07:00
Родитель b0500382e4
Коммит e8eb8bee2f
4 изменённых файлов: 72 добавлений и 31 удалений

Просмотреть файл

@ -300,16 +300,13 @@ public class BrowserContract {
public static final String POSITION = "position";
}
public static final class Clients {
public static final class Clients implements CommonColumns {
private Clients() {}
public static final Uri CONTENT_RECENCY_URI = Uri.withAppendedPath(TABS_AUTHORITY_URI, "clients_recency");
public static final Uri CONTENT_URI = Uri.withAppendedPath(TABS_AUTHORITY_URI, "clients");
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/client";
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/client";
// Implicit rowid in SQL table.
public static final String ROWID = "rowid";
// Client-provided name string. Could conceivably be null.
public static final String NAME = "name";

Просмотреть файл

@ -39,7 +39,7 @@ import android.util.Log;
final class BrowserDatabaseHelper extends SQLiteOpenHelper {
private static final String LOGTAG = "GeckoBrowserDBHelper";
public static final int DATABASE_VERSION = 24;
public static final int DATABASE_VERSION = 25;
public static final String DATABASE_NAME = "browser.db";
final protected Context mContext;
@ -197,12 +197,13 @@ final class BrowserDatabaseHelper extends SQLiteOpenHelper {
" ON " + TABLE_CLIENTS + "(" + BrowserContract.Clients.GUID + ")");
}
private void createTabsTable(SQLiteDatabase db) {
private boolean didCreateTabsTable = false;
private void createTabsTable(SQLiteDatabase db, final String tableName) {
debug("Creating tabs.db: " + db.getPath());
debug("Creating " + TABLE_TABS + " table");
debug("Creating " + tableName + " table");
// Table for each tab on any client.
db.execSQL("CREATE TABLE " + TABLE_TABS + "(" +
db.execSQL("CREATE TABLE " + tableName + "(" +
BrowserContract.Tabs._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
BrowserContract.Tabs.CLIENT_GUID + " TEXT," +
BrowserContract.Tabs.TITLE + " TEXT," +
@ -210,14 +211,18 @@ final class BrowserDatabaseHelper extends SQLiteOpenHelper {
BrowserContract.Tabs.HISTORY + " TEXT," +
BrowserContract.Tabs.FAVICON + " TEXT," +
BrowserContract.Tabs.LAST_USED + " INTEGER," +
BrowserContract.Tabs.POSITION + " INTEGER" +
BrowserContract.Tabs.POSITION + " INTEGER, " +
"FOREIGN KEY (" + BrowserContract.Tabs.CLIENT_GUID + ") REFERENCES " +
TABLE_CLIENTS + "(" + BrowserContract.Clients.GUID + ") ON DELETE CASCADE" +
");");
}
private void createTabsTableIndices(SQLiteDatabase db, final String tableName) {
// Indices on CLIENT_GUID and POSITION.
db.execSQL("CREATE INDEX " + TabsProvider.INDEX_TABS_GUID +
" ON " + TABLE_TABS + "(" + BrowserContract.Tabs.CLIENT_GUID + ")");
" ON " + tableName + "(" + BrowserContract.Tabs.CLIENT_GUID + ")");
db.execSQL("CREATE INDEX " + TabsProvider.INDEX_TABS_POSITION +
" ON " + TABLE_TABS + "(" + BrowserContract.Tabs.POSITION + ")");
" ON " + tableName + "(" + BrowserContract.Tabs.POSITION + ")");
}
// Insert a client row for our local Fennec client.
@ -341,9 +346,12 @@ final class BrowserDatabaseHelper extends SQLiteOpenHelper {
createHistoryTable(db);
createFaviconsTable(db);
createThumbnailsTable(db);
createTabsTable(db);
createClientsTable(db);
createLocalClient(db);
createTabsTable(db, TABLE_TABS);
didCreateTabsTable = true;
createTabsTableIndices(db, TABLE_TABS);
createBookmarksWithFaviconsView(db);
createHistoryWithFaviconsView(db);
@ -366,8 +374,10 @@ final class BrowserDatabaseHelper extends SQLiteOpenHelper {
* @param destinationDB The destination database.
*/
public void copyTabsDB(File tabsDBFile, SQLiteDatabase destinationDB) {
createTabsTable(destinationDB);
createClientsTable(destinationDB);
createTabsTable(destinationDB, TABLE_TABS);
didCreateTabsTable = true;
createTabsTableIndices(destinationDB, TABLE_TABS);
SQLiteDatabase oldTabsDB = null;
try {
@ -987,6 +997,41 @@ final class BrowserDatabaseHelper extends SQLiteOpenHelper {
}
}
private void upgradeDatabaseFrom24to25(SQLiteDatabase db) {
if (didCreateTabsTable) {
debug("No need to rev tabs schema; foreign key constraint exists.");
return;
}
debug("Rewriting tabs table.");
createTabsTable(db, "tmp_tabs");
// Remove indexes. We don't need them now, and we'll be throwing away the table.
db.execSQL("DROP INDEX IF EXISTS " + TabsProvider.INDEX_TABS_GUID);
db.execSQL("DROP INDEX IF EXISTS " + TabsProvider.INDEX_TABS_POSITION);
db.execSQL("INSERT INTO tmp_tabs (" +
// Here are the columns we can preserve.
BrowserContract.Tabs._ID + ", " +
BrowserContract.Tabs.CLIENT_GUID + ", " +
BrowserContract.Tabs.TITLE + ", " +
BrowserContract.Tabs.URL + ", " +
BrowserContract.Tabs.HISTORY + ", " +
BrowserContract.Tabs.FAVICON + ", " +
BrowserContract.Tabs.LAST_USED + ", " +
BrowserContract.Tabs.POSITION +
") " +
"SELECT " +
"_id, client_guid, title, url, history, favicon, last_used, position" +
" FROM " + TABLE_TABS);
// Now switch these tables over and recreate the indices.
db.execSQL("DROP TABLE " + TABLE_TABS);
db.execSQL("ALTER TABLE tmp_tabs RENAME TO " + TABLE_TABS);
createTabsTableIndices(db, TABLE_TABS);
didCreateTabsTable =true;
}
private void createV19CombinedView(SQLiteDatabase db) {
db.execSQL("DROP VIEW IF EXISTS " + VIEW_COMBINED);
db.execSQL("DROP VIEW IF EXISTS " + VIEW_COMBINED_WITH_FAVICONS);
@ -1062,6 +1107,10 @@ final class BrowserDatabaseHelper extends SQLiteOpenHelper {
case 24:
upgradeDatabaseFrom23to24(db);
break;
case 25:
upgradeDatabaseFrom24to25(db);
break;
}
}

Просмотреть файл

@ -162,14 +162,13 @@ public class TabsProvider extends SharedBrowserDatabaseProvider {
switch (match) {
case CLIENTS_ID:
trace("Delete on CLIENTS_ID: " + uri);
selection = DBUtils.concatenateWhere(selection, selectColumn(TABLE_CLIENTS, Clients.ROWID));
selection = DBUtils.concatenateWhere(selection, selectColumn(TABLE_CLIENTS, Clients._ID));
selectionArgs = DBUtils.appendSelectionArgs(selectionArgs,
new String[] { Long.toString(ContentUris.parseId(uri)) });
// fall through
case CLIENTS:
trace("Delete on CLIENTS: " + uri);
// Delete from both TABLE_TABS and TABLE_CLIENTS.
deleteValues(uri, selection, selectionArgs, TABLE_TABS);
deleted = deleteValues(uri, selection, selectionArgs, TABLE_CLIENTS);
break;
@ -236,7 +235,7 @@ public class TabsProvider extends SharedBrowserDatabaseProvider {
switch (match) {
case CLIENTS_ID:
trace("Update on CLIENTS_ID: " + uri);
selection = DBUtils.concatenateWhere(selection, selectColumn(TABLE_CLIENTS, Clients.ROWID));
selection = DBUtils.concatenateWhere(selection, selectColumn(TABLE_CLIENTS, Clients._ID));
selectionArgs = DBUtils.appendSelectionArgs(selectionArgs,
new String[] { Long.toString(ContentUris.parseId(uri)) });
// fall through
@ -297,7 +296,7 @@ public class TabsProvider extends SharedBrowserDatabaseProvider {
case CLIENTS_ID:
trace("Query is on CLIENTS_ID: " + uri);
selection = DBUtils.concatenateWhere(selection, selectColumn(TABLE_CLIENTS, Clients.ROWID));
selection = DBUtils.concatenateWhere(selection, selectColumn(TABLE_CLIENTS, Clients._ID));
selectionArgs = DBUtils.appendSelectionArgs(selectionArgs,
new String[] { Long.toString(ContentUris.parseId(uri)) });
// fall through

Просмотреть файл

@ -355,32 +355,28 @@ public class FennecTabsRepository extends Repository {
}
/**
* Deletes all non-local clients and remote tabs.
*
* This function doesn't delete non-local clients due to bug in TabsProvider. Refer Bug 1025128.
*
* Upon remote tabs deletion, the clients without tabs are not shown in UI.
* Deletes all non-local clients and their associated remote tabs.
*/
public static void deleteNonLocalClientsAndTabs(Context context) {
final String nonLocalTabsSelection = BrowserContract.Tabs.CLIENT_GUID + " IS NOT NULL";
final String nonLocalClientSelection = BrowserContract.Clients.GUID + " IS NOT NULL";
ContentProviderClient tabsProvider = context.getContentResolver()
.acquireContentProviderClient(BrowserContractHelpers.TABS_CONTENT_URI);
if (tabsProvider == null) {
Logger.warn(LOG_TAG, "Unable to create tabsProvider!");
ContentProviderClient clientsProvider = context.getContentResolver()
.acquireContentProviderClient(BrowserContractHelpers.CLIENTS_CONTENT_URI);
if (clientsProvider == null) {
Logger.warn(LOG_TAG, "Unable to create clientsProvider!");
return;
}
try {
Logger.info(LOG_TAG, "Clearing all non-local tabs for default profile.");
tabsProvider.delete(BrowserContractHelpers.TABS_CONTENT_URI, nonLocalTabsSelection, null);
Logger.info(LOG_TAG, "Clearing all non-local clients and their associated remote tabs for default profile.");
clientsProvider.delete(BrowserContractHelpers.CLIENTS_CONTENT_URI, nonLocalClientSelection, null);
} catch (RemoteException e) {
Logger.warn(LOG_TAG, "Error while deleting", e);
} finally {
try {
tabsProvider.release();
clientsProvider.release();
} catch (Exception e) {
Logger.warn(LOG_TAG, "Got exception releasing tabsProvider!", e);
Logger.warn(LOG_TAG, "Got exception releasing clientsProvider!", e);
}
}
}