Changeset 261892 in webkit


Ignore:
Timestamp:
May 19, 2020 3:55:49 PM (4 years ago)
Author:
Kate Cheney
Message:

ITP database should finalize all prepared statements before closing
https://bugs.webkit.org/show_bug.cgi?id=211929
<rdar://problem/63246945>

Reviewed by John Wilander.

No new tests, behavior confirmed by existing tests.

Convert all SQLite statement objects to be unique pointers to better
manage the lifetime of each statement object. Only initialize and
prepare an object when it is needed instead of preparing all objects
at once. Set each statement to null before closing the database
because ~SQLiteStatement() will finalize the statement.

This patch removes all reset() commands now that we initialize
each statement using SQLiteStatementAutoResetScope.

  • NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp:

(WebKit::ResourceLoadStatisticsDatabaseStore::ResourceLoadStatisticsDatabaseStore):
(WebKit::ResourceLoadStatisticsDatabaseStore::close):
(WebKit::ResourceLoadStatisticsDatabaseStore::getScopedStatement const):
Function to initialize and prepare a statement.

(WebKit::ResourceLoadStatisticsDatabaseStore::insertDomainRelationship):
This function is not used and can be deleted.

(WebKit::ResourceLoadStatisticsDatabaseStore::checkForMissingTablesInSchema):
(WebKit::ResourceLoadStatisticsDatabaseStore::isMigrationNecessary):
(WebKit::ResourceLoadStatisticsDatabaseStore::openAndUpdateSchemaIfNecessary):
(WebKit::ResourceLoadStatisticsDatabaseStore::isEmpty const):
(WebKit::ResourceLoadStatisticsDatabaseStore::destroyStatements):
(WebKit::ResourceLoadStatisticsDatabaseStore::insertObservedDomain):
(WebKit::ResourceLoadStatisticsDatabaseStore::relationshipExists const):
(WebKit::ResourceLoadStatisticsDatabaseStore::domainID const):
(WebKit::ResourceLoadStatisticsDatabaseStore::merge):
(WebKit::ResourceLoadStatisticsDatabaseStore::mergeStatistic):
(WebKit::CompletionHandler<void):
(WebKit::ResourceLoadStatisticsDatabaseStore::prepareStatements): Deleted.

  • NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h:

Updated all statement variables to end with "Statement" to follow the
established pattern.

  • NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp:

(WebKit::WebResourceLoadStatisticsStore::flushAndDestroyPersistentStore):

