summaryrefslogtreecommitdiffstats
path: root/webkit/database/database_tracker.h
blob: 2bcfc6f474554614be702903d6d448192cf4cac9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef WEBKIT_DATABASE_DATABASE_TRACKER_H_
#define WEBKIT_DATABASE_DATABASE_TRACKER_H_

#include <map>

#include "base/file_path.h"
#include "base/observer_list.h"
#include "base/ref_counted.h"
#include "base/scoped_ptr.h"
#include "base/string16.h"
#include "testing/gtest/include/gtest/gtest_prod.h"

namespace sql {
class Connection;
class MetaTable;
}

namespace webkit_database {

class DatabasesTable;

// This class manages the main database, and keeps track of per origin quotas.
//
// The data in this class is not thread-safe, so all methods of this class
// should be called on the same thread. The only exception is
// database_directory() which returns a constant that is initialized when
// the DatabaseTracker instance is created.
//
// Furthermore, some methods of this class have to read/write data from/to
// the disk. Therefore, in a multi-threaded application, all methods of this
// class should be called on the thread dedicated to file operations (file
// thread in the browser process, for example), if such a thread exists.
class DatabaseTracker
    : public base::RefCountedThreadSafe<DatabaseTracker> {
 public:
  class Observer {
   public:
    virtual void OnDatabaseSizeChanged(const string16& origin_identifier,
                                       const string16& database_name,
                                       int64 database_size,
                                       int64 space_available) = 0;
    virtual ~Observer() {}
  };

  explicit DatabaseTracker(const FilePath& profile_path);

  void DatabaseOpened(const string16& origin_identifier,
                      const string16& database_name,
                      const string16& database_details,
                      int64 estimated_size,
                      int64* database_size,
                      int64* space_available);
  void DatabaseModified(const string16& origin_identifier,
                        const string16& database_name);
  void DatabaseClosed(const string16& origin_identifier,
                      const string16& database_name);

  void AddObserver(Observer* observer);
  void RemoveObserver(Observer* observer);

  void CloseTrackerDatabaseAndClearCaches();

  const FilePath& DatabaseDirectory() const { return db_dir_; }
  FilePath GetFullDBFilePath(const string16& origin_identifier,
                             const string16& database_name) const;

 private:
  friend class base::RefCountedThreadSafe<DatabaseTracker>;

  ~DatabaseTracker();

  class CachedOriginInfo {
   public:
    CachedOriginInfo() : total_size_(0) { }
    int64 TotalSize() const { return total_size_; }
    int64 GetCachedDatabaseSize(const string16& database_name) {
      return cached_database_sizes_[database_name];
    }
    void SetCachedDatabaseSize(const string16& database_name, int64 new_size) {
      int64 old_size = cached_database_sizes_[database_name];
      cached_database_sizes_[database_name] = new_size;
      if (new_size != old_size)
        total_size_ += new_size - old_size;
    }

   private:
    int64 total_size_;
    std::map<string16, int64> cached_database_sizes_;
  };

  bool LazyInit();
  void InsertOrUpdateDatabaseDetails(const string16& origin_identifier,
                                     const string16& database_name,
                                     const string16& database_details,
                                     int64 estimated_size);

  void ClearAllCachedOriginInfo();
  CachedOriginInfo* GetCachedOriginInfo(const string16& origin_identifier);
  int64 GetCachedDatabaseFileSize(const string16& origin_identifier,
                                  const string16& database_name);
  int64 UpdateCachedDatabaseFileSize(const string16& origin_identifier,
                                     const string16& database_name);
  int64 GetDBFileSize(const string16& origin_identifier,
                      const string16& database_name) const;
  int64 GetOriginUsage(const string16& origin_identifer);
  int64 GetOriginQuota(const string16& origin_identifier) const;
  int64 GetOriginSpaceAvailable(const string16& origin_identifier);

  bool initialized_;
  const FilePath db_dir_;
  scoped_ptr<sql::Connection> db_;
  scoped_ptr<DatabasesTable> databases_table_;
  scoped_ptr<sql::MetaTable> meta_table_;
  ObserverList<Observer> observers_;
  std::map<string16, CachedOriginInfo> origins_info_map_;

  FRIEND_TEST(DatabaseTrackerTest, TestIt);
};

}  // namespace webkit_database

#endif  // WEBKIT_DATABASE_DATABASE_TRACKER_H_