1/*
2 * Copyright (C) 2016 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#if ENABLE(INDEXED_DATABASE)
29
30#include "IDBBackingStore.h"
31#include "IDBDatabaseIdentifier.h"
32#include "IDBDatabaseInfo.h"
33#include "IDBResourceIdentifier.h"
34#include "SQLiteIDBTransaction.h"
35#include <JavaScriptCore/Strong.h>
36#include <wtf/HashMap.h>
37
38namespace WebCore {
39
40class IndexKey;
41class SQLiteDatabase;
42class SQLiteStatement;
43
44namespace IDBServer {
45
46class SQLiteIDBCursor;
47
48class SQLiteIDBBackingStore : public IDBBackingStore {
49 WTF_MAKE_FAST_ALLOCATED;
50public:
51 SQLiteIDBBackingStore(const IDBDatabaseIdentifier&, const String& databaseRootDirectory, IDBBackingStoreTemporaryFileHandler&, uint64_t quota);
52
53 ~SQLiteIDBBackingStore() final;
54
55 IDBError getOrEstablishDatabaseInfo(IDBDatabaseInfo&) final;
56
57 IDBError beginTransaction(const IDBTransactionInfo&) final;
58 IDBError abortTransaction(const IDBResourceIdentifier& transactionIdentifier) final;
59 IDBError commitTransaction(const IDBResourceIdentifier& transactionIdentifier) final;
60 IDBError createObjectStore(const IDBResourceIdentifier& transactionIdentifier, const IDBObjectStoreInfo&) final;
61 IDBError deleteObjectStore(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier) final;
62 IDBError renameObjectStore(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const String& newName) final;
63 IDBError clearObjectStore(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier) final;
64 IDBError createIndex(const IDBResourceIdentifier& transactionIdentifier, const IDBIndexInfo&) final;
65 IDBError deleteIndex(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier) final;
66 IDBError renameIndex(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const String& newName) final;
67 IDBError keyExistsInObjectStore(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&, bool& keyExists) final;
68 IDBError deleteRange(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyRangeData&) final;
69 IDBError addRecord(const IDBResourceIdentifier& transactionIdentifier, const IDBObjectStoreInfo&, const IDBKeyData&, const IDBValue&) final;
70 IDBError getRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyRangeData&, IDBGetRecordDataType, IDBGetResult& outValue) final;
71 IDBError getAllRecords(const IDBResourceIdentifier& transactionIdentifier, const IDBGetAllRecordsData&, IDBGetAllResult& outValue) final;
72 IDBError getIndexRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, IndexedDB::IndexRecordType, const IDBKeyRangeData&, IDBGetResult& outValue) final;
73 IDBError getCount(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const IDBKeyRangeData&, uint64_t& outCount) final;
74 IDBError generateKeyNumber(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t& keyNumber) final;
75 IDBError revertGeneratedKeyNumber(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t keyNumber) final;
76 IDBError maybeUpdateKeyGeneratorNumber(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, double newKeyNumber) final;
77 IDBError openCursor(const IDBResourceIdentifier& transactionIdentifier, const IDBCursorInfo&, IDBGetResult& outResult) final;
78 IDBError iterateCursor(const IDBResourceIdentifier& transactionIdentifier, const IDBResourceIdentifier& cursorIdentifier, const IDBIterateCursorData&, IDBGetResult& outResult) final;
79 bool prefetchCursor(const IDBResourceIdentifier&, const IDBResourceIdentifier&) final;
80
81 IDBObjectStoreInfo* infoForObjectStore(uint64_t objectStoreIdentifier) final;
82 void deleteBackingStore() final;
83
84 void setQuota(uint64_t quota) final { m_quota = quota; }
85 uint64_t databasesSizeForOrigin() const final;
86
87 bool supportsSimultaneousTransactions() final { return false; }
88 bool isEphemeral() final { return false; }
89
90 void unregisterCursor(SQLiteIDBCursor&);
91
92 IDBBackingStoreTemporaryFileHandler& temporaryFileHandler() const { return m_temporaryFileHandler; }
93
94 IDBError getBlobRecordsForObjectStoreRecord(int64_t objectStoreRecord, Vector<String>& blobURLs, PAL::SessionID&, Vector<String>& blobFilePaths);
95
96 static String databaseNameFromEncodedFilename(const String&);
97 static uint64_t databasesSizeForFolder(const String& folder);
98
99 String databaseDirectory() const { return m_databaseDirectory; };
100 static String fullDatabasePathForDirectory(const String&);
101 static String databaseNameFromFile(const String&);
102
103 bool hasTransaction(const IDBResourceIdentifier&) const final;
104private:
105 String filenameForDatabaseName() const;
106 String fullDatabasePath() const;
107 String fullDatabaseDirectoryWithUpgrade();
108
109 uint64_t quotaForOrigin() const;
110 uint64_t maximumSize() const;
111
112 bool ensureValidRecordsTable();
113 bool ensureValidIndexRecordsTable();
114 bool ensureValidIndexRecordsIndex();
115 bool ensureValidBlobTables();
116 std::unique_ptr<IDBDatabaseInfo> createAndPopulateInitialDatabaseInfo();
117 std::unique_ptr<IDBDatabaseInfo> extractExistingDatabaseInfo();
118
119 IDBError deleteRecord(SQLiteIDBTransaction&, int64_t objectStoreID, const IDBKeyData&);
120 IDBError uncheckedGetKeyGeneratorValue(int64_t objectStoreID, uint64_t& outValue);
121 IDBError uncheckedSetKeyGeneratorValue(int64_t objectStoreID, uint64_t value);
122
123 IDBError updateAllIndexesForAddRecord(const IDBObjectStoreInfo&, const IDBKeyData&, const ThreadSafeDataBuffer& value, int64_t recordID);
124 IDBError updateOneIndexForAddRecord(const IDBIndexInfo&, const IDBKeyData&, const ThreadSafeDataBuffer& value, int64_t recordID);
125 IDBError uncheckedPutIndexKey(const IDBIndexInfo&, const IDBKeyData& keyValue, const IndexKey&, int64_t recordID);
126 IDBError uncheckedPutIndexRecord(int64_t objectStoreID, int64_t indexID, const IDBKeyData& keyValue, const IDBKeyData& indexKey, int64_t recordID);
127 IDBError uncheckedHasIndexRecord(const IDBIndexInfo&, const IDBKeyData&, bool& hasRecord);
128 IDBError uncheckedGetIndexRecordForOneKey(int64_t indexeID, int64_t objectStoreID, IndexedDB::IndexRecordType, const IDBKeyData&, IDBGetResult&);
129
130 IDBError deleteUnusedBlobFileRecords(SQLiteIDBTransaction&);
131
132 IDBError getAllObjectStoreRecords(const IDBResourceIdentifier& transactionIdentifier, const IDBGetAllRecordsData&, IDBGetAllResult& outValue);
133 IDBError getAllIndexRecords(const IDBResourceIdentifier& transactionIdentifier, const IDBGetAllRecordsData&, IDBGetAllResult& outValue);
134
135 void closeSQLiteDB();
136
137 enum class SQL : size_t {
138 CreateObjectStoreInfo,
139 CreateObjectStoreKeyGenerator,
140 DeleteObjectStoreInfo,
141 DeleteObjectStoreKeyGenerator,
142 DeleteObjectStoreRecords,
143 DeleteObjectStoreIndexInfo,
144 DeleteObjectStoreIndexRecords,
145 DeleteObjectStoreBlobRecords,
146 RenameObjectStore,
147 ClearObjectStoreRecords,
148 ClearObjectStoreIndexRecords,
149 CreateIndexInfo,
150 DeleteIndexInfo,
151 HasIndexRecord,
152 PutIndexRecord,
153 GetIndexRecordForOneKey,
154 DeleteIndexRecords,
155 RenameIndex,
156 KeyExistsInObjectStore,
157 GetUnusedBlobFilenames,
158 DeleteUnusedBlobs,
159 GetObjectStoreRecordID,
160 DeleteBlobRecord,
161 DeleteObjectStoreRecord,
162 DeleteObjectStoreIndexRecord,
163 AddObjectStoreRecord,
164 AddBlobRecord,
165 BlobFilenameForBlobURL,
166 AddBlobFilename,
167 GetBlobURL,
168 GetKeyGeneratorValue,
169 SetKeyGeneratorValue,
170 GetAllKeyRecordsLowerOpenUpperOpen,
171 GetAllKeyRecordsLowerOpenUpperClosed,
172 GetAllKeyRecordsLowerClosedUpperOpen,
173 GetAllKeyRecordsLowerClosedUpperClosed,
174 GetValueRecordsLowerOpenUpperOpen,
175 GetValueRecordsLowerOpenUpperClosed,
176 GetValueRecordsLowerClosedUpperOpen,
177 GetValueRecordsLowerClosedUpperClosed,
178 GetKeyRecordsLowerOpenUpperOpen,
179 GetKeyRecordsLowerOpenUpperClosed,
180 GetKeyRecordsLowerClosedUpperOpen,
181 GetKeyRecordsLowerClosedUpperClosed,
182 Count
183 };
184
185 SQLiteStatement* cachedStatement(SQL, const char*);
186 SQLiteStatement* cachedStatementForGetAllObjectStoreRecords(const IDBGetAllRecordsData&);
187
188 std::unique_ptr<SQLiteStatement> m_cachedStatements[static_cast<int>(SQL::Count)];
189
190 JSC::VM& vm();
191 JSC::JSGlobalObject& globalObject();
192 void initializeVM();
193
194 IDBDatabaseIdentifier m_identifier;
195 std::unique_ptr<IDBDatabaseInfo> m_databaseInfo;
196 std::unique_ptr<IDBDatabaseInfo> m_originalDatabaseInfoBeforeVersionChange;
197
198 std::unique_ptr<SQLiteDatabase> m_sqliteDB;
199
200 HashMap<IDBResourceIdentifier, std::unique_ptr<SQLiteIDBTransaction>> m_transactions;
201 HashMap<IDBResourceIdentifier, SQLiteIDBCursor*> m_cursors;
202
203 String m_databaseRootDirectory;
204 String m_databaseDirectory;
205
206 RefPtr<JSC::VM> m_vm;
207 JSC::Strong<JSC::JSGlobalObject> m_globalObject;
208
209 IDBBackingStoreTemporaryFileHandler& m_temporaryFileHandler;
210
211 uint64_t m_quota;
212};
213
214} // namespace IDBServer
215} // namespace WebCore
216
217#endif // ENABLE(INDEXED_DATABASE)
218