<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[277601] trunk/Source</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/277601">277601</a></dd>
<dt>Author</dt> <dd>cdumez@apple.com</dd>
<dt>Date</dt> <dd>2021-05-17 12:26:06 -0700 (Mon, 17 May 2021)</dd>
</dl>

<h3>Log Message</h3>
<pre>Avoid more String creations when preparing SQLite statements
https://bugs.webkit.org/show_bug.cgi?id=225855

Reviewed by Alex Christensen.

Avoid more String creations when preparing SQLite statements by using ASCIILiteral. Also rename the
Source/WebCore:

SQLiteDatabase::prepareStatement() / SQLiteDatabase::executeCommand() overloads that take in a
String to make sure they are not called by mistake.

* Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:
(WebCore::IDBServer::v3RecordsTableSchema):
(WebCore::IDBServer::v3RecordsTableSchemaAlternate):
(WebCore::IDBServer::v3IndexRecordsTableSchema):
(WebCore::IDBServer::v3IndexRecordsTableSchemaAlternate):
(WebCore::IDBServer::blobRecordsTableSchema):
(WebCore::IDBServer::blobRecordsTableSchemaAlternate):
(WebCore::IDBServer::blobFilesTableSchema):
(WebCore::IDBServer::blobFilesTableSchemaAlternate):
(WebCore::IDBServer::createOrMigrateRecordsTableIfNecessary):
(WebCore::IDBServer::SQLiteIDBBackingStore::ensureValidRecordsTable):
(WebCore::IDBServer::SQLiteIDBBackingStore::ensureValidIndexRecordsTable):
(WebCore::IDBServer::SQLiteIDBBackingStore::ensureValidIndexRecordsIndex):
(WebCore::IDBServer::SQLiteIDBBackingStore::createAndPopulateInitialDatabaseInfo):
(WebCore::IDBServer::SQLiteIDBBackingStore::ensureValidObjectStoreInfoTable):
(WebCore::IDBServer::SQLiteIDBBackingStore::migrateIndexInfoTableForIDUpdate):
(WebCore::IDBServer::SQLiteIDBBackingStore::migrateIndexRecordsTableForIDUpdate):
* Modules/indexeddb/server/SQLiteIDBCursor.cpp:
(WebCore::IDBServer::SQLiteIDBCursor::createSQLiteStatement):
(WebCore::IDBServer::SQLiteIDBCursor::resetAndRebindPreIndexStatementIfNecessary):
* Modules/webdatabase/Database.cpp:
(WebCore::setTextValueInDatabase):
(WebCore::retrieveTextResultFromDatabase):
(WebCore::Database::performOpenAndVerify):
* Modules/webdatabase/DatabaseTracker.cpp:
(WebCore::DatabaseTracker::openTrackerDatabase):
(WebCore::DatabaseTracker::deleteDatabaseFileIfEmpty):
* Modules/webdatabase/SQLStatement.cpp:
(WebCore::SQLStatement::execute):
* loader/appcache/ApplicationCacheStorage.cpp:
(WebCore::ApplicationCacheStorage::executeSQLCommand):
(WebCore::ApplicationCacheStorage::verifySchemaVersion):
(WebCore::ApplicationCacheStorage::openDatabase):
(WebCore::ApplicationCacheStorage::empty):
(WebCore::ApplicationCacheStorage::checkForDeletedResources):
* loader/appcache/ApplicationCacheStorage.h:
* platform/network/curl/CookieJarDB.cpp:
(WebCore::CookieJarDB::verifySchemaVersion):
(WebCore::CookieJarDB::createPrepareStatement):
(WebCore::executeSQLStatement):
(WebCore::CookieJarDB::executeSqlSlow):
(WebCore::CookieJarDB::executeSql):
* platform/network/curl/CookieJarDB.h:
* platform/sql/SQLiteDatabase.cpp:
(WebCore::SQLiteDatabase::setMaximumSize):
(WebCore::SQLiteDatabase::setSynchronous):
(WebCore::SQLiteDatabase::executeCommandSlow):
(WebCore::SQLiteDatabase::tableExists):
(WebCore::SQLiteDatabase::clearAllTables):
(WebCore::SQLiteDatabase::prepareStatementSlow):
(WebCore::SQLiteDatabase::prepareHeapStatementSlow):
* platform/sql/SQLiteDatabase.h:
* platform/sql/SQLiteTransaction.cpp:
(WebCore::SQLiteTransaction::begin):
(WebCore::SQLiteTransaction::commit):
(WebCore::SQLiteTransaction::rollback):
* platform/win/SearchPopupMenuDB.cpp:
(WebCore::SearchPopupMenuDB::verifySchemaVersion):
(WebCore::executeSQLStatement):
(WebCore::SearchPopupMenuDB::executeSimpleSql):
* platform/win/SearchPopupMenuDB.h:

Source/WebKit:

SQLiteDatabase::prepareStatement() / SQLiteDatabase::executeCommand() overloads that take in a
String to make sure they are not called by mistake.

* NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp:
(WebKit::ResourceLoadStatisticsDatabaseStore::currentTableAndIndexQueries):
(WebKit::insertDistinctValuesInTableStatement):
(WebKit::ResourceLoadStatisticsDatabaseStore::migrateDataToNewTablesIfNecessary):
(WebKit::ResourceLoadStatisticsDatabaseStore::columnsForTable):
(WebKit::ResourceLoadStatisticsDatabaseStore::addMissingColumnsToTable):
(WebKit::ResourceLoadStatisticsDatabaseStore::renameColumnInTable):
(WebKit::ResourceLoadStatisticsDatabaseStore::insertDomainRelationshipList):
(WebKit::joinSubStatisticsForSorting):
(WebKit::ResourceLoadStatisticsDatabaseStore::aggregatedThirdPartyData const):
(WebKit::ResourceLoadStatisticsDatabaseStore::incrementRecordsDeletedCountForDomains):
(WebKit::ResourceLoadStatisticsDatabaseStore::markAsPrevalentIfHasRedirectedToPrevalent):
(WebKit::ResourceLoadStatisticsDatabaseStore::findNotVeryPrevalentResources):
(WebKit::ResourceLoadStatisticsDatabaseStore::grandfatherDataForDomains):
(WebKit::ResourceLoadStatisticsDatabaseStore::setDomainsAsPrevalent):
(WebKit::ResourceLoadStatisticsDatabaseStore::clearGrandfathering):
(WebKit::ResourceLoadStatisticsDatabaseStore::pruneStatisticsIfNeeded):
(WebKit::ResourceLoadStatisticsDatabaseStore::getSubStatisticStatement const):
(WebKit::ResourceLoadStatisticsDatabaseStore::appendSubStatisticList const):
* NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h:
* NetworkProcess/WebStorage/LocalStorageDatabase.cpp:
(WebKit::LocalStorageDatabase::openDatabase):
(WebKit::LocalStorageDatabase::migrateItemTableIfNeeded):
* UIProcess/API/glib/IconDatabase.cpp:
(WebKit::IconDatabase::createTablesIfNeeded):
(WebKit::IconDatabase::populatePageURLToIconURLMap):

Source/WebKitLegacy:

SQLiteDatabase::prepareStatement() / SQLiteDatabase::executeCommand() overloads that take in a
String to make sure they are not called by mistake.

