mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 22:32:46 +00:00
Bug 328532 r=bryner Normalize annotation names in a separate table, migration
code from alpha1.
This commit is contained in:
parent
17b624959b
commit
c945ce38f4
@ -79,7 +79,7 @@ nsAnnotationService::nsAnnotationService()
|
||||
|
||||
nsAnnotationService::~nsAnnotationService()
|
||||
{
|
||||
NS_ASSERTION(gAnnotationService == this,
|
||||
NS_ASSERTION(gAnnotationService == this,
|
||||
"Deleting a non-singleton annotation service");
|
||||
if (gAnnotationService == this)
|
||||
gAnnotationService = nsnull;
|
||||
@ -102,23 +102,67 @@ nsAnnotationService::Init()
|
||||
mDBConn = history->GetStorageConnection();
|
||||
|
||||
// annotation statements
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING("UPDATE moz_anno SET mime_type = ?4, content = ?5, flags = ?6, expiration = ?7 WHERE anno_id = ?1"),
|
||||
getter_AddRefs(mDBSetAnnotation));
|
||||
|
||||
// mDBSetAnnotation
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"UPDATE moz_anno "
|
||||
"SET mime_type = ?4, content = ?5, flags = ?6, expiration = ?7 "
|
||||
"WHERE anno_id = ?1"),
|
||||
getter_AddRefs(mDBSetAnnotation));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING("SELECT * FROM moz_anno WHERE page = ?1 AND name = ?2"),
|
||||
getter_AddRefs(mDBGetAnnotation));
|
||||
|
||||
// mDBGetAnnotation
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"SELECT * "
|
||||
"FROM moz_anno "
|
||||
"WHERE page = ?1 AND name_id = "
|
||||
"(SELECT name_id FROM moz_anno_name WHERE name = ?2)"),
|
||||
getter_AddRefs(mDBGetAnnotation));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING("SELECT name FROM moz_anno WHERE page = ?1"),
|
||||
getter_AddRefs(mDBGetAnnotationNames));
|
||||
|
||||
// mDBGetAnnotationNames
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"SELECT n.name "
|
||||
"FROM moz_anno a LEFT JOIN moz_anno_name n ON a.name_id = n.name_id "
|
||||
"WHERE a.page = ?1"),
|
||||
getter_AddRefs(mDBGetAnnotationNames));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING("SELECT a.anno_id, a.page, a.name, a.mime_type, a.content, a.flags, a.expiration FROM moz_history h JOIN moz_anno a ON h.id = a.page WHERE h.url = ?1 AND a.name = ?2"),
|
||||
getter_AddRefs(mDBGetAnnotationFromURI));
|
||||
|
||||
// mDBGetAnnotationFromURI
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"SELECT a.anno_id, a.page, ?2, a.mime_type, a.content, a.flags, a.expiration "
|
||||
"FROM moz_history h JOIN moz_anno a ON h.id = a.page "
|
||||
"WHERE h.url = ?1 AND a.name_id = "
|
||||
"(SELECT name_id FROM moz_anno_name WHERE name = ?2)"),
|
||||
getter_AddRefs(mDBGetAnnotationFromURI));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING("INSERT INTO moz_anno (page, name, mime_type, content, flags, expiration) VALUES (?2, ?3, ?4, ?5, ?6, ?7)"),
|
||||
getter_AddRefs(mDBAddAnnotation));
|
||||
|
||||
// mDBGetAnnotationNameID
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"SELECT name_id FROM moz_anno_name WHERE name = ?1"),
|
||||
getter_AddRefs(mDBGetAnnotationNameID));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING("DELETE FROM moz_anno WHERE page = ?1 AND name = ?2"),
|
||||
getter_AddRefs(mDBRemoveAnnotation));
|
||||
|
||||
// mDBAddAnnotationName
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"INSERT INTO moz_anno_name (name) VALUES (?1)"),
|
||||
getter_AddRefs(mDBAddAnnotationName));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// mDBAddAnnotation
|
||||
// Note: kAnnoIndex_Name here is a name ID and not a string like the getters
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"INSERT INTO moz_anno "
|
||||
"(page, name_id, mime_type, content, flags, expiration) "
|
||||
"VALUES (?2, ?3, ?4, ?5, ?6, ?7)"),
|
||||
getter_AddRefs(mDBAddAnnotation));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// mDBRemoveAnnotation
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"DELETE FROM moz_anno WHERE page = ?1 AND name_id = "
|
||||
"(SELECT name_id FROM moz_anno_name WHERE name = ?2)"),
|
||||
getter_AddRefs(mDBRemoveAnnotation));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
@ -139,13 +183,14 @@ nsAnnotationService::InitTables(mozIStorageConnection* aDBConn)
|
||||
{
|
||||
nsresult rv;
|
||||
PRBool exists;
|
||||
PRBool migrateFromAlpha1 = PR_FALSE;
|
||||
rv = aDBConn->TableExists(NS_LITERAL_CSTRING("moz_anno"), &exists);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (! exists) {
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING("CREATE TABLE moz_anno ("
|
||||
"anno_id INTEGER PRIMARY KEY,"
|
||||
"page INTEGER NOT NULL,"
|
||||
"name VARCHAR(32) NOT NULL,"
|
||||
"name_id INTEGER,"
|
||||
"mime_type VARCHAR(32) DEFAULT NULL,"
|
||||
"content LONGVARCHAR, flags INTEGER DEFAULT 0,"
|
||||
"expiration INTEGER DEFAULT 0)"));
|
||||
@ -154,7 +199,31 @@ nsAnnotationService::InitTables(mozIStorageConnection* aDBConn)
|
||||
"CREATE INDEX moz_anno_pageindex ON moz_anno (page)"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE INDEX moz_anno_nameindex ON moz_anno (name)"));
|
||||
"CREATE INDEX moz_anno_nameindex ON moz_anno (name_id)"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else {
|
||||
rv = aDBConn->TableExists(NS_LITERAL_CSTRING("moz_anno_name"), &exists);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (! exists)
|
||||
migrateFromAlpha1 = PR_TRUE;
|
||||
}
|
||||
|
||||
rv = aDBConn->TableExists(NS_LITERAL_CSTRING("moz_anno_name"), &exists);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (! exists) {
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE TABLE moz_anno_name ("
|
||||
"name_id INTEGER PRIMARY KEY,"
|
||||
"name VARCHAR(32) UNIQUE NOT NULL)"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE INDEX moz_anno_name_nameindex ON moz_anno_name (name)"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// this needs to happen after moz_anno_name gets created
|
||||
if (migrateFromAlpha1) {
|
||||
rv = MigrateFromAlpha1(aDBConn);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
return NS_OK;
|
||||
@ -451,7 +520,10 @@ nsAnnotationService::GetPagesWithAnnotation(const nsACString& aName,
|
||||
// statement. Perhaps this should change.
|
||||
nsCOMPtr<mozIStorageStatement> statement;
|
||||
nsresult rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"SELECT h.url FROM moz_anno a JOIN moz_history h ON a.page = h.id WHERE a.name = ?1"),
|
||||
"SELECT h.url FROM moz_anno_name n "
|
||||
"LEFT JOIN moz_anno a ON n.name_id = a.name_id "
|
||||
"LEFT JOIN moz_history h ON a.page = h.id "
|
||||
"WHERE n.name = ?1"),
|
||||
getter_AddRefs(statement));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
@ -581,6 +653,10 @@ nsAnnotationService::HasAnnotation(nsIURI* aURI,
|
||||
|
||||
|
||||
// nsAnnotationService::RemoveAnnotation
|
||||
//
|
||||
// We don't remove anything from the moz_anno_name table. If we delete the
|
||||
// last item of a given name, that item really should go away. It will get
|
||||
// cleaned up on the next shutdown.
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAnnotationService::RemoveAnnotation(nsIURI* aURI,
|
||||
@ -664,6 +740,10 @@ nsAnnotationService::RemovePageAnnotations(nsIURI* aURI)
|
||||
// XXX: If we use annotations for some standard items like GeckoFlags, it
|
||||
// might be a good idea to blacklist these standard annotations from this
|
||||
// copy function.
|
||||
//
|
||||
// We operate on strings from GetPageAnnotationNamesTArray. This is less
|
||||
// efficient than operating on name IDs, which we should consider if this
|
||||
// is too slow.
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAnnotationService::CopyAnnotations(nsIURI* aSourceURI, nsIURI* aDestURI,
|
||||
@ -712,9 +792,10 @@ nsAnnotationService::CopyAnnotations(nsIURI* aSourceURI, nsIURI* aDestURI,
|
||||
// source with the same values of the annotation on dest.
|
||||
nsCOMPtr<mozIStorageStatement> statement;
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"INSERT INTO moz_anno (page, name, mime_type, content, flags, expiration) "
|
||||
"SELECT ?1, ?3, mime_type, content, flags, expiration "
|
||||
"FROM moz_anno WHERE page = ?2 AND name = ?3"),
|
||||
"INSERT INTO moz_anno (page, name_id, mime_type, content, flags, expiration) "
|
||||
"SELECT ?1, name_id, mime_type, content, flags, expiration "
|
||||
"FROM moz_anno WHERE page = ?2 AND name_id = "
|
||||
"(SELECT name_id FROM moz_anno_name WHERE name = ?3)"),
|
||||
getter_AddRefs(statement));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
@ -897,9 +978,33 @@ nsAnnotationService::StartSetAnnotation(nsIURI* aURI,
|
||||
rv = (*aStatement)->BindInt64Parameter(kAnnoIndex_ID, annotationID);
|
||||
} else {
|
||||
*aStatement = mDBAddAnnotation;
|
||||
rv = (*aStatement)->BindInt64Parameter(kAnnoIndex_Page, uriID);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = (*aStatement)->BindUTF8StringParameter(kAnnoIndex_Name, aName);
|
||||
|
||||
// make sure the name exists
|
||||
{
|
||||
mozStorageStatementScoper scoper(mDBGetAnnotationNameID);
|
||||
rv = mDBGetAnnotationNameID->BindUTF8StringParameter(0, aName);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
PRBool hasName;
|
||||
PRInt64 nameID;
|
||||
if (NS_FAILED(mDBGetAnnotationNameID->ExecuteStep(&hasName)) || ! hasName) {
|
||||
// add a new annotation name
|
||||
mDBGetAnnotationNameID->Reset();
|
||||
mozStorageStatementScoper addNameScoper(mDBAddAnnotationName);
|
||||
rv = mDBAddAnnotationName->BindUTF8StringParameter(0, aName);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = mDBAddAnnotationName->Execute();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mDBConn->GetLastInsertRowID(&nameID);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else {
|
||||
nameID = mDBGetAnnotationNameID->AsInt64(0);
|
||||
}
|
||||
rv = (*aStatement)->BindInt64Parameter(kAnnoIndex_Page, uriID);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = (*aStatement)->BindInt64Parameter(kAnnoIndex_Name, nameID);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
mozStorageStatementScoper statementResetter(*aStatement);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -923,3 +1028,109 @@ nsAnnotationService::CallSetObservers(nsIURI* aURI, const nsACString& aName)
|
||||
for (PRInt32 i = 0; i < mObservers.Count(); i ++)
|
||||
mObservers[i]->OnAnnotationSet(aURI, aName);
|
||||
}
|
||||
|
||||
|
||||
// nsAnnotationService::MigrateFromAlpha1
|
||||
//
|
||||
// The alpha 1 release had a column called "name" with the names of the
|
||||
// annotations. We need to delete that and move the strings to a
|
||||
// moz_anno_name table. Since sqlite can not change columns, we rename the
|
||||
// table, copy the data, and delete the renamed version.
|
||||
|
||||
nsresult // static
|
||||
nsAnnotationService::MigrateFromAlpha1(mozIStorageConnection* aDBConn)
|
||||
{
|
||||
// rename current annotation table
|
||||
nsresult rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"ALTER TABLE moz_anno RENAME TO moz_anno_old"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// create the new annotation table: should be the same as InitTables
|
||||
// (this migration code is temporary, so we don't worry about maintenance
|
||||
// too much). Note we create the indices later because we need to delete
|
||||
// the old ones first.
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING("CREATE TABLE moz_anno ("
|
||||
"anno_id INTEGER PRIMARY KEY,"
|
||||
"page INTEGER NOT NULL,"
|
||||
"name_id INTEGER,"
|
||||
"mime_type VARCHAR(32) DEFAULT NULL,"
|
||||
"content LONGVARCHAR, flags INTEGER DEFAULT 0,"
|
||||
"expiration INTEGER DEFAULT 0)"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Add an ID column to the old table. We can then set this and copy all
|
||||
// values to the new table at once.
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"ALTER TABLE moz_anno_old ADD COLUMN name_id"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// get the unique column names
|
||||
nsCOMPtr<mozIStorageStatement> statement;
|
||||
rv = aDBConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"SELECT DISTINCT name FROM moz_anno_old"), getter_AddRefs(statement));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
PRBool hasMore;
|
||||
nsCStringArray uniqueNames;
|
||||
while (NS_SUCCEEDED(statement->ExecuteStep(&hasMore)) && hasMore) {
|
||||
nsCAutoString curName;
|
||||
rv = statement->GetUTF8String(0, curName);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
uniqueNames.AppendCString(curName);
|
||||
}
|
||||
|
||||
rv = aDBConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"INSERT INTO moz_anno_name (name) VALUES (?1)"),
|
||||
getter_AddRefs(statement));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// add the proper name_id values into the old table
|
||||
nsCOMPtr<mozIStorageStatement> updateAnno;
|
||||
rv = aDBConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"UPDATE moz_anno_old SET name_id = ?1 WHERE name = ?2"),
|
||||
getter_AddRefs(updateAnno));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
for (PRInt32 i = 0; i < uniqueNames.Count(); i ++) {
|
||||
// insert the name into the moz_anno_name table
|
||||
rv = statement->BindUTF8StringParameter(0, *uniqueNames[i]);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = statement->Execute();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRInt64 nameID;
|
||||
rv = aDBConn->GetLastInsertRowID(&nameID);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// update the corresponding entries in the moz_anno table to reference it
|
||||
rv = updateAnno->BindInt64Parameter(0, nameID);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = updateAnno->BindUTF8StringParameter(1, *uniqueNames[i]);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = updateAnno->Execute();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// copy values to the new table
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"INSERT INTO moz_anno "
|
||||
"(anno_id, page, name_id, mime_type, content, flags, expiration) "
|
||||
"SELECT anno_id, page, name_id, mime_type, content, flags, expiration "
|
||||
"FROM moz_anno_old"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// delete old table & indices (which will be automatically dropped when their
|
||||
// table is deleted)
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"DROP TABLE moz_anno_old"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// create indices on the new table
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE INDEX moz_anno_pageindex ON moz_anno (page)"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"CREATE INDEX moz_anno_nameindex ON moz_anno (name_id)"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -91,6 +91,8 @@ protected:
|
||||
nsCOMPtr<mozIStorageStatement> mDBGetAnnotation;
|
||||
nsCOMPtr<mozIStorageStatement> mDBGetAnnotationNames;
|
||||
nsCOMPtr<mozIStorageStatement> mDBGetAnnotationFromURI;
|
||||
nsCOMPtr<mozIStorageStatement> mDBGetAnnotationNameID;
|
||||
nsCOMPtr<mozIStorageStatement> mDBAddAnnotationName;
|
||||
nsCOMPtr<mozIStorageStatement> mDBAddAnnotation;
|
||||
nsCOMPtr<mozIStorageStatement> mDBRemoveAnnotation;
|
||||
|
||||
@ -115,6 +117,8 @@ protected:
|
||||
PRInt32 aFlags, PRInt32 aExpiration,
|
||||
mozIStorageStatement** aStatement);
|
||||
void CallSetObservers(nsIURI* aURI, const nsACString& aName);
|
||||
|
||||
static nsresult MigrateFromAlpha1(mozIStorageConnection* aDBConn);
|
||||
};
|
||||
|
||||
#endif /* nsAnnotationService_h___ */
|
||||
|
@ -3121,7 +3121,7 @@ nsNavHistory::QueryToSelectClause(nsNavHistoryQuery* aQuery, // const
|
||||
|
||||
if (aQuery->AnnotationIsNot())
|
||||
aClause->AppendLiteral("NOT ");
|
||||
aClause->AppendLiteral("EXISTS (SELECT anno_id FROM moz_anno anno WHERE anno.page = h.id AND anno.name = ");
|
||||
aClause->AppendLiteral("EXISTS (SELECT anno_id FROM moz_anno anno JOIN moz_anno_name annoname ON anno.name_id = annoname.name_id WHERE anno.page = h.id AND annoname.name = ");
|
||||
aClause->Append(paramString);
|
||||
aClause->AppendLiteral(") ");
|
||||
// annotation-based queries don't get the common conditions, so you get
|
||||
|
Loading…
Reference in New Issue
Block a user