1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#ifndef STORAGE_BROWSER_QUOTA_QUOTA_DATABASE_H_
61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#define STORAGE_BROWSER_QUOTA_QUOTA_DATABASE_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/gtest_prod_util.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/timer/timer.h"
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/storage_browser_export.h"
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/quota/quota_types.h"
20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochnamespace content {
230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochclass QuotaDatabaseTest;
240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace sql {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Connection;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MetaTable;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GURL;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace storage {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SpecialStoragePolicy;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// All the methods of this class must run on the DB thread.
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass STORAGE_EXPORT_PRIVATE QuotaDatabase {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Constants for {Get,Set}QuotaConfigValue keys.
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kDesiredAvailableSpaceKey[];
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kTemporaryQuotaOverrideKey[];
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If 'path' is empty, an in memory database will be used.
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit QuotaDatabase(const base::FilePath& path);
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~QuotaDatabase();
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CloseConnection();
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool GetHostQuota(const std::string& host, StorageType type, int64* quota);
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool SetHostQuota(const std::string& host, StorageType type, int64 quota);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool DeleteHostQuota(const std::string& host, StorageType type);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool SetOriginLastAccessTime(const GURL& origin,
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               StorageType type,
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               base::Time last_access_time);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool SetOriginLastModifiedTime(const GURL& origin,
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 StorageType type,
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 base::Time last_modified_time);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Register initial |origins| info |type| to the database.
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This method is assumed to be called only after the installation or
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the database schema reset.
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool RegisterInitialOriginInfo(
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::set<GURL>& origins, StorageType type);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool DeleteOriginInfo(const GURL& origin, StorageType type);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool GetQuotaConfigValue(const char* key, int64* value);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool SetQuotaConfigValue(const char* key, int64 value);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sets |origin| to the least recently used origin of origins not included
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in |exceptions| and not granted the special unlimited storage right.
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It returns false when it failed in accessing the database.
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |origin| is set to empty when there is no matching origin.
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool GetLRUOrigin(StorageType type,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    const std::set<GURL>& exceptions,
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    SpecialStoragePolicy* special_storage_policy,
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    GURL* origin);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Populates |origins| with the ones that have been modified since
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the |modified_since|.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool GetOriginsModifiedSince(StorageType type,
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               std::set<GURL>* origins,
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               base::Time modified_since);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns false if SetOriginDatabaseBootstrapped has never
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // been called before, which means existing origins may not have been
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // registered.
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsOriginDatabaseBootstrapped();
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool SetOriginDatabaseBootstrapped(bool bootstrap_flag);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  struct STORAGE_EXPORT_PRIVATE QuotaTableEntry {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    QuotaTableEntry();
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    QuotaTableEntry(
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const std::string& host,
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        StorageType type,
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int64 quota);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string host;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StorageType type;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 quota;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  friend STORAGE_EXPORT_PRIVATE bool operator <(
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const QuotaTableEntry& lhs, const QuotaTableEntry& rhs);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  struct STORAGE_EXPORT_PRIVATE OriginInfoTableEntry {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OriginInfoTableEntry();
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OriginInfoTableEntry(
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const GURL& origin,
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        StorageType type,
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int used_count,
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const base::Time& last_access_time,
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const base::Time& last_modified_time);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL origin;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StorageType type;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int used_count;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::Time last_access_time;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::Time last_modified_time;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  friend STORAGE_EXPORT_PRIVATE bool operator <(
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const OriginInfoTableEntry& lhs, const OriginInfoTableEntry& rhs);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Structures used for CreateSchema.
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct TableSchema {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* table_name;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* columns;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct IndexSchema {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* index_name;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* table_name;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* columns;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool unique;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef base::Callback<bool (const QuotaTableEntry&)> QuotaTableCallback;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef base::Callback<bool (const OriginInfoTableEntry&)>
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OriginInfoTableCallback;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct QuotaTableImporter;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For long-running transactions support.  We always keep a transaction open
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so that multiple transactions can be batched.  They are flushed
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // with a delay after a modification has been made.  We support neither
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // nested transactions nor rollback (as we don't need them for now).
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Commit();
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ScheduleCommit();
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool FindOriginUsedCount(const GURL& origin,
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           StorageType type,
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           int* used_count);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool LazyOpen(bool create_if_needed);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool EnsureDatabaseVersion();
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ResetSchema();
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool UpgradeSchema(int current_version);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool CreateSchema(
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sql::Connection* database,
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sql::MetaTable* meta_table,
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int schema_version, int compatible_version,
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const TableSchema* tables, size_t tables_size,
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const IndexSchema* indexes, size_t indexes_size);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |callback| may return false to stop reading data.
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool DumpQuotaTable(const QuotaTableCallback& callback);
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool DumpOriginInfoTable(const OriginInfoTableCallback& callback);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath db_file_path_;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<sql::Connection> db_;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<sql::MetaTable> meta_table_;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_recreating_;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_disabled_;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::OneShotTimer<QuotaDatabase> timer_;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  friend class content::QuotaDatabaseTest;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class QuotaManager;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const TableSchema kTables[];
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const IndexSchema kIndexes[];
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(QuotaDatabase);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}  // namespace storage
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif  // STORAGE_BROWSER_QUOTA_QUOTA_DATABASE_H_
191