Location:
trunk/Source/WebKit
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r261884 r261892  
     12020-05-19  Kate Cheney  <katherine_cheney@apple.com>
     2
     3        ITP database should finalize all prepared statements before closing
     4        https://bugs.webkit.org/show_bug.cgi?id=211929
     5        <rdar://problem/63246945>
     6
     7        Reviewed by John Wilander.
     8
     9        No new tests, behavior confirmed by existing tests.
     10
     11        Convert all SQLite statement objects to be unique pointers to better
     12        manage the lifetime of each statement object. Only initialize and
     13        prepare an object when it is needed instead of preparing all objects
     14        at once. Set each statement to null before closing the database
     15        because ~SQLiteStatement() will finalize the statement.
     16
     17        This patch removes all reset() commands now that we initialize
     18        each statement using SQLiteStatementAutoResetScope.
     19
     20        * NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp:
     21        (WebKit::ResourceLoadStatisticsDatabaseStore::ResourceLoadStatisticsDatabaseStore):
     22        (WebKit::ResourceLoadStatisticsDatabaseStore::close):
     23        (WebKit::ResourceLoadStatisticsDatabaseStore::getScopedStatement const):
     24        Function to initialize and prepare a statement.
     25
     26        (WebKit::ResourceLoadStatisticsDatabaseStore::insertDomainRelationship):
     27        This function is not used and can be deleted.
     28
     29        (WebKit::ResourceLoadStatisticsDatabaseStore::checkForMissingTablesInSchema):
     30        (WebKit::ResourceLoadStatisticsDatabaseStore::isMigrationNecessary):
     31        (WebKit::ResourceLoadStatisticsDatabaseStore::openAndUpdateSchemaIfNecessary):
     32        (WebKit::ResourceLoadStatisticsDatabaseStore::isEmpty const):
     33        (WebKit::ResourceLoadStatisticsDatabaseStore::destroyStatements):
     34        (WebKit::ResourceLoadStatisticsDatabaseStore::insertObservedDomain):
     35        (WebKit::ResourceLoadStatisticsDatabaseStore::relationshipExists const):
     36        (WebKit::ResourceLoadStatisticsDatabaseStore::domainID const):
     37        (WebKit::ResourceLoadStatisticsDatabaseStore::merge):
     38        (WebKit::ResourceLoadStatisticsDatabaseStore::mergeStatistic):
     39        (WebKit::CompletionHandler<void):
     40        (WebKit::ResourceLoadStatisticsDatabaseStore::prepareStatements): Deleted.
     41        * NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h:
     42        Updated all statement variables to end with "Statement" to follow the
     43        established pattern.
     44
     45        * NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp:
     46        (WebKit::WebResourceLoadStatisticsStore::flushAndDestroyPersistentStore):
     47
    1482020-05-19  Per Arne Vollan  <pvollan@apple.com>
    249
  • trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp

    r261242 r261892  
    276276    : ResourceLoadStatisticsStore(store, workQueue, shouldIncludeLocalhost)
    277277    , m_storageDirectoryPath(storageDirectoryPath + "/observations.db")
    278     , m_observedDomainCount(m_database, observedDomainCountQuery)
    279     , m_insertObservedDomainStatement(m_database, insertObservedDomainQuery)
    280     , m_insertTopLevelDomainStatement(m_database, insertTopLevelDomainQuery)
    281     , m_domainIDFromStringStatement(m_database, domainIDFromStringQuery)
    282     , m_topFrameLinkDecorationsFromExists(m_database, topFrameLinkDecorationsFromExistsQuery)
    283     , m_topFrameLoadedThirdPartyScriptsExists(m_database, topFrameLoadedThirdPartyScriptsExistsQuery)
    284     , m_subframeUnderTopFrameDomainExists(m_database, subframeUnderTopFrameDomainExistsQuery)
    285     , m_subresourceUnderTopFrameDomainExists(m_database, subresourceUnderTopFrameDomainExistsQuery)
    286     , m_subresourceUniqueRedirectsToExists(m_database, subresourceUniqueRedirectsToExistsQuery)
    287     , m_mostRecentUserInteractionStatement(m_database, mostRecentUserInteractionQuery)
    288     , m_updateLastSeenStatement(m_database, updateLastSeenQuery)
    289     , m_updateDataRecordsRemovedStatement(m_database, updateDataRecordsRemovedQuery)
    290     , m_updatePrevalentResourceStatement(m_database, updatePrevalentResourceQuery)
    291     , m_isPrevalentResourceStatement(m_database, isPrevalentResourceQuery)
    292     , m_updateVeryPrevalentResourceStatement(m_database, updateVeryPrevalentResourceQuery)
    293     , m_isVeryPrevalentResourceStatement(m_database, isVeryPrevalentResourceQuery)
    294     , m_clearPrevalentResourceStatement(m_database, clearPrevalentResourceQuery)
    295     , m_hadUserInteractionStatement(m_database, hadUserInteractionQuery)
    296     , m_updateGrandfatheredStatement(m_database, updateGrandfatheredQuery)
    297     , m_updateIsScheduledForAllButCookieDataRemovalStatement(m_database, updateIsScheduledForAllButCookieDataRemovalQuery)
    298     , m_isGrandfatheredStatement(m_database, isGrandfatheredQuery)
    299     , m_findExpiredUserInteractionStatement(m_database, findExpiredUserInteractionQuery)
    300     , m_countPrevalentResourcesStatement(m_database, countPrevalentResourcesQuery)
    301     , m_countPrevalentResourcesWithUserInteractionStatement(m_database, countPrevalentResourcesWithUserInteractionQuery)
    302     , m_countPrevalentResourcesWithoutUserInteractionStatement(m_database, countPrevalentResourcesWithoutUserInteractionQuery)
    303     , m_getResourceDataByDomainNameStatement(m_database, getResourceDataByDomainNameQuery)
    304     , m_getAllDomainsStatement(m_database, getAllDomainsQuery)
    305     , m_domainStringFromDomainIDStatement(m_database, domainStringFromDomainIDQuery)
    306     , m_getAllSubStatisticsStatement(m_database, getAllSubStatisticsUnderDomainQuery)
    307     , m_storageAccessExistsStatement(m_database, storageAccessExistsQuery)
    308     , m_getMostRecentlyUpdatedTimestampStatement(m_database, getMostRecentlyUpdatedTimestampQuery)
    309     , m_linkDecorationExistsStatement(m_database, linkDecorationExistsQuery)
    310     , m_scriptLoadExistsStatement(m_database, scriptLoadExistsQuery)
    311     , m_subFrameExistsStatement(m_database, subFrameExistsQuery)
    312     , m_subResourceExistsStatement(m_database, subResourceExistsQuery)
    313     , m_uniqueRedirectExistsStatement(m_database, uniqueRedirectExistsQuery)
    314     , m_observedDomainsExistsStatement(m_database, observedDomainsExistsQuery)
    315     , m_removeAllDataStatement(m_database, removeAllDataQuery)
    316278    , m_sessionID(sessionID)
    317279{
     
    326288    if (!m_database.turnOnIncrementalAutoVacuum())
    327289        RELEASE_LOG_ERROR(Network, "%p - ResourceLoadStatisticsDatabaseStore::turnOnIncrementalAutoVacuum failed, error message: %" PUBLIC_LOG_STRING, this, m_database.lastErrorMsg());
    328 
    329     if (!prepareStatements()) {
    330         RELEASE_LOG_ERROR(Network, "%p - ResourceLoadStatisticsDatabaseStore::prepareStatements failed, error message: %" PUBLIC_LOG_STRING ", database path: %" PUBLIC_LOG_STRING, this, m_database.lastErrorMsg(), m_storageDirectoryPath.utf8().data());
    331         ASSERT_NOT_REACHED();
    332         return;
    333     }
    334290
    335291    workQueue.dispatchAfter(5_s, [weakThis = makeWeakPtr(*this)] {
     
    337293            weakThis->calculateAndSubmitTelemetry();
    338294    });
     295}
     296
     297ResourceLoadStatisticsDatabaseStore::~ResourceLoadStatisticsDatabaseStore()
     298{
     299    close();
     300}
     301
     302void ResourceLoadStatisticsDatabaseStore::close()
     303{
     304    destroyStatements();
     305    if (m_database.isOpen())
     306        m_database.close();
    339307}
    340308
     
    367335}
    368336
    369 static void resetStatement(SQLiteStatement& statement)
    370 {
    371     int resetResult = statement.reset();
    372     ASSERT_UNUSED(resetResult, resetResult == SQLITE_OK);
    373 }
    374 
    375337Optional<Vector<String>> ResourceLoadStatisticsDatabaseStore::checkForMissingTablesInSchema()
    376338{
     
    391353            missingTables.append(String(table));
    392354        }
    393         resetStatement(statement);
    394355    }
    395356    if (missingTables.isEmpty())
     
    422383    if (statement.step() != SQLITE_ROW) {
    423384        LOG_ERROR("Error executing statement to fetch schema.");
    424         m_database.close();
     385        close();
    425386        FileSystem::deleteFile(m_storageDirectoryPath);
    426387        openITPDatabase();
     
    520481        if (statement.step() != SQLITE_ROW) {
    521482            LOG_ERROR("Error executing statement to fetch schema for the Observed Domains table.");
    522             m_database.close();
     483            close();
    523484            FileSystem::deleteFile(m_storageDirectoryPath);
    524485            openITPDatabase();
     
    534495    // FIXME: Migrate old ObservedDomains data to new table schema.
    535496    if (currentSchema != ObservedDomainsTableSchemaV1() && currentSchema != ObservedDomainsTableSchemaV1Alternate()) {
    536         m_database.close();
     497        close();
    537498        FileSystem::deleteFile(m_storageDirectoryPath);
    538499        openITPDatabase();
     
    541502}
    542503
     504SQLiteStatementAutoResetScope ResourceLoadStatisticsDatabaseStore::scopedStatement(std::unique_ptr<WebCore::SQLiteStatement>& statement, const String& query, const String& logString) const
     505{
     506    if (!statement) {
     507        statement = makeUnique<WebCore::SQLiteStatement>(m_database, query);
     508        ASSERT(m_database.isOpen());
     509        if (statement->prepare() != SQLITE_OK) {
     510            RELEASE_LOG_ERROR(Network, "%p - ResourceLoadStatisticsDatabaseStore::%s failed to prepare statement, error message: %" PUBLIC_LOG_STRING, this, logString.ascii().data(), m_database.lastErrorMsg());
     511            ASSERT_NOT_REACHED();
     512        }
     513    }
     514    return SQLiteStatementAutoResetScope { statement.get() };
     515}
     516
    543517bool ResourceLoadStatisticsDatabaseStore::isEmpty() const
    544518{
    545519    ASSERT(!RunLoop::isMain());
    546520   
    547     bool result = false;
    548     if (m_observedDomainCount.step() == SQLITE_ROW)
    549         result = !m_observedDomainCount.getColumnInt(0);
    550    
    551     int resetResult = m_observedDomainCount.reset();
    552     ASSERT_UNUSED(resetResult, resetResult == SQLITE_OK);
    553    
    554     return result;
     521    auto scopedStatement = this->scopedStatement(m_observedDomainCountStatement, observedDomainCountQuery, "isEmpty"_s);
     522    if (!scopedStatement
     523        || scopedStatement->step() != SQLITE_ROW) {
     524        RELEASE_LOG_ERROR(Network, "%p - ResourceLoadStatisticsDatabaseStore::isEmpty failed to step, error message: %{private}s", this, m_database.lastErrorMsg());
     525        ASSERT_NOT_REACHED();
     526        return false;
     527    }
     528    return !scopedStatement->getColumnInt(0);
    555529}
    556530
     
    643617}
    644618
    645 bool ResourceLoadStatisticsDatabaseStore::prepareStatements()
    646 {
    647     ASSERT(!RunLoop::isMain());
    648        
    649     if (m_observedDomainCount.prepare() != SQLITE_OK
    650         || m_insertObservedDomainStatement.prepare() != SQLITE_OK
    651         || m_insertTopLevelDomainStatement.prepare() != SQLITE_OK
    652         || m_domainIDFromStringStatement.prepare() != SQLITE_OK
    653         || m_subframeUnderTopFrameDomainExists.prepare() != SQLITE_OK
    654         || m_subresourceUnderTopFrameDomainExists.prepare() != SQLITE_OK
    655         || m_subresourceUniqueRedirectsToExists.prepare() != SQLITE_OK
    656         || m_updateLastSeenStatement.prepare() != SQLITE_OK
    657         || m_updateDataRecordsRemovedStatement.prepare() != SQLITE_OK
    658         || m_mostRecentUserInteractionStatement.prepare() != SQLITE_OK
    659         || m_updatePrevalentResourceStatement.prepare() != SQLITE_OK
    660         || m_isPrevalentResourceStatement.prepare() != SQLITE_OK
    661         || m_updateVeryPrevalentResourceStatement.prepare() != SQLITE_OK
    662         || m_isVeryPrevalentResourceStatement.prepare() != SQLITE_OK
    663         || m_clearPrevalentResourceStatement.prepare() != SQLITE_OK
    664         || m_hadUserInteractionStatement.prepare() != SQLITE_OK
    665         || m_updateGrandfatheredStatement.prepare() != SQLITE_OK
    666         || m_updateIsScheduledForAllButCookieDataRemovalStatement.prepare() != SQLITE_OK
    667         || m_isGrandfatheredStatement.prepare() != SQLITE_OK
    668         || m_findExpiredUserInteractionStatement.prepare() != SQLITE_OK
    669         || m_topFrameLinkDecorationsFromExists.prepare() != SQLITE_OK
    670         || m_topFrameLoadedThirdPartyScriptsExists.prepare() != SQLITE_OK
    671         || m_countPrevalentResourcesStatement.prepare() != SQLITE_OK
    672         || m_countPrevalentResourcesWithUserInteractionStatement.prepare() != SQLITE_OK
    673         || m_countPrevalentResourcesWithoutUserInteractionStatement.prepare() != SQLITE_OK
    674         || m_getResourceDataByDomainNameStatement.prepare() != SQLITE_OK
    675         || m_getAllDomainsStatement.prepare() != SQLITE_OK
    676         || m_domainStringFromDomainIDStatement.prepare() != SQLITE_OK
    677         || m_getAllSubStatisticsStatement.prepare() != SQLITE_OK
    678         || m_storageAccessExistsStatement.prepare() != SQLITE_OK
    679         || m_getMostRecentlyUpdatedTimestampStatement.prepare() != SQLITE_OK
    680         || m_linkDecorationExistsStatement.prepare() != SQLITE_OK
    681         || m_scriptLoadExistsStatement.prepare() != SQLITE_OK
    682         || m_subFrameExistsStatement.prepare() != SQLITE_OK
    683         || m_subResourceExistsStatement.prepare() != SQLITE_OK
    684         || m_uniqueRedirectExistsStatement.prepare() != SQLITE_OK
    685         || m_observedDomainsExistsStatement.prepare() != SQLITE_OK
    686         || m_removeAllDataStatement.prepare() != SQLITE_OK
    687         ) {
    688         RELEASE_LOG_ERROR(Network, "%p - ResourceLoadStatisticsDatabaseStore::prepareStatements failed to prepare, error message: %" PUBLIC_LOG_STRING, this, m_database.lastErrorMsg());
    689         ASSERT_NOT_REACHED();
    690         return false;
    691     }
    692 
    693     return true;
     619void ResourceLoadStatisticsDatabaseStore::destroyStatements()
     620{
     621    ASSERT(!RunLoop::isMain());
     622
     623    m_observedDomainCountStatement = nullptr;
     624    m_insertObservedDomainStatement = nullptr;
     625    m_insertTopLevelDomainStatement = nullptr;
     626    m_domainIDFromStringStatement = nullptr;
     627    m_subframeUnderTopFrameDomainExistsStatement = nullptr;
     628    m_subresourceUnderTopFrameDomainExistsStatement = nullptr;
     629    m_subresourceUniqueRedirectsToExistsStatement = nullptr;
     630    m_updateLastSeenStatement = nullptr;
     631    m_updateDataRecordsRemovedStatement = nullptr;
     632    m_mostRecentUserInteractionStatement = nullptr;
     633    m_updatePrevalentResourceStatement = nullptr;
     634    m_isPrevalentResourceStatement = nullptr;
     635    m_updateVeryPrevalentResourceStatement = nullptr;
     636    m_isVeryPrevalentResourceStatement = nullptr;
     637    m_clearPrevalentResourceStatement = nullptr;
     638    m_hadUserInteractionStatement = nullptr;
     639    m_updateGrandfatheredStatement = nullptr;
     640    m_updateIsScheduledForAllButCookieDataRemovalStatement = nullptr;
     641    m_isGrandfatheredStatement = nullptr;
     642    m_findExpiredUserInteractionStatement = nullptr;
     643    m_topFrameLinkDecorationsFromExistsStatement = nullptr;
     644    m_topFrameLoadedThirdPartyScriptsExistsStatement = nullptr;
     645    m_countPrevalentResourcesStatement = nullptr;
     646    m_countPrevalentResourcesWithUserInteractionStatement = nullptr;
     647    m_countPrevalentResourcesWithoutUserInteractionStatement = nullptr;
     648    m_getResourceDataByDomainNameStatement = nullptr;
     649    m_getAllDomainsStatement = nullptr;
     650    m_domainStringFromDomainIDStatement = nullptr;
     651    m_getAllSubStatisticsStatement = nullptr;
     652    m_storageAccessExistsStatement = nullptr;
     653    m_getMostRecentlyUpdatedTimestampStatement = nullptr;
     654    m_linkDecorationExistsStatement = nullptr;
     655    m_scriptLoadExistsStatement = nullptr;
     656    m_subFrameExistsStatement = nullptr;
     657    m_subResourceExistsStatement = nullptr;
     658    m_uniqueRedirectExistsStatement = nullptr;
     659    m_observedDomainsExistsStatement = nullptr;
     660    m_removeAllDataStatement = nullptr;
    694661}
    695662
     
    703670        return false;
    704671    }
    705 
    706     if (m_insertObservedDomainStatement.bindText(RegistrableDomainIndex, loadStatistics.registrableDomain.string()) != SQLITE_OK
    707         || m_insertObservedDomainStatement.bindDouble(LastSeenIndex, loadStatistics.lastSeen.secondsSinceEpoch().value()) != SQLITE_OK
    708         || m_insertObservedDomainStatement.bindInt(HadUserInteractionIndex, loadStatistics.hadUserInteraction) != SQLITE_OK
    709         || m_insertObservedDomainStatement.bindDouble(MostRecentUserInteractionTimeIndex, loadStatistics.mostRecentUserInteractionTime.secondsSinceEpoch().value()) != SQLITE_OK
    710         || m_insertObservedDomainStatement.bindInt(GrandfatheredIndex, loadStatistics.grandfathered) != SQLITE_OK
    711         || m_insertObservedDomainStatement.bindInt(IsPrevalentIndex, loadStatistics.isPrevalentResource) != SQLITE_OK
    712         || m_insertObservedDomainStatement.bindInt(IsVeryPrevalentIndex, loadStatistics.isVeryPrevalentResource) != SQLITE_OK
    713         || m_insertObservedDomainStatement.bindInt(DataRecordsRemovedIndex, loadStatistics.dataRecordsRemoved) != SQLITE_OK
    714         || m_insertObservedDomainStatement.bindInt(TimesAccessedAsFirstPartyDueToUserInteractionIndex, loadStatistics.timesAccessedAsFirstPartyDueToUserInteraction) != SQLITE_OK
    715         || m_insertObservedDomainStatement.bindInt(TimesAccessedAsFirstPartyDueToStorageAccessAPIIndex, loadStatistics.timesAccessedAsFirstPartyDueToStorageAccessAPI) != SQLITE_OK
    716         || m_insertObservedDomainStatement.bindInt(IsScheduledForAllButCookieDataRemovalIndex, loadStatistics.gotLinkDecorationFromPrevalentResource) != SQLITE_OK) {
     672    auto scopedStatement = this->scopedStatement(m_insertObservedDomainStatement, insertObservedDomainQuery, "insertObservedDomain"_s);
     673    if (!scopedStatement
     674        || scopedStatement->bindText(RegistrableDomainIndex, loadStatistics.registrableDomain.string()) != SQLITE_OK
     675        || scopedStatement->bindDouble(LastSeenIndex, loadStatistics.lastSeen.secondsSinceEpoch().value()) != SQLITE_OK
     676        || scopedStatement->bindInt(HadUserInteractionIndex, loadStatistics.hadUserInteraction) != SQLITE_OK
     677        || scopedStatement->bindDouble(MostRecentUserInteractionTimeIndex, loadStatistics.mostRecentUserInteractionTime.secondsSinceEpoch().value()) != SQLITE_OK
     678        || scopedStatement->bindInt(GrandfatheredIndex, loadStatistics.grandfathered) != SQLITE_OK
     679        || scopedStatement->bindInt(IsPrevalentIndex, loadStatistics.isPrevalentResource) != SQLITE_OK
     680        || scopedStatement->bindInt(IsVeryPrevalentIndex, loadStatistics.isVeryPrevalentResource) != SQLITE_OK
     681        || scopedStatement->bindInt(DataRecordsRemovedIndex, loadStatistics.dataRecordsRemoved) != SQLITE_OK
     682        || scopedStatement->bindInt(TimesAccessedAsFirstPartyDueToUserInteractionIndex, loadStatistics.timesAccessedAsFirstPartyDueToUserInteraction) != SQLITE_OK
     683        || scopedStatement->bindInt(TimesAccessedAsFirstPartyDueToStorageAccessAPIIndex, loadStatistics.timesAccessedAsFirstPartyDueToStorageAccessAPI) != SQLITE_OK
     684        || scopedStatement->bindInt(IsScheduledForAllButCookieDataRemovalIndex, loadStatistics.gotLinkDecorationFromPrevalentResource) != SQLITE_OK) {
    717685        RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::insertObservedDomain failed to bind, error message: %{private}s", this, m_database.lastErrorMsg());
    718686        ASSERT_NOT_REACHED();
     
    720688    }
    721689
    722     if (m_insertObservedDomainStatement.step() != SQLITE_DONE) {
     690    if (scopedStatement->step() != SQLITE_DONE) {
    723691        RELEASE_LOG_ERROR(Network, "%p - ResourceLoadStatisticsDatabaseStore::insertObservedDomain failed to commit, error message: %{private}s", this, m_database.lastErrorMsg());
    724692        ASSERT_NOT_REACHED();
    725693        return false;
    726694    }
    727 
    728     int resetResult = m_insertObservedDomainStatement.reset();
    729     ASSERT_UNUSED(resetResult, resetResult == SQLITE_OK);
    730 
    731695    return true;
    732696}
    733697
    734 bool ResourceLoadStatisticsDatabaseStore::relationshipExists(WebCore::SQLiteStatement& statement, Optional<unsigned> firstDomainID, const RegistrableDomain& secondDomain) const
     698bool ResourceLoadStatisticsDatabaseStore::relationshipExists(SQLiteStatementAutoResetScope& statement, Optional<unsigned> firstDomainID, const RegistrableDomain& secondDomain) const
    735699{
    736700    if (!firstDomainID)
     
    739703    ASSERT(!RunLoop::isMain());
    740704
    741     if (statement.bindInt(1, *firstDomainID) != SQLITE_OK
    742         || statement.bindText(2, secondDomain.string()) != SQLITE_OK
    743         || statement.step() != SQLITE_ROW) {
     705    if (!statement
     706        || statement->bindInt(1, *firstDomainID) != SQLITE_OK
     707        || statement->bindText(2, secondDomain.string()) != SQLITE_OK
     708        || statement->step() != SQLITE_ROW) {
    744709        RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::relationshipExists failed to bind, error message: %{private}s", this, m_database.lastErrorMsg());
    745710        ASSERT_NOT_REACHED();
    746711        return false;
    747712    }
    748     bool relationshipExists = !!statement.getColumnInt(0);
    749 
    750     int resetResult = statement.reset();
    751     ASSERT_UNUSED(resetResult, resetResult == SQLITE_OK);
    752    
    753     return relationshipExists;
    754 }
    755 
    756 bool ResourceLoadStatisticsDatabaseStore::insertDomainRelationship(WebCore::SQLiteStatement& statement, unsigned domainID, const RegistrableDomain& topFrame)
    757 {
    758     ASSERT(!RunLoop::isMain());
    759 
    760     if (statement.bindInt(1, domainID) != SQLITE_OK
    761         || statement.bindText(2, topFrame.string()) != SQLITE_OK
    762         || statement.step() != SQLITE_DONE) {
    763         RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::m_insertDomainRelationshipStatement failed to bind, error message: %{private}s", this, m_database.lastErrorMsg());
    764         ASSERT_NOT_REACHED();
    765         return false;
    766     }
    767 
    768     int resetResult = statement.reset();
    769     ASSERT_UNUSED(resetResult, resetResult == SQLITE_OK);
    770    
    771     return true;
     713    return !!statement->getColumnInt(0);
    772714}
    773715
     
    776718    ASSERT(!RunLoop::isMain());
    777719
    778     unsigned domainID = 0;
    779 
    780     if (m_domainIDFromStringStatement.bindText(1, domain.string()) != SQLITE_OK) {
     720    auto scopedStatement = this->scopedStatement(m_domainIDFromStringStatement, domainIDFromStringQuery, "domainID"_s);
     721    if (!scopedStatement
     722        || scopedStatement->bindText(1, domain.string()) != SQLITE_OK) {
    781723        RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::domainIDFromString failed, error message: %{private}s", this, m_database.lastErrorMsg());
    782724        return WTF::nullopt;
    783725    }
    784726   
    785     if (m_domainIDFromStringStatement.step() != SQLITE_ROW) {
    786         int resetResult = m_domainIDFromStringStatement.reset();
    787         ASSERT_UNUSED(resetResult, resetResult == SQLITE_OK);
     727    if (scopedStatement->step() != SQLITE_ROW)
    788728        return WTF::nullopt;
    789     }
    790 
    791     domainID = m_domainIDFromStringStatement.getColumnInt(0);
    792 
    793     int resetResult = m_domainIDFromStringStatement.reset();
    794     ASSERT_UNUSED(resetResult, resetResult == SQLITE_OK);
    795    
    796     return domainID;
     729
     730    return scopedStatement->getColumnInt(0);
    797731}
    798732
     
    885819}
    886820
    887 void ResourceLoadStatisticsDatabaseStore::merge(WebCore::SQLiteStatement& current, const ResourceLoadStatistics& other)
    888 {
    889     ASSERT(!RunLoop::isMain());
    890 
    891     auto currentRegistrableDomain = current.getColumnText(RegistrableDomainIndex);
    892     auto currentLastSeen = current.getColumnDouble(LastSeenIndex);
    893     auto currentMostRecentUserInteraction = current.getColumnDouble(MostRecentUserInteractionTimeIndex);
    894     bool currentGrandfathered = current.getColumnInt(GrandfatheredIndex);
    895     bool currentIsPrevalent = current.getColumnInt(IsPrevalentIndex);
    896     bool currentIsVeryPrevalent = current.getColumnInt(IsVeryPrevalentIndex);
    897     unsigned currentDataRecordsRemoved = current.getColumnInt(DataRecordsRemovedIndex);
    898     bool currentIsScheduledForAllButCookieDataRemoval = current.getColumnInt(IsScheduledForAllButCookieDataRemovalIndex);
     821void ResourceLoadStatisticsDatabaseStore::merge(WebCore::SQLiteStatement* current, const ResourceLoadStatistics& other)
     822{
     823    ASSERT(!RunLoop::isMain());
     824
     825    auto currentRegistrableDomain = current->getColumnText(RegistrableDomainIndex);
     826    auto currentLastSeen = current->getColumnDouble(LastSeenIndex);
     827    auto currentMostRecentUserInteraction = current->getColumnDouble(MostRecentUserInteractionTimeIndex);
     828    bool currentGrandfathered = current->getColumnInt(GrandfatheredIndex);
     829    bool currentIsPrevalent = current->getColumnInt(IsPrevalentIndex);
     830    bool currentIsVeryPrevalent = current->getColumnInt(IsVeryPrevalentIndex);
     831    unsigned currentDataRecordsRemoved = current->getColumnInt(DataRecordsRemovedIndex);
     832    bool currentIsScheduledForAllButCookieDataRemoval = current->getColumnInt(IsScheduledForAllButCookieDataRemovalIndex);
    899833
    900834    ASSERT(currentRegistrableDomain == other.registrableDomain.string());
     
    926860    ASSERT(!RunLoop::isMain());
    927861
    928     if (m_getResourceDataByDomainNameStatement.bindText(1, statistic.registrableDomain.string()) != SQLITE_OK
    929         || m_getResourceDataByDomainNameStatement.step() != SQLITE_ROW) {
     862    auto scopedStatement = this->scopedStatement(m_getResourceDataByDomainNameStatement, getResourceDataByDomainNameQuery, "mergeStatistic"_s);
     863    if (!scopedStatement
     864        || scopedStatement->bindText(1, statistic.registrableDomain.string()) != SQLITE_OK
     865        || scopedStatement->step() != SQLITE_ROW) {
    930866        RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::mergeStatistic. Statement failed to bind or domain was not found, error message: %{private}s", this, m_database.lastErrorMsg());
    931867        ASSERT_NOT_REACHED();
     
    933869    }
    934870
    935     merge(m_getResourceDataByDomainNameStatement, statistic);
    936     resetStatement(m_getResourceDataByDomainNameStatement);
     871    merge(scopedStatement.get(), statistic);
    937872}
    938873
     
    988923Vector<WebResourceLoadStatisticsStore::ThirdPartyDataForSpecificFirstParty> ResourceLoadStatisticsDatabaseStore::getThirdPartyDataForSpecificFirstPartyDomains(unsigned thirdPartyDomainID, const RegistrableDomain& thirdPartyDomain) const
    989924{
    990     if (m_getAllSubStatisticsStatement.bindInt(1, thirdPartyDomainID) != SQLITE_OK
    991         || m_getAllSubStatisticsStatement.bindInt(2, thirdPartyDomainID) != SQLITE_OK
    992         || m_getAllSubStatisticsStatement.bindInt(3, thirdPartyDomainID) != SQLITE_OK) {
     925    auto scopedStatement = this->scopedStatement(m_getAllSubStatisticsStatement, getAllSubStatisticsUnderDomainQuery, "getThirdPartyDataForSpecificFirstPartyDomains"_s);
     926    if (!scopedStatement
     927        || scopedStatement->bindInt(1, thirdPartyDomainID) != SQLITE_OK
     928        || scopedStatement->bindInt(2, thirdPartyDomainID) != SQLITE_OK
     929        || scopedStatement->bindInt(3, thirdPartyDomainID) != SQLITE_OK) {
    993930        RELEASE_LOG_ERROR(Network, "ResourceLoadStatisticsDatabaseStore::getThirdPartyDataForSpecificFirstPartyDomain, error message: %" PUBLIC_LOG_STRING, m_database.lastErrorMsg());
    994931        ASSERT_NOT_REACHED();
    995932    }
    996933    Vector<WebResourceLoadStatisticsStore::ThirdPartyDataForSpecificFirstParty> thirdPartyDataForSpecificFirstPartyDomains;
    997     while (m_getAllSubStatisticsStatement.step() == SQLITE_ROW) {
    998         RegistrableDomain firstPartyDomain = RegistrableDomain::uncheckedCreateFromRegistrableDomainString(getDomainStringFromDomainID(m_getAllSubStatisticsStatement.getColumnInt(0)));
     934    while (scopedStatement->step() == SQLITE_ROW) {
     935        RegistrableDomain firstPartyDomain = RegistrableDomain::uncheckedCreateFromRegistrableDomainString(getDomainStringFromDomainID(m_getAllSubStatisticsStatement->getColumnInt(0)));
    999936        thirdPartyDataForSpecificFirstPartyDomains.appendIfNotContains(WebResourceLoadStatisticsStore::ThirdPartyDataForSpecificFirstParty { firstPartyDomain, hasStorageAccess(firstPartyDomain, thirdPartyDomain), getMostRecentlyUpdatedTimestamp(thirdPartyDomain, firstPartyDomain) });
    1000937    }
    1001     resetStatement(m_getAllSubStatisticsStatement);
    1002938    return thirdPartyDataForSpecificFirstPartyDomains;
    1003939}
     
    11211057unsigned ResourceLoadStatisticsDatabaseStore::getNumberOfPrevalentResources() const
    11221058{
    1123     auto stepValue = m_countPrevalentResourcesStatement.step();
     1059    auto scopedStatement = this->scopedStatement(m_countPrevalentResourcesStatement, countPrevalentResourcesQuery, "getNumberOfPrevalentResources"_s);
     1060    if (!scopedStatement)
     1061        return 0;
     1062   
     1063    auto stepValue = scopedStatement->step();
    11241064    if (stepValue != SQLITE_ROW && stepValue != SQLITE_DONE) {
    11251065        RELEASE_LOG_ERROR(Network, "ResourceLoadStatisticsDatabaseStore::getNumberOfPrevalentResources failed to step, error message: %" PUBLIC_LOG_STRING, m_database.lastErrorMsg());
     
    11281068    }
    11291069    if (stepValue == SQLITE_ROW) {
    1130         unsigned prevalentResourceCount = m_countPrevalentResourcesStatement.getColumnInt(0);
    1131         if (prevalentResourceCount >= minimumPrevalentResourcesForTelemetry) {
    1132             resetStatement(m_countPrevalentResourcesStatement);
     1070        unsigned prevalentResourceCount = scopedStatement->getColumnInt(0);
     1071        if (prevalentResourceCount >= minimumPrevalentResourcesForTelemetry)
    11331072            return prevalentResourceCount;
    1134         }
    1135     }
    1136     resetStatement(m_countPrevalentResourcesStatement);
     1073    }
    11371074    return 0;
    11381075}
     
    11401077unsigned ResourceLoadStatisticsDatabaseStore::getNumberOfPrevalentResourcesWithUI() const
    11411078{
    1142     if (m_countPrevalentResourcesWithUserInteractionStatement.step() == SQLITE_ROW) {
    1143         int count = m_countPrevalentResourcesWithUserInteractionStatement.getColumnInt(0);
    1144         resetStatement(m_countPrevalentResourcesWithUserInteractionStatement);
     1079    auto scopedStatement = this->scopedStatement(m_countPrevalentResourcesWithUserInteractionStatement, countPrevalentResourcesWithUserInteractionQuery, "getNumberOfPrevalentResourcesWithUI"_s);
     1080    if (scopedStatement && scopedStatement->step() == SQLITE_ROW) {
     1081        int count = scopedStatement->getColumnInt(0);
    11451082        return count;
    11461083    }
    1147     resetStatement(m_countPrevalentResourcesWithUserInteractionStatement);
    11481084    return 0;
    11491085}
     
    12591195unsigned ResourceLoadStatisticsDatabaseStore::getNumberOfPrevalentResourcesWithoutUI() const
    12601196{
    1261     if (m_countPrevalentResourcesWithoutUserInteractionStatement.step() == SQLITE_ROW) {
    1262         int count = m_countPrevalentResourcesWithoutUserInteractionStatement.getColumnInt(0);
    1263         resetStatement(m_countPrevalentResourcesWithoutUserInteractionStatement);
     1197    auto scopedStatement = this->scopedStatement(m_countPrevalentResourcesWithoutUserInteractionStatement, countPrevalentResourcesWithoutUserInteractionQuery, "getNumberOfPrevalentResourcesWithoutUI"_s);
     1198    if (scopedStatement && scopedStatement->step() == SQLITE_ROW) {
     1199        int count = m_countPrevalentResourcesWithoutUserInteractionStatement->getColumnInt(0);
    12641200        return count;
    12651201    }
    1266     resetStatement(m_countPrevalentResourcesWithoutUserInteractionStatement);
    12671202    return 0;
    12681203}
     
    15201455bool ResourceLoadStatisticsDatabaseStore::hasStorageAccess(const TopFrameDomain& topFrameDomain, const SubFrameDomain& subFrameDomain) const
    15211456{
    1522     return relationshipExists(m_storageAccessExistsStatement, domainID(subFrameDomain), topFrameDomain);
     1457    auto scopedStatement = this->scopedStatement(m_storageAccessExistsStatement, storageAccessExistsQuery, "hasStorageAccess"_s);
     1458    return relationshipExists(scopedStatement, domainID(subFrameDomain), topFrameDomain);
    15231459}
    15241460
     
    18421778{
    18431779    ASSERT(!RunLoop::isMain());
    1844 
    1845     if (m_mostRecentUserInteractionStatement.bindInt(1, hadUserInteraction) != SQLITE_OK
    1846         || m_mostRecentUserInteractionStatement.bindDouble(2, mostRecentInteraction.secondsSinceEpoch().value()) != SQLITE_OK
    1847         || m_mostRecentUserInteractionStatement.bindText(3, domain.string()) != SQLITE_OK
    1848         || m_mostRecentUserInteractionStatement.step() != SQLITE_DONE) {
     1780   
     1781    auto scopedStatement = this->scopedStatement(m_mostRecentUserInteractionStatement, mostRecentUserInteractionQuery, "setUserInteraction"_s);
     1782    if (!scopedStatement
     1783        || scopedStatement->bindInt(1, hadUserInteraction) != SQLITE_OK
     1784        || scopedStatement->bindDouble(2, mostRecentInteraction.secondsSinceEpoch().value()) != SQLITE_OK
     1785        || scopedStatement->bindText(3, domain.string()) != SQLITE_OK
     1786        || scopedStatement->step() != SQLITE_DONE) {
    18491787        RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::setUserInteraction, error message: %{private}s", this, m_database.lastErrorMsg());
    18501788        ASSERT_NOT_REACHED();
    18511789        return;
    18521790    }
    1853 
    1854     int resetResult = m_mostRecentUserInteractionStatement.reset();
    1855     ASSERT_UNUSED(resetResult, resetResult == SQLITE_OK);
    18561791}
    18571792
     
    19021837{
    19031838    ASSERT(!RunLoop::isMain());
    1904 
    1905     if (m_hadUserInteractionStatement.bindText(1, domain.string()) != SQLITE_OK
    1906         || m_hadUserInteractionStatement.step() != SQLITE_ROW) {
     1839   
     1840    auto scopedStatement = this->scopedStatement(m_hadUserInteractionStatement, hadUserInteractionQuery, "hasHadUserInteraction"_s);
     1841    if (!scopedStatement
     1842        || scopedStatement->bindText(1, domain.string()) != SQLITE_OK
     1843        || scopedStatement->step() != SQLITE_ROW) {
    19071844        RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::m_hadUserInteractionStatement failed, error message: %{private}s", this, m_database.lastErrorMsg());
    1908 
    1909         int resetResult = m_hadUserInteractionStatement.reset();
    1910         ASSERT_UNUSED(resetResult, resetResult == SQLITE_OK);
    1911         return false;
    1912     }
    1913 
    1914     bool hadUserInteraction = !!m_hadUserInteractionStatement.getColumnInt(0);
    1915     if (!hadUserInteraction) {
    1916         int resetResult = m_hadUserInteractionStatement.reset();
    1917         ASSERT_UNUSED(resetResult, resetResult == SQLITE_OK);
    1918         return false;
    1919     }
    1920    
    1921     WallTime mostRecentUserInteractionTime = WallTime::fromRawSeconds(m_hadUserInteractionStatement.getColumnDouble(1));
     1845        return false;
     1846    }
     1847
     1848    bool hadUserInteraction = !!scopedStatement->getColumnInt(0);
     1849    if (!hadUserInteraction)
     1850        return false;
     1851   
     1852    WallTime mostRecentUserInteractionTime = WallTime::fromRawSeconds(scopedStatement->getColumnDouble(1));
    19221853
    19231854    if (hasStatisticsExpired(mostRecentUserInteractionTime, operatingDatesWindow)) {
     
    19281859        hadUserInteraction = false;
    19291860    }
    1930    
    1931     int resetResult = m_hadUserInteractionStatement.reset();
    1932     ASSERT_UNUSED(resetResult, resetResult == SQLITE_OK);
    1933 
    19341861    return hadUserInteraction;
    19351862}
     
    19411868        return;
    19421869
    1943     if (m_updatePrevalentResourceStatement.bindInt(1, 1) != SQLITE_OK
    1944         || m_updatePrevalentResourceStatement.bindText(2, domain.string()) != SQLITE_OK
    1945         || m_updatePrevalentResourceStatement.step() != SQLITE_DONE) {
     1870    auto scopedUpdatePrevalentResourceStatement = this->scopedStatement(m_updatePrevalentResourceStatement, updatePrevalentResourceQuery, "setPrevalentResource"_s);
     1871    if (!scopedUpdatePrevalentResourceStatement
     1872        || scopedUpdatePrevalentResourceStatement->bindInt(1, 1) != SQLITE_OK
     1873        || scopedUpdatePrevalentResourceStatement->bindText(2, domain.string()) != SQLITE_OK
     1874        || scopedUpdatePrevalentResourceStatement->step() != SQLITE_DONE) {
    19461875        RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::m_updatePrevalentResourceStatement failed, error message: %{private}s", this, m_database.lastErrorMsg());
    19471876        ASSERT_NOT_REACHED();
    19481877        return;
    19491878    }
    1950    
    1951     int resetResult = m_updatePrevalentResourceStatement.reset();
    1952     ASSERT_UNUSED(resetResult, resetResult == SQLITE_OK);
    1953 
     1879
     1880    auto scopedUpdateVeryPrevalentResourceStatement = this->scopedStatement(m_updateVeryPrevalentResourceStatement, updateVeryPrevalentResourceQuery, "setPrevalentResource updateVeryPrevalentResource"_s);
    19541881    if (newPrevalence == ResourceLoadPrevalence::VeryHigh) {
    1955         if (m_updateVeryPrevalentResourceStatement.bindInt(1, 1) != SQLITE_OK
    1956             || m_updateVeryPrevalentResourceStatement.bindText(2, domain.string()) != SQLITE_OK
    1957             || m_updateVeryPrevalentResourceStatement.step() != SQLITE_DONE) {
     1882        if (!scopedUpdateVeryPrevalentResourceStatement
     1883            || scopedUpdateVeryPrevalentResourceStatement->bindInt(1, 1) != SQLITE_OK
     1884            || scopedUpdateVeryPrevalentResourceStatement->bindText(2, domain.string()) != SQLITE_OK
     1885            || scopedUpdateVeryPrevalentResourceStatement->step() != SQLITE_DONE) {
    19581886            RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::m_updateVeryPrevalentResourceStatement failed, error message: %{private}s", this, m_database.lastErrorMsg());
    19591887            ASSERT_NOT_REACHED();
    19601888            return;
    19611889        }
    1962 
    1963         int resetResult = m_updateVeryPrevalentResourceStatement.reset();
    1964         ASSERT_UNUSED(resetResult, resetResult == SQLITE_OK);
    19651890    }
    19661891
     
    19931918    }
    19941919
     1920    auto scopedStatement = this->scopedStatement(m_getAllDomainsStatement, getAllDomainsQuery, "dumpResourceLoadStatistics"_s);
     1921    if (!scopedStatement)
     1922        return;
     1923   
    19951924    Vector<String> domains;
    1996     while (m_getAllDomainsStatement.step() == SQLITE_ROW)
    1997         domains.append(m_getAllDomainsStatement.getColumnText(0));
     1925    while (scopedStatement->step() == SQLITE_ROW)
     1926        domains.append(scopedStatement->getColumnText(0));
    19981927    std::sort(domains.begin(), domains.end(), WTF::codePointCompareLessThan);
    19991928
     
    20111940        }
    20121941    }
    2013     resetStatement(m_getAllDomainsStatement);
    20141942    completionHandler(result.toString());
    20151943}
    20161944
    2017 bool ResourceLoadStatisticsDatabaseStore::predicateValueForDomain(WebCore::SQLiteStatement& predicateStatement, const RegistrableDomain& domain) const
    2018 {
    2019     ASSERT(!RunLoop::isMain());
    2020    
    2021     if (predicateStatement.bindText(1, domain.string()) != SQLITE_OK
    2022         || predicateStatement.step() != SQLITE_ROW) {
    2023 
    2024         int resetResult = predicateStatement.reset();
    2025         ASSERT_UNUSED(resetResult, resetResult == SQLITE_OK);
    2026 
     1945bool ResourceLoadStatisticsDatabaseStore::predicateValueForDomain(SQLiteStatementAutoResetScope& predicateStatement, const RegistrableDomain& domain) const
     1946{
     1947    ASSERT(!RunLoop::isMain());
     1948
     1949    if (!predicateStatement
     1950        || predicateStatement->bindText(1, domain.string()) != SQLITE_OK
     1951        || predicateStatement->step() != SQLITE_ROW) {
    20271952        RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::predicateValueForDomain failed to bind, error message: %{private}s", this, m_database.lastErrorMsg());
    20281953        return false;
    20291954    }
    2030 
    2031     bool result = !!predicateStatement.getColumnInt(0);
    2032     int resetResult = predicateStatement.reset();
    2033     ASSERT_UNUSED(resetResult, resetResult == SQLITE_OK);
    2034     return result;
     1955    return !!predicateStatement->getColumnInt(0);
    20351956}
    20361957
     
    20421963        return false;
    20431964
    2044     return predicateValueForDomain(m_isPrevalentResourceStatement, domain);
     1965    auto scopedStatement = this->scopedStatement(m_isPrevalentResourceStatement, isPrevalentResourceQuery, "isPrevalentResource"_s);
     1966    return predicateValueForDomain(scopedStatement, domain);
    20451967}
    20461968
     
    20521974        return false;
    20531975
    2054     return predicateValueForDomain(m_isVeryPrevalentResourceStatement, domain);
     1976    auto scopedStatement = this->scopedStatement(m_isVeryPrevalentResourceStatement, isVeryPrevalentResourceQuery, "isVeryPrevalentResource"_s);
     1977    return predicateValueForDomain(scopedStatement, domain);
    20551978}
    20561979
     
    20591982    ASSERT(!RunLoop::isMain());
    20601983
    2061     return relationshipExists(m_subresourceUnderTopFrameDomainExists, domainID(subresourceDomain), topFrameDomain);
     1984    auto scopedStatement = this->scopedStatement(m_subresourceUnderTopFrameDomainExistsStatement, subresourceUnderTopFrameDomainExistsQuery, "isRegisteredAsSubresourceUnder"_s);
     1985    return relationshipExists(scopedStatement, domainID(subresourceDomain), topFrameDomain);
    20621986}
    20631987
     
    20651989{
    20661990    ASSERT(!RunLoop::isMain());
    2067 
    2068     return relationshipExists(m_subframeUnderTopFrameDomainExists, domainID(subFrameDomain), topFrameDomain);
     1991   
     1992    auto scopedStatement = this->scopedStatement(m_subframeUnderTopFrameDomainExistsStatement, subframeUnderTopFrameDomainExistsQuery, "isRegisteredAsSubFrameUnder"_s);
     1993    return relationshipExists(scopedStatement, domainID(subFrameDomain), topFrameDomain);
    20691994}
    20701995
     
    20731998    ASSERT(!RunLoop::isMain());
    20741999
    2075     return relationshipExists(m_subresourceUniqueRedirectsToExists, domainID(redirectedFromDomain), redirectedToDomain);
     2000    auto scopedStatement = this->scopedStatement(m_subresourceUniqueRedirectsToExistsStatement, subresourceUniqueRedirectsToExistsQuery, "isRegisteredAsRedirectingTo"_s);
     2001    return relationshipExists(scopedStatement, domainID(redirectedFromDomain), redirectedToDomain);
    20762002}
    20772003
     
    20852011        return;
    20862012    }
    2087     if (m_clearPrevalentResourceStatement.bindText(1, domain.string()) != SQLITE_OK
    2088         || m_clearPrevalentResourceStatement.step() != SQLITE_DONE) {
     2013   
     2014    auto scopedStatement = this->scopedStatement(m_clearPrevalentResourceStatement, clearPrevalentResourceQuery, "clearPrevalentResource"_s);
     2015   
     2016    if (!scopedStatement
     2017        || scopedStatement->bindText(1, domain.string()) != SQLITE_OK
     2018        || scopedStatement->step() != SQLITE_DONE) {
    20892019        RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::clearPrevalentResource, error message: %{private}s", this, m_database.lastErrorMsg());
    20902020        ASSERT_NOT_REACHED();
    20912021        return;
    20922022    }
    2093    
    2094     int resetResult = m_clearPrevalentResourceStatement.reset();
    2095     ASSERT_UNUSED(resetResult, resetResult == SQLITE_OK);
    20962023}
    20972024
     
    21052032        return;
    21062033    }
    2107     if (m_updateGrandfatheredStatement.bindInt(1, value) != SQLITE_OK
    2108         || m_updateGrandfatheredStatement.bindText(2, domain.string()) != SQLITE_OK
    2109         || m_updateGrandfatheredStatement.step() != SQLITE_DONE) {
     2034   
     2035    auto scopedStatement = this->scopedStatement(m_updateGrandfatheredStatement, updateGrandfatheredQuery, "setGrandfathered"_s);
     2036    if (!scopedStatement
     2037        || scopedStatement->bindInt(1, value) != SQLITE_OK
     2038        || scopedStatement->bindText(2, domain.string()) != SQLITE_OK
     2039        || scopedStatement->step() != SQLITE_DONE) {
    21102040        RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::setGrandfathered failed to bind, error message: %{private}s", this, m_database.lastErrorMsg());
    21112041        ASSERT_NOT_REACHED();
    2112         return;
    2113     }
    2114    
    2115     int resetResult = m_updateGrandfatheredStatement.reset();
    2116     ASSERT_UNUSED(resetResult, resetResult == SQLITE_OK);
     2042    }
    21172043}
    21182044
     
    21262052        return;
    21272053    }
    2128     if (m_updateIsScheduledForAllButCookieDataRemovalStatement.bindInt(1, value) != SQLITE_OK
    2129         || m_updateIsScheduledForAllButCookieDataRemovalStatement.bindText(2, domain.string()) != SQLITE_OK
    2130         || m_updateIsScheduledForAllButCookieDataRemovalStatement.step() != SQLITE_DONE) {
     2054   
     2055    auto scopedStatement = this->scopedStatement(m_updateIsScheduledForAllButCookieDataRemovalStatement, updateIsScheduledForAllButCookieDataRemovalQuery, "setIsScheduledForAllButCookieDataRemoval"_s);
     2056    if (!scopedStatement
     2057        || scopedStatement->bindInt(1, value) != SQLITE_OK
     2058        || scopedStatement->bindText(2, domain.string()) != SQLITE_OK
     2059        || scopedStatement->step() != SQLITE_DONE) {
    21312060        RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::setIsScheduledForAllButCookieDataRemoval failed to bind, error message: %{private}s", this, m_database.lastErrorMsg());
    21322061        ASSERT_NOT_REACHED();
    2133         return;
    2134     }
    2135 
    2136     resetStatement(m_updateIsScheduledForAllButCookieDataRemovalStatement);
    2137 }
     2062    }
     2063}
     2064
    21382065Seconds ResourceLoadStatisticsDatabaseStore::getMostRecentlyUpdatedTimestamp(const RegistrableDomain& subDomain, const TopFrameDomain& topFrameDomain) const
    21392066{
     
    21452072    if (!subFrameDomainID || !topFrameDomainID)
    21462073        return Seconds { ResourceLoadStatistics::NoExistingTimestamp };
    2147 
    2148     if (m_getMostRecentlyUpdatedTimestampStatement.bindInt(1, *subFrameDomainID) != SQLITE_OK
    2149         || m_getMostRecentlyUpdatedTimestampStatement.bindInt(2, *topFrameDomainID) != SQLITE_OK
    2150         || m_getMostRecentlyUpdatedTimestampStatement.bindInt(3, *subFrameDomainID) != SQLITE_OK
    2151         || m_getMostRecentlyUpdatedTimestampStatement.bindInt(4, *topFrameDomainID) != SQLITE_OK
    2152         || m_getMostRecentlyUpdatedTimestampStatement.bindInt(5, *subFrameDomainID) != SQLITE_OK
    2153         || m_getMostRecentlyUpdatedTimestampStatement.bindInt(6, *topFrameDomainID) != SQLITE_OK
    2154         || m_getMostRecentlyUpdatedTimestampStatement.bindInt(7, *subFrameDomainID) != SQLITE_OK
    2155         || m_getMostRecentlyUpdatedTimestampStatement.bindInt(8, *topFrameDomainID) != SQLITE_OK) {
     2074   
     2075    auto scopedStatement = this->scopedStatement(m_getMostRecentlyUpdatedTimestampStatement, getMostRecentlyUpdatedTimestampQuery, "getMostRecentlyUpdatedTimestamp"_s);
     2076    if (!scopedStatement
     2077        || scopedStatement->bindInt(1, *subFrameDomainID) != SQLITE_OK
     2078        || scopedStatement->bindInt(2, *topFrameDomainID) != SQLITE_OK
     2079        || scopedStatement->bindInt(3, *subFrameDomainID) != SQLITE_OK
     2080        || scopedStatement->bindInt(4, *topFrameDomainID) != SQLITE_OK
     2081        || scopedStatement->bindInt(5, *subFrameDomainID) != SQLITE_OK
     2082        || scopedStatement->bindInt(6, *topFrameDomainID) != SQLITE_OK
     2083        || scopedStatement->bindInt(7, *subFrameDomainID) != SQLITE_OK
     2084        || scopedStatement->bindInt(8, *topFrameDomainID) != SQLITE_OK) {
    21562085        RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::getMostRecentlyUpdatedTimestamp failed to bind, error message: %{private}s", this, m_database.lastErrorMsg());
    21572086        ASSERT_NOT_REACHED();
    21582087        return Seconds { ResourceLoadStatistics::NoExistingTimestamp  };
    21592088    }
    2160     if (m_getMostRecentlyUpdatedTimestampStatement.step() != SQLITE_ROW) {
    2161         resetStatement(m_getMostRecentlyUpdatedTimestampStatement);
     2089    if (scopedStatement->step() != SQLITE_ROW)
    21622090        return Seconds { ResourceLoadStatistics::NoExistingTimestamp  };
    2163     }
    2164     double mostRecentlyUpdatedTimestamp = m_getMostRecentlyUpdatedTimestampStatement.getColumnDouble(0);
    2165     resetStatement(m_getMostRecentlyUpdatedTimestampStatement);
    2166     return Seconds { mostRecentlyUpdatedTimestamp };
     2091
     2092    return Seconds { scopedStatement->getColumnDouble(0) };
    21672093}
    21682094
     
    21712097    ASSERT(!RunLoop::isMain());
    21722098
    2173     return predicateValueForDomain(m_isGrandfatheredStatement, domain);
     2099    auto scopedStatement = this->scopedStatement(m_isGrandfatheredStatement, isGrandfatheredQuery, "isGrandfathered"_s);
     2100    return predicateValueForDomain(scopedStatement, domain);
    21742101}
    21752102
     
    22562183{
    22572184    ASSERT(!RunLoop::isMain());
    2258 
    2259     if (m_domainIDFromStringStatement.bindText(1, domain.string()) != SQLITE_OK) {
     2185   
     2186    auto scopedStatement = this->scopedStatement(m_domainIDFromStringStatement, domainIDFromStringQuery, "ensureResourceStatisticsForRegistrableDomain"_s);
     2187    if (!scopedStatement
     2188        || scopedStatement->bindText(1, domain.string()) != SQLITE_OK) {
    22602189        RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::ensureResourceStatisticsForRegistrableDomain failed, error message: %{private}s", this, m_database.lastErrorMsg());
    22612190        ASSERT_NOT_REACHED();
     
    22632192    }
    22642193   
    2265     if (m_domainIDFromStringStatement.step() == SQLITE_ROW) {
    2266         unsigned domainID = m_domainIDFromStringStatement.getColumnInt(0);
    2267 
    2268         int resetResult = m_domainIDFromStringStatement.reset();
    2269         ASSERT_UNUSED(resetResult, resetResult == SQLITE_OK);
     2194    if (scopedStatement->step() == SQLITE_ROW) {
     2195        unsigned domainID = scopedStatement->getColumnInt(0);
    22702196        return { AddedRecord::No, domainID };
    22712197    }
    2272 
    2273     int resetResult = m_domainIDFromStringStatement.reset();
    2274     ASSERT_UNUSED(resetResult, resetResult == SQLITE_OK);
    22752198
    22762199    ResourceLoadStatistics newObservation(domain);
     
    23022225    if (!domainIDToRemove)
    23032226        return;
    2304 
    2305     if (m_removeAllDataStatement.bindInt(1, *domainIDToRemove) != SQLITE_OK
    2306         || m_removeAllDataStatement.step() != SQLITE_DONE) {
     2227   
     2228    auto scopedStatement = this->scopedStatement(m_removeAllDataStatement, removeAllDataQuery, "removeDataForDomain"_s);
     2229    if (!scopedStatement
     2230        || scopedStatement->bindInt(1, *domainIDToRemove) != SQLITE_OK
     2231        || scopedStatement->step() != SQLITE_DONE) {
    23072232        RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::removeDataForDomain failed, error message: %{private}s", this, m_database.lastErrorMsg());
    23082233        ASSERT_NOT_REACHED();
    23092234    }
    2310    
    2311     resetStatement(m_removeAllDataStatement);
    23122235}
    23132236
     
    24912414    if (!expirationDateTime)
    24922415        return results;
    2493 
    2494     if (m_findExpiredUserInteractionStatement.bindDouble(1, expirationDateTime.value().value()) != SQLITE_OK)
     2416   
     2417    auto scopedStatement = this->scopedStatement(m_findExpiredUserInteractionStatement, findExpiredUserInteractionQuery, "findExpiredUserInteractions"_s);
     2418    if (!scopedStatement
     2419        || scopedStatement->bindDouble(1, expirationDateTime.value().value()) != SQLITE_OK)
    24952420        return results;
    24962421
    2497     while (m_findExpiredUserInteractionStatement.step() == SQLITE_ROW)
    2498         results.append(m_findExpiredUserInteractionStatement.getColumnInt(0));
    2499 
    2500     int resetResult = m_findExpiredUserInteractionStatement.reset();
    2501     ASSERT_UNUSED(resetResult, resetResult == SQLITE_OK);
     2422    while (scopedStatement->step() == SQLITE_ROW)
     2423        results.append(scopedStatement->getColumnInt(0));
    25022424
    25032425    return results;
     
    26602582
    26612583    unsigned count = 0;
    2662     if (m_observedDomainCount.step() == SQLITE_ROW)
    2663         count = m_observedDomainCount.getColumnInt(0);
    2664 
    2665     int resetResult = m_observedDomainCount.reset();
    2666     ASSERT_UNUSED(resetResult, resetResult == SQLITE_OK);
     2584    auto scopedStatement = this->scopedStatement(m_observedDomainCountStatement, observedDomainCountQuery, "pruneStatisticsIfNeeded"_s);
     2585    if (!scopedStatement)
     2586        return;
     2587   
     2588    if (scopedStatement->step() == SQLITE_ROW)
     2589        count = scopedStatement->getColumnInt(0);
    26672590
    26682591    if (count <= parameters().maxStatisticsEntries)
     
    27002623{
    27012624    ASSERT(!RunLoop::isMain());
    2702 
    2703     if (m_updateLastSeenStatement.bindDouble(1, lastSeen.secondsSinceEpoch().value()) != SQLITE_OK
    2704         || m_updateLastSeenStatement.bindText(2, domain.string()) != SQLITE_OK
    2705         || m_updateLastSeenStatement.step() != SQLITE_DONE) {
     2625   
     2626    auto scopedStatement = this->scopedStatement(m_updateLastSeenStatement, updateLastSeenQuery, "updateLastSeen"_s);
     2627    if (!scopedStatement
     2628        || scopedStatement->bindDouble(1, lastSeen.secondsSinceEpoch().value()) != SQLITE_OK
     2629        || scopedStatement->bindText(2, domain.string()) != SQLITE_OK
     2630        || scopedStatement->step() != SQLITE_DONE) {
    27062631        RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::updateLastSeen failed to bind, error message: %{private}s", this, m_database.lastErrorMsg());
    27072632        ASSERT_NOT_REACHED();
    27082633        return;
    27092634    }
    2710    
    2711     int resetResult = m_updateLastSeenStatement.reset();
    2712     ASSERT_UNUSED(resetResult, resetResult == SQLITE_OK);
    27132635}
    27142636
     
    27612683{
    27622684    ASSERT(!RunLoop::isMain());
    2763 
    2764     if (m_updateDataRecordsRemovedStatement.bindInt(1, value) != SQLITE_OK
    2765         || m_updateDataRecordsRemovedStatement.bindText(2, domain.string()) != SQLITE_OK
    2766         || m_updateDataRecordsRemovedStatement.step() != SQLITE_DONE) {
     2685   
     2686    auto scopedStatement = this->scopedStatement(m_updateDataRecordsRemovedStatement, updateDataRecordsRemovedQuery, "updateDataRecordsRemoved"_s);
     2687    if (!scopedStatement
     2688        || scopedStatement->bindInt(1, value) != SQLITE_OK
     2689        || scopedStatement->bindText(2, domain.string()) != SQLITE_OK
     2690        || scopedStatement->step() != SQLITE_DONE) {
    27672691        RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::updateDataRecordsRemoved failed to bind, error message: %{private}s", this, m_database.lastErrorMsg());
    27682692        ASSERT_NOT_REACHED();
    27692693        return;
    27702694    }
    2771 
    2772     int resetResult = m_updateDataRecordsRemovedStatement.reset();
    2773     ASSERT_UNUSED(resetResult, resetResult == SQLITE_OK);
    27742695}
    27752696
     
    28262747    auto result = emptyString();
    28272748   
    2828     if (m_domainStringFromDomainIDStatement.bindInt(1, domainID) != SQLITE_OK) {
     2749    auto scopedStatement = this->scopedStatement(m_domainStringFromDomainIDStatement, domainStringFromDomainIDQuery, "getDomainStringFromDomainID"_s);
     2750    if (!scopedStatement
     2751        || scopedStatement->bindInt(1, domainID) != SQLITE_OK) {
    28292752        RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::getDomainStringFromDomainID. Statement failed to prepare or bind, error message: %{private}s", this, m_database.lastErrorMsg());
    28302753        ASSERT_NOT_REACHED();
     
    28322755    }
    28332756   
    2834     if (m_domainStringFromDomainIDStatement.step() == SQLITE_ROW)
    2835         result = m_domainStringFromDomainIDStatement.getColumnText(0);
    2836    
    2837     resetStatement(m_domainStringFromDomainIDStatement);
     2757    if (scopedStatement->step() == SQLITE_ROW)
     2758        result = m_domainStringFromDomainIDStatement->getColumnText(0);
     2759   
    28382760    return result;
    28392761}
     
    29022824void ResourceLoadStatisticsDatabaseStore::resourceToString(StringBuilder& builder, const String& domain) const
    29032825{
    2904     if (m_getResourceDataByDomainNameStatement.bindText(1, domain) != SQLITE_OK
    2905         || m_getResourceDataByDomainNameStatement.step() != SQLITE_ROW) {
     2826    auto scopedStatement = this->scopedStatement(m_getResourceDataByDomainNameStatement, getResourceDataByDomainNameQuery, "resourceToString"_s);
     2827    if (!scopedStatement
     2828        || scopedStatement->bindText(1, domain) != SQLITE_OK
     2829        || scopedStatement->step() != SQLITE_ROW) {
    29062830        RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::resourceToString. Statement failed to bind or domain was not found, error message: %{private}s", this, m_database.lastErrorMsg());
    29072831        ASSERT_NOT_REACHED();
     
    29142838   
    29152839    // User interaction
    2916     appendBoolean(builder, "hadUserInteraction", m_getResourceDataByDomainNameStatement.getColumnInt(HadUserInteractionIndex));
     2840    appendBoolean(builder, "hadUserInteraction", m_getResourceDataByDomainNameStatement->getColumnInt(HadUserInteractionIndex));
    29172841    builder.append('\n');
    29182842    builder.appendLiteral("    mostRecentUserInteraction: ");
    2919     if (hasHadRecentUserInteraction(Seconds(m_getResourceDataByDomainNameStatement.getColumnDouble(MostRecentUserInteractionTimeIndex))))
     2843    if (hasHadRecentUserInteraction(Seconds(m_getResourceDataByDomainNameStatement->getColumnDouble(MostRecentUserInteractionTimeIndex))))
    29202844        builder.appendLiteral("within 24 hours");
    29212845    else
    29222846        builder.appendLiteral("-1");
    29232847    builder.append('\n');
    2924     appendBoolean(builder, "grandfathered", m_getResourceDataByDomainNameStatement.getColumnInt(GrandfatheredIndex));
     2848    appendBoolean(builder, "grandfathered", m_getResourceDataByDomainNameStatement->getColumnInt(GrandfatheredIndex));
    29252849    builder.append('\n');
    29262850
     
    29352859    appendSubStatisticList(builder, "TopFrameLoadedThirdPartyScripts", domain);
    29362860
    2937     appendBoolean(builder, "IsScheduledForAllButCookieDataRemoval", m_getResourceDataByDomainNameStatement.getColumnInt(IsScheduledForAllButCookieDataRemovalIndex));
     2861    appendBoolean(builder, "IsScheduledForAllButCookieDataRemoval", m_getResourceDataByDomainNameStatement->getColumnInt(IsScheduledForAllButCookieDataRemovalIndex));
    29382862    builder.append('\n');
    29392863
     
    29472871
    29482872    // Prevalent Resource
    2949     appendBoolean(builder, "isPrevalentResource", m_getResourceDataByDomainNameStatement.getColumnInt(IsPrevalentIndex));
     2873    appendBoolean(builder, "isPrevalentResource", m_getResourceDataByDomainNameStatement->getColumnInt(IsPrevalentIndex));
    29502874    builder.append('\n');
    2951     appendBoolean(builder, "isVeryPrevalentResource", m_getResourceDataByDomainNameStatement.getColumnInt(IsVeryPrevalentIndex));
     2875    appendBoolean(builder, "isVeryPrevalentResource", m_getResourceDataByDomainNameStatement->getColumnInt(IsVeryPrevalentIndex));
    29522876    builder.append('\n');
    29532877    builder.appendLiteral("    dataRecordsRemoved: ");
    2954     builder.appendNumber(m_getResourceDataByDomainNameStatement.getColumnInt(DataRecordsRemovedIndex));
     2878    builder.appendNumber(m_getResourceDataByDomainNameStatement->getColumnInt(DataRecordsRemovedIndex));
    29552879    builder.append('\n');
    2956 
    2957     resetStatement(m_getResourceDataByDomainNameStatement);
    29582880}
    29592881
    29602882bool ResourceLoadStatisticsDatabaseStore::domainIDExistsInDatabase(int domainID)
    29612883{
    2962     if (m_linkDecorationExistsStatement.bindInt(1, domainID) != SQLITE_OK
    2963         || m_linkDecorationExistsStatement.bindInt(2, domainID) != SQLITE_OK
    2964         || m_scriptLoadExistsStatement.bindInt(1, domainID) != SQLITE_OK
    2965         || m_scriptLoadExistsStatement.bindInt(2, domainID) != SQLITE_OK
    2966         || m_subFrameExistsStatement.bindInt(1, domainID) != SQLITE_OK
    2967         || m_subFrameExistsStatement.bindInt(2, domainID) != SQLITE_OK
    2968         || m_subResourceExistsStatement.bindInt(1, domainID) != SQLITE_OK
    2969         || m_subResourceExistsStatement.bindInt(2, domainID) != SQLITE_OK
    2970         || m_uniqueRedirectExistsStatement.bindInt(1, domainID) != SQLITE_OK
    2971         || m_uniqueRedirectExistsStatement.bindInt(2, domainID) != SQLITE_OK
    2972         || m_observedDomainsExistsStatement.bindInt(1, domainID) != SQLITE_OK) {
     2884    auto scopedLinkDecorationExistsStatement = this->scopedStatement(m_linkDecorationExistsStatement, linkDecorationExistsQuery, "domainIDExistsInDatabase"_s);
     2885    auto scopedScriptLoadExistsStatement = this->scopedStatement(m_scriptLoadExistsStatement, scriptLoadExistsQuery, "domainIDExistsInDatabase linkDecorationExistsStatement"_s);
     2886    auto scopedSubFrameExistsStatement = this->scopedStatement(m_subFrameExistsStatement, subFrameExistsQuery, "domainIDExistsInDatabase subFrameExistsStatement"_s);
     2887    auto scopedSubResourceExistsStatement = this->scopedStatement(m_subResourceExistsStatement, subResourceExistsQuery, "domainIDExistsInDatabase subResourceExistsStatement"_s);
     2888    auto scopedUniqueRedirectExistsStatement = this->scopedStatement(m_uniqueRedirectExistsStatement, uniqueRedirectExistsQuery, "domainIDExistsInDatabase uniqueRedirectExistsStatement"_s);
     2889    auto scopedObservedDomainsExistsStatement = this->scopedStatement(m_observedDomainsExistsStatement, observedDomainsExistsQuery, "domainIDExistsInDatabase observedDomainsExistsStatement"_s);
     2890   
     2891    if (!scopedLinkDecorationExistsStatement
     2892        || !scopedScriptLoadExistsStatement
     2893        || !scopedSubFrameExistsStatement
     2894        || !scopedSubResourceExistsStatement
     2895        || !scopedUniqueRedirectExistsStatement
     2896        || !scopedObservedDomainsExistsStatement
     2897        || m_linkDecorationExistsStatement->bindInt(1, domainID) != SQLITE_OK
     2898        || m_linkDecorationExistsStatement->bindInt(2, domainID) != SQLITE_OK
     2899        || m_scriptLoadExistsStatement->bindInt(1, domainID) != SQLITE_OK
     2900        || m_scriptLoadExistsStatement->bindInt(2, domainID) != SQLITE_OK
     2901        || m_subFrameExistsStatement->bindInt(1, domainID) != SQLITE_OK
     2902        || m_subFrameExistsStatement->bindInt(2, domainID) != SQLITE_OK
     2903        || m_subResourceExistsStatement->bindInt(1, domainID) != SQLITE_OK
     2904        || m_subResourceExistsStatement->bindInt(2, domainID) != SQLITE_OK
     2905        || m_uniqueRedirectExistsStatement->bindInt(1, domainID) != SQLITE_OK
     2906        || m_uniqueRedirectExistsStatement->bindInt(2, domainID) != SQLITE_OK
     2907        || m_observedDomainsExistsStatement->bindInt(1, domainID) != SQLITE_OK) {
    29732908        RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::domainIDExistsInDatabase failed to bind, error message: %{private}s", this, m_database.lastErrorMsg());
    29742909        ASSERT_NOT_REACHED();
     
    29762911    }
    29772912
    2978     if (m_linkDecorationExistsStatement.step() != SQLITE_ROW
    2979         || m_scriptLoadExistsStatement.step() != SQLITE_ROW
    2980         || m_subFrameExistsStatement.step() != SQLITE_ROW
    2981         || m_subResourceExistsStatement.step() != SQLITE_ROW
    2982         || m_uniqueRedirectExistsStatement.step() != SQLITE_ROW
    2983         || m_observedDomainsExistsStatement.step() != SQLITE_ROW) {
     2913    if (m_linkDecorationExistsStatement->step() != SQLITE_ROW
     2914        || m_scriptLoadExistsStatement->step() != SQLITE_ROW
     2915        || m_subFrameExistsStatement->step() != SQLITE_ROW
     2916        || m_subResourceExistsStatement->step() != SQLITE_ROW
     2917        || m_uniqueRedirectExistsStatement->step() != SQLITE_ROW
     2918        || m_observedDomainsExistsStatement->step() != SQLITE_ROW) {
    29842919        RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::domainIDExistsInDatabase failed to step, error message: %{private}s", this, m_database.lastErrorMsg());
    29852920        ASSERT_NOT_REACHED();
    29862921        return false;
    29872922    }
    2988    
    2989     resetStatement(m_linkDecorationExistsStatement);
    2990     resetStatement(m_scriptLoadExistsStatement);
    2991     resetStatement(m_subFrameExistsStatement);
    2992     resetStatement(m_subResourceExistsStatement);
    2993     resetStatement(m_uniqueRedirectExistsStatement);
    2994     resetStatement(m_observedDomainsExistsStatement);
    2995 
    2996     return m_linkDecorationExistsStatement.getColumnInt(0) || m_scriptLoadExistsStatement.getColumnInt(0) || m_subFrameExistsStatement.getColumnInt(0) || m_subResourceExistsStatement.getColumnInt(0) || m_uniqueRedirectExistsStatement.getColumnInt(0) || m_observedDomainsExistsStatement.getColumnInt(0);
     2923
     2924    return m_linkDecorationExistsStatement->getColumnInt(0) || m_scriptLoadExistsStatement->getColumnInt(0) || m_subFrameExistsStatement->getColumnInt(0) || m_subResourceExistsStatement->getColumnInt(0) || m_uniqueRedirectExistsStatement->getColumnInt(0) || m_observedDomainsExistsStatement->getColumnInt(0);
    29972925}
    29982926
  • trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h

    r260841 r261892  
    3232#include <WebCore/SQLiteDatabase.h>
    3333#include <WebCore/SQLiteStatement.h>
     34#include <WebCore/SQLiteStatementAutoResetScope.h>
    3435#include <pal/SessionID.h>
    3536#include <wtf/CompletionHandler.h>
     
    8081public:
    8182    ResourceLoadStatisticsDatabaseStore(WebResourceLoadStatisticsStore&, WorkQueue&, ShouldIncludeLocalhost, const String& storageDirectoryPath, PAL::SessionID);
    82 
     83    ~ResourceLoadStatisticsDatabaseStore();
    8384    void populateFromMemoryStore(const ResourceLoadStatisticsMemoryStore&);
    8485    void mergeStatistics(Vector<ResourceLoadStatistics>&&) override;
    8586    void clear(CompletionHandler<void()>&&) override;
    8687    bool isEmpty() const override;
     88    void close();
    8789
    8890    Vector<WebResourceLoadStatisticsStore::ThirdPartyData> aggregatedThirdPartyData() const override;
     
    149151    bool isMigrationNecessary();
    150152    void migrateDataToNewTablesIfNecessary();
     153    void destroyStatements();
     154    WebCore::SQLiteStatementAutoResetScope scopedStatement(std::unique_ptr<WebCore::SQLiteStatement>&, const String&, const String&) const;
     155
    151156    bool hasStorageAccess(const TopFrameDomain&, const SubFrameDomain&) const;
    152157    Vector<WebResourceLoadStatisticsStore::ThirdPartyDataForSpecificFirstParty> getThirdPartyDataForSpecificFirstPartyDomains(unsigned, const RegistrableDomain&) const;
     
    156161    void appendSubStatisticList(StringBuilder&, const String& tableName, const String& domain) const;
    157162    void mergeStatistic(const ResourceLoadStatistics&);
    158     void merge(WebCore::SQLiteStatement&, const ResourceLoadStatistics&);
     163    void merge(WebCore::SQLiteStatement*, const ResourceLoadStatistics&);
    159164    void clearDatabaseContents();
    160165    unsigned getNumberOfPrevalentResources() const;
     
    168173    void insertDomainRelationships(const ResourceLoadStatistics&);
    169174    void insertDomainRelationshipList(const String&, const HashSet<RegistrableDomain>&, unsigned);
    170     bool insertDomainRelationship(WebCore::SQLiteStatement&, unsigned domainID, const RegistrableDomain& topFrameDomain);
    171     bool relationshipExists(WebCore::SQLiteStatement&, Optional<unsigned> firstDomainID, const RegistrableDomain& secondDomain) const;
     175    bool relationshipExists(WebCore::SQLiteStatementAutoResetScope&, Optional<unsigned> firstDomainID, const RegistrableDomain& secondDomain) const;
    172176    Optional<unsigned> domainID(const RegistrableDomain&) const;
    173177    bool domainExists(const RegistrableDomain&) const;
     
    207211    HashMap<unsigned, NotVeryPrevalentResources> findNotVeryPrevalentResources();
    208212
    209     bool predicateValueForDomain(WebCore::SQLiteStatement&, const RegistrableDomain&) const;
     213    bool predicateValueForDomain(WebCore::SQLiteStatementAutoResetScope&, const RegistrableDomain&) const;
    210214
    211215    bool areAllThirdPartyCookiesBlockedUnder(const TopFrameDomain&) override;
     
    230234    bool createUniqueIndices();
    231235    bool createSchema();
    232     bool prepareStatements();
    233236    String ensureAndMakeDomainList(const HashSet<RegistrableDomain>&);
    234 
    235237   
    236238    const String m_storageDirectoryPath;
    237239    mutable WebCore::SQLiteDatabase m_database;
    238     mutable WebCore::SQLiteStatement m_observedDomainCount;
    239     WebCore::SQLiteStatement m_insertObservedDomainStatement;
    240     WebCore::SQLiteStatement m_insertTopLevelDomainStatement;
    241     mutable WebCore::SQLiteStatement m_domainIDFromStringStatement;
    242     mutable WebCore::SQLiteStatement m_topFrameLinkDecorationsFromExists;
    243     mutable WebCore::SQLiteStatement m_topFrameLoadedThirdPartyScriptsExists;
    244     mutable WebCore::SQLiteStatement m_subframeUnderTopFrameDomainExists;
    245     mutable WebCore::SQLiteStatement m_subresourceUnderTopFrameDomainExists;
    246     mutable WebCore::SQLiteStatement m_subresourceUniqueRedirectsToExists;
    247     WebCore::SQLiteStatement m_mostRecentUserInteractionStatement;
    248     WebCore::SQLiteStatement m_updateLastSeenStatement;
    249     mutable WebCore::SQLiteStatement m_updateDataRecordsRemovedStatement;
    250     WebCore::SQLiteStatement m_updatePrevalentResourceStatement;
    251     mutable WebCore::SQLiteStatement m_isPrevalentResourceStatement;
    252     WebCore::SQLiteStatement m_updateVeryPrevalentResourceStatement;
    253     mutable WebCore::SQLiteStatement m_isVeryPrevalentResourceStatement;
    254     WebCore::SQLiteStatement m_clearPrevalentResourceStatement;
    255     mutable WebCore::SQLiteStatement m_hadUserInteractionStatement;
    256     WebCore::SQLiteStatement m_updateGrandfatheredStatement;
    257     mutable WebCore::SQLiteStatement m_updateIsScheduledForAllButCookieDataRemovalStatement;
    258     mutable WebCore::SQLiteStatement m_isGrandfatheredStatement;
    259     mutable WebCore::SQLiteStatement m_findExpiredUserInteractionStatement;
    260     mutable WebCore::SQLiteStatement m_countPrevalentResourcesStatement;
    261     mutable WebCore::SQLiteStatement m_countPrevalentResourcesWithUserInteractionStatement;
    262     mutable WebCore::SQLiteStatement m_countPrevalentResourcesWithoutUserInteractionStatement;
    263     mutable WebCore::SQLiteStatement m_getResourceDataByDomainNameStatement;
    264     mutable WebCore::SQLiteStatement m_getAllDomainsStatement;
    265     mutable WebCore::SQLiteStatement m_domainStringFromDomainIDStatement;
    266     mutable WebCore::SQLiteStatement m_getAllSubStatisticsStatement;
    267     mutable WebCore::SQLiteStatement m_storageAccessExistsStatement;
    268     mutable WebCore::SQLiteStatement m_getMostRecentlyUpdatedTimestampStatement;
    269     mutable WebCore::SQLiteStatement m_linkDecorationExistsStatement;
    270     mutable WebCore::SQLiteStatement m_scriptLoadExistsStatement;
    271     mutable WebCore::SQLiteStatement m_subFrameExistsStatement;
    272     mutable WebCore::SQLiteStatement m_subResourceExistsStatement;
    273     mutable WebCore::SQLiteStatement m_uniqueRedirectExistsStatement;
    274     mutable WebCore::SQLiteStatement m_observedDomainsExistsStatement;
    275     mutable WebCore::SQLiteStatement m_removeAllDataStatement;
     240    mutable std::unique_ptr<WebCore::SQLiteStatement> m_observedDomainCountStatement;
     241    std::unique_ptr<WebCore::SQLiteStatement> m_insertObservedDomainStatement;
     242    std::unique_ptr<WebCore::SQLiteStatement> m_insertTopLevelDomainStatement;
     243    mutable std::unique_ptr<WebCore::SQLiteStatement> m_domainIDFromStringStatement;
     244    mutable std::unique_ptr<WebCore::SQLiteStatement> m_topFrameLinkDecorationsFromExistsStatement;
     245    mutable std::unique_ptr<WebCore::SQLiteStatement> m_topFrameLoadedThirdPartyScriptsExistsStatement;
     246    mutable std::unique_ptr<WebCore::SQLiteStatement> m_subframeUnderTopFrameDomainExistsStatement;
     247    mutable std::unique_ptr<WebCore::SQLiteStatement> m_subresourceUnderTopFrameDomainExistsStatement;
     248    mutable std::unique_ptr<WebCore::SQLiteStatement> m_subresourceUniqueRedirectsToExistsStatement;
     249    std::unique_ptr<WebCore::SQLiteStatement> m_mostRecentUserInteractionStatement;
     250    std::unique_ptr<WebCore::SQLiteStatement> m_updateLastSeenStatement;
     251    mutable std::unique_ptr<WebCore::SQLiteStatement> m_updateDataRecordsRemovedStatement;
     252    std::unique_ptr<WebCore::SQLiteStatement> m_updatePrevalentResourceStatement;
     253    mutable std::unique_ptr<WebCore::SQLiteStatement> m_isPrevalentResourceStatement;
     254    std::unique_ptr<WebCore::SQLiteStatement> m_updateVeryPrevalentResourceStatement;
     255    mutable std::unique_ptr<WebCore::SQLiteStatement> m_isVeryPrevalentResourceStatement;
     256    std::unique_ptr<WebCore::SQLiteStatement> m_clearPrevalentResourceStatement;
     257    mutable std::unique_ptr<WebCore::SQLiteStatement> m_hadUserInteractionStatement;
     258    std::unique_ptr<WebCore::SQLiteStatement> m_updateGrandfatheredStatement;
     259    mutable std::unique_ptr<WebCore::SQLiteStatement> m_updateIsScheduledForAllButCookieDataRemovalStatement;
     260    mutable std::unique_ptr<WebCore::SQLiteStatement> m_isGrandfatheredStatement;
     261    mutable std::unique_ptr<WebCore::SQLiteStatement> m_findExpiredUserInteractionStatement;
     262    mutable std::unique_ptr<WebCore::SQLiteStatement> m_countPrevalentResourcesStatement;
     263    mutable std::unique_ptr<WebCore::SQLiteStatement> m_countPrevalentResourcesWithUserInteractionStatement;
     264    mutable std::unique_ptr<WebCore::SQLiteStatement> m_countPrevalentResourcesWithoutUserInteractionStatement;
     265    mutable std::unique_ptr<WebCore::SQLiteStatement> m_getResourceDataByDomainNameStatement;
     266    mutable std::unique_ptr<WebCore::SQLiteStatement> m_getAllDomainsStatement;
     267    mutable std::unique_ptr<WebCore::SQLiteStatement> m_domainStringFromDomainIDStatement;
     268    mutable std::unique_ptr<WebCore::SQLiteStatement> m_getAllSubStatisticsStatement;
     269    mutable std::unique_ptr<WebCore::SQLiteStatement> m_storageAccessExistsStatement;
     270    mutable std::unique_ptr<WebCore::SQLiteStatement> m_getMostRecentlyUpdatedTimestampStatement;
     271    mutable std::unique_ptr<WebCore::SQLiteStatement> m_linkDecorationExistsStatement;
     272    mutable std::unique_ptr<WebCore::SQLiteStatement> m_scriptLoadExistsStatement;
     273    mutable std::unique_ptr<WebCore::SQLiteStatement> m_subFrameExistsStatement;
     274    mutable std::unique_ptr<WebCore::SQLiteStatement> m_subResourceExistsStatement;
     275    mutable std::unique_ptr<WebCore::SQLiteStatement> m_uniqueRedirectExistsStatement;
     276    mutable std::unique_ptr<WebCore::SQLiteStatement> m_observedDomainsExistsStatement;
     277    mutable std::unique_ptr<WebCore::SQLiteStatement> m_removeAllDataStatement;
    276278    PAL::SessionID m_sessionID;
    277279    bool m_isNewResourceLoadStatisticsDatabaseFile { false };
Note: See TracChangeset for help on using the changeset viewer.