1/*
2 * Copyright (C) 2015, 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 "EventTarget.h"
31#include "IDBActiveDOMObject.h"
32#include "IDBConnectionProxy.h"
33#include "IDBDatabaseInfo.h"
34#include "IDBKeyPath.h"
35#include "IDBTransactionMode.h"
36
37namespace WebCore {
38
39class DOMStringList;
40class IDBObjectStore;
41class IDBOpenDBRequest;
42class IDBResultData;
43class IDBTransaction;
44class IDBTransactionInfo;
45
46struct EventNames;
47
48class IDBDatabase final : public ThreadSafeRefCounted<IDBDatabase>, public EventTargetWithInlineData, public IDBActiveDOMObject {
49 WTF_MAKE_ISO_ALLOCATED(IDBDatabase);
50public:
51 static Ref<IDBDatabase> create(ScriptExecutionContext&, IDBClient::IDBConnectionProxy&, const IDBResultData&);
52
53 virtual ~IDBDatabase();
54
55 // IDBDatabase IDL
56 const String name() const;
57 uint64_t version() const;
58 Ref<DOMStringList> objectStoreNames() const;
59
60 struct ObjectStoreParameters {
61 Optional<IDBKeyPath> keyPath;
62 bool autoIncrement;
63 };
64
65 ExceptionOr<Ref<IDBObjectStore>> createObjectStore(const String& name, ObjectStoreParameters&&);
66
67 using StringOrVectorOfStrings = WTF::Variant<String, Vector<String>>;
68 ExceptionOr<Ref<IDBTransaction>> transaction(StringOrVectorOfStrings&& storeNames, IDBTransactionMode);
69 ExceptionOr<void> deleteObjectStore(const String& name);
70 void close();
71
72 void renameObjectStore(IDBObjectStore&, const String& newName);
73 void renameIndex(IDBIndex&, const String& newName);
74
75 // EventTarget
76 EventTargetInterface eventTargetInterface() const final { return IDBDatabaseEventTargetInterfaceType; }
77 ScriptExecutionContext* scriptExecutionContext() const final { return ActiveDOMObject::scriptExecutionContext(); }
78 void refEventTarget() final { ThreadSafeRefCounted<IDBDatabase>::ref(); }
79 void derefEventTarget() final { ThreadSafeRefCounted<IDBDatabase>::deref(); }
80
81 using ThreadSafeRefCounted<IDBDatabase>::ref;
82 using ThreadSafeRefCounted<IDBDatabase>::deref;
83
84 const char* activeDOMObjectName() const final;
85 bool canSuspendForDocumentSuspension() const final;
86 void stop() final;
87
88 const IDBDatabaseInfo& info() const { return m_info; }
89 uint64_t databaseConnectionIdentifier() const { return m_databaseConnectionIdentifier; }
90
91 Ref<IDBTransaction> startVersionChangeTransaction(const IDBTransactionInfo&, IDBOpenDBRequest&);
92 void didStartTransaction(IDBTransaction&);
93
94 void willCommitTransaction(IDBTransaction&);
95 void didCommitTransaction(IDBTransaction&);
96 void willAbortTransaction(IDBTransaction&);
97 void didAbortTransaction(IDBTransaction&);
98
99 void fireVersionChangeEvent(const IDBResourceIdentifier& requestIdentifier, uint64_t requestedVersion);
100 void didCloseFromServer(const IDBError&);
101 void connectionToServerLost(const IDBError&);
102
103 IDBClient::IDBConnectionProxy& connectionProxy() { return m_connectionProxy.get(); }
104
105 void didCreateIndexInfo(const IDBIndexInfo&);
106 void didDeleteIndexInfo(const IDBIndexInfo&);
107
108 bool isClosingOrClosed() const { return m_closePending || m_closedInServer; }
109
110 void dispatchEvent(Event&) final;
111
112 bool hasPendingActivity() const final;
113
114private:
115 IDBDatabase(ScriptExecutionContext&, IDBClient::IDBConnectionProxy&, const IDBResultData&);
116
117 void didCommitOrAbortTransaction(IDBTransaction&);
118
119 void maybeCloseInServer();
120
121 Ref<IDBClient::IDBConnectionProxy> m_connectionProxy;
122 IDBDatabaseInfo m_info;
123 uint64_t m_databaseConnectionIdentifier { 0 };
124
125 bool m_closePending { false };
126 bool m_closedInServer { false };
127
128 RefPtr<IDBTransaction> m_versionChangeTransaction;
129 HashMap<IDBResourceIdentifier, RefPtr<IDBTransaction>> m_activeTransactions;
130 HashMap<IDBResourceIdentifier, RefPtr<IDBTransaction>> m_committingTransactions;
131 HashMap<IDBResourceIdentifier, RefPtr<IDBTransaction>> m_abortingTransactions;
132
133 const EventNames& m_eventNames; // Need to cache this so we can use it from GC threads.
134};
135
136} // namespace WebCore
137
138#endif // ENABLE(INDEXED_DATABASE)
139