/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// "scope" to "origin attributes suffix" and "origin key" convertor
class ExtractOriginData : protected mozilla::Tokenizer { public:
ExtractOriginData(const nsACString& scope, nsACString& suffix,
nsACString& origin)
: mozilla::Tokenizer(scope) { using mozilla::OriginAttributes;
// Parse optional appId:isInIsolatedMozBrowserElement: string, in case // we don't find it, the scope is our new origin key and suffix // is empty.
suffix.Truncate();
origin.Assign(scope);
// Bail out if it isn't appId. // AppId doesn't exist any more but we could have old storage data...
uint32_t appId; if (!ReadInteger(&appId)) { return;
}
// Should be followed by a colon. if (!CheckChar(':')) { return;
}
// Bail out if it isn't 'isolatedBrowserFlag'.
nsDependentCSubstring isolatedBrowserFlag; if (!ReadWord(isolatedBrowserFlag)) { return;
}
// Should be followed by a colon. if (!CheckChar(':')) { return;
}
// OK, we have found appId and inIsolatedMozBrowser flag, create the suffix // from it and take the rest as the origin key.
// If the profile went through schema 1 -> schema 0 -> schema 1 switching // we may have stored the full attributes origin suffix when there were // more than just appId and inIsolatedMozBrowser set on storage principal's // OriginAttributes. // // To preserve full uniqueness we store this suffix to the scope key. // Schema 0 code will just ignore it while keeping the scoping unique. // // The whole scope string is in one of the following forms (when we are // here): // // "1001:f:^appId=1001&inBrowser=false&addonId=101:gro.allizom.rxd.:https:443" // "1001:f:gro.allizom.rxd.:https:443" // | // +- the parser cursor position. // // If there is '^', the full origin attributes suffix follows. We search // for ':' since it is the delimiter used in the scope string and is never // contained in the origin attributes suffix. Remaining string after // the comma is the reversed-domain+schema+port tuple.
Record(); if (CheckChar('^')) {
Token t; while (Next(t)) { if (t.Equals(Token::Char(':'))) {
Claim(suffix); break;
}
}
} else {
StorageOriginAttributes originAttributes(inIsolatedMozBrowser);
originAttributes.CreateSuffix(suffix);
}
// Consume the rest of the input as "origin".
origin.Assign(Substring(mCursor, mEnd));
}
};
class GetOriginParticular final : public mozIStorageFunction { public: enum EParticular { ORIGIN_ATTRIBUTES_SUFFIX, ORIGIN_KEY };
// Deserialize and re-serialize to automatically drop any obsolete origin // attributes.
OriginAttributes oa; bool ok = oa.PopulateFromSuffix(suffix);
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
rv = aWorkerConnection->ExecuteSimpleSQL(nsLiteralCString( "CREATE TABLE IF NOT EXISTS webappsstore2 (" "originAttributes TEXT, " "originKey TEXT, " "scope TEXT, "// Only for schema0 downgrade compatibility "key TEXT, " "value TEXT)"));
NS_ENSURE_SUCCESS(rv, rv);
rv = aWorkerConnection->ExecuteSimpleSQL(
nsLiteralCString("CREATE UNIQUE INDEX IF NOT EXISTS origin_key_index" " ON webappsstore2(originAttributes, originKey, key)"));
NS_ENSURE_SUCCESS(rv, rv);
if (schema0IndexExists) { // If this index exists, the database (already updated to schema >1) // has been run again on schema 0 code. That recreated that index // and might store some new rows while updating only the 'scope' column. // For such added rows we must fill the new 'origin*' columns correctly // otherwise there would be a data loss. The safest way to do it is to // simply run the whole update to schema 1 again.
schemaVer = 0;
}
}
if (!webappsstore2Exists && !webappsstoreExists &&
!moz_webappsstoreExists) { // The database is empty, this is the first start. Just create the // schema table and break to the next version to update to, i.e. bypass // update from the old version.
// XXX What does "break to the next version to update to" mean here? It // seems to refer to the 'break' statement below, but that breaks out of // the 'switch' statement and continues with committing the transaction. // Either this is wrong, or the comment above is misleading.
rv = aWorkerConnection->ExecuteSimpleSQL(
nsLiteralCString("CREATE UNIQUE INDEX IF NOT EXISTS scope_key_index" " ON webappsstore2(scope, key)"));
NS_ENSURE_SUCCESS(rv, rv);
// Check if there is storage of Gecko 1.9.0 and if so, upgrade that // storage to actual webappsstore2 table and drop the obsolete table. // First process this newer table upgrade to priority potential duplicates // from older storage table. if (webappsstoreExists) {
rv = aWorkerConnection->ExecuteSimpleSQL(nsLiteralCString( "INSERT OR IGNORE INTO " "webappsstore2(scope, key, value, secure, owner) " "SELECT REVERSESTRING(domain) || '.:', key, value, secure, owner " "FROM webappsstore"));
NS_ENSURE_SUCCESS(rv, rv);
// Check if there is storage of Gecko 1.8 and if so, upgrade that storage // to actual webappsstore2 table and drop the obsolete table. Potential // duplicates will be ignored. if (moz_webappsstoreExists) {
rv = aWorkerConnection->ExecuteSimpleSQL(nsLiteralCString( "INSERT OR IGNORE INTO " "webappsstore2(scope, key, value, secure, owner) " "SELECT REVERSESTRING(domain) || '.:', key, value, secure, domain " "FROM moz_webappsstore"));
NS_ENSURE_SUCCESS(rv, rv);
// Update the scoping to match the new implememntation: split to oa suffix // and origin key First rename the old table, we want to remove some // columns no longer needed, but even before that drop all indexes from it // (CREATE IF NOT EXISTS for index on the new table would falsely find the // index!)
rv = aWorkerConnection->ExecuteSimpleSQL(nsLiteralCString( "DROP INDEX IF EXISTS webappsstore2.origin_key_index"));
NS_ENSURE_SUCCESS(rv, rv);
rv = aWorkerConnection->ExecuteSimpleSQL(nsLiteralCString( "DROP INDEX IF EXISTS webappsstore2.scope_key_index"));
NS_ENSURE_SUCCESS(rv, rv);
[[fallthrough]];
} case CURRENT_SCHEMA_VERSION: // Ensure the tables and indexes are up. This is mostly a no-op // in common scenarios.
rv = CreateSchema1Tables(aWorkerConnection);
NS_ENSURE_SUCCESS(rv, rv);
// Nothing more to do here, this is the current schema version break;
if (doVacuum) { // In some cases this can make the disk file of the database significantly // smaller. VACUUM cannot be executed inside a transaction.
rv = aWorkerConnection->ExecuteSimpleSQL("VACUUM"_ns);
NS_ENSURE_SUCCESS(rv, rv);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.