* Storage/StorageAreaSync.cpp:
(WebKit::StorageAreaSync::openDatabase):
(WebKit::StorageAreaSync::migrateItemTableIfNeeded):
* Storage/StorageTracker.cpp:
(WebKit::StorageTracker::openTrackerDatabase):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverSQLiteIDBBackingStorecpp">trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverSQLiteIDBCursorcpp">trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.cpp</a></li>
<li><a href="#trunkSourceWebCoreModuleswebdatabaseDatabasecpp">trunk/Source/WebCore/Modules/webdatabase/Database.cpp</a></li>
<li><a href="#trunkSourceWebCoreModuleswebdatabaseDatabaseTrackercpp">trunk/Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp</a></li>
<li><a href="#trunkSourceWebCoreModuleswebdatabaseSQLStatementcpp">trunk/Source/WebCore/Modules/webdatabase/SQLStatement.cpp</a></li>
<li><a href="#trunkSourceWebCoreloaderappcacheApplicationCacheStoragecpp">trunk/Source/WebCore/loader/appcache/ApplicationCacheStorage.cpp</a></li>
<li><a href="#trunkSourceWebCoreloaderappcacheApplicationCacheStorageh">trunk/Source/WebCore/loader/appcache/ApplicationCacheStorage.h</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkcurlCookieJarDBcpp">trunk/Source/WebCore/platform/network/curl/CookieJarDB.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkcurlCookieJarDBh">trunk/Source/WebCore/platform/network/curl/CookieJarDB.h</a></li>
<li><a href="#trunkSourceWebCoreplatformsqlSQLiteDatabasecpp">trunk/Source/WebCore/platform/sql/SQLiteDatabase.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformsqlSQLiteDatabaseh">trunk/Source/WebCore/platform/sql/SQLiteDatabase.h</a></li>
<li><a href="#trunkSourceWebCoreplatformsqlSQLiteTransactioncpp">trunk/Source/WebCore/platform/sql/SQLiteTransaction.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformwinSearchPopupMenuDBcpp">trunk/Source/WebCore/platform/win/SearchPopupMenuDB.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformwinSearchPopupMenuDBh">trunk/Source/WebCore/platform/win/SearchPopupMenuDB.h</a></li>
<li><a href="#trunkSourceWebCoreworkersserviceserverRegistrationDatabasecpp">trunk/Source/WebCore/workers/service/server/RegistrationDatabase.cpp</a></li>
<li><a href="#trunkSourceWebKitChangeLog">trunk/Source/WebKit/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitNetworkProcessClassifierResourceLoadStatisticsDatabaseStorecpp">trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp</a></li>
<li><a href="#trunkSourceWebKitNetworkProcessClassifierResourceLoadStatisticsDatabaseStoreh">trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h</a></li>
<li><a href="#trunkSourceWebKitNetworkProcessWebStorageLocalStorageDatabasecpp">trunk/Source/WebKit/NetworkProcess/WebStorage/LocalStorageDatabase.cpp</a></li>
<li><a href="#trunkSourceWebKitUIProcessAPIglibIconDatabasecpp">trunk/Source/WebKit/UIProcess/API/glib/IconDatabase.cpp</a></li>
<li><a href="#trunkSourceWebKitLegacyChangeLog">trunk/Source/WebKitLegacy/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitLegacyStorageStorageAreaSynccpp">trunk/Source/WebKitLegacy/Storage/StorageAreaSync.cpp</a></li>
<li><a href="#trunkSourceWebKitLegacyStorageStorageTrackercpp">trunk/Source/WebKitLegacy/Storage/StorageTracker.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (277600 => 277601)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2021-05-17 19:09:02 UTC (rev 277600)
+++ trunk/Source/WebCore/ChangeLog      2021-05-17 19:26:06 UTC (rev 277601)
</span><span class="lines">@@ -1,3 +1,76 @@
</span><ins>+2021-05-17  Chris Dumez  <cdumez@apple.com>
+
+        Avoid more String creations when preparing SQLite statements
+        https://bugs.webkit.org/show_bug.cgi?id=225855
+
+        Reviewed by Alex Christensen.
+
+        Avoid more String creations when preparing SQLite statements by using ASCIILiteral. Also rename the
+        SQLiteDatabase::prepareStatement() / SQLiteDatabase::executeCommand() overloads that take in a
+        String to make sure they are not called by mistake.
+
+        * Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:
+        (WebCore::IDBServer::v3RecordsTableSchema):
+        (WebCore::IDBServer::v3RecordsTableSchemaAlternate):
+        (WebCore::IDBServer::v3IndexRecordsTableSchema):
+        (WebCore::IDBServer::v3IndexRecordsTableSchemaAlternate):
+        (WebCore::IDBServer::blobRecordsTableSchema):
+        (WebCore::IDBServer::blobRecordsTableSchemaAlternate):
+        (WebCore::IDBServer::blobFilesTableSchema):
+        (WebCore::IDBServer::blobFilesTableSchemaAlternate):
+        (WebCore::IDBServer::createOrMigrateRecordsTableIfNecessary):
+        (WebCore::IDBServer::SQLiteIDBBackingStore::ensureValidRecordsTable):
+        (WebCore::IDBServer::SQLiteIDBBackingStore::ensureValidIndexRecordsTable):
+        (WebCore::IDBServer::SQLiteIDBBackingStore::ensureValidIndexRecordsIndex):
+        (WebCore::IDBServer::SQLiteIDBBackingStore::createAndPopulateInitialDatabaseInfo):
+        (WebCore::IDBServer::SQLiteIDBBackingStore::ensureValidObjectStoreInfoTable):
+        (WebCore::IDBServer::SQLiteIDBBackingStore::migrateIndexInfoTableForIDUpdate):
+        (WebCore::IDBServer::SQLiteIDBBackingStore::migrateIndexRecordsTableForIDUpdate):
+        * Modules/indexeddb/server/SQLiteIDBCursor.cpp:
+        (WebCore::IDBServer::SQLiteIDBCursor::createSQLiteStatement):
+        (WebCore::IDBServer::SQLiteIDBCursor::resetAndRebindPreIndexStatementIfNecessary):
+        * Modules/webdatabase/Database.cpp:
+        (WebCore::setTextValueInDatabase):
+        (WebCore::retrieveTextResultFromDatabase):
+        (WebCore::Database::performOpenAndVerify):
+        * Modules/webdatabase/DatabaseTracker.cpp:
+        (WebCore::DatabaseTracker::openTrackerDatabase):
+        (WebCore::DatabaseTracker::deleteDatabaseFileIfEmpty):
+        * Modules/webdatabase/SQLStatement.cpp:
+        (WebCore::SQLStatement::execute):
+        * loader/appcache/ApplicationCacheStorage.cpp:
+        (WebCore::ApplicationCacheStorage::executeSQLCommand):
+        (WebCore::ApplicationCacheStorage::verifySchemaVersion):
+        (WebCore::ApplicationCacheStorage::openDatabase):
+        (WebCore::ApplicationCacheStorage::empty):
+        (WebCore::ApplicationCacheStorage::checkForDeletedResources):
+        * loader/appcache/ApplicationCacheStorage.h:
+        * platform/network/curl/CookieJarDB.cpp:
+        (WebCore::CookieJarDB::verifySchemaVersion):
+        (WebCore::CookieJarDB::createPrepareStatement):
+        (WebCore::executeSQLStatement):
+        (WebCore::CookieJarDB::executeSqlSlow):
+        (WebCore::CookieJarDB::executeSql):
+        * platform/network/curl/CookieJarDB.h:
+        * platform/sql/SQLiteDatabase.cpp:
+        (WebCore::SQLiteDatabase::setMaximumSize):
+        (WebCore::SQLiteDatabase::setSynchronous):
+        (WebCore::SQLiteDatabase::executeCommandSlow):
+        (WebCore::SQLiteDatabase::tableExists):
+        (WebCore::SQLiteDatabase::clearAllTables):
+        (WebCore::SQLiteDatabase::prepareStatementSlow):
+        (WebCore::SQLiteDatabase::prepareHeapStatementSlow):
+        * platform/sql/SQLiteDatabase.h:
+        * platform/sql/SQLiteTransaction.cpp:
+        (WebCore::SQLiteTransaction::begin):
+        (WebCore::SQLiteTransaction::commit):
+        (WebCore::SQLiteTransaction::rollback):
+        * platform/win/SearchPopupMenuDB.cpp:
+        (WebCore::SearchPopupMenuDB::verifySchemaVersion):
+        (WebCore::executeSQLStatement):
+        (WebCore::SearchPopupMenuDB::executeSimpleSql):
+        * platform/win/SearchPopupMenuDB.h:
+
</ins><span class="cx"> 2021-05-17  Frederic Wang  <fwang@igalia.com>
</span><span class="cx"> 
</span><span class="cx">         REGRESSION(r277425): Crash in FrameSelection::selectFrameElementInParentIfFullySelected
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverSQLiteIDBBackingStorecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp (277600 => 277601)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp  2021-05-17 19:09:02 UTC (rev 277600)
+++ trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp     2021-05-17 19:26:06 UTC (rev 277601)
</span><span class="lines">@@ -71,6 +71,13 @@
</span><span class="cx"> // The IndexedDatabase spec defines the max key generator value as 2^53.
</span><span class="cx"> static const uint64_t maxGeneratorValue = 0x20000000000000;
</span><span class="cx"> 
</span><ins>+#define TABLE_SCHEMA_PREFIX "CREATE TABLE "
+#define V3_RECORDS_TABLE_SCHEMA_SUFFIX " (objectStoreID INTEGER NOT NULL ON CONFLICT FAIL, key TEXT COLLATE IDBKEY NOT NULL ON CONFLICT FAIL, value NOT NULL ON CONFLICT FAIL, recordID INTEGER PRIMARY KEY)"_s
+#define V3_INDEX_RECORDS_TABLE_SCHEMA_SUFFIX " (indexID INTEGER NOT NULL ON CONFLICT FAIL, objectStoreID INTEGER NOT NULL ON CONFLICT FAIL, key TEXT COLLATE IDBKEY NOT NULL ON CONFLICT FAIL, value TEXT COLLATE IDBKEY NOT NULL ON CONFLICT FAIL, objectStoreRecordID INTEGER NOT NULL ON CONFLICT FAIL)"_s;
+#define INDEX_INFO_TABLE_SCHEMA_SUFFIX " (id INTEGER NOT NULL ON CONFLICT FAIL, name TEXT NOT NULL ON CONFLICT FAIL, objectStoreID INTEGER NOT NULL ON CONFLICT FAIL, keyPath BLOB NOT NULL ON CONFLICT FAIL, isUnique INTEGER NOT NULL ON CONFLICT FAIL, multiEntry INTEGER NOT NULL ON CONFLICT FAIL)"_s;
+#define BLOB_RECORDS_TABLE_SCHEMA_SUFFIX " (objectStoreRow INTEGER NOT NULL ON CONFLICT FAIL, blobURL TEXT NOT NULL ON CONFLICT FAIL)"_s;
+#define BLOB_FILES_TABLE_SCHEMA_SUFFIX " (blobURL TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT FAIL, fileName TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT FAIL)"_s;
+
</ins><span class="cx"> static int idbKeyCollate(int aLength, const void* aBuffer, int bLength, const void* bBuffer)
</span><span class="cx"> {
</span><span class="cx">     IDBKeyData a, b;
</span><span class="lines">@@ -126,21 +133,19 @@
</span><span class="cx">     return v2RecordsTableSchemaString;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static const String v3RecordsTableSchema(const String& tableName)
</del><ins>+static ASCIILiteral v3RecordsTableSchema()
</ins><span class="cx"> {
</span><del>-    return makeString("CREATE TABLE ", tableName, " (objectStoreID INTEGER NOT NULL ON CONFLICT FAIL, key TEXT COLLATE IDBKEY NOT NULL ON CONFLICT FAIL, value NOT NULL ON CONFLICT FAIL, recordID INTEGER PRIMARY KEY)");
</del><ins>+    return TABLE_SCHEMA_PREFIX "Records" V3_RECORDS_TABLE_SCHEMA_SUFFIX;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static const String& v3RecordsTableSchema()
</del><ins>+static ASCIILiteral v3RecordsTableSchemaAlternate()
</ins><span class="cx"> {
</span><del>-    static NeverDestroyed<WTF::String> v3RecordsTableSchemaString(v3RecordsTableSchema("Records"));
-    return v3RecordsTableSchemaString;
</del><ins>+    return TABLE_SCHEMA_PREFIX "\"Records\"" V3_RECORDS_TABLE_SCHEMA_SUFFIX;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static const String& v3RecordsTableSchemaAlternate()
</del><ins>+static ASCIILiteral v3RecordsTableSchemaTemp()
</ins><span class="cx"> {
</span><del>-    static NeverDestroyed<WTF::String> v3RecordsTableSchemaString(v3RecordsTableSchema("\"Records\""));
-    return v3RecordsTableSchemaString;
</del><ins>+    return TABLE_SCHEMA_PREFIX "_Temp_Records" V3_RECORDS_TABLE_SCHEMA_SUFFIX;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static const String v1IndexRecordsTableSchema(const String& tableName)
</span><span class="lines">@@ -177,57 +182,41 @@
</span><span class="cx">     return v2IndexRecordsTableSchemaString;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static const String v3IndexRecordsTableSchema(const String& tableName)
</del><ins>+static ASCIILiteral v3IndexRecordsTableSchema()
</ins><span class="cx"> {
</span><del>-    return makeString("CREATE TABLE ", tableName, " (indexID INTEGER NOT NULL ON CONFLICT FAIL, objectStoreID INTEGER NOT NULL ON CONFLICT FAIL, key TEXT COLLATE IDBKEY NOT NULL ON CONFLICT FAIL, value TEXT COLLATE IDBKEY NOT NULL ON CONFLICT FAIL, objectStoreRecordID INTEGER NOT NULL ON CONFLICT FAIL)");
</del><ins>+    return TABLE_SCHEMA_PREFIX "IndexRecords" V3_INDEX_RECORDS_TABLE_SCHEMA_SUFFIX;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static const String v3IndexRecordsTableSchema()
</del><ins>+static ASCIILiteral v3IndexRecordsTableSchemaAlternate()
</ins><span class="cx"> {
</span><del>-    static NeverDestroyed<WTF::String> indexRecordsTableSchemaString = v3IndexRecordsTableSchema("IndexRecords");
-    return indexRecordsTableSchemaString;
</del><ins>+    return TABLE_SCHEMA_PREFIX "\"IndexRecords\"" V3_INDEX_RECORDS_TABLE_SCHEMA_SUFFIX;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static const String v3IndexRecordsTableSchemaAlternate()
</del><ins>+static ASCIILiteral v3IndexRecordsTableSchemaTemp()
</ins><span class="cx"> {
</span><del>-    static NeverDestroyed<WTF::String> indexRecordsTableSchemaString = v3IndexRecordsTableSchema("\"IndexRecords\"");
-    return indexRecordsTableSchemaString;
</del><ins>+    return TABLE_SCHEMA_PREFIX "_Temp_IndexRecords" V3_INDEX_RECORDS_TABLE_SCHEMA_SUFFIX;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static const String blobRecordsTableSchema(const String& tableName)
</del><ins>+static ASCIILiteral blobRecordsTableSchema()
</ins><span class="cx"> {
</span><del>-    return makeString("CREATE TABLE ", tableName, " (objectStoreRow INTEGER NOT NULL ON CONFLICT FAIL, blobURL TEXT NOT NULL ON CONFLICT FAIL)");
</del><ins>+    return TABLE_SCHEMA_PREFIX "BlobRecords" BLOB_RECORDS_TABLE_SCHEMA_SUFFIX;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static const String& blobRecordsTableSchema()
</del><ins>+static ASCIILiteral blobRecordsTableSchemaAlternate()
</ins><span class="cx"> {
</span><del>-    static NeverDestroyed<String> blobRecordsTableSchemaString(blobRecordsTableSchema("BlobRecords"));
-    return blobRecordsTableSchemaString;
</del><ins>+    return TABLE_SCHEMA_PREFIX "\"BlobRecords\"" BLOB_RECORDS_TABLE_SCHEMA_SUFFIX;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static const String& blobRecordsTableSchemaAlternate()
</del><ins>+static ASCIILiteral blobFilesTableSchema()
</ins><span class="cx"> {
</span><del>-    static NeverDestroyed<String> blobRecordsTableSchemaString(blobRecordsTableSchema("\"BlobRecords\""));
-    return blobRecordsTableSchemaString;
</del><ins>+    return TABLE_SCHEMA_PREFIX "BlobFiles" BLOB_FILES_TABLE_SCHEMA_SUFFIX;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static const String blobFilesTableSchema(const String& tableName)
</del><ins>+static ASCIILiteral blobFilesTableSchemaAlternate()
</ins><span class="cx"> {
</span><del>-    return makeString("CREATE TABLE ", tableName, " (blobURL TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT FAIL, fileName TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT FAIL)");
</del><ins>+    return TABLE_SCHEMA_PREFIX "\"BlobFiles\"" BLOB_FILES_TABLE_SCHEMA_SUFFIX;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static const String& blobFilesTableSchema()
-{
-    static NeverDestroyed<String> blobFilesTableSchemaString(blobFilesTableSchema("BlobFiles"));
-    return blobFilesTableSchemaString;
-}
-
-static const String& blobFilesTableSchemaAlternate()
-{
-    static NeverDestroyed<String> blobFilesTableSchemaString(blobFilesTableSchema("\"BlobFiles\""));
-    return blobFilesTableSchemaString;
-}
-
</del><span class="cx"> static String createV1ObjectStoreInfoSchema(ASCIILiteral tableName)
</span><span class="cx"> {
</span><span class="cx">     return makeString("CREATE TABLE ", tableName, " (id INTEGER PRIMARY KEY NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT FAIL, name TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT FAIL, keyPath BLOB NOT NULL ON CONFLICT FAIL, autoInc INTEGER NOT NULL ON CONFLICT FAIL, maxIndexID INTEGER NOT NULL ON CONFLICT FAIL)");
</span><span class="lines">@@ -238,11 +227,16 @@
</span><span class="cx">     return makeString("CREATE TABLE ", tableName, " (id INTEGER PRIMARY KEY NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT FAIL, name TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT FAIL, keyPath BLOB NOT NULL ON CONFLICT FAIL, autoInc INTEGER NOT NULL ON CONFLICT FAIL)");
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static String indexInfoTableSchema(ASCIILiteral tableName)
</del><ins>+static ASCIILiteral indexInfoTableSchema()
</ins><span class="cx"> {
</span><del>-    return makeString("CREATE TABLE ", tableName, " (id INTEGER NOT NULL ON CONFLICT FAIL, name TEXT NOT NULL ON CONFLICT FAIL, objectStoreID INTEGER NOT NULL ON CONFLICT FAIL, keyPath BLOB NOT NULL ON CONFLICT FAIL, isUnique INTEGER NOT NULL ON CONFLICT FAIL, multiEntry INTEGER NOT NULL ON CONFLICT FAIL)");
</del><ins>+    return TABLE_SCHEMA_PREFIX "IndexInfo" INDEX_INFO_TABLE_SCHEMA_SUFFIX;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static ASCIILiteral indexInfoTableSchemaTemp()
+{
+    return TABLE_SCHEMA_PREFIX "_Temp_IndexInfo" INDEX_INFO_TABLE_SCHEMA_SUFFIX;
+}
+
</ins><span class="cx"> SQLiteIDBBackingStore::SQLiteIDBBackingStore(PAL::SessionID sessionID, const IDBDatabaseIdentifier& identifier, const String& databaseRootDirectory)
</span><span class="cx">     : m_sessionID(sessionID)
</span><span class="cx">     , m_identifier(identifier)
</span><span class="lines">@@ -305,22 +299,22 @@
</span><span class="cx">     transaction.begin();
</span><span class="cx"> 
</span><span class="cx">     // Create a temporary table with the correct schema and migrate all existing content over.
</span><del>-    if (!database.executeCommand(v3RecordsTableSchema("_Temp_Records"))) {
</del><ins>+    if (!database.executeCommand(v3RecordsTableSchemaTemp())) {
</ins><span class="cx">         LOG_ERROR("Could not create temporary records table in database (%i) - %s", database.lastError(), database.lastErrorMsg());
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (!database.executeCommand("INSERT INTO _Temp_Records (objectStoreID, key, value) SELECT objectStoreID, CAST(key AS TEXT), value FROM Records")) {
</del><ins>+    if (!database.executeCommand("INSERT INTO _Temp_Records (objectStoreID, key, value) SELECT objectStoreID, CAST(key AS TEXT), value FROM Records"_s)) {
</ins><span class="cx">         LOG_ERROR("Could not migrate existing Records content (%i) - %s", database.lastError(), database.lastErrorMsg());
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (!database.executeCommand("DROP TABLE Records")) {
</del><ins>+    if (!database.executeCommand("DROP TABLE Records"_s)) {
</ins><span class="cx">         LOG_ERROR("Could not drop existing Records table (%i) - %s", database.lastError(), database.lastErrorMsg());
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (!database.executeCommand("ALTER TABLE _Temp_Records RENAME TO Records")) {
</del><ins>+    if (!database.executeCommand("ALTER TABLE _Temp_Records RENAME TO Records"_s)) {
</ins><span class="cx">         LOG_ERROR("Could not rename temporary Records table (%i) - %s", database.lastError(), database.lastErrorMsg());
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="lines">@@ -412,7 +406,7 @@
</span><span class="cx"> 
</span><span class="cx">     // Whether the updated records table already existed or if it was just created and the data migrated over,
</span><span class="cx">     // make sure the uniqueness index exists.
</span><del>-    if (!m_sqliteDB->executeCommand("CREATE UNIQUE INDEX IF NOT EXISTS RecordsIndex ON Records (objectStoreID, key);")) {
</del><ins>+    if (!m_sqliteDB->executeCommand("CREATE UNIQUE INDEX IF NOT EXISTS RecordsIndex ON Records (objectStoreID, key);"_s)) {
</ins><span class="cx">         LOG_ERROR("Could not create RecordsIndex on Records table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="lines">@@ -470,22 +464,22 @@
</span><span class="cx">     transaction.begin();
</span><span class="cx"> 
</span><span class="cx">     // Create a temporary table with the correct schema and migrate all existing content over.
</span><del>-    if (!m_sqliteDB->executeCommand(v3IndexRecordsTableSchema("_Temp_IndexRecords"))) {
</del><ins>+    if (!m_sqliteDB->executeCommand(v3IndexRecordsTableSchemaTemp())) {
</ins><span class="cx">         LOG_ERROR("Could not create temporary index records table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (!m_sqliteDB->executeCommand("INSERT INTO _Temp_IndexRecords SELECT IndexRecords.indexID, IndexRecords.objectStoreID, IndexRecords.key, IndexRecords.value, Records.rowid FROM IndexRecords INNER JOIN Records ON Records.key = IndexRecords.value AND Records.objectStoreID = IndexRecords.objectStoreID")) {
</del><ins>+    if (!m_sqliteDB->executeCommand("INSERT INTO _Temp_IndexRecords SELECT IndexRecords.indexID, IndexRecords.objectStoreID, IndexRecords.key, IndexRecords.value, Records.rowid FROM IndexRecords INNER JOIN Records ON Records.key = IndexRecords.value AND Records.objectStoreID = IndexRecords.objectStoreID"_s)) {
</ins><span class="cx">         LOG_ERROR("Could not migrate existing IndexRecords content (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (!m_sqliteDB->executeCommand("DROP TABLE IndexRecords")) {
</del><ins>+    if (!m_sqliteDB->executeCommand("DROP TABLE IndexRecords"_s)) {
</ins><span class="cx">         LOG_ERROR("Could not drop existing IndexRecords table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (!m_sqliteDB->executeCommand("ALTER TABLE _Temp_IndexRecords RENAME TO IndexRecords")) {
</del><ins>+    if (!m_sqliteDB->executeCommand("ALTER TABLE _Temp_IndexRecords RENAME TO IndexRecords"_s)) {
</ins><span class="cx">         LOG_ERROR("Could not rename temporary IndexRecords table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="lines">@@ -539,7 +533,7 @@
</span><span class="cx">     SQLiteTransaction transaction(*m_sqliteDB);
</span><span class="cx">     transaction.begin();
</span><span class="cx"> 
</span><del>-    if (!m_sqliteDB->executeCommand("DROP INDEX IndexRecordsIndex")) {
</del><ins>+    if (!m_sqliteDB->executeCommand("DROP INDEX IndexRecordsIndex"_s)) {
</ins><span class="cx">         LOG_ERROR("Could not drop index IndexRecordsIndex in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="lines">@@ -599,7 +593,7 @@
</span><span class="cx">     ASSERT(m_sqliteDB);
</span><span class="cx">     ASSERT(m_sqliteDB->isOpen());
</span><span class="cx"> 
</span><del>-    if (!m_sqliteDB->executeCommand("CREATE TABLE IDBDatabaseInfo (key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE, value TEXT NOT NULL ON CONFLICT FAIL);")) {
</del><ins>+    if (!m_sqliteDB->executeCommand("CREATE TABLE IDBDatabaseInfo (key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE, value TEXT NOT NULL ON CONFLICT FAIL);"_s)) {
</ins><span class="cx">         LOG_ERROR("Could not create IDBDatabaseInfo table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
</span><span class="cx">         closeSQLiteDB();
</span><span class="cx">         return nullptr;
</span><span class="lines">@@ -611,13 +605,13 @@
</span><span class="cx">         return nullptr;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (!m_sqliteDB->executeCommand(indexInfoTableSchema("IndexInfo"_s))) {
</del><ins>+    if (!m_sqliteDB->executeCommand(indexInfoTableSchema())) {
</ins><span class="cx">         LOG_ERROR("Could not create IndexInfo table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
</span><span class="cx">         closeSQLiteDB();
</span><span class="cx">         return nullptr;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (!m_sqliteDB->executeCommand("CREATE TABLE KeyGenerators (objectStoreID INTEGER NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE, currentKey INTEGER NOT NULL ON CONFLICT FAIL);")) {
</del><ins>+    if (!m_sqliteDB->executeCommand("CREATE TABLE KeyGenerators (objectStoreID INTEGER NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE, currentKey INTEGER NOT NULL ON CONFLICT FAIL);"_s)) {
</ins><span class="cx">         LOG_ERROR("Could not create KeyGenerators table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
</span><span class="cx">         closeSQLiteDB();
</span><span class="cx">         return nullptr;
</span><span class="lines">@@ -702,22 +696,22 @@
</span><span class="cx">     SQLiteTransaction transaction(*m_sqliteDB);
</span><span class="cx">     transaction.begin();
</span><span class="cx"> 
</span><del>-    if (!m_sqliteDB->executeCommand(createV2ObjectStoreInfoSchema("_Temp_ObjectStoreInfo"_s))) {
</del><ins>+    if (!m_sqliteDB->executeCommandSlow(createV2ObjectStoreInfoSchema("_Temp_ObjectStoreInfo"_s))) {
</ins><span class="cx">         LOG_ERROR("Could not create temporary ObjectStoreInfo table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
</span><span class="cx">         return WTF::nullopt;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (!m_sqliteDB->executeCommand("INSERT INTO _Temp_ObjectStoreInfo (id, name, keyPath, autoInc) SELECT id, name, keyPath, autoInc FROM ObjectStoreInfo")) {
</del><ins>+    if (!m_sqliteDB->executeCommand("INSERT INTO _Temp_ObjectStoreInfo (id, name, keyPath, autoInc) SELECT id, name, keyPath, autoInc FROM ObjectStoreInfo"_s)) {
</ins><span class="cx">         LOG_ERROR("Could not migrate existing ObjectStoreInfo content (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
</span><span class="cx">         return WTF::nullopt;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (!m_sqliteDB->executeCommand("DROP TABLE ObjectStoreInfo")) {
</del><ins>+    if (!m_sqliteDB->executeCommand("DROP TABLE ObjectStoreInfo"_s)) {
</ins><span class="cx">         LOG_ERROR("Could not drop existing ObjectStoreInfo table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
</span><span class="cx">         return WTF::nullopt;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (!m_sqliteDB->executeCommand("ALTER TABLE _Temp_ObjectStoreInfo RENAME TO ObjectStoreInfo")) {
</del><ins>+    if (!m_sqliteDB->executeCommand("ALTER TABLE _Temp_ObjectStoreInfo RENAME TO ObjectStoreInfo"_s)) {
</ins><span class="cx">         LOG_ERROR("Could not rename temporary ObjectStoreInfo table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
</span><span class="cx">         return WTF::nullopt;
</span><span class="cx">     }
</span><span class="lines">@@ -733,7 +727,7 @@
</span><span class="cx">     SQLiteTransaction transaction(database);
</span><span class="cx">     transaction.begin();
</span><span class="cx"> 
</span><del>-    if (!database.executeCommand(indexInfoTableSchema("_Temp_IndexInfo"_s))) {
</del><ins>+    if (!database.executeCommand(indexInfoTableSchemaTemp())) {
</ins><span class="cx">         LOG_ERROR("Error creating _Temp_IndexInfo table in database (%i) - %s", database.lastError(), database.lastErrorMsg());
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="lines">@@ -778,12 +772,12 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (!database.executeCommand("DROP TABLE IndexInfo")) {
</del><ins>+    if (!database.executeCommand("DROP TABLE IndexInfo"_s)) {
</ins><span class="cx">         LOG_ERROR("Error dropping existing IndexInfo table (%i) - %s", database.lastError(), database.lastErrorMsg());
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (!database.executeCommand("ALTER TABLE _Temp_IndexInfo RENAME TO IndexInfo")) {
</del><ins>+    if (!database.executeCommand("ALTER TABLE _Temp_IndexInfo RENAME TO IndexInfo"_s)) {
</ins><span class="cx">         LOG_ERROR("Error renaming _Temp_IndexInfo table (%i) - %s", database.lastError(), database.lastErrorMsg());
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="lines">@@ -798,7 +792,7 @@
</span><span class="cx">     SQLiteTransaction transaction(database);
</span><span class="cx">     transaction.begin();
</span><span class="cx"> 
</span><del>-    if (!database.executeCommand(v3IndexRecordsTableSchema("_Temp_IndexRecords"))) {
</del><ins>+    if (!database.executeCommand(v3IndexRecordsTableSchemaTemp())) {
</ins><span class="cx">         LOG_ERROR("Error creating _Temp_IndexRecords table in database (%i) - %s", database.lastError(), database.lastErrorMsg());
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="lines">@@ -842,12 +836,12 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (!database.executeCommand("DROP TABLE IndexRecords")) {
</del><ins>+    if (!database.executeCommand("DROP TABLE IndexRecords"_s)) {
</ins><span class="cx">         LOG_ERROR("Error dropping existing IndexRecords table (%i) - %s", database.lastError(), database.lastErrorMsg());
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (!database.executeCommand("ALTER TABLE _Temp_IndexRecords RENAME TO IndexRecords")) {
</del><ins>+    if (!database.executeCommand("ALTER TABLE _Temp_IndexRecords RENAME TO IndexRecords"_s)) {
</ins><span class="cx">         LOG_ERROR("Error renaming temporary IndexRecords table (%i) - %s", database.lastError(), database.lastErrorMsg());
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="lines">@@ -3070,5 +3064,12 @@
</span><span class="cx">     return m_transactions.contains(transactionIdentifier);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#undef TABLE_SCHEMA_PREFIX
+#undef V3_RECORDS_TABLE_SCHEMA_SUFFIX
+#undef V3_INDEX_RECORDS_TABLE_SCHEMA_SUFFIX
+#undef INDEX_INFO_TABLE_SCHEMA_SUFFIX
+#undef BLOB_RECORDS_TABLE_SCHEMA_SUFFIX
+#undef BLOB_FILES_TABLE_SCHEMA_SUFFIX
+
</ins><span class="cx"> } // namespace IDBServer
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverSQLiteIDBCursorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.cpp (277600 => 277601)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.cpp        2021-05-17 19:09:02 UTC (rev 277600)
+++ trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.cpp   2021-05-17 19:26:06 UTC (rev 277601)
</span><span class="lines">@@ -235,7 +235,7 @@
</span><span class="cx">     ASSERT(!m_currentUpperKey.isNull());
</span><span class="cx">     ASSERT(m_transaction->sqliteTransaction());
</span><span class="cx"> 
</span><del>-    auto statement = m_transaction->sqliteTransaction()->database().prepareHeapStatement(sql);
</del><ins>+    auto statement = m_transaction->sqliteTransaction()->database().prepareHeapStatementSlow(sql);
</ins><span class="cx">     if (!statement) {
</span><span class="cx">         LOG_ERROR("Could not create cursor statement (prepare/id) - '%s'", m_transaction->sqliteTransaction()->database().lastErrorMsg());
</span><span class="cx">         return false;
</span><span class="lines">@@ -341,7 +341,7 @@
</span><span class="cx"> 
</span><span class="cx">     auto& database = m_transaction->sqliteTransaction()->database();
</span><span class="cx">     if (!m_preIndexStatement) {
</span><del>-        auto preIndexStatement = database.prepareHeapStatement(buildPreIndexStatement(isDirectionNext()));
</del><ins>+        auto preIndexStatement = database.prepareHeapStatementSlow(buildPreIndexStatement(isDirectionNext()));
</ins><span class="cx">         if (!preIndexStatement) {
</span><span class="cx">             LOG_ERROR("Could not prepare pre statement - '%s'", database.lastErrorMsg());
</span><span class="cx">             return false;
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebdatabaseDatabasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webdatabase/Database.cpp (277600 => 277601)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webdatabase/Database.cpp    2021-05-17 19:09:02 UTC (rev 277600)
+++ trunk/Source/WebCore/Modules/webdatabase/Database.cpp       2021-05-17 19:26:06 UTC (rev 277601)
</span><span class="lines">@@ -113,7 +113,7 @@
</span><span class="cx"> 
</span><span class="cx"> static bool setTextValueInDatabase(SQLiteDatabase& db, const String& query, const String& value)
</span><span class="cx"> {
</span><del>-    auto statement = db.prepareStatement(query);
</del><ins>+    auto statement = db.prepareStatementSlow(query);
</ins><span class="cx">     if (!statement) {
</span><span class="cx">         LOG_ERROR("Failed to prepare statement to set value in database (%s)", query.ascii().data());
</span><span class="cx">         return false;
</span><span class="lines">@@ -131,7 +131,7 @@
</span><span class="cx"> 
</span><span class="cx"> static bool retrieveTextResultFromDatabase(SQLiteDatabase& db, const String& query, String& resultString)
</span><span class="cx"> {
</span><del>-    auto statement = db.prepareStatement(query);
</del><ins>+    auto statement = db.prepareStatementSlow(query);
</ins><span class="cx">     if (!statement) {
</span><span class="cx">         LOG_ERROR("Error (%i) preparing statement to read text result from database (%s)", statement.error(), query.ascii().data());
</span><span class="cx">         return false;
</span><span class="lines">@@ -370,7 +370,7 @@
</span><span class="cx">             if (!m_sqliteDatabase.tableExists(tableName)) {
</span><span class="cx">                 m_new = true;
</span><span class="cx"> 
</span><del>-                if (!m_sqliteDatabase.executeCommand("CREATE TABLE " + tableName + " (key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE,value TEXT NOT NULL ON CONFLICT FAIL);")) {
</del><ins>+                if (!m_sqliteDatabase.executeCommandSlow("CREATE TABLE " + tableName + " (key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE,value TEXT NOT NULL ON CONFLICT FAIL);")) {
</ins><span class="cx">                     String message = formatErrorMessage("unable to open database, failed to create 'info' table", m_sqliteDatabase.lastError(), m_sqliteDatabase.lastErrorMsg());
</span><span class="cx">                     transaction.rollback();
</span><span class="cx">                     m_sqliteDatabase.close();
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebdatabaseDatabaseTrackercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp (277600 => 277601)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp     2021-05-17 19:09:02 UTC (rev 277600)
+++ trunk/Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp        2021-05-17 19:26:06 UTC (rev 277601)
</span><span class="lines">@@ -127,7 +127,7 @@
</span><span class="cx">     m_database.disableThreadingChecks();
</span><span class="cx"> 
</span><span class="cx">     if (!m_database.tableExists("Origins")) {
</span><del>-        if (!m_database.executeCommand("CREATE TABLE Origins (origin TEXT UNIQUE ON CONFLICT REPLACE, quota INTEGER NOT NULL ON CONFLICT FAIL);")) {
</del><ins>+        if (!m_database.executeCommand("CREATE TABLE Origins (origin TEXT UNIQUE ON CONFLICT REPLACE, quota INTEGER NOT NULL ON CONFLICT FAIL);"_s)) {
</ins><span class="cx">             // FIXME: and here
</span><span class="cx">             LOG_ERROR("Failed to create Origins table");
</span><span class="cx">         }
</span><span class="lines">@@ -134,7 +134,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (!m_database.tableExists("Databases")) {
</span><del>-        if (!m_database.executeCommand("CREATE TABLE Databases (guid INTEGER PRIMARY KEY AUTOINCREMENT, origin TEXT, name TEXT, displayName TEXT, estimatedSize INTEGER, path TEXT);")) {
</del><ins>+        if (!m_database.executeCommand("CREATE TABLE Databases (guid INTEGER PRIMARY KEY AUTOINCREMENT, origin TEXT, name TEXT, displayName TEXT, estimatedSize INTEGER, path TEXT);"_s)) {
</ins><span class="cx">             // FIXME: and here
</span><span class="cx">             LOG_ERROR("Failed to create Databases table");
</span><span class="cx">         }
</span><span class="lines">@@ -1267,15 +1267,15 @@
</span><span class="cx">             return false;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (!database.executeCommand("BEGIN EXCLUSIVE TRANSACTION;"))
</del><ins>+    if (!database.executeCommand("BEGIN EXCLUSIVE TRANSACTION;"_s))
</ins><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="cx">     // At this point, we hold the exclusive lock to this file.
</span><span class="cx">     // Check that the database doesn't contain any tables.
</span><del>-    if (!database.executeCommand("SELECT name FROM sqlite_master WHERE type='table';"))
</del><ins>+    if (!database.executeCommand("SELECT name FROM sqlite_master WHERE type='table';"_s))
</ins><span class="cx">         return false;
</span><span class="cx"> 
</span><del>-    database.executeCommand("COMMIT TRANSACTION;");
</del><ins>+    database.executeCommand("COMMIT TRANSACTION;"_s);
</ins><span class="cx"> 
</span><span class="cx">     database.close();
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebdatabaseSQLStatementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webdatabase/SQLStatement.cpp (277600 => 277601)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webdatabase/SQLStatement.cpp        2021-05-17 19:09:02 UTC (rev 277600)
+++ trunk/Source/WebCore/Modules/webdatabase/SQLStatement.cpp   2021-05-17 19:26:06 UTC (rev 277601)
</span><span class="lines">@@ -112,7 +112,7 @@
</span><span class="cx"> 
</span><span class="cx">     SQLiteDatabase& database = db.sqliteDatabase();
</span><span class="cx"> 
</span><del>-    auto statement = database.prepareStatement(m_statement);
</del><ins>+    auto statement = database.prepareStatementSlow(m_statement);
</ins><span class="cx">     if (!statement) {
</span><span class="cx">         LOG(StorageAPI, "Unable to verify correctness of statement %s - error %i (%s)", m_statement.ascii().data(), statement.error(), database.lastErrorMsg());
</span><span class="cx">         if (statement.error() == SQLITE_INTERRUPT)
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderappcacheApplicationCacheStoragecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/appcache/ApplicationCacheStorage.cpp (277600 => 277601)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/appcache/ApplicationCacheStorage.cpp 2021-05-17 19:09:02 UTC (rev 277600)
+++ trunk/Source/WebCore/loader/appcache/ApplicationCacheStorage.cpp    2021-05-17 19:26:06 UTC (rev 277601)
</span><span class="lines">@@ -41,6 +41,7 @@
</span><span class="cx"> #include <wtf/UUID.h>
</span><span class="cx"> #include <wtf/text/CString.h>
</span><span class="cx"> #include <wtf/text/StringBuilder.h>
</span><ins>+#include <wtf/text/StringConcatenateNumbers.h>
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="lines">@@ -532,7 +533,7 @@
</span><span class="cx">     return executeStatement(updateStatement.value());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool ApplicationCacheStorage::executeSQLCommand(const String& sql)
</del><ins>+bool ApplicationCacheStorage::executeSQLCommand(ASCIILiteral sql)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(SQLiteDatabaseTracker::hasTransactionInProgress());
</span><span class="cx">     ASSERT(m_database.isOpen());
</span><span class="lines">@@ -539,8 +540,7 @@
</span><span class="cx">     
</span><span class="cx">     bool result = m_database.executeCommand(sql);
</span><span class="cx">     if (!result)
</span><del>-        LOG_ERROR("Application Cache Storage: failed to execute statement \"%s\" error \"%s\"", 
-                  sql.utf8().data(), m_database.lastErrorMsg());
</del><ins>+        LOG_ERROR("Application Cache Storage: failed to execute statement \"%s\" error \"%s\"", sql.characters(), m_database.lastErrorMsg());
</ins><span class="cx"> 
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="lines">@@ -567,11 +567,7 @@
</span><span class="cx">     SQLiteTransaction setDatabaseVersion(m_database);
</span><span class="cx">     setDatabaseVersion.begin();
</span><span class="cx"> 
</span><del>-    char userVersionSQL[32];
-    int unusedNumBytes = snprintf(userVersionSQL, sizeof(userVersionSQL), "PRAGMA user_version=%d", schemaVersion);
-    ASSERT_UNUSED(unusedNumBytes, static_cast<int>(sizeof(userVersionSQL)) >= unusedNumBytes);
-
-    auto statement = m_database.prepareStatement(userVersionSQL);
</del><ins>+    auto statement = m_database.prepareStatementSlow(makeString("PRAGMA user_version=%", schemaVersion));
</ins><span class="cx">     if (!statement)
</span><span class="cx">         return;
</span><span class="cx">     
</span><span class="lines">@@ -604,18 +600,18 @@
</span><span class="cx">     
</span><span class="cx">     // Create tables
</span><span class="cx">     executeSQLCommand("CREATE TABLE IF NOT EXISTS CacheGroups (id INTEGER PRIMARY KEY AUTOINCREMENT, "
</span><del>-                      "manifestHostHash INTEGER NOT NULL ON CONFLICT FAIL, manifestURL TEXT UNIQUE ON CONFLICT FAIL, newestCache INTEGER, origin TEXT)");
-    executeSQLCommand("CREATE TABLE IF NOT EXISTS Caches (id INTEGER PRIMARY KEY AUTOINCREMENT, cacheGroup INTEGER, size INTEGER)");
-    executeSQLCommand("CREATE TABLE IF NOT EXISTS CacheWhitelistURLs (url TEXT NOT NULL ON CONFLICT FAIL, cache INTEGER NOT NULL ON CONFLICT FAIL)");
-    executeSQLCommand("CREATE TABLE IF NOT EXISTS CacheAllowsAllNetworkRequests (wildcard INTEGER NOT NULL ON CONFLICT FAIL, cache INTEGER NOT NULL ON CONFLICT FAIL)");
</del><ins>+                      "manifestHostHash INTEGER NOT NULL ON CONFLICT FAIL, manifestURL TEXT UNIQUE ON CONFLICT FAIL, newestCache INTEGER, origin TEXT)"_s);
+    executeSQLCommand("CREATE TABLE IF NOT EXISTS Caches (id INTEGER PRIMARY KEY AUTOINCREMENT, cacheGroup INTEGER, size INTEGER)"_s);
+    executeSQLCommand("CREATE TABLE IF NOT EXISTS CacheWhitelistURLs (url TEXT NOT NULL ON CONFLICT FAIL, cache INTEGER NOT NULL ON CONFLICT FAIL)"_s);
+    executeSQLCommand("CREATE TABLE IF NOT EXISTS CacheAllowsAllNetworkRequests (wildcard INTEGER NOT NULL ON CONFLICT FAIL, cache INTEGER NOT NULL ON CONFLICT FAIL)"_s);
</ins><span class="cx">     executeSQLCommand("CREATE TABLE IF NOT EXISTS FallbackURLs (namespace TEXT NOT NULL ON CONFLICT FAIL, fallbackURL TEXT NOT NULL ON CONFLICT FAIL, "
</span><del>-                      "cache INTEGER NOT NULL ON CONFLICT FAIL)");
-    executeSQLCommand("CREATE TABLE IF NOT EXISTS CacheEntries (cache INTEGER NOT NULL ON CONFLICT FAIL, type INTEGER, resource INTEGER NOT NULL)");
</del><ins>+                      "cache INTEGER NOT NULL ON CONFLICT FAIL)"_s);
+    executeSQLCommand("CREATE TABLE IF NOT EXISTS CacheEntries (cache INTEGER NOT NULL ON CONFLICT FAIL, type INTEGER, resource INTEGER NOT NULL)"_s);
</ins><span class="cx">     executeSQLCommand("CREATE TABLE IF NOT EXISTS CacheResources (id INTEGER PRIMARY KEY AUTOINCREMENT, url TEXT NOT NULL ON CONFLICT FAIL, "
</span><del>-                      "statusCode INTEGER NOT NULL, responseURL TEXT NOT NULL, mimeType TEXT, textEncodingName TEXT, headers TEXT, data INTEGER NOT NULL ON CONFLICT FAIL)");
-    executeSQLCommand("CREATE TABLE IF NOT EXISTS CacheResourceData (id INTEGER PRIMARY KEY AUTOINCREMENT, data BLOB, path TEXT)");
-    executeSQLCommand("CREATE TABLE IF NOT EXISTS DeletedCacheResources (id INTEGER PRIMARY KEY AUTOINCREMENT, path TEXT)");
-    executeSQLCommand("CREATE TABLE IF NOT EXISTS Origins (origin TEXT UNIQUE ON CONFLICT IGNORE, quota INTEGER NOT NULL ON CONFLICT FAIL)");
</del><ins>+                      "statusCode INTEGER NOT NULL, responseURL TEXT NOT NULL, mimeType TEXT, textEncodingName TEXT, headers TEXT, data INTEGER NOT NULL ON CONFLICT FAIL)"_s);
+    executeSQLCommand("CREATE TABLE IF NOT EXISTS CacheResourceData (id INTEGER PRIMARY KEY AUTOINCREMENT, data BLOB, path TEXT)"_s);
+    executeSQLCommand("CREATE TABLE IF NOT EXISTS DeletedCacheResources (id INTEGER PRIMARY KEY AUTOINCREMENT, path TEXT)"_s);
+    executeSQLCommand("CREATE TABLE IF NOT EXISTS Origins (origin TEXT UNIQUE ON CONFLICT IGNORE, quota INTEGER NOT NULL ON CONFLICT FAIL)"_s);
</ins><span class="cx"> 
</span><span class="cx">     // When a cache is deleted, all its entries and its allowlist should be deleted.
</span><span class="cx">     executeSQLCommand("CREATE TRIGGER IF NOT EXISTS CacheDeleted AFTER DELETE ON Caches"
</span><span class="lines">@@ -624,19 +620,19 @@
</span><span class="cx">                       "  DELETE FROM CacheWhitelistURLs WHERE cache = OLD.id;"
</span><span class="cx">                       "  DELETE FROM CacheAllowsAllNetworkRequests WHERE cache = OLD.id;"
</span><span class="cx">                       "  DELETE FROM FallbackURLs WHERE cache = OLD.id;"
</span><del>-                      " END");
</del><ins>+                      " END"_s);
</ins><span class="cx"> 
</span><span class="cx">     // When a cache entry is deleted, its resource should also be deleted.
</span><span class="cx">     executeSQLCommand("CREATE TRIGGER IF NOT EXISTS CacheEntryDeleted AFTER DELETE ON CacheEntries"
</span><span class="cx">                       " FOR EACH ROW BEGIN"
</span><span class="cx">                       "  DELETE FROM CacheResources WHERE id = OLD.resource;"
</span><del>-                      " END");
</del><ins>+                      " END"_s);
</ins><span class="cx"> 
</span><span class="cx">     // When a cache resource is deleted, its data blob should also be deleted.
</span><span class="cx">     executeSQLCommand("CREATE TRIGGER IF NOT EXISTS CacheResourceDeleted AFTER DELETE ON CacheResources"
</span><span class="cx">                       " FOR EACH ROW BEGIN"
</span><span class="cx">                       "  DELETE FROM CacheResourceData WHERE id = OLD.data;"
</span><del>-                      " END");
</del><ins>+                      " END"_s);
</ins><span class="cx">     
</span><span class="cx">     // When a cache resource is deleted, if it contains a non-empty path, that path should
</span><span class="cx">     // be added to the DeletedCacheResources table so the flat file at that path can
</span><span class="lines">@@ -645,7 +641,7 @@
</span><span class="cx">                       " FOR EACH ROW"
</span><span class="cx">                       " WHEN OLD.path NOT NULL BEGIN"
</span><span class="cx">                       "  INSERT INTO DeletedCacheResources (path) values (OLD.path);"
</span><del>-                      " END");
</del><ins>+                      " END"_s);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool ApplicationCacheStorage::executeStatement(SQLiteStatement& statement)
</span><span class="lines">@@ -1256,9 +1252,9 @@
</span><span class="cx">         return;
</span><span class="cx">     
</span><span class="cx">     // Clear cache groups, caches, cache resources, and origins.
</span><del>-    executeSQLCommand("DELETE FROM CacheGroups");
-    executeSQLCommand("DELETE FROM Caches");
-    executeSQLCommand("DELETE FROM Origins");
</del><ins>+    executeSQLCommand("DELETE FROM CacheGroups"_s);
+    executeSQLCommand("DELETE FROM Caches"_s);
+    executeSQLCommand("DELETE FROM Origins"_s);
</ins><span class="cx">     
</span><span class="cx">     // Clear the storage IDs for the caches in memory.
</span><span class="cx">     // The caches will still work, but cached resources will not be saved to disk 
</span><span class="lines">@@ -1439,7 +1435,7 @@
</span><span class="cx">         FileSystem::deleteFile(fullPath);
</span><span class="cx">     } while (selectPaths->step() == SQLITE_ROW);
</span><span class="cx">     
</span><del>-    executeSQLCommand("DELETE FROM DeletedCacheResources");
</del><ins>+    executeSQLCommand("DELETE FROM DeletedCacheResources"_s);
</ins><span class="cx"> }
</span><span class="cx">     
</span><span class="cx"> long long ApplicationCacheStorage::flatFileAreaSize()
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderappcacheApplicationCacheStorageh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/appcache/ApplicationCacheStorage.h (277600 => 277601)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/appcache/ApplicationCacheStorage.h   2021-05-17 19:09:02 UTC (rev 277600)
+++ trunk/Source/WebCore/loader/appcache/ApplicationCacheStorage.h      2021-05-17 19:26:06 UTC (rev 277601)
</span><span class="lines">@@ -131,7 +131,7 @@
</span><span class="cx">     void openDatabase(bool createIfDoesNotExist);
</span><span class="cx">     
</span><span class="cx">     bool executeStatement(SQLiteStatement&);
</span><del>-    bool executeSQLCommand(const String&);
</del><ins>+    bool executeSQLCommand(ASCIILiteral);
</ins><span class="cx"> 
</span><span class="cx">     void checkForMaxSizeReached();
</span><span class="cx">     void checkForDeletedResources();
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkcurlCookieJarDBcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/curl/CookieJarDB.cpp (277600 => 277601)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/curl/CookieJarDB.cpp       2021-05-17 19:09:02 UTC (rev 277600)
+++ trunk/Source/WebCore/platform/network/curl/CookieJarDB.cpp  2021-05-17 19:26:06 UTC (rev 277601)
</span><span class="lines">@@ -59,32 +59,32 @@
</span><span class="cx">     "  httponly INTEGER NOT NULL DEFAULT 0,"\
</span><span class="cx">     "  secure INTEGER NOT NULL DEFAULT 0,"\
</span><span class="cx">     "  lastupdated INTEGER NOT NULL DEFAULT CURRENT_TIMESTAMP, "\
</span><del>-    "  UNIQUE(name, domain, path));"
</del><ins>+    "  UNIQUE(name, domain, path));"_s
</ins><span class="cx"> #define CREATE_DOMAIN_INDEX_SQL \
</span><del>-    "CREATE INDEX IF NOT EXISTS domain_index ON Cookie(domain);"
</del><ins>+    "CREATE INDEX IF NOT EXISTS domain_index ON Cookie(domain);"_s
</ins><span class="cx"> #define CREATE_PATH_INDEX_SQL \
</span><del>-    "CREATE INDEX IF NOT EXISTS path_index ON Cookie(path);"
</del><ins>+    "CREATE INDEX IF NOT EXISTS path_index ON Cookie(path);"_s
</ins><span class="cx"> #define SELECT_ALL_DOMAINS_SQL \
</span><del>-    "SELECT DISTINCT domain FROM Cookie;"
</del><ins>+    "SELECT DISTINCT domain FROM Cookie;"_s
</ins><span class="cx"> #define CHECK_EXISTS_COOKIE_SQL \
</span><del>-    "SELECT domain FROM Cookie WHERE ((domain = ?) OR (domain GLOB ?));"
</del><ins>+    "SELECT domain FROM Cookie WHERE ((domain = ?) OR (domain GLOB ?));"_s
</ins><span class="cx"> #define CHECK_EXISTS_HTTPONLY_COOKIE_SQL \
</span><del>-    "SELECT name FROM Cookie WHERE (name = ?) AND (domain = ?) AND (path = ?) AND (httponly = 1);"
</del><ins>+    "SELECT name FROM Cookie WHERE (name = ?) AND (domain = ?) AND (path = ?) AND (httponly = 1);"_s
</ins><span class="cx"> #define SET_COOKIE_SQL \
</span><span class="cx">     "INSERT OR REPLACE INTO Cookie (name, value, domain, path, expires, size, session, httponly, secure) "\
</span><del>-    "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);"
</del><ins>+    "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);"_s
</ins><span class="cx"> #define DELETE_COOKIE_BY_NAME_DOMAIN_PATH_SQL \
</span><del>-    "DELETE FROM Cookie WHERE name = ? AND domain = ? AND path = ?;"
</del><ins>+    "DELETE FROM Cookie WHERE name = ? AND domain = ? AND path = ?;"_s
</ins><span class="cx"> #define DELETE_COOKIE_BY_NAME_DOMAIN_SQL \
</span><del>-    "DELETE FROM Cookie WHERE name = ? AND domain = ?;"
</del><ins>+    "DELETE FROM Cookie WHERE name = ? AND domain = ?;"_s
</ins><span class="cx"> #define DELETE_ALL_SESSION_COOKIE_SQL \
</span><del>-    "DELETE FROM Cookie WHERE session = 1;"
</del><ins>+    "DELETE FROM Cookie WHERE session = 1;"_s
</ins><span class="cx"> #define DELETE_COOKIES_BY_DOMAIN_SQL \
</span><del>-    "DELETE FROM Cookie WHERE domain = ? ;"
</del><ins>+    "DELETE FROM Cookie WHERE domain = ? ;"_s
</ins><span class="cx"> #define DELETE_COOKIES_BY_DOMAIN_EXCEPT_HTTP_ONLY_SQL \
</span><del>-    "DELETE FROM Cookie WHERE (domain = ?) AND (httponly = 0);"
</del><ins>+    "DELETE FROM Cookie WHERE (domain = ?) AND (httponly = 0);"_s
</ins><span class="cx"> #define DELETE_ALL_COOKIE_SQL \
</span><del>-    "DELETE FROM Cookie;"
</del><ins>+    "DELETE FROM Cookie;"_s
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> // If the database schema is updated:
</span><span class="lines">@@ -123,7 +123,7 @@
</span><span class="cx">     if (existsDatabaseFile) {
</span><span class="cx">         if (m_database.open(m_databasePath)) {
</span><span class="cx">             if (checkDatabaseValidity())
</span><del>-                executeSql(DELETE_ALL_SESSION_COOKIE_SQL);
</del><ins>+                executeSQLStatement(m_database.prepareStatement(DELETE_ALL_SESSION_COOKIE_SQL));
</ins><span class="cx">             else {
</span><span class="cx">                 // delete database and try to re-create again
</span><span class="cx">                 LOG_ERROR("Cookie database validity check failed, attempting to recreate the database");
</span><span class="lines">@@ -154,7 +154,9 @@
</span><span class="cx">     verifySchemaVersion();
</span><span class="cx"> 
</span><span class="cx">     if (!existsDatabaseFile || !m_database.tableExists("Cookie")) {
</span><del>-        bool ok = executeSql(CREATE_COOKIE_TABLE_SQL) && executeSql(CREATE_DOMAIN_INDEX_SQL) && executeSql(CREATE_PATH_INDEX_SQL);
</del><ins>+        bool ok = executeSQLStatement(m_database.prepareStatement(CREATE_COOKIE_TABLE_SQL))
+            && executeSQLStatement(m_database.prepareStatement(CREATE_DOMAIN_INDEX_SQL))
+            && executeSQLStatement(m_database.prepareStatement(CREATE_PATH_INDEX_SQL));
</ins><span class="cx"> 
</span><span class="cx">         if (!ok) {
</span><span class="cx">             // give up create database at this time (all cookies on request/response are ignored)
</span><span class="lines">@@ -211,7 +213,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Update version
</span><del>-    executeSql(makeString("PRAGMA user_version=", schemaVersion));
</del><ins>+    executeSQLStatement(m_database.prepareStatementSlow(makeString("PRAGMA user_version=", schemaVersion)));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void CookieJarDB::deleteAllTables()
</span><span class="lines">@@ -621,10 +623,10 @@
</span><span class="cx">     if (!isEnabled() || !m_database.isOpen())
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><del>-    return executeSql(DELETE_ALL_COOKIE_SQL);
</del><ins>+    return executeSQLStatement(m_database.prepareStatement(DELETE_ALL_COOKIE_SQL));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CookieJarDB::createPrepareStatement(const String& sql)
</del><ins>+void CookieJarDB::createPrepareStatement(ASCIILiteral sql)
</ins><span class="cx"> {
</span><span class="cx">     auto statement = m_database.prepareHeapStatement(sql);
</span><span class="cx">     ASSERT(statement);
</span><span class="lines">@@ -639,9 +641,8 @@
</span><span class="cx">     return *statement;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool CookieJarDB::executeSql(const String& sql)
</del><ins>+bool CookieJarDB::executeSQLStatement(Expected<SQLiteStatement, int>&& statement)
</ins><span class="cx"> {
</span><del>-    auto statement = m_database.prepareStatement(sql);
</del><span class="cx">     if (!statement && !checkSQLiteReturnCode(statement.error())) {
</span><span class="cx">         LOG_ERROR("Failed to prepare %s error: %s", sql.ascii().data(), m_database.lastErrorMsg());
</span><span class="cx">         return false;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkcurlCookieJarDBh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/curl/CookieJarDB.h (277600 => 277601)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/curl/CookieJarDB.h 2021-05-17 19:09:02 UTC (rev 277600)
+++ trunk/Source/WebCore/platform/network/curl/CookieJarDB.h    2021-05-17 19:26:06 UTC (rev 277601)
</span><span class="lines">@@ -93,9 +93,9 @@
</span><span class="cx">     void verifySchemaVersion();
</span><span class="cx">     void deleteAllTables();
</span><span class="cx"> 
</span><del>-    void createPrepareStatement(const String&);
</del><ins>+    void createPrepareStatement(ASCIILiteral);
</ins><span class="cx">     SQLiteStatement& preparedStatement(const String&);
</span><del>-    bool executeSql(const String&);
</del><ins>+    bool executeSQLStatement(Expected<SQLiteStatement, int>&&);
</ins><span class="cx"> 
</span><span class="cx">     bool deleteCookieInternal(const String& name, const String& domain, const String& path);
</span><span class="cx">     bool hasHttpOnlyCookie(const String& name, const String& domain, const String& path);
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformsqlSQLiteDatabasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/sql/SQLiteDatabase.cpp (277600 => 277601)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/sql/SQLiteDatabase.cpp     2021-05-17 19:09:02 UTC (rev 277600)
+++ trunk/Source/WebCore/platform/sql/SQLiteDatabase.cpp        2021-05-17 19:26:06 UTC (rev 277601)
</span><span class="lines">@@ -293,7 +293,7 @@
</span><span class="cx">     LockHolder locker(m_authorizerLock);
</span><span class="cx">     enableAuthorizer(false);
</span><span class="cx"> 
</span><del>-    auto statement = prepareStatement(makeString("PRAGMA max_page_count = ", newMaxPageCount));
</del><ins>+    auto statement = prepareStatementSlow(makeString("PRAGMA max_page_count = ", newMaxPageCount));
</ins><span class="cx">     if (!statement || statement->step() != SQLITE_ROW)
</span><span class="cx">         LOG_ERROR("Failed to set maximum size of database to %lli bytes", static_cast<long long>(size));
</span><span class="cx"> 
</span><span class="lines">@@ -351,7 +351,7 @@
</span><span class="cx"> 
</span><span class="cx"> void SQLiteDatabase::setSynchronous(SynchronousPragma sync)
</span><span class="cx"> {
</span><del>-    executeCommand(makeString("PRAGMA synchronous = ", static_cast<unsigned>(sync)));
</del><ins>+    executeCommandSlow(makeString("PRAGMA synchronous = ", static_cast<unsigned>(sync)));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void SQLiteDatabase::setBusyTimeout(int ms)
</span><span class="lines">@@ -370,9 +370,9 @@
</span><span class="cx">         LOG(SQLDatabase, "Busy handler set on non-open database");
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool SQLiteDatabase::executeCommand(const String& query)
</del><ins>+bool SQLiteDatabase::executeCommandSlow(const String& query)
</ins><span class="cx"> {
</span><del>-    auto statement = prepareStatement(query);
</del><ins>+    auto statement = prepareStatementSlow(query);
</ins><span class="cx">     return statement && statement->executeCommand();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -382,19 +382,17 @@
</span><span class="cx">     return statement && statement->executeCommand();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool SQLiteDatabase::returnsAtLeastOneResult(const String& sql)
</del><ins>+bool SQLiteDatabase::tableExists(const String& tableName)
</ins><span class="cx"> {
</span><del>-    auto statement = prepareStatement(sql);
-    return statement && statement->returnsAtLeastOneResult();
-}
-
-bool SQLiteDatabase::tableExists(const String& tablename)
-{
</del><span class="cx">     if (!isOpen())
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><del>-    auto statement = prepareStatement("SELECT name FROM sqlite_master WHERE type = 'table' AND name = '" + tablename + "';"_s);
-    return statement && statement->step() == SQLITE_ROW;
</del><ins>+    auto statement = prepareStatement("SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?;"_s);
+    if (!statement)
+        return false;
+    if (statement->bindText(1, tableName) != SQLITE_OK)
+        return false;
+    return statement->step() == SQLITE_ROW;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void SQLiteDatabase::clearAllTables()
</span><span class="lines">@@ -409,7 +407,7 @@
</span><span class="cx">     for (Vector<String>::iterator table = tables.begin(); table != tables.end(); ++table ) {
</span><span class="cx">         if (*table == "sqlite_sequence")
</span><span class="cx">             continue;
</span><del>-        if (!executeCommand("DROP TABLE " + *table))
</del><ins>+        if (!executeCommandSlow("DROP TABLE " + *table))
</ins><span class="cx">             LOG(SQLDatabase, "Unable to drop table %s", (*table).ascii().data());
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="lines">@@ -677,7 +675,7 @@
</span><span class="cx">     return statement;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Expected<SQLiteStatement, int> SQLiteDatabase::prepareStatement(const String& queryString)
</del><ins>+Expected<SQLiteStatement, int> SQLiteDatabase::prepareStatementSlow(const String& queryString)
</ins><span class="cx"> {
</span><span class="cx">     CString query = queryString.stripWhiteSpace().utf8();
</span><span class="cx">     auto sqlStatement = constructAndPrepareStatement(*this, query.data(), query.length());
</span><span class="lines">@@ -698,7 +696,7 @@
</span><span class="cx">     return SQLiteStatement { *this, sqlStatement.value() };
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Expected<UniqueRef<SQLiteStatement>, int> SQLiteDatabase::prepareHeapStatement(const String& queryString)
</del><ins>+Expected<UniqueRef<SQLiteStatement>, int> SQLiteDatabase::prepareHeapStatementSlow(const String& queryString)
</ins><span class="cx"> {
</span><span class="cx">     CString query = queryString.stripWhiteSpace().utf8();
</span><span class="cx">     auto sqlStatement = constructAndPrepareStatement(*this, query.data(), query.length());
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformsqlSQLiteDatabaseh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/sql/SQLiteDatabase.h (277600 => 277601)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/sql/SQLiteDatabase.h       2021-05-17 19:09:02 UTC (rev 277600)
+++ trunk/Source/WebCore/platform/sql/SQLiteDatabase.h  2021-05-17 19:26:06 UTC (rev 277601)
</span><span class="lines">@@ -62,10 +62,8 @@
</span><span class="cx"> 
</span><span class="cx">     WEBCORE_EXPORT void updateLastChangesCount();
</span><span class="cx"> 
</span><del>-    WEBCORE_EXPORT bool executeCommand(const String&);
</del><ins>+    WEBCORE_EXPORT bool executeCommandSlow(const String&);
</ins><span class="cx">     WEBCORE_EXPORT bool executeCommand(ASCIILiteral);
</span><del>-
-    bool returnsAtLeastOneResult(const String&);
</del><span class="cx">     
</span><span class="cx">     WEBCORE_EXPORT bool tableExists(const String&);
</span><span class="cx">     WEBCORE_EXPORT void clearAllTables();
</span><span class="lines">@@ -74,9 +72,9 @@
</span><span class="cx">     
</span><span class="cx">     bool transactionInProgress() const { return m_transactionInProgress; }
</span><span class="cx"> 
</span><del>-    WEBCORE_EXPORT Expected<SQLiteStatement, int> prepareStatement(const String& query);
</del><ins>+    WEBCORE_EXPORT Expected<SQLiteStatement, int> prepareStatementSlow(const String& query);
</ins><span class="cx">     WEBCORE_EXPORT Expected<SQLiteStatement, int> prepareStatement(ASCIILiteral query);
</span><del>-    WEBCORE_EXPORT Expected<UniqueRef<SQLiteStatement>, int> prepareHeapStatement(const String& query);
</del><ins>+    WEBCORE_EXPORT Expected<UniqueRef<SQLiteStatement>, int> prepareHeapStatementSlow(const String& query);
</ins><span class="cx">     WEBCORE_EXPORT Expected<UniqueRef<SQLiteStatement>, int> prepareHeapStatement(ASCIILiteral query);
</span><span class="cx"> 
</span><span class="cx">     // Aborts the current database operation. This is thread safe.
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformsqlSQLiteTransactioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/sql/SQLiteTransaction.cpp (277600 => 277601)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/sql/SQLiteTransaction.cpp  2021-05-17 19:09:02 UTC (rev 277600)
+++ trunk/Source/WebCore/platform/sql/SQLiteTransaction.cpp     2021-05-17 19:26:06 UTC (rev 277601)
</span><span class="lines">@@ -62,9 +62,9 @@
</span><span class="cx">         SQLiteDatabaseTracker::incrementTransactionInProgressCount();
</span><span class="cx"> #endif
</span><span class="cx">         if (m_readOnly)
</span><del>-            m_inProgress = m_db.executeCommand("BEGIN");
</del><ins>+            m_inProgress = m_db.executeCommand("BEGIN"_s);
</ins><span class="cx">         else
</span><del>-            m_inProgress = m_db.executeCommand("BEGIN IMMEDIATE");
</del><ins>+            m_inProgress = m_db.executeCommand("BEGIN IMMEDIATE"_s);
</ins><span class="cx">         m_db.m_transactionInProgress = m_inProgress;
</span><span class="cx"> #if PLATFORM(IOS_FAMILY)
</span><span class="cx">         if (!m_inProgress)
</span><span class="lines">@@ -77,7 +77,7 @@
</span><span class="cx"> {
</span><span class="cx">     if (m_inProgress) {
</span><span class="cx">         ASSERT(m_db.m_transactionInProgress);
</span><del>-        m_inProgress = !m_db.executeCommand("COMMIT");
</del><ins>+        m_inProgress = !m_db.executeCommand("COMMIT"_s);
</ins><span class="cx">         m_db.m_transactionInProgress = m_inProgress;
</span><span class="cx"> #if PLATFORM(IOS_FAMILY)
</span><span class="cx">         if (!m_inProgress)
</span><span class="lines">@@ -94,7 +94,7 @@
</span><span class="cx">     // a non-zero/true result (http://www.sqlite.org/lang_transaction.html).
</span><span class="cx">     if (m_inProgress) {
</span><span class="cx">         ASSERT(m_db.m_transactionInProgress);
</span><del>-        m_db.executeCommand("ROLLBACK");
</del><ins>+        m_db.executeCommand("ROLLBACK"_s);
</ins><span class="cx">         m_inProgress = false;
</span><span class="cx">         m_db.m_transactionInProgress = false;
</span><span class="cx"> #if PLATFORM(IOS_FAMILY)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformwinSearchPopupMenuDBcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/win/SearchPopupMenuDB.cpp (277600 => 277601)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/win/SearchPopupMenuDB.cpp  2021-05-17 19:09:02 UTC (rev 277600)
+++ trunk/Source/WebCore/platform/win/SearchPopupMenuDB.cpp     2021-05-17 19:26:06 UTC (rev 277601)
</span><span class="lines">@@ -204,7 +204,7 @@
</span><span class="cx"> 
</span><span class="cx">     bool databaseValidity = true;
</span><span class="cx">     if (!existsDatabaseFile || !m_database.tableExists("Search"))
</span><del>-        databaseValidity = databaseValidity && (executeSimpleSql(createSearchTableSQL) == SQLITE_DONE);
</del><ins>+        databaseValidity = databaseValidity && (executeSQLStatement(m_database.prepareStatement(createSearchTableSQL)) == SQLITE_DONE);
</ins><span class="cx"> 
</span><span class="cx">     if (!databaseValidity) {
</span><span class="cx">         // give up create database at this time (search terms will not be saved)
</span><span class="lines">@@ -254,7 +254,8 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Update version
</span><del>-    executeSimpleSql(makeString("PRAGMA user_version=", schemaVersion));
</del><ins>+
+    executeSQLStatement(m_database.prepareStatementSlow(makeString("PRAGMA user_version=", schemaVersion)));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void SearchPopupMenuDB::checkSQLiteReturnCode(int actual)
</span><span class="lines">@@ -271,9 +272,8 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-int SearchPopupMenuDB::executeSimpleSql(const String& sql, bool ignoreError)
</del><ins>+int SearchPopupMenuDB::executeSQLStatement(Expected<SQLiteStatement, int>&& statement)
</ins><span class="cx"> {
</span><del>-    auto statement = m_database.prepareStatement(sql);
</del><span class="cx">     if (!statement) {
</span><span class="cx">         checkSQLiteReturnCode(statement.error());
</span><span class="cx">         return statement.error();
</span><span class="lines">@@ -280,7 +280,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     int ret = statement->step();
</span><del>-    if (ret != SQLITE_OK && ret != SQLITE_DONE && ret != SQLITE_ROW && !ignoreError)
</del><ins>+    if (ret != SQLITE_OK && ret != SQLITE_DONE && ret != SQLITE_ROW)
</ins><span class="cx">         LOG_ERROR("Failed to execute %s error: %s", sql.ascii().data(), m_database.lastErrorMsg());
</span><span class="cx">     return ret;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformwinSearchPopupMenuDBh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/win/SearchPopupMenuDB.h (277600 => 277601)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/win/SearchPopupMenuDB.h    2021-05-17 19:09:02 UTC (rev 277600)
+++ trunk/Source/WebCore/platform/win/SearchPopupMenuDB.h       2021-05-17 19:26:06 UTC (rev 277601)
</span><span class="lines">@@ -49,7 +49,7 @@
</span><span class="cx">     bool checkDatabaseValidity();
</span><span class="cx">     void deleteAllDatabaseFiles();
</span><span class="cx">     void verifySchemaVersion();
</span><del>-    int executeSimpleSql(const String& sql, bool ignoreError = false);
</del><ins>+    int executeSQLStatement(Expected<SQLiteStatement, int>&&);
</ins><span class="cx">     void checkSQLiteReturnCode(int actual);
</span><span class="cx">     std::unique_ptr<SQLiteStatement> createPreparedStatement(ASCIILiteral sql);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreworkersserviceserverRegistrationDatabasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/workers/service/server/RegistrationDatabase.cpp (277600 => 277601)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/workers/service/server/RegistrationDatabase.cpp     2021-05-17 19:09:02 UTC (rev 277600)
+++ trunk/Source/WebCore/workers/service/server/RegistrationDatabase.cpp        2021-05-17 19:26:06 UTC (rev 277601)
</span><span class="lines">@@ -52,36 +52,30 @@
</span><span class="cx"> 
</span><span class="cx"> static const uint64_t schemaVersion = 6;
</span><span class="cx"> 
</span><del>-static const String recordsTableSchema(const String& tableName)
-{
-    return makeString("CREATE TABLE ", tableName, " ("
-        "key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE"
-        ", origin TEXT NOT NULL ON CONFLICT FAIL"
-        ", scopeURL TEXT NOT NULL ON CONFLICT FAIL"
-        ", topOrigin TEXT NOT NULL ON CONFLICT FAIL"
-        ", lastUpdateCheckTime DOUBLE NOT NULL ON CONFLICT FAIL"
-        ", updateViaCache TEXT NOT NULL ON CONFLICT FAIL"
-        ", scriptURL TEXT NOT NULL ON CONFLICT FAIL"
-        ", workerType TEXT NOT NULL ON CONFLICT FAIL"
-        ", contentSecurityPolicy BLOB NOT NULL ON CONFLICT FAIL"
-        ", referrerPolicy TEXT NOT NULL ON CONFLICT FAIL"
-        ", scriptResourceMap BLOB NOT NULL ON CONFLICT FAIL"
-        ", certificateInfo BLOB NOT NULL ON CONFLICT FAIL"
-        ")");
-}
</del><ins>+#define RECORDS_TABLE_SCHEMA_PREFIX "CREATE TABLE "
+#define RECORDS_TABLE_SCHEMA_SUFFIX "(" \
+    "key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE" \
+    ", origin TEXT NOT NULL ON CONFLICT FAIL" \
+    ", scopeURL TEXT NOT NULL ON CONFLICT FAIL" \
+    ", topOrigin TEXT NOT NULL ON CONFLICT FAIL" \
+    ", lastUpdateCheckTime DOUBLE NOT NULL ON CONFLICT FAIL" \
+    ", updateViaCache TEXT NOT NULL ON CONFLICT FAIL" \
+    ", scriptURL TEXT NOT NULL ON CONFLICT FAIL" \
+    ", workerType TEXT NOT NULL ON CONFLICT FAIL" \
+    ", contentSecurityPolicy BLOB NOT NULL ON CONFLICT FAIL" \
+    ", referrerPolicy TEXT NOT NULL ON CONFLICT FAIL" \
+    ", scriptResourceMap BLOB NOT NULL ON CONFLICT FAIL" \
+    ", certificateInfo BLOB NOT NULL ON CONFLICT FAIL" \
+    ")"_s;
</ins><span class="cx"> 
</span><del>-static const String recordsTableSchema()
</del><ins>+static ASCIILiteral recordsTableSchema()
</ins><span class="cx"> {
</span><del>-    ASSERT(!isMainThread());
-    static NeverDestroyed<String> schema(recordsTableSchema("Records"));
-    return schema;
</del><ins>+    return RECORDS_TABLE_SCHEMA_PREFIX "Records" RECORDS_TABLE_SCHEMA_SUFFIX;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static const String recordsTableSchemaAlternate()
</del><ins>+static ASCIILiteral recordsTableSchemaAlternate()
</ins><span class="cx"> {
</span><del>-    ASSERT(!isMainThread());
-    static NeverDestroyed<String> schema(recordsTableSchema("\"Records\""));
-    return schema;
</del><ins>+    return RECORDS_TABLE_SCHEMA_PREFIX "\"Records\"" RECORDS_TABLE_SCHEMA_SUFFIX;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static inline String databaseFilenameFromVersion(uint64_t version)
</span><span class="lines">@@ -610,6 +604,9 @@
</span><span class="cx">         m_store->databaseOpenedAndRecordsImported();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#undef RECORDS_TABLE_SCHEMA_PREFIX
+#undef RECORDS_TABLE_SCHEMA_SUFFIX
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(SERVICE_WORKER)
</span></span></pre></div>
<a id="trunkSourceWebKitChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/ChangeLog (277600 => 277601)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/ChangeLog    2021-05-17 19:09:02 UTC (rev 277600)
+++ trunk/Source/WebKit/ChangeLog       2021-05-17 19:26:06 UTC (rev 277601)
</span><span class="lines">@@ -1,3 +1,41 @@
</span><ins>+2021-05-17  Chris Dumez  <cdumez@apple.com>
+
+        Avoid more String creations when preparing SQLite statements
+        https://bugs.webkit.org/show_bug.cgi?id=225855
+
+        Reviewed by Alex Christensen.
+
+        Avoid more String creations when preparing SQLite statements by using ASCIILiteral. Also rename the
+        SQLiteDatabase::prepareStatement() / SQLiteDatabase::executeCommand() overloads that take in a 
+        String to make sure they are not called by mistake.
+
+        * NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp:
+        (WebKit::ResourceLoadStatisticsDatabaseStore::currentTableAndIndexQueries):
+        (WebKit::insertDistinctValuesInTableStatement):
+        (WebKit::ResourceLoadStatisticsDatabaseStore::migrateDataToNewTablesIfNecessary):
+        (WebKit::ResourceLoadStatisticsDatabaseStore::columnsForTable):
+        (WebKit::ResourceLoadStatisticsDatabaseStore::addMissingColumnsToTable):
+        (WebKit::ResourceLoadStatisticsDatabaseStore::renameColumnInTable):
+        (WebKit::ResourceLoadStatisticsDatabaseStore::insertDomainRelationshipList):
+        (WebKit::joinSubStatisticsForSorting):
+        (WebKit::ResourceLoadStatisticsDatabaseStore::aggregatedThirdPartyData const):
+        (WebKit::ResourceLoadStatisticsDatabaseStore::incrementRecordsDeletedCountForDomains):
+        (WebKit::ResourceLoadStatisticsDatabaseStore::markAsPrevalentIfHasRedirectedToPrevalent):
+        (WebKit::ResourceLoadStatisticsDatabaseStore::findNotVeryPrevalentResources):
+        (WebKit::ResourceLoadStatisticsDatabaseStore::grandfatherDataForDomains):
+        (WebKit::ResourceLoadStatisticsDatabaseStore::setDomainsAsPrevalent):
+        (WebKit::ResourceLoadStatisticsDatabaseStore::clearGrandfathering):
+        (WebKit::ResourceLoadStatisticsDatabaseStore::pruneStatisticsIfNeeded):
+        (WebKit::ResourceLoadStatisticsDatabaseStore::getSubStatisticStatement const):
+        (WebKit::ResourceLoadStatisticsDatabaseStore::appendSubStatisticList const):
+        * NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h:
+        * NetworkProcess/WebStorage/LocalStorageDatabase.cpp:
+        (WebKit::LocalStorageDatabase::openDatabase):
+        (WebKit::LocalStorageDatabase::migrateItemTableIfNeeded):
+        * UIProcess/API/glib/IconDatabase.cpp:
+        (WebKit::IconDatabase::createTablesIfNeeded):
+        (WebKit::IconDatabase::populatePageURLToIconURLMap):
+
</ins><span class="cx"> 2021-05-14  Simon Fraser  <simon.fraser@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Allow wheel events to be coalesced during scroll deceleration
</span></span></pre></div>
<a id="trunkSourceWebKitNetworkProcessClassifierResourceLoadStatisticsDatabaseStorecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp (277600 => 277601)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp    2021-05-17 19:09:02 UTC (rev 277600)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp       2021-05-17 19:26:06 UTC (rev 277601)
</span><span class="lines">@@ -436,7 +436,7 @@
</span><span class="cx"> 
</span><span class="cx"> TableAndIndexPair ResourceLoadStatisticsDatabaseStore::currentTableAndIndexQueries(const String& tableName)
</span><span class="cx"> {
</span><del>-    auto getTableStatement = m_database.prepareStatement(makeString("SELECT sql FROM sqlite_master WHERE tbl_name='", tableName, "' AND type = 'table'"));
</del><ins>+    auto getTableStatement = m_database.prepareStatement("SELECT sql FROM sqlite_master WHERE tbl_name=? AND type = 'table'"_s);
</ins><span class="cx">     if (!getTableStatement) {
</span><span class="cx">         RELEASE_LOG_ERROR(Network, "%p - ResourceLoadStatisticsDatabaseStore::currentTableAndIndexQueries Unable to prepare statement to fetch schema for the table, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());
</span><span class="cx">         ASSERT_NOT_REACHED();
</span><span class="lines">@@ -443,6 +443,12 @@
</span><span class="cx">         return { };
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    if (getTableStatement->bindText(1, tableName) != SQLITE_OK) {
+        RELEASE_LOG_ERROR(Network, "%p - ResourceLoadStatisticsDatabaseStore::currentTableAndIndexQueries Unable to bind statement to fetch schema for the table, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());
+        ASSERT_NOT_REACHED();
+        return { };
+    }
+
</ins><span class="cx">     if (getTableStatement->step() != SQLITE_ROW) {
</span><span class="cx">         RELEASE_LOG_ERROR(Network, "%p - ResourceLoadStatisticsDatabaseStore::currentTableAndIndexQueries error executing statement to fetch table schema, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());
</span><span class="cx">         ASSERT_NOT_REACHED();
</span><span class="lines">@@ -451,7 +457,7 @@
</span><span class="cx"> 
</span><span class="cx">     String createTableQuery = getTableStatement->getColumnText(0);
</span><span class="cx"> 
</span><del>-    auto getIndexStatement = m_database.prepareStatement(makeString("SELECT sql FROM sqlite_master WHERE tbl_name='", tableName, "' AND type = 'index'"));
</del><ins>+    auto getIndexStatement = m_database.prepareStatement("SELECT sql FROM sqlite_master WHERE tbl_name=? AND type = 'index'"_s);
</ins><span class="cx">     if (!getIndexStatement) {
</span><span class="cx">         RELEASE_LOG_ERROR(Network, "%p - ResourceLoadStatisticsDatabaseStore::currentTableAndIndexQueries Unable to prepare statement to fetch index for the table, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());
</span><span class="cx">         ASSERT_NOT_REACHED();
</span><span class="lines">@@ -458,6 +464,12 @@
</span><span class="cx">         return { };
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    if (getIndexStatement->bindText(1, tableName) != SQLITE_OK) {
+        RELEASE_LOG_ERROR(Network, "%p - ResourceLoadStatisticsDatabaseStore::currentTableAndIndexQueries Unable to bind statement to fetch index for the table, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());
+        ASSERT_NOT_REACHED();
+        return { };
+    }
+
</ins><span class="cx">     Optional<String> index;
</span><span class="cx">     if (getIndexStatement->step() == SQLITE_ROW) {
</span><span class="cx">         auto rawIndex = String(getIndexStatement->getColumnText(0));
</span><span class="lines">@@ -521,27 +533,27 @@
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static String insertDistinctValuesInTableQuery(const String& table)
</del><ins>+static Expected<SQLiteStatement, int> insertDistinctValuesInTableStatement(SQLiteDatabase& database, const String& table)
</ins><span class="cx"> {
</span><span class="cx">     if (table == "SubframeUnderTopFrameDomains")
</span><del>-        return makeString("INSERT INTO SubframeUnderTopFrameDomains SELECT subFrameDomainID, MAX(lastUpdated), topFrameDomainID FROM _SubframeUnderTopFrameDomains GROUP BY subFrameDomainID, topFrameDomainID");
</del><ins>+        return database.prepareStatement("INSERT INTO SubframeUnderTopFrameDomains SELECT subFrameDomainID, MAX(lastUpdated), topFrameDomainID FROM _SubframeUnderTopFrameDomains GROUP BY subFrameDomainID, topFrameDomainID"_s);
</ins><span class="cx"> 
</span><span class="cx">     if (table == "SubresourceUnderTopFrameDomains")
</span><del>-        return makeString("INSERT INTO SubresourceUnderTopFrameDomains SELECT subresourceDomainID, MAX(lastUpdated), topFrameDomainID FROM _SubresourceUnderTopFrameDomains GROUP BY subresourceDomainID, topFrameDomainID");
</del><ins>+        return database.prepareStatement("INSERT INTO SubresourceUnderTopFrameDomains SELECT subresourceDomainID, MAX(lastUpdated), topFrameDomainID FROM _SubresourceUnderTopFrameDomains GROUP BY subresourceDomainID, topFrameDomainID"_s);
</ins><span class="cx"> 
</span><span class="cx">     if (table == "SubresourceUniqueRedirectsTo")
</span><del>-        return makeString("INSERT INTO SubresourceUniqueRedirectsTo SELECT subresourceDomainID, MAX(lastUpdated), toDomainID FROM _SubresourceUniqueRedirectsTo GROUP BY subresourceDomainID, toDomainID");
</del><ins>+        return database.prepareStatement("INSERT INTO SubresourceUniqueRedirectsTo SELECT subresourceDomainID, MAX(lastUpdated), toDomainID FROM _SubresourceUniqueRedirectsTo GROUP BY subresourceDomainID, toDomainID"_s);
</ins><span class="cx"> 
</span><span class="cx">     if (table == "TopFrameLinkDecorationsFrom")
</span><del>-        return makeString("INSERT INTO TopFrameLinkDecorationsFrom SELECT toDomainID, MAX(lastUpdated), fromDomainID FROM _TopFrameLinkDecorationsFrom GROUP BY toDomainID, fromDomainID");
</del><ins>+        return database.prepareStatement("INSERT INTO TopFrameLinkDecorationsFrom SELECT toDomainID, MAX(lastUpdated), fromDomainID FROM _TopFrameLinkDecorationsFrom GROUP BY toDomainID, fromDomainID"_s);
</ins><span class="cx"> 
</span><span class="cx">     if (table == "UnattributedPrivateClickMeasurement")
</span><del>-        return makeString("INSERT INTO UnattributedPrivateClickMeasurement SELECT sourceSiteDomainID, destinationSiteDomainID, sourceID, MAX(timeOfAdClick), token, signature, keyID FROM _UnattributedPrivateClickMeasurement GROUP BY sourceSiteDomainID, destinationSiteDomainID");
</del><ins>+        return database.prepareStatement("INSERT INTO UnattributedPrivateClickMeasurement SELECT sourceSiteDomainID, destinationSiteDomainID, sourceID, MAX(timeOfAdClick), token, signature, keyID FROM _UnattributedPrivateClickMeasurement GROUP BY sourceSiteDomainID, destinationSiteDomainID"_s);
</ins><span class="cx"> 
</span><span class="cx">     if (table == "AttributedPrivateClickMeasurement")
</span><del>-        return makeString("INSERT INTO AttributedPrivateClickMeasurement SELECT sourceSiteDomainID, destinationSiteDomainID, sourceID, attributionTriggerData, priority, MAX(timeOfAdClick), earliestTimeToSendToSource, token, signature, keyID, earliestTimeToSendToDestination FROM _AttributedPrivateClickMeasurement GROUP BY sourceSiteDomainID, destinationSiteDomainID");
</del><ins>+        return database.prepareStatement("INSERT INTO AttributedPrivateClickMeasurement SELECT sourceSiteDomainID, destinationSiteDomainID, sourceID, attributionTriggerData, priority, MAX(timeOfAdClick), earliestTimeToSendToSource, token, signature, keyID, earliestTimeToSendToDestination FROM _AttributedPrivateClickMeasurement GROUP BY sourceSiteDomainID, destinationSiteDomainID"_s);
</ins><span class="cx"> 
</span><del>-    return makeString("INSERT INTO ", table, " SELECT DISTINCT * FROM _", table);
</del><ins>+    return database.prepareStatementSlow(makeString("INSERT INTO ", table, " SELECT DISTINCT * FROM _", table));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ResourceLoadStatisticsDatabaseStore::migrateDataToNewTablesIfNecessary()
</span><span class="lines">@@ -553,8 +565,7 @@
</span><span class="cx">     transaction.begin();
</span><span class="cx"> 
</span><span class="cx">     for (auto& table : expectedTableAndIndexQueries().keys()) {
</span><del>-        auto query = makeString("ALTER TABLE ", table, " RENAME TO _", table);
-        auto alterTable = m_database.prepareStatement(query);
</del><ins>+        auto alterTable = m_database.prepareStatementSlow(makeString("ALTER TABLE ", table, " RENAME TO _", table));
</ins><span class="cx">         if (!alterTable || alterTable->step() != SQLITE_DONE) {
</span><span class="cx">             RELEASE_LOG_ERROR(Network, "%p - ResourceLoadStatisticsDatabaseStore::migrateDataToNewTablesIfNecessary failed to rename table, error message: %s", this, m_database.lastErrorMsg());
</span><span class="cx">             ASSERT_NOT_REACHED();
</span><span class="lines">@@ -569,8 +580,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     for (auto& table : expectedTableAndIndexQueries().keys()) {
</span><del>-        auto query = insertDistinctValuesInTableQuery(table);
-        auto migrateTableData = m_database.prepareStatement(query);
</del><ins>+        auto migrateTableData = insertDistinctValuesInTableStatement(m_database, table);
</ins><span class="cx">         if (!migrateTableData || migrateTableData->step() != SQLITE_DONE) {
</span><span class="cx">             RELEASE_LOG_ERROR(Network, "%p - ResourceLoadStatisticsDatabaseStore::migrateDataToNewTablesIfNecessary failed to migrate schema, error message: %s", this, m_database.lastErrorMsg());
</span><span class="cx">             ASSERT_NOT_REACHED();
</span><span class="lines">@@ -577,8 +587,7 @@
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        auto dropQuery = makeString("DROP TABLE _", table);
-        auto dropTableQuery = m_database.prepareStatement(dropQuery);
</del><ins>+        auto dropTableQuery = m_database.prepareStatementSlow(makeString("DROP TABLE _", table));
</ins><span class="cx">         if (!dropTableQuery || dropTableQuery->step() != SQLITE_DONE) {
</span><span class="cx">             RELEASE_LOG_ERROR(Network, "%p - ResourceLoadStatisticsDatabaseStore::migrateDataToNewTablesIfNecessary failed to drop temporary tables, error message: %s", this, m_database.lastErrorMsg());
</span><span class="cx">             ASSERT_NOT_REACHED();
</span><span class="lines">@@ -597,7 +606,7 @@
</span><span class="cx"> 
</span><span class="cx"> Vector<String> ResourceLoadStatisticsDatabaseStore::columnsForTable(const String& tableName)
</span><span class="cx"> {
</span><del>-    auto statement = m_database.prepareStatement(makeString("PRAGMA table_info(", tableName, ")"));
</del><ins>+    auto statement = m_database.prepareStatementSlow(makeString("PRAGMA table_info(", tableName, ")"));
</ins><span class="cx"> 
</span><span class="cx">     if (!statement) {
</span><span class="cx">         RELEASE_LOG_ERROR(Network, "%p - ResourceLoadStatisticsDatabaseStore::getColumnsFromTableInfoStatement Unable to prepare statement to fetch schema for table, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());
</span><span class="lines">@@ -622,7 +631,7 @@
</span><span class="cx">         if (existingColumns.contains(column))
</span><span class="cx">             continue;
</span><span class="cx">         
</span><del>-        auto statement = m_database.prepareStatement(makeString("ALTER TABLE ", tableName, " ADD COLUMN ", column));
</del><ins>+        auto statement = m_database.prepareStatementSlow(makeString("ALTER TABLE ", tableName, " ADD COLUMN ", column));
</ins><span class="cx">         if (!statement) {
</span><span class="cx">             RELEASE_LOG_ERROR(Network, "%p - ResourceLoadStatisticsDatabaseStore::addMissingColumnsToTable Unable to prepare statement to add missing columns to table, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());
</span><span class="cx">             ASSERT_NOT_REACHED();
</span><span class="lines">@@ -648,7 +657,7 @@
</span><span class="cx"> 
</span><span class="cx"> void ResourceLoadStatisticsDatabaseStore::renameColumnInTable(String&& tableName, ExistingColumnName&& existingColumnName, ExpectedColumnName&& expectedColumnName)
</span><span class="cx"> {
</span><del>-    auto statement = m_database.prepareStatement(makeString("ALTER TABLE ", tableName, " RENAME COLUMN ", existingColumnName, " TO ", expectedColumnName));
</del><ins>+    auto statement = m_database.prepareStatementSlow(makeString("ALTER TABLE ", tableName, " RENAME COLUMN ", existingColumnName, " TO ", expectedColumnName));
</ins><span class="cx">     if (!statement) {
</span><span class="cx">         RELEASE_LOG_ERROR(Network, "%p - ResourceLoadStatisticsDatabaseStore::addMissingColumnsToTable Unable to prepare statement to rename column in table, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());
</span><span class="cx">         ASSERT_NOT_REACHED();
</span><span class="lines">@@ -693,7 +702,7 @@
</span><span class="cx"> 
</span><span class="cx">     for (auto& table : *missingTables) {
</span><span class="cx">         auto createTableQuery = expectedTableAndIndexQueries().get(table).first;
</span><del>-        if (!m_database.executeCommand(createTableQuery))
</del><ins>+        if (!m_database.executeCommandSlow(createTableQuery))
</ins><span class="cx">             RELEASE_LOG_ERROR(Network, "%p - ResourceLoadStatisticsDatabaseStore::addMissingTables failed to execute, error message: %" PUBLIC_LOG_STRING, this, m_database.lastErrorMsg());
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -1040,7 +1049,7 @@
</span><span class="cx"> 
</span><span class="cx"> void ResourceLoadStatisticsDatabaseStore::insertDomainRelationshipList(const String& statement, const HashSet<RegistrableDomain>& domainList, unsigned domainID)
</span><span class="cx"> {
</span><del>-    auto insertRelationshipStatement = m_database.prepareStatement(makeString(statement, ensureAndMakeDomainList(domainList), " );"));
</del><ins>+    auto insertRelationshipStatement = m_database.prepareStatementSlow(makeString(statement, ensureAndMakeDomainList(domainList), " );"));
</ins><span class="cx">     
</span><span class="cx">     if (!insertRelationshipStatement
</span><span class="cx">         || insertRelationshipStatement->bindInt(1, domainID) != SQLITE_OK) {
</span><span class="lines">@@ -1181,9 +1190,9 @@
</span><span class="cx">         insertDomainRelationships(statistic);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static const StringView joinSubStatisticsForSorting()
</del><ins>+static ASCIILiteral joinSubStatisticsForSorting()
</ins><span class="cx"> {
</span><del>-    return "domainID,"
</del><ins>+    return "SELECT domainID,"
</ins><span class="cx">         "(countSubFrameUnderTopFrame + countSubResourceUnderTopFrame + countUniqueRedirectTo) as sum  "
</span><span class="cx">         "FROM ( "
</span><span class="cx">         "SELECT "
</span><span class="lines">@@ -1198,7 +1207,7 @@
</span><span class="cx">         "LEFT JOIN SubresourceUniqueRedirectsTo u ON o.domainID = u.subresourceDomainID "
</span><span class="cx">         "WHERE isPrevalent LIKE ? "
</span><span class="cx">         "and hadUserInteraction LIKE ? "
</span><del>-        "GROUP BY domainID) ORDER BY sum DESC ";
</del><ins>+        "GROUP BY domainID) ORDER BY sum DESC;"_s;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Vector<WebResourceLoadStatisticsStore::ThirdPartyDataForSpecificFirstParty> ResourceLoadStatisticsDatabaseStore::getThirdPartyDataForSpecificFirstPartyDomains(unsigned thirdPartyDomainID, const RegistrableDomain& thirdPartyDomain) const
</span><span class="lines">@@ -1230,7 +1239,7 @@
</span><span class="cx"> 
</span><span class="cx">     Vector<WebResourceLoadStatisticsStore::ThirdPartyData> thirdPartyDataList;
</span><span class="cx">     const auto prevalentDomainsBindParameter = thirdPartyCookieBlockingMode() == ThirdPartyCookieBlockingMode::All ? "%" : "1";
</span><del>-    auto sortedStatistics = m_database.prepareStatement(makeString("SELECT ", joinSubStatisticsForSorting()));
</del><ins>+    auto sortedStatistics = m_database.prepareStatement(joinSubStatisticsForSorting());
</ins><span class="cx">     if (!sortedStatistics
</span><span class="cx">         || sortedStatistics->bindText(1, prevalentDomainsBindParameter)
</span><span class="cx">         || sortedStatistics->bindText(2, "%") != SQLITE_OK) {
</span><span class="lines">@@ -1266,7 +1275,7 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!RunLoop::isMain());
</span><span class="cx"> 
</span><del>-    auto domainsToUpdateStatement = m_database.prepareStatement(makeString("UPDATE ObservedDomains SET dataRecordsRemoved = dataRecordsRemoved + 1 WHERE registrableDomain IN (", domainsToString(domains), ")"));
</del><ins>+    auto domainsToUpdateStatement = m_database.prepareStatementSlow(makeString("UPDATE ObservedDomains SET dataRecordsRemoved = dataRecordsRemoved + 1 WHERE registrableDomain IN (", domainsToString(domains), ")"));
</ins><span class="cx">     if (!domainsToUpdateStatement || domainsToUpdateStatement->step() != SQLITE_DONE) {
</span><span class="cx">         RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::incrementStatisticsForDomains failed, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());
</span><span class="cx">         ASSERT_NOT_REACHED();
</span><span class="lines">@@ -1352,7 +1361,7 @@
</span><span class="cx">             prevalentDueToRedirect.insert(topFrameRedirectStatement->getColumnInt(0));
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    auto markPrevalentStatement = m_database.prepareStatement(makeString("UPDATE ObservedDomains SET isPrevalent = 1 WHERE domainID IN (", buildList(WTF::IteratorRange<StdSet<unsigned>::iterator>(prevalentDueToRedirect.begin(), prevalentDueToRedirect.end())), ")"));
</del><ins>+    auto markPrevalentStatement = m_database.prepareStatementSlow(makeString("UPDATE ObservedDomains SET isPrevalent = 1 WHERE domainID IN (", buildList(WTF::IteratorRange<StdSet<unsigned>::iterator>(prevalentDueToRedirect.begin(), prevalentDueToRedirect.end())), ")"));
</ins><span class="cx">     if (!markPrevalentStatement || markPrevalentStatement->step() != SQLITE_DONE) {
</span><span class="cx">         RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::markAsPrevalentIfHasRedirectedToPrevalent failed to execute, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());
</span><span class="cx">         ASSERT_NOT_REACHED();
</span><span class="lines">@@ -1384,7 +1393,7 @@
</span><span class="cx"> 
</span><span class="cx">     auto domainIDsOfInterest = builder.toString();
</span><span class="cx"> 
</span><del>-    auto subresourceUnderTopFrameDomainsStatement = m_database.prepareStatement(makeString("SELECT subresourceDomainID, COUNT(topFrameDomainID) FROM SubresourceUnderTopFrameDomains WHERE subresourceDomainID IN (", domainIDsOfInterest, ") GROUP BY subresourceDomainID"));
</del><ins>+    auto subresourceUnderTopFrameDomainsStatement = m_database.prepareStatementSlow(makeString("SELECT subresourceDomainID, COUNT(topFrameDomainID) FROM SubresourceUnderTopFrameDomains WHERE subresourceDomainID IN (", domainIDsOfInterest, ") GROUP BY subresourceDomainID"));
</ins><span class="cx">     if (subresourceUnderTopFrameDomainsStatement) {
</span><span class="cx">         while (subresourceUnderTopFrameDomainsStatement->step() == SQLITE_ROW) {
</span><span class="cx">             unsigned domainID = static_cast<unsigned>(subresourceUnderTopFrameDomainsStatement->getColumnInt(0));
</span><span class="lines">@@ -1394,7 +1403,7 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    auto subresourceUniqueRedirectsToCountStatement = m_database.prepareStatement(makeString("SELECT subresourceDomainID, COUNT(toDomainID) FROM SubresourceUniqueRedirectsTo WHERE subresourceDomainID IN (", domainIDsOfInterest, ") GROUP BY subresourceDomainID"));
</del><ins>+    auto subresourceUniqueRedirectsToCountStatement = m_database.prepareStatementSlow(makeString("SELECT subresourceDomainID, COUNT(toDomainID) FROM SubresourceUniqueRedirectsTo WHERE subresourceDomainID IN (", domainIDsOfInterest, ") GROUP BY subresourceDomainID"));
</ins><span class="cx">     if (subresourceUniqueRedirectsToCountStatement) {
</span><span class="cx">         while (subresourceUniqueRedirectsToCountStatement->step() == SQLITE_ROW) {
</span><span class="cx">             unsigned domainID = static_cast<unsigned>(subresourceUniqueRedirectsToCountStatement->getColumnInt(0));
</span><span class="lines">@@ -1404,7 +1413,7 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    auto subframeUnderTopFrameDomainsCountStatement = m_database.prepareStatement(makeString("SELECT subframeDomainID, COUNT(topFrameDomainID) FROM SubframeUnderTopFrameDomains WHERE subframeDomainID IN (", domainIDsOfInterest, ") GROUP BY subframeDomainID"));
</del><ins>+    auto subframeUnderTopFrameDomainsCountStatement = m_database.prepareStatementSlow(makeString("SELECT subframeDomainID, COUNT(topFrameDomainID) FROM SubframeUnderTopFrameDomains WHERE subframeDomainID IN (", domainIDsOfInterest, ") GROUP BY subframeDomainID"));
</ins><span class="cx">     if (subframeUnderTopFrameDomainsCountStatement) {
</span><span class="cx">         while (subframeUnderTopFrameDomainsCountStatement->step() == SQLITE_ROW) {
</span><span class="cx">             unsigned domainID = static_cast<unsigned>(subframeUnderTopFrameDomainsCountStatement->getColumnInt(0));
</span><span class="lines">@@ -1414,7 +1423,7 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    auto topFrameUniqueRedirectsToCountStatement = m_database.prepareStatement(makeString("SELECT sourceDomainID, COUNT(toDomainID) FROM TopFrameUniqueRedirectsTo WHERE sourceDomainID IN (", domainIDsOfInterest, ") GROUP BY sourceDomainID"));
</del><ins>+    auto topFrameUniqueRedirectsToCountStatement = m_database.prepareStatementSlow(makeString("SELECT sourceDomainID, COUNT(toDomainID) FROM TopFrameUniqueRedirectsTo WHERE sourceDomainID IN (", domainIDsOfInterest, ") GROUP BY sourceDomainID"));
</ins><span class="cx">     if (topFrameUniqueRedirectsToCountStatement) {
</span><span class="cx">         while (topFrameUniqueRedirectsToCountStatement->step() == SQLITE_ROW) {
</span><span class="cx">             unsigned domainID = static_cast<unsigned>(topFrameUniqueRedirectsToCountStatement->getColumnInt(0));
</span><span class="lines">@@ -1644,7 +1653,7 @@
</span><span class="cx">             RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::grandfatherDataForDomains was not completed due to failed insert attempt", this);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    auto domainsToUpdateStatement = m_database.prepareStatement(makeString("UPDATE ObservedDomains SET grandfathered = 1 WHERE registrableDomain IN (", domainsToString(domains), ")"));
</del><ins>+    auto domainsToUpdateStatement = m_database.prepareStatementSlow(makeString("UPDATE ObservedDomains SET grandfathered = 1 WHERE registrableDomain IN (", domainsToString(domains), ")"));
</ins><span class="cx">     if (!domainsToUpdateStatement || domainsToUpdateStatement->step() != SQLITE_DONE) {
</span><span class="cx">         RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::grandfatherDataForDomains failed, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());
</span><span class="cx">         ASSERT_NOT_REACHED();
</span><span class="lines">@@ -1915,7 +1924,7 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!RunLoop::isMain());
</span><span class="cx"> 
</span><del>-    auto domainsToUpdateStatement = m_database.prepareStatement(makeString("UPDATE ObservedDomains SET isPrevalent = 1 WHERE domainID IN (", buildList(WTF::IteratorRange<StdSet<unsigned>::iterator>(domains.begin(), domains.end())), ")"));
</del><ins>+    auto domainsToUpdateStatement = m_database.prepareStatementSlow(makeString("UPDATE ObservedDomains SET isPrevalent = 1 WHERE domainID IN (", buildList(WTF::IteratorRange<StdSet<unsigned>::iterator>(domains.begin(), domains.end())), ")"));
</ins><span class="cx">     if (!domainsToUpdateStatement || domainsToUpdateStatement->step() != SQLITE_DONE) {
</span><span class="cx">         RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::setDomainsAsPrevalent failed, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());
</span><span class="cx">         ASSERT_NOT_REACHED();
</span><span class="lines">@@ -2466,7 +2475,7 @@
</span><span class="cx"> 
</span><span class="cx">     auto listToClear = buildList(WTF::IteratorRange<Vector<unsigned>::iterator>(domainIDsToClear.begin(), domainIDsToClear.end()));
</span><span class="cx"> 
</span><del>-    auto clearGrandfatheringStatement = m_database.prepareStatement(makeString("UPDATE ObservedDomains SET grandfathered = 0 WHERE domainID IN (", listToClear, ")"));
</del><ins>+    auto clearGrandfatheringStatement = m_database.prepareStatementSlow(makeString("UPDATE ObservedDomains SET grandfathered = 0 WHERE domainID IN (", listToClear, ")"));
</ins><span class="cx">     if (!clearGrandfatheringStatement)
</span><span class="cx">         return;
</span><span class="cx">     
</span><span class="lines">@@ -2623,7 +2632,7 @@
</span><span class="cx"> 
</span><span class="cx">     auto listToPrune = buildList(WTF::IteratorRange<Vector<unsigned>::iterator>(entriesToPrune.begin(), entriesToPrune.end()));
</span><span class="cx"> 
</span><del>-    auto pruneCommand = m_database.prepareStatement(makeString("DELETE from ObservedDomains WHERE domainID IN (", listToPrune, ")"));
</del><ins>+    auto pruneCommand = m_database.prepareStatementSlow(makeString("DELETE from ObservedDomains WHERE domainID IN (", listToPrune, ")"));
</ins><span class="cx">     if (!pruneCommand || pruneCommand->step() != SQLITE_DONE) {
</span><span class="cx">         RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::pruneStatisticsIfNeeded failed, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());
</span><span class="cx">         ASSERT_NOT_REACHED();
</span><span class="lines">@@ -2770,28 +2779,28 @@
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-String ResourceLoadStatisticsDatabaseStore::getSubStatisticStatement(const String& tableName) const
</del><ins>+ASCIILiteral ResourceLoadStatisticsDatabaseStore::getSubStatisticStatement(const String& tableName) const
</ins><span class="cx"> {
</span><span class="cx">     if (tableName == "StorageAccessUnderTopFrameDomains")
</span><del>-        return "SELECT topLevelDomainID from StorageAccessUnderTopFrameDomains WHERE domainID = ?";
</del><ins>+        return "SELECT topLevelDomainID from StorageAccessUnderTopFrameDomains WHERE domainID = ?"_s;
</ins><span class="cx">     if (tableName == "TopFrameUniqueRedirectsTo")
</span><del>-        return "SELECT toDomainID from TopFrameUniqueRedirectsTo WHERE sourceDomainID = ?";
</del><ins>+        return "SELECT toDomainID from TopFrameUniqueRedirectsTo WHERE sourceDomainID = ?"_s;
</ins><span class="cx">     if (tableName == "TopFrameUniqueRedirectsFrom")
</span><del>-        return "SELECT fromDomainID from TopFrameUniqueRedirectsFrom WHERE targetDomainID = ?";
</del><ins>+        return "SELECT fromDomainID from TopFrameUniqueRedirectsFrom WHERE targetDomainID = ?"_s;
</ins><span class="cx">     if (tableName == "TopFrameLinkDecorationsFrom")
</span><del>-        return "SELECT fromDomainID from TopFrameLinkDecorationsFrom WHERE toDomainID = ?";
</del><ins>+        return "SELECT fromDomainID from TopFrameLinkDecorationsFrom WHERE toDomainID = ?"_s;
</ins><span class="cx">     if (tableName == "TopFrameLoadedThirdPartyScripts")
</span><del>-        return "SELECT subresourceDomainID from TopFrameLoadedThirdPartyScripts WHERE topFrameDomainID = ?";
</del><ins>+        return "SELECT subresourceDomainID from TopFrameLoadedThirdPartyScripts WHERE topFrameDomainID = ?"_s;
</ins><span class="cx">     if (tableName == "SubframeUnderTopFrameDomains")
</span><del>-        return "SELECT topFrameDomainID from SubframeUnderTopFrameDomains WHERE subFrameDomainID = ?";
</del><ins>+        return "SELECT topFrameDomainID from SubframeUnderTopFrameDomains WHERE subFrameDomainID = ?"_s;
</ins><span class="cx">     if (tableName == "SubresourceUnderTopFrameDomains")
</span><del>-        return "SELECT topFrameDomainID from SubresourceUnderTopFrameDomains WHERE subresourceDomainID = ?";
</del><ins>+        return "SELECT topFrameDomainID from SubresourceUnderTopFrameDomains WHERE subresourceDomainID = ?"_s;
</ins><span class="cx">     if (tableName == "SubresourceUniqueRedirectsTo")
</span><del>-        return "SELECT toDomainID from SubresourceUniqueRedirectsTo WHERE subresourceDomainID = ?";
</del><ins>+        return "SELECT toDomainID from SubresourceUniqueRedirectsTo WHERE subresourceDomainID = ?"_s;
</ins><span class="cx">     if (tableName == "SubresourceUniqueRedirectsFrom")
</span><del>-        return "SELECT fromDomainID from SubresourceUniqueRedirectsFrom WHERE subresourceDomainID = ?";
</del><ins>+        return "SELECT fromDomainID from SubresourceUniqueRedirectsFrom WHERE subresourceDomainID = ?"_s;
</ins><span class="cx">     
</span><del>-    return emptyString();
</del><ins>+    return ""_s;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ResourceLoadStatisticsDatabaseStore::appendSubStatisticList(StringBuilder& builder, const String& tableName, const String& domain) const
</span><span class="lines">@@ -2798,7 +2807,7 @@
</span><span class="cx"> {
</span><span class="cx">     auto query = getSubStatisticStatement(tableName);
</span><span class="cx">     
</span><del>-    if (query.isEmpty())
</del><ins>+    if (!query.length())
</ins><span class="cx">         return;
</span><span class="cx">     
</span><span class="cx">     auto data = m_database.prepareStatement(query);
</span></span></pre></div>
<a id="trunkSourceWebKitNetworkProcessClassifierResourceLoadStatisticsDatabaseStoreh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h (277600 => 277601)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h      2021-05-17 19:09:02 UTC (rev 277600)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h 2021-05-17 19:26:06 UTC (rev 277601)
</span><span class="lines">@@ -181,7 +181,7 @@
</span><span class="cx">     Vector<WebResourceLoadStatisticsStore::ThirdPartyDataForSpecificFirstParty> getThirdPartyDataForSpecificFirstPartyDomains(unsigned, const RegistrableDomain&) const;
</span><span class="cx">     void openAndUpdateSchemaIfNecessary();
</span><span class="cx">     String getDomainStringFromDomainID(unsigned) const;
</span><del>-    String getSubStatisticStatement(const String&) const;
</del><ins>+    ASCIILiteral getSubStatisticStatement(const String&) const;
</ins><span class="cx">     void appendSubStatisticList(StringBuilder&, const String& tableName, const String& domain) const;
</span><span class="cx">     void mergeStatistic(const ResourceLoadStatistics&);
</span><span class="cx">     void merge(WebCore::SQLiteStatement*, const ResourceLoadStatistics&);
</span></span></pre></div>
<a id="trunkSourceWebKitNetworkProcessWebStorageLocalStorageDatabasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/NetworkProcess/WebStorage/LocalStorageDatabase.cpp (277600 => 277601)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/NetworkProcess/WebStorage/LocalStorageDatabase.cpp   2021-05-17 19:09:02 UTC (rev 277600)
+++ trunk/Source/WebKit/NetworkProcess/WebStorage/LocalStorageDatabase.cpp      2021-05-17 19:26:06 UTC (rev 277601)
</span><span class="lines">@@ -81,11 +81,11 @@
</span><span class="cx">     if (!migrateItemTableIfNeeded()) {
</span><span class="cx">         // We failed to migrate the item table. In order to avoid trying to migrate the table over and over,
</span><span class="cx">         // just delete it and start from scratch.
</span><del>-        if (!m_database.executeCommand("DROP TABLE ItemTable"))
</del><ins>+        if (!m_database.executeCommand("DROP TABLE ItemTable"_s))
</ins><span class="cx">             LOG_ERROR("Failed to delete table ItemTable for local storage");
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (!m_database.executeCommand("CREATE TABLE IF NOT EXISTS ItemTable (key TEXT UNIQUE ON CONFLICT REPLACE, value BLOB NOT NULL ON CONFLICT FAIL)")) {
</del><ins>+    if (!m_database.executeCommand("CREATE TABLE IF NOT EXISTS ItemTable (key TEXT UNIQUE ON CONFLICT REPLACE, value BLOB NOT NULL ON CONFLICT FAIL)"_s)) {
</ins><span class="cx">         LOG_ERROR("Failed to create table ItemTable for local storage");
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="lines">@@ -106,13 +106,13 @@
</span><span class="cx">         return true;
</span><span class="cx"> 
</span><span class="cx">     // Create a new table with the right type, copy all the data over to it and then replace the new table with the old table.
</span><del>-    static const char* commands[] = {
-        "DROP TABLE IF EXISTS ItemTable2",
-        "CREATE TABLE ItemTable2 (key TEXT UNIQUE ON CONFLICT REPLACE, value BLOB NOT NULL ON CONFLICT FAIL)",
-        "INSERT INTO ItemTable2 SELECT * from ItemTable",
-        "DROP TABLE ItemTable",
-        "ALTER TABLE ItemTable2 RENAME TO ItemTable",
-        0,
</del><ins>+    static const ASCIILiteral commands[] = {
+        "DROP TABLE IF EXISTS ItemTable2"_s,
+        "CREATE TABLE ItemTable2 (key TEXT UNIQUE ON CONFLICT REPLACE, value BLOB NOT NULL ON CONFLICT FAIL)"_s,
+        "INSERT INTO ItemTable2 SELECT * from ItemTable"_s,
+        "DROP TABLE ItemTable"_s,
+        "ALTER TABLE ItemTable2 RENAME TO ItemTable"_s,
+        ASCIILiteral::null(),
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     SQLiteTransaction transaction(m_database);
</span><span class="lines">@@ -122,7 +122,7 @@
</span><span class="cx">         if (m_database.executeCommand(commands[i]))
</span><span class="cx">             continue;
</span><span class="cx"> 
</span><del>-        LOG_ERROR("Failed to migrate table ItemTable for local storage when executing: %s", commands[i]);
</del><ins>+        LOG_ERROR("Failed to migrate table ItemTable for local storage when executing: %s", commands[i].characters());
</ins><span class="cx"> 
</span><span class="cx">         return false;
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessAPIglibIconDatabasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/API/glib/IconDatabase.cpp (277600 => 277601)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/API/glib/IconDatabase.cpp  2021-05-17 19:09:02 UTC (rev 277600)
+++ trunk/Source/WebKit/UIProcess/API/glib/IconDatabase.cpp     2021-05-17 19:26:06 UTC (rev 277601)
</span><span class="lines">@@ -124,42 +124,43 @@
</span><span class="cx"> 
</span><span class="cx">     m_db.clearAllTables();
</span><span class="cx"> 
</span><del>-    if (!m_db.executeCommand("CREATE TABLE PageURL (url TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE,iconID INTEGER NOT NULL ON CONFLICT FAIL);")) {
</del><ins>+    if (!m_db.executeCommand("CREATE TABLE PageURL (url TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE,iconID INTEGER NOT NULL ON CONFLICT FAIL);"_s)) {
</ins><span class="cx">         LOG_ERROR("Could not create PageURL table in database (%i) - %s", m_db.lastError(), m_db.lastErrorMsg());
</span><span class="cx">         m_db.close();
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><del>-    if (!m_db.executeCommand("CREATE INDEX PageURLIndex ON PageURL (url);")) {
</del><ins>+    if (!m_db.executeCommand("CREATE INDEX PageURLIndex ON PageURL (url);"_s)) {
</ins><span class="cx">         LOG_ERROR("Could not create PageURL index in database (%i) - %s", m_db.lastError(), m_db.lastErrorMsg());
</span><span class="cx">         m_db.close();
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><del>-    if (!m_db.executeCommand("CREATE TABLE IconInfo (iconID INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE ON CONFLICT REPLACE, url TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT FAIL, stamp INTEGER);")) {
</del><ins>+    if (!m_db.executeCommand("CREATE TABLE IconInfo (iconID INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE ON CONFLICT REPLACE, url TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT FAIL, stamp INTEGER);"_s)) {
</ins><span class="cx">         LOG_ERROR("Could not create IconInfo table in database (%i) - %s", m_db.lastError(), m_db.lastErrorMsg());
</span><span class="cx">         m_db.close();
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><del>-    if (!m_db.executeCommand("CREATE INDEX IconInfoIndex ON IconInfo (url, iconID);")) {
</del><ins>+    if (!m_db.executeCommand("CREATE INDEX IconInfoIndex ON IconInfo (url, iconID);"_s)) {
</ins><span class="cx">         LOG_ERROR("Could not create PageURL index in database (%i) - %s", m_db.lastError(), m_db.lastErrorMsg());
</span><span class="cx">         m_db.close();
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><del>-    if (!m_db.executeCommand("CREATE TABLE IconData (iconID INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE ON CONFLICT REPLACE, data BLOB);")) {
</del><ins>+    if (!m_db.executeCommand("CREATE TABLE IconData (iconID INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE ON CONFLICT REPLACE, data BLOB);"_s)) {
</ins><span class="cx">         LOG_ERROR("Could not create IconData table in database (%i) - %s", m_db.lastError(), m_db.lastErrorMsg());
</span><span class="cx">         m_db.close();
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><del>-    if (!m_db.executeCommand("CREATE INDEX IconDataIndex ON IconData (iconID);")) {
</del><ins>+    if (!m_db.executeCommand("CREATE INDEX IconDataIndex ON IconData (iconID);"_s)) {
</ins><span class="cx">         LOG_ERROR("Could not create PageURL index in database (%i) - %s", m_db.lastError(), m_db.lastErrorMsg());
</span><span class="cx">         m_db.close();
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><del>-    if (!m_db.executeCommand("CREATE TABLE IconDatabaseInfo (key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE,value TEXT NOT NULL ON CONFLICT FAIL);")) {
</del><ins>+    if (!m_db.executeCommand("CREATE TABLE IconDatabaseInfo (key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE,value TEXT NOT NULL ON CONFLICT FAIL);"_s)) {
</ins><span class="cx">         LOG_ERROR("Could not create IconDatabaseInfo table in database (%i) - %s", m_db.lastError(), m_db.lastErrorMsg());
</span><span class="cx">         m_db.close();
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><del>-    if (!m_db.executeCommand(String("INSERT INTO IconDatabaseInfo VALUES ('Version', ") + String::number(currentDatabaseVersion) + ");")) {
</del><ins>+    auto statement = m_db.prepareStatement("INSERT INTO IconDatabaseInfo VALUES ('Version', ?);"_s);
+    if (!statement || statement->bindInt(1, currentDatabaseVersion) != SQLITE_OK || !statement->executeCommand()) {
</ins><span class="cx">         LOG_ERROR("Could not insert icon database version into IconDatabaseInfo table (%i) - %s", m_db.lastError(), m_db.lastErrorMsg());
</span><span class="cx">         m_db.close();
</span><span class="cx">         return false;
</span><span class="lines">@@ -175,13 +176,17 @@
</span><span class="cx">     if (!m_db.isOpen())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    String importQuery = makeString("SELECT PageURL.url, IconInfo.url, IconInfo.stamp FROM PageURL INNER JOIN IconInfo ON PageURL.iconID=IconInfo.iconID WHERE IconInfo.stamp > ", floor((WallTime::now() - notUsedIconExpirationTime).secondsSinceEpoch().seconds()), ';');
-    auto query = m_db.prepareStatement(importQuery);
</del><ins>+    auto query = m_db.prepareStatement("SELECT PageURL.url, IconInfo.url, IconInfo.stamp FROM PageURL INNER JOIN IconInfo ON PageURL.iconID=IconInfo.iconID WHERE IconInfo.stamp > (?);"_s);
</ins><span class="cx">     if (!query) {
</span><span class="cx">         LOG_ERROR("Unable to prepare icon url import query");
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    if (query->bindInt64(1, floor((WallTime::now() - notUsedIconExpirationTime).secondsSinceEpoch().seconds())) != SQLITE_OK) {
+        LOG_ERROR("IconDatabase::populatePageURLToIconURLMap: failed to bind statement: %s", m_db.lastErrorMsg());
+        return;
+    }
+
</ins><span class="cx">     auto result = query->step();
</span><span class="cx">     LockHolder lockHolder(m_pageURLToIconURLMapLock);
</span><span class="cx">     while (result == SQLITE_ROW) {
</span></span></pre></div>
<a id="trunkSourceWebKitLegacyChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKitLegacy/ChangeLog (277600 => 277601)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKitLegacy/ChangeLog      2021-05-17 19:09:02 UTC (rev 277600)
+++ trunk/Source/WebKitLegacy/ChangeLog 2021-05-17 19:26:06 UTC (rev 277601)
</span><span class="lines">@@ -1,3 +1,20 @@
</span><ins>+2021-05-17  Chris Dumez  <cdumez@apple.com>
+
+        Avoid more String creations when preparing SQLite statements
+        https://bugs.webkit.org/show_bug.cgi?id=225855
+
+        Reviewed by Alex Christensen.
+
+        Avoid more String creations when preparing SQLite statements by using ASCIILiteral. Also rename the
+        SQLiteDatabase::prepareStatement() / SQLiteDatabase::executeCommand() overloads that take in a 
+        String to make sure they are not called by mistake.
+
+        * Storage/StorageAreaSync.cpp:
+        (WebKit::StorageAreaSync::openDatabase):
+        (WebKit::StorageAreaSync::migrateItemTableIfNeeded):
+        * Storage/StorageTracker.cpp:
+        (WebKit::StorageTracker::openTrackerDatabase):
+
</ins><span class="cx"> 2021-05-16  Chris Dumez  <cdumez@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Modernize / Optimize SQLiteStatement creation and preparation
</span></span></pre></div>
<a id="trunkSourceWebKitLegacyStorageStorageAreaSynccpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKitLegacy/Storage/StorageAreaSync.cpp (277600 => 277601)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKitLegacy/Storage/StorageAreaSync.cpp    2021-05-17 19:09:02 UTC (rev 277600)
+++ trunk/Source/WebKitLegacy/Storage/StorageAreaSync.cpp       2021-05-17 19:26:06 UTC (rev 277601)
</span><span class="lines">@@ -262,7 +262,7 @@
</span><span class="cx"> 
</span><span class="cx">     migrateItemTableIfNeeded();
</span><span class="cx"> 
</span><del>-    if (!m_database.executeCommand("CREATE TABLE IF NOT EXISTS ItemTable (key TEXT UNIQUE ON CONFLICT REPLACE, value BLOB NOT NULL ON CONFLICT FAIL)")) {
</del><ins>+    if (!m_database.executeCommand("CREATE TABLE IF NOT EXISTS ItemTable (key TEXT UNIQUE ON CONFLICT REPLACE, value BLOB NOT NULL ON CONFLICT FAIL)"_s)) {
</ins><span class="cx">         LOG_ERROR("Failed to create table ItemTable for local storage");
</span><span class="cx">         markImported();
</span><span class="cx">         m_databaseOpenFailed = true;
</span><span class="lines">@@ -285,13 +285,13 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // alter table for backward compliance, change the value type from TEXT to BLOB.
</span><del>-    static const char* commands[] = {
-        "DROP TABLE IF EXISTS ItemTable2",
-        "CREATE TABLE ItemTable2 (key TEXT UNIQUE ON CONFLICT REPLACE, value BLOB NOT NULL ON CONFLICT FAIL)",
-        "INSERT INTO ItemTable2 SELECT * from ItemTable",
-        "DROP TABLE ItemTable",
-        "ALTER TABLE ItemTable2 RENAME TO ItemTable",
-        0,
</del><ins>+    static const ASCIILiteral commands[] = {
+        "DROP TABLE IF EXISTS ItemTable2"_s,
+        "CREATE TABLE ItemTable2 (key TEXT UNIQUE ON CONFLICT REPLACE, value BLOB NOT NULL ON CONFLICT FAIL)"_s,
+        "INSERT INTO ItemTable2 SELECT * from ItemTable"_s,
+        "DROP TABLE ItemTable"_s,
+        "ALTER TABLE ItemTable2 RENAME TO ItemTable"_s,
+        ASCIILiteral::null(),
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     SQLiteTransaction transaction(m_database, false);
</span><span class="lines">@@ -298,7 +298,7 @@
</span><span class="cx">     transaction.begin();
</span><span class="cx">     for (size_t i = 0; commands[i]; ++i) {
</span><span class="cx">         if (!m_database.executeCommand(commands[i])) {
</span><del>-            LOG_ERROR("Failed to migrate table ItemTable for local storage when executing: %s", commands[i]);
</del><ins>+            LOG_ERROR("Failed to migrate table ItemTable for local storage when executing: %s", commands[i].characters());
</ins><span class="cx">             transaction.rollback();
</span><span class="cx"> 
</span><span class="cx">             // finally it will try to keep a backup of ItemTable for the future restoration.
</span><span class="lines">@@ -306,7 +306,7 @@
</span><span class="cx">             // than continually hitting this case and never being able to use the local storage.
</span><span class="cx">             // if this is ever hit, it's definitely a bug.
</span><span class="cx">             ASSERT_NOT_REACHED();
</span><del>-            if (!m_database.executeCommand("ALTER TABLE ItemTable RENAME TO Backup_ItemTable"))
</del><ins>+            if (!m_database.executeCommand("ALTER TABLE ItemTable RENAME TO Backup_ItemTable"_s))
</ins><span class="cx">                 LOG_ERROR("Failed to save ItemTable after migration job failed.");
</span><span class="cx"> 
</span><span class="cx">             return;
</span></span></pre></div>
<a id="trunkSourceWebKitLegacyStorageStorageTrackercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKitLegacy/Storage/StorageTracker.cpp (277600 => 277601)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKitLegacy/Storage/StorageTracker.cpp     2021-05-17 19:09:02 UTC (rev 277600)
+++ trunk/Source/WebKitLegacy/Storage/StorageTracker.cpp        2021-05-17 19:26:06 UTC (rev 277601)
</span><span class="lines">@@ -146,7 +146,7 @@
</span><span class="cx">     m_database.disableThreadingChecks();
</span><span class="cx">     
</span><span class="cx">     if (!m_database.tableExists("Origins")) {
</span><del>-        if (!m_database.executeCommand("CREATE TABLE Origins (origin TEXT UNIQUE ON CONFLICT REPLACE, path TEXT);"))
</del><ins>+        if (!m_database.executeCommand("CREATE TABLE Origins (origin TEXT UNIQUE ON CONFLICT REPLACE, path TEXT);"_s))
</ins><span class="cx">             LOG_ERROR("Failed to create Origins table.");
</span><span class="cx">     }
</span><span class="cx"> }
</span></span></pre>
</div>
</div>

</body>
</html>