summaryrefslogtreecommitdiffstats
path: root/webkit/dom_storage/dom_storage_database.h
blob: e651a555bfd31ac7dc32e974ad7772153ec24d97 (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
// Copyright (c) 2012 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_DOM_STORAGE_DOM_STORAGE_DATABASE_H_
#define WEBKIT_DOM_STORAGE_DOM_STORAGE_DATABASE_H_
#pragma once

#include <map>

#include "base/file_path.h"
#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/nullable_string16.h"
#include "base/string16.h"
#include "sql/connection.h"
#include "webkit/dom_storage/dom_storage_types.h"

namespace dom_storage {

// Represents a SQLite based backing for DOM storage data. This
// class is designed to be used on a single thread.
class DomStorageDatabase {
 public:
  explicit DomStorageDatabase(const FilePath& file_path);
  ~DomStorageDatabase();

  // Reads all the key, value pairs stored in the database and returns
  // them. |result| is assumed to be empty and any duplicate keys will
  // be overwritten. If the database exists on disk then it will be
  // opened. If it does not exist then it will not be created and
  // |result| will be unmodified.
  void ReadAllValues(ValuesMap* result);

  // Updates the backing database. Will remove all keys before updating
  // the database if |clear_all_first| is set. Then all entries in
  // |changes| will be examined - keys mapped to a null NullableString16
  // will be removed and all others will be inserted/updated as appropriate.
  bool CommitChanges(bool clear_all_first, const ValuesMap& changes);

 private:
  FRIEND_TEST_ALL_PREFIXES(DomStorageDatabaseTest, SimpleOpenAndClose);
  FRIEND_TEST_ALL_PREFIXES(DomStorageDatabaseTest, TestLazyOpenIsLazy);
  FRIEND_TEST_ALL_PREFIXES(DomStorageDatabaseTest, TestDetectSchemaVersion);
  FRIEND_TEST_ALL_PREFIXES(DomStorageDatabaseTest,
                           TestLazyOpenUpgradesDatabase);
  FRIEND_TEST_ALL_PREFIXES(DomStorageDatabaseTest, SimpleWriteAndReadBack);
  FRIEND_TEST_ALL_PREFIXES(DomStorageDatabaseTest, WriteWithClear);
  FRIEND_TEST_ALL_PREFIXES(DomStorageDatabaseTest,
                           UpgradeFromV1ToV2WithData);
  FRIEND_TEST_ALL_PREFIXES(DomStorageDatabaseTest, TestSimpleRemoveOneValue);
  FRIEND_TEST_ALL_PREFIXES(DomStorageDatabaseTest,
                           TestCanOpenAndReadWebCoreDatabase);
  FRIEND_TEST_ALL_PREFIXES(DomStorageDatabaseTest,
                           TestCanOpenFileThatIsNotADatabase);

  enum SchemaVersion {
    INVALID,
    V1,
    V2
  };

  // Open the database at file_path_ if it exists already and creates it if
  // |create_if_needed| is true.
  // Ensures we are at the correct database version and creates or updates
  // tables as necessary. Returns false on failure.
  bool LazyOpen(bool create_if_needed);

  // Analyses the database to verify that the connection that is open is indeed
  // a valid database and works out the schema version.
  SchemaVersion DetectSchemaVersion();

  // Creates the database table at V2. Returns true if the table was created
  // successfully, false otherwise. Will return false if the table already
  // exists.
  bool CreateTableV2();

  // If we have issues while trying to open the file (corrupted databse,
  // failing to upgrade, that sort of thing) this function will remove
  // the file from disk and attempt to create a new database from
  // scratch.
  bool DeleteFileAndRecreate();

  // Version 1 -> 2 migrates the value column in the ItemTable from a TEXT
  // to a BLOB. Exisitng data is preserved on success. Returns false if the
  // upgrade failed. If true is returned, the database is guaranteed to be at
  // version 2.
  bool UpgradeVersion1To2();

  void Close();
  bool IsOpen() const { return db_.get() ? db_->is_open() : false; }

#ifdef UNIT_TEST
  // This constructor allows us to bypass the DCHECK in the public
  // constructor that normally verifies a valid file path was passed to
  // back the database on disk. We want to be able to run unit tests
  // from in-memory databases where possible, so we use an empty
  // backing file path to signify we should open the database in memory
  // inside LazyOpen. This constructor will allow us to bypass the
  // DCHECK when running the unit tests.
  DomStorageDatabase();
#endif

  // Path to the database on disk.
  FilePath file_path_;
  scoped_ptr<sql::Connection> db_;
  bool failed_to_open_;
  bool tried_to_recreate_;
};

}  // namespace dom_storage

#endif  // WEBKIT_DOM_STORAGE_DOM_STORAGE_DATABASE_H_