10529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
20529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
30529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// found in the LICENSE file.
40529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
50529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_DATABASE_H_
60529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_DATABASE_H_
70529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
8010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include <map>
95c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include <set>
105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include <vector>
115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/files/file_path.h"
13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/gtest_prod_util.h"
140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/macros.h"
150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/memory/scoped_ptr.h"
160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/sequence_checker.h"
170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/time/time.h"
180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "content/common/content_export.h"
19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/common/service_worker/service_worker_status_code.h"
200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "url/gurl.h"
210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochnamespace leveldb {
230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochclass DB;
240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochclass Env;
255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuclass Status;
260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochclass WriteBatch;
270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochnamespace content {
300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Class to persist serviceworker registration data in a database.
320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Should NOT be used on the IO thread since this does blocking
330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// file io. The ServiceWorkerStorage class owns this class and
340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// is responsible for only calling it serially on background
355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// non-IO threads (ala SequencedWorkerPool).
360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochclass CONTENT_EXPORT ServiceWorkerDatabase {
370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public:
380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // We do leveldb stuff in |path| or in memory if |path| is empty.
390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  explicit ServiceWorkerDatabase(const base::FilePath& path);
400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ~ServiceWorkerDatabase();
410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Used in UMA. A new value must be appended only.
43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  enum Status {
44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    STATUS_OK,
45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    STATUS_ERROR_NOT_FOUND,
4646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    STATUS_ERROR_IO_ERROR,
47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    STATUS_ERROR_CORRUPTED,
48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    STATUS_ERROR_FAILED,
4946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    STATUS_ERROR_MAX,
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  };
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  struct CONTENT_EXPORT RegistrationData {
530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // These values are immutable for the life of a registration.
540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    int64 registration_id;
550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    GURL scope;
560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // Versions are first stored once they successfully install and become
580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // the waiting version. Then transition to the active version. The stored
59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // version may be in the ACTIVATED state or in the INSTALLED state.
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    GURL script;
610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    int64 version_id;
620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    bool is_active;
630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    bool has_fetch_handler;
640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    base::Time last_update_check;
650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    RegistrationData();
670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    ~RegistrationData();
680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  struct ResourceRecord {
715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    int64 resource_id;
725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    GURL url;
735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ResourceRecord() {}
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ResourceRecord(int64 id, GURL url) : resource_id(id), url(url) {}
76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  };
775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Reads next available ids from the database. Returns OK if they are
79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // successfully read. Fills the arguments with an initial value and returns
80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // OK if they are not found in the database. Otherwise, returns an error.
81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Status GetNextAvailableIds(
82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      int64* next_avail_registration_id,
83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      int64* next_avail_version_id,
84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      int64* next_avail_resource_id);
85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Reads origins that have one or more than one registration from the
87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // database. Returns OK if they are successfully read or not found.
88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Otherwise, returns an error.
89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Status GetOriginsWithRegistrations(std::set<GURL>* origins);
90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Reads registrations for |origin| from the database. Returns OK if they are
92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // successfully read or not found. Otherwise, returns an error.
93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Status GetRegistrationsForOrigin(
94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const GURL& origin,
95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      std::vector<RegistrationData>* registrations);
96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Reads all registrations from the database. Returns OK if successfully read
98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // or not found. Otherwise, returns an error.
99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Status GetAllRegistrations(std::vector<RegistrationData>* registrations);
100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
1015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Saving, retrieving, and updating registration data.
1025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // (will bump next_avail_xxxx_ids as needed)
1035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // (resource ids will be added/removed from the uncommitted/purgeable
1045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // lists as needed)
1055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Reads a registration for |registration_id| and resource records associated
107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // with it from the database. Returns OK if they are successfully read.
108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Otherwise, returns an error.
109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Status ReadRegistration(
110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      int64 registration_id,
111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const GURL& origin,
112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      RegistrationData* registration,
113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      std::vector<ResourceRecord>* resources);
114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Writes |registration| and |resources| into the database and does following
116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // things:
117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //   - If an old version of the registration exists, deletes it and sets
118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //   |deleted_version_id| to the old version id and
119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //   |newly_purgeable_resources| to its resources. Otherwise, sets
120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //   |deleted_version_id| to -1.
121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  //   - Bumps the next registration id and the next version id if needed.
122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  //   - Removes |resources| from the uncommitted list if exist.
123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Returns OK they are successfully written. Otherwise, returns an error.
124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  Status WriteRegistration(const RegistrationData& registration,
125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                           const std::vector<ResourceRecord>& resources,
126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                           int64* deleted_version_id,
127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                           std::vector<int64>* newly_purgeable_resources);
128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Updates a registration for |registration_id| to an active state. Returns OK
130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // if it's successfully updated. Otherwise, returns an error.
131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Status UpdateVersionToActive(
132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      int64 registration_id,
133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const GURL& origin);
134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Updates last check time of a registration for |registration_id| by |time|.
136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Returns OK if it's successfully updated. Otherwise, returns an error.
137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Status UpdateLastCheckTime(
138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      int64 registration_id,
139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const GURL& origin,
140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const base::Time& time);
141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Deletes a registration for |registration_id| and moves resource records
143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // associated with it into the purgeable list. If deletion occurred, sets
144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // |version_id| to the id of the version that was deleted and
145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // |newly_purgeable_resources| to its resources; otherwise, sets |version_id|
146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // to -1. Returns OK if it's successfully deleted or not found in the
147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // database. Otherwise, returns an error.
148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  Status DeleteRegistration(int64 registration_id,
149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            const GURL& origin,
150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            int64* version_id,
151116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            std::vector<int64>* newly_purgeable_resources);
1525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // As new resources are put into the diskcache, they go into an uncommitted
1545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // list. When a registration is saved that refers to those ids, they're
1555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // removed from that list. When a resource no longer has any registrations or
1565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // caches referring to it, it's added to the purgeable list. Periodically,
1575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // the purgeable list can be purged from the diskcache. At system startup, all
1585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // uncommitted ids are moved to the purgeable list.
1595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Reads uncommitted resource ids from the database. Returns OK on success.
161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Otherwise clears |ids| and returns an error.
162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Status GetUncommittedResourceIds(std::set<int64>* ids);
1635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Writes |ids| into the database as uncommitted resources. Returns OK on
165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // success. Otherwise writes nothing and returns an error.
166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Status WriteUncommittedResourceIds(const std::set<int64>& ids);
1675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Deletes uncommitted resource ids specified by |ids| from the database.
169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Returns OK on success. Otherwise deletes nothing and returns an error.
170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Status ClearUncommittedResourceIds(const std::set<int64>& ids);
1715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Reads purgeable resource ids from the database. Returns OK on success.
173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Otherwise clears |ids| and returns an error.
174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Status GetPurgeableResourceIds(std::set<int64>* ids);
1755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Writes |ids| into the database as purgeable resources. Returns OK on
177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // success. Otherwise writes nothing and returns an error.
178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Status WritePurgeableResourceIds(const std::set<int64>& ids);
1795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Deletes purgeable resource ids specified by |ids| from the database.
181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Returns OK on success. Otherwise deletes nothing and returns an error.
182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Status ClearPurgeableResourceIds(const std::set<int64>& ids);
1830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Moves |ids| from the uncommitted list to the purgeable list.
185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Returns OK on success. Otherwise deletes nothing and returns an error.
186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Status PurgeUncommittedResourceIds(const std::set<int64>& ids);
187010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Deletes all data for |origin|, namely, unique origin, registrations and
189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // resource records. Resources are moved to the purgeable list. Returns OK if
190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // they are successfully deleted or not found in the database. Otherwise,
191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // returns an error.
192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Status DeleteAllDataForOrigin(
193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const GURL& origin,
194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      std::vector<int64>* newly_purgeable_resources);
1950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
196f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Completely deletes the contents of the database.
197f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Be careful using this function.
198f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Status DestroyDatabase();
199f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
2000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private:
2010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Opens the database at the |path_|. This is lazily called when the first
202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // database API is called. Returns OK if the database is successfully opened.
203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Returns NOT_FOUND if the database does not exist and |create_if_missing| is
204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // false. Otherwise, returns an error.
205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Status LazyOpen(bool create_if_missing);
206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Helper for LazyOpen(). |status| must be the return value from LazyOpen()
208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // and this must be called just after LazyOpen() is called. Returns true if
209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // the database is new or nonexistent, that is, it has never been used.
210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool IsNewOrNonexistentDatabase(Status status);
211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Reads the next available id for |id_key|. Returns OK if it's successfully
213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // read. Fills |next_avail_id| with an initial value and returns OK if it's
214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // not found in the database. Otherwise, returns an error.
215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Status ReadNextAvailableId(
216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const char* id_key,
217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      int64* next_avail_id);
218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Reads registration data for |registration_id| from the database. Returns OK
220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // if successfully reads. Otherwise, returns an error.
221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Status ReadRegistrationData(
222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      int64 registration_id,
223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const GURL& origin,
224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      RegistrationData* registration);
225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Reads resource records for |version_id| from the database. Returns OK if
227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // it's successfully read or not found in the database. Otherwise, returns an
228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // error.
229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Status ReadResourceRecords(
230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      int64 version_id,
231cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      std::vector<ResourceRecord>* resources);
232cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Deletes resource records for |version_id| from the database. Returns OK if
234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // they are successfully deleted or not found in the database. Otherwise,
235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // returns an error.
236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Status DeleteResourceRecords(
237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      int64 version_id,
238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      std::vector<int64>* newly_purgeable_resources,
239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      leveldb::WriteBatch* batch);
240cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
241cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Reads resource ids for |id_key_prefix| from the database. Returns OK if
242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // it's successfully read or not found in the database. Otherwise, returns an
243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // error.
244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Status ReadResourceIds(
245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const char* id_key_prefix,
246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      std::set<int64>* ids);
247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Write resource ids for |id_key_prefix| into the database. Returns OK on
249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // success. Otherwise, returns writes nothing and returns an error.
250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Status WriteResourceIds(
251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const char* id_key_prefix,
252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const std::set<int64>& ids);
253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Status WriteResourceIdsInBatch(
254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const char* id_key_prefix,
255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const std::set<int64>& ids,
256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      leveldb::WriteBatch* batch);
257cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
258cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Deletes resource ids for |id_key_prefix| from the database. Returns OK if
259cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // it's successfully deleted or not found in the database. Otherwise, returns
260cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // an error.
261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Status DeleteResourceIds(
262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const char* id_key_prefix,
263cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const std::set<int64>& ids);
264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Status DeleteResourceIdsInBatch(
265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const char* id_key_prefix,
266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const std::set<int64>& ids,
267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      leveldb::WriteBatch* batch);
268010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
269010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Reads the current schema version from the database. If the database hasn't
270cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // been written anything yet, sets |db_version| to 0 and returns OK.
271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Status ReadDatabaseVersion(int64* db_version);
2725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Writes a batch into the database.
2745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // NOTE: You must call this when you want to put something into the database
2755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // because this initializes the database if needed.
276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Status WriteBatch(leveldb::WriteBatch* batch);
2775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
2785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Bumps the next available id if |used_id| is greater than or equal to the
2795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // cached one.
280cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void BumpNextRegistrationIdIfNeeded(
281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      int64 used_id,
282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      leveldb::WriteBatch* batch);
283116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void BumpNextResourceIdIfNeeded(
284116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      int64 used_id,
285116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      leveldb::WriteBatch* batch);
286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void BumpNextVersionIdIfNeeded(
287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      int64 used_id,
288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      leveldb::WriteBatch* batch);
2890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  bool IsOpen();
2915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
29246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void Disable(
293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const tracked_objects::Location& from_here,
29446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      Status status);
29546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void HandleOpenResult(
29646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      const tracked_objects::Location& from_here,
29746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      Status status);
29846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void HandleReadResult(
29946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      const tracked_objects::Location& from_here,
30046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      Status status);
30146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void HandleWriteResult(
30246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      const tracked_objects::Location& from_here,
30346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      Status status);
3040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  base::FilePath path_;
3060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<leveldb::Env> env_;
3070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<leveldb::DB> db_;
3080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  int64 next_avail_registration_id_;
3105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  int64 next_avail_resource_id_;
3115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  int64 next_avail_version_id_;
3125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
313cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  enum State {
314cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    UNINITIALIZED,
315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    INITIALIZED,
316cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DISABLED,
317cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  };
318cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  State state_;
3195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
3200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  base::SequenceChecker sequence_checker_;
3210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDatabaseTest, OpenDatabase);
3230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDatabaseTest, OpenDatabase_InMemory);
324010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDatabaseTest, DatabaseVersion);
3250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDatabaseTest, GetNextAvailableIds);
326f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDatabaseTest, DestroyDatabase);
3270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DISALLOW_COPY_AND_ASSIGN(ServiceWorkerDatabase);
3290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch};
3300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}  // namespace content
3320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#endif  // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_DATABASE_H_
334