#ifndef CONTENT_BROWSER_AGGREGATION_SERVICE_AGGREGATION_SERVICE_STORAGE_SQL_H_
#define CONTENT_BROWSER_AGGREGATION_SERVICE_AGGREGATION_SERVICE_STORAGE_SQL_H_
#include <stdint.h>
#include <optional>
#include <set>
#include <string_view>
#include <vector>
#include "base/files/file_path.h"
#include "base/memory/raw_ref.h"
#include "base/sequence_checker.h"
#include "base/thread_annotations.h"
#include "base/time/time.h"
#include "content/browser/aggregation_service/aggregation_service.h"
#include "content/browser/aggregation_service/aggregation_service_storage.h"
#include "content/common/content_export.h"
#include "content/public/browser/storage_partition.h"
#include "sql/database.h"
#include "sql/meta_table.h"
class GURL;
namespace base {
class Clock;
}
namespace sql {
class Statement;
}
namespace url {
class Origin;
}
namespace content {
class AggregatableReportRequest;
struct PublicKey;
struct PublicKeyset;
class CONTENT_EXPORT AggregationServiceStorageSql
: public AggregationServiceStorage {
public:
static const int kCurrentVersionNumber;
static const int kCompatibleVersionNumber;
static const int kDeprecatedVersionNumber;
AggregationServiceStorageSql(
bool run_in_memory,
const base::FilePath& path_to_database,
const base::Clock* clock,
int max_stored_requests_per_reporting_origin =
AggregationService::kMaxStoredReportsPerReportingOrigin);
AggregationServiceStorageSql(const AggregationServiceStorageSql& other) =
delete;
AggregationServiceStorageSql& operator=(
const AggregationServiceStorageSql& other) = delete;
~AggregationServiceStorageSql() override;
std::vector<PublicKey> GetPublicKeys(const GURL& url) override;
void SetPublicKeys(const GURL& url, const PublicKeyset& keyset) override;
void ClearPublicKeys(const GURL& url) override;
void ClearPublicKeysExpiredBy(base::Time delete_end) override;
void StoreRequest(AggregatableReportRequest request) override;
void DeleteRequest(AggregationServiceStorage::RequestId request_id) override;
void UpdateReportForSendFailure(
AggregationServiceStorage::RequestId request_id,
base::Time new_report_time) override;
std::optional<base::Time> NextReportTimeAfter(
base::Time strictly_after_time) override;
std::vector<AggregationServiceStorage::RequestAndId>
GetRequestsReportingOnOrBefore(base::Time not_after_time,
std::optional<int> limit) override;
std::vector<AggregationServiceStorage::RequestAndId> GetRequests(
const std::vector<AggregationServiceStorage::RequestId>& ids) override;
std::optional<base::Time> AdjustOfflineReportTimes(
base::Time now,
base::TimeDelta min_delay,
base::TimeDelta max_delay) override;
void ClearDataBetween(
base::Time delete_begin,
base::Time delete_end,
StoragePartition::StorageKeyMatcherFunction filter) override;
std::set<url::Origin> GetReportRequestReportingOrigins() override;
void set_ignore_errors_for_testing(bool ignore_for_testing)
VALID_CONTEXT_REQUIRED(sequence_checker_) {
ignore_errors_for_testing_ = ignore_for_testing;
}
enum class InitStatus {
kSuccess = 0,
kFailedToOpenDbInMemory = 1,
kFailedToOpenDbFile = 2,
kFailedToCreateDir = 3,
kFailedToInitializeSchema = 4,
kMaxValue = kFailedToInitializeSchema,
};
private:
enum class DbStatus {
kOpen,
kDeferringCreation,
kDeferringOpen,
kClosed,
kClosedDueToCatastrophicError,
};
enum class DbCreationPolicy {
kCreateIfAbsent,
kFailIfAbsent,
};
bool InsertPublicKeysImpl(const GURL& url, const PublicKeyset& keyset)
VALID_CONTEXT_REQUIRED(sequence_checker_);
bool ClearPublicKeysImpl(const GURL& url)
VALID_CONTEXT_REQUIRED(sequence_checker_);
bool ClearPublicKeysByUrlId(int64_t url_id)
VALID_CONTEXT_REQUIRED(sequence_checker_);
void ClearPublicKeysFetchedBetween(base::Time delete_begin,
base::Time delete_end)
VALID_CONTEXT_REQUIRED(sequence_checker_);
void ClearAllPublicKeys() VALID_CONTEXT_REQUIRED(sequence_checker_);
bool DeleteRequestImpl(RequestId request_id)
VALID_CONTEXT_REQUIRED(sequence_checker_);
std::optional<base::Time> NextReportTimeAfterImpl(
base::Time strictly_after_time) VALID_CONTEXT_REQUIRED(sequence_checker_);
void ClearRequestsStoredBetween(
base::Time delete_begin,
base::Time delete_end,
StoragePartition::StorageKeyMatcherFunction filter)
VALID_CONTEXT_REQUIRED(sequence_checker_);
void ClearAllRequests() VALID_CONTEXT_REQUIRED(sequence_checker_);
bool ReportingOriginHasCapacity(std::string_view serialized_reporting_origin)
VALID_CONTEXT_REQUIRED(sequence_checker_);
[[nodiscard]] bool EnsureDatabaseOpen(DbCreationPolicy creation_policy)
VALID_CONTEXT_REQUIRED(sequence_checker_);
[[nodiscard]] bool InitializeSchema(bool db_empty)
VALID_CONTEXT_REQUIRED(sequence_checker_);
[[nodiscard]] bool CreateSchema() VALID_CONTEXT_REQUIRED(sequence_checker_);
void HandleInitializationFailure(InitStatus status)
VALID_CONTEXT_REQUIRED(sequence_checker_);
void DatabaseErrorCallback(int extended_error, sql::Statement* stmt);
bool ignore_errors_for_testing_ GUARDED_BY_CONTEXT(sequence_checker_) = false;
const bool run_in_memory_;
const base::FilePath path_to_database_;
const raw_ref<const base::Clock> clock_;
int max_stored_requests_per_reporting_origin_;
std::optional<DbStatus> db_status_ GUARDED_BY_CONTEXT(sequence_checker_);
sql::Database db_ GUARDED_BY_CONTEXT(sequence_checker_);
sql::MetaTable meta_table_ GUARDED_BY_CONTEXT(sequence_checker_);
SEQUENCE_CHECKER(sequence_checker_);
};
}
#endif