initial import
[vuplus_webkit] / Source / WebCore / storage / IDBObjectStore.cpp
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 #include "config.h"
27 #include "IDBObjectStore.h"
28
29 #if ENABLE(INDEXED_DATABASE)
30
31 #include "DOMStringList.h"
32 #include "IDBAny.h"
33 #include "IDBDatabaseException.h"
34 #include "IDBIndex.h"
35 #include "IDBKey.h"
36 #include "IDBKeyPath.h"
37 #include "IDBKeyRange.h"
38 #include "IDBTransaction.h"
39 #include "SerializedScriptValue.h"
40 #include <wtf/UnusedParam.h>
41
42 namespace WebCore {
43
44 static const unsigned short defaultDirection = IDBCursor::NEXT;
45
46 IDBObjectStore::IDBObjectStore(PassRefPtr<IDBObjectStoreBackendInterface> idbObjectStore, IDBTransaction* transaction)
47     : m_objectStore(idbObjectStore)
48     , m_transaction(transaction)
49 {
50     ASSERT(m_objectStore);
51     ASSERT(m_transaction);
52     // We pass a reference to this object before it can be adopted.
53     relaxAdoptionRequirement();
54 }
55
56 String IDBObjectStore::name() const
57 {
58     return m_objectStore->name();
59 }
60
61 String IDBObjectStore::keyPath() const
62 {
63     return m_objectStore->keyPath();
64 }
65
66 PassRefPtr<DOMStringList> IDBObjectStore::indexNames() const
67 {
68     return m_objectStore->indexNames();
69 }
70
71 PassRefPtr<IDBRequest> IDBObjectStore::get(ScriptExecutionContext* context, PassRefPtr<IDBKey> key, ExceptionCode& ec)
72 {
73     RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get());
74     m_objectStore->get(key, request, m_transaction->backend(), ec);
75     if (ec) {
76         request->markEarlyDeath();
77         return 0;
78     }
79     return request.release();
80 }
81
82 PassRefPtr<IDBRequest> IDBObjectStore::add(ScriptExecutionContext* context, PassRefPtr<SerializedScriptValue> value, PassRefPtr<IDBKey> key, ExceptionCode& ec)
83 {
84     RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get());
85     m_objectStore->put(value, key, IDBObjectStoreBackendInterface::AddOnly, request, m_transaction->backend(), ec);
86     if (ec) {
87         request->markEarlyDeath();
88         return 0;
89     }
90     return request.release();
91 }
92
93 PassRefPtr<IDBRequest> IDBObjectStore::put(ScriptExecutionContext* context, PassRefPtr<SerializedScriptValue> value, PassRefPtr<IDBKey> key, ExceptionCode& ec)
94 {
95     RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get());
96     m_objectStore->put(value, key, IDBObjectStoreBackendInterface::AddOrUpdate, request, m_transaction->backend(), ec);
97     if (ec) {
98         request->markEarlyDeath();
99         return 0;
100     }
101     return request.release();
102 }
103
104 PassRefPtr<IDBRequest> IDBObjectStore::deleteFunction(ScriptExecutionContext* context, PassRefPtr<IDBKey> key, ExceptionCode& ec)
105 {
106     RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get());
107     m_objectStore->deleteFunction(key, request, m_transaction->backend(), ec);
108     if (ec) {
109         request->markEarlyDeath();
110         return 0;
111     }
112     return request.release();
113 }
114
115 PassRefPtr<IDBRequest> IDBObjectStore::clear(ScriptExecutionContext* context, ExceptionCode& ec)
116 {
117     RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get());
118     m_objectStore->clear(request, m_transaction->backend(), ec);
119     if (ec) {
120         request->markEarlyDeath();
121         return 0;
122     }
123     return request.release();
124 }
125
126 PassRefPtr<IDBIndex> IDBObjectStore::createIndex(const String& name, const String& keyPath, const OptionsObject& options, ExceptionCode& ec)
127 {
128     if (!IDBIsValidKeyPath(keyPath)) {
129         ec = IDBDatabaseException::NON_TRANSIENT_ERR;
130         return 0;
131     }
132
133     bool unique = false;
134     options.getKeyBool("unique", unique);
135
136     RefPtr<IDBIndexBackendInterface> index = m_objectStore->createIndex(name, keyPath, unique, m_transaction->backend(), ec);
137     ASSERT(!index != !ec); // If we didn't get an index, we should have gotten an exception code. And vice versa.
138     if (!index)
139         return 0;
140     return IDBIndex::create(index.release(), this, m_transaction.get());
141 }
142
143 PassRefPtr<IDBIndex> IDBObjectStore::index(const String& name, ExceptionCode& ec)
144 {
145     RefPtr<IDBIndexBackendInterface> index = m_objectStore->index(name, ec);
146     ASSERT(!index != !ec); // If we didn't get an index, we should have gotten an exception code. And vice versa.
147     if (!index)
148         return 0;
149     return IDBIndex::create(index.release(), this, m_transaction.get());
150 }
151
152 void IDBObjectStore::deleteIndex(const String& name, ExceptionCode& ec)
153 {
154     m_objectStore->deleteIndex(name, m_transaction->backend(), ec);
155 }
156
157 PassRefPtr<IDBRequest> IDBObjectStore::openCursor(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> range, unsigned short direction, ExceptionCode& ec)
158 {
159     if (direction != IDBCursor::NEXT && direction != IDBCursor::NEXT_NO_DUPLICATE && direction != IDBCursor::PREV && direction != IDBCursor::PREV_NO_DUPLICATE) {
160         // FIXME: May need to change when specced: http://www.w3.org/Bugs/Public/show_bug.cgi?id=11406
161         ec = IDBDatabaseException::CONSTRAINT_ERR;
162         return 0;
163     }
164
165     RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get());
166     request->setCursorType(IDBCursorBackendInterface::ObjectStoreCursor);
167     m_objectStore->openCursor(range, direction, request, m_transaction->backend(), ec);
168     if (ec) {
169         request->markEarlyDeath();
170         return 0;
171     }
172     return request.release();
173 }
174
175 } // namespace WebCore
176
177 #endif // ENABLE(INDEXED_DATABASE)