1/*
2 * Copyright (C) 2010 Google 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 *
8 * 1.  Redistributions of source code must retain the above copyright
9 *     notice, this list of conditions and the following disclaimer.
10 * 2.  Redistributions in binary form must reproduce the above copyright
11 *     notice, this list of conditions and the following disclaimer in the
12 *     documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef IDBTransaction_h
27#define IDBTransaction_h
28
29#include "bindings/v8/ScriptWrappable.h"
30#include "core/dom/ActiveDOMObject.h"
31#include "core/dom/DOMError.h"
32#include "core/events/Event.h"
33#include "core/events/EventListener.h"
34#include "core/events/EventTarget.h"
35#include "core/events/ThreadLocalEventNames.h"
36#include "modules/indexeddb/IDBMetadata.h"
37#include "modules/indexeddb/IndexedDB.h"
38#include "public/platform/WebIDBDatabase.h"
39#include "wtf/HashSet.h"
40#include "wtf/RefCounted.h"
41
42namespace WebCore {
43
44class DOMError;
45class ExceptionState;
46class IDBCursor;
47class IDBDatabase;
48class IDBObjectStore;
49class IDBOpenDBRequest;
50struct IDBObjectStoreMetadata;
51
52class IDBTransaction : public ScriptWrappable, public RefCounted<IDBTransaction>, public EventTargetWithInlineData, public ActiveDOMObject {
53    REFCOUNTED_EVENT_TARGET(IDBTransaction);
54
55public:
56    static PassRefPtr<IDBTransaction> create(ExecutionContext*, int64_t, const Vector<String>& objectStoreNames, IndexedDB::TransactionMode, IDBDatabase*);
57    static PassRefPtr<IDBTransaction> create(ExecutionContext*, int64_t, IDBDatabase*, IDBOpenDBRequest*, const IDBDatabaseMetadata& previousMetadata);
58    virtual ~IDBTransaction();
59
60    static const AtomicString& modeReadOnly();
61    static const AtomicString& modeReadWrite();
62    static const AtomicString& modeVersionChange();
63
64    static IndexedDB::TransactionMode stringToMode(const String&, ExceptionState&);
65    static const AtomicString& modeToString(IndexedDB::TransactionMode);
66
67    blink::WebIDBDatabase* backendDB() const;
68
69    int64_t id() const { return m_id; }
70    bool isActive() const { return m_state == Active; }
71    bool isFinished() const { return m_state == Finished; }
72    bool isReadOnly() const { return m_mode == IndexedDB::TransactionReadOnly; }
73    bool isVersionChange() const { return m_mode == IndexedDB::TransactionVersionChange; }
74
75    // Implement the IDBTransaction IDL
76    const String& mode() const;
77    IDBDatabase* db() const { return m_database.get(); }
78    PassRefPtr<DOMError> error() const { return m_error; }
79    PassRefPtr<IDBObjectStore> objectStore(const String& name, ExceptionState&);
80    void abort(ExceptionState&);
81
82    void registerRequest(IDBRequest*);
83    void unregisterRequest(IDBRequest*);
84    void objectStoreCreated(const String&, PassRefPtr<IDBObjectStore>);
85    void objectStoreDeleted(const String&);
86    void setActive(bool);
87    void setError(PassRefPtr<DOMError>);
88
89    DEFINE_ATTRIBUTE_EVENT_LISTENER(abort);
90    DEFINE_ATTRIBUTE_EVENT_LISTENER(complete);
91    DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
92
93    virtual void onAbort(PassRefPtr<DOMError>);
94    virtual void onComplete();
95
96    // EventTarget
97    virtual const AtomicString& interfaceName() const OVERRIDE;
98    virtual ExecutionContext* executionContext() const OVERRIDE;
99
100    using EventTarget::dispatchEvent;
101    virtual bool dispatchEvent(PassRefPtr<Event>) OVERRIDE;
102
103    // ActiveDOMObject
104    virtual bool hasPendingActivity() const OVERRIDE;
105    virtual void stop() OVERRIDE;
106
107private:
108    IDBTransaction(ExecutionContext*, int64_t, const Vector<String>&, IndexedDB::TransactionMode, IDBDatabase*, IDBOpenDBRequest*, const IDBDatabaseMetadata&);
109
110    void enqueueEvent(PassRefPtr<Event>);
111
112    enum State {
113        Inactive, // Created or started, but not in an event callback
114        Active, // Created or started, in creation scope or an event callback
115        Finishing, // In the process of aborting or completing.
116        Finished, // No more events will fire and no new requests may be filed.
117    };
118
119    int64_t m_id;
120    RefPtr<IDBDatabase> m_database;
121    const Vector<String> m_objectStoreNames;
122    IDBOpenDBRequest* m_openDBRequest;
123    const IndexedDB::TransactionMode m_mode;
124    State m_state;
125    bool m_hasPendingActivity;
126    bool m_contextStopped;
127    RefPtr<DOMError> m_error;
128
129    ListHashSet<RefPtr<IDBRequest> > m_requestList;
130
131    typedef HashMap<String, RefPtr<IDBObjectStore> > IDBObjectStoreMap;
132    IDBObjectStoreMap m_objectStoreMap;
133
134    typedef HashSet<RefPtr<IDBObjectStore> > IDBObjectStoreSet;
135    IDBObjectStoreSet m_deletedObjectStores;
136
137    typedef HashMap<RefPtr<IDBObjectStore>, IDBObjectStoreMetadata> IDBObjectStoreMetadataMap;
138    IDBObjectStoreMetadataMap m_objectStoreCleanupMap;
139    IDBDatabaseMetadata m_previousMetadata;
140};
141
142} // namespace WebCore
143
144#endif // IDBTransaction_h
145