18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
22daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * Copyright (C) 2011 Google Inc. All rights reserved.
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met:
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1.  Redistributions of source code must retain the above copyright
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     notice, this list of conditions and the following disclaimer.
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2.  Redistributions in binary form must reproduce the above copyright
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     notice, this list of conditions and the following disclaimer in the
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     documentation and/or other materials provided with the distribution.
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
255af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
26dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "config.h"
27dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#include "IDBDatabaseBackendImpl.h"
285af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
29a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#if ENABLE(INDEXED_DATABASE)
30a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
31a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "CrossThreadTask.h"
325af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke#include "DOMStringList.h"
3381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "IDBBackingStore.h"
34545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch#include "IDBDatabaseException.h"
3528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu#include "IDBFactoryBackendImpl.h"
36dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#include "IDBObjectStoreBackendImpl.h"
3728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu#include "IDBTransactionBackendImpl.h"
38e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#include "IDBTransactionCoordinator.h"
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochclass IDBDatabaseBackendImpl::PendingSetVersionCall : public RefCounted<PendingSetVersionCall> {
4381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochpublic:
4481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    static PassRefPtr<PendingSetVersionCall> create(const String& version, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBDatabaseCallbacks> databaseCallbacks)
4581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    {
4681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return adoptRef(new PendingSetVersionCall(version, callbacks, databaseCallbacks));
47f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    }
4881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    String version() { return m_version; }
4981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    PassRefPtr<IDBCallbacks> callbacks() { return m_callbacks; }
5081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    PassRefPtr<IDBDatabaseCallbacks> databaseCallbacks() { return m_databaseCallbacks; }
5181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
5281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochprivate:
5381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    PendingSetVersionCall(const String& version, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBDatabaseCallbacks> databaseCallbacks)
5481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        : m_version(version)
5581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        , m_callbacks(callbacks)
5681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        , m_databaseCallbacks(databaseCallbacks)
5781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    {
58f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    }
5981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    String m_version;
6081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    RefPtr<IDBCallbacks> m_callbacks;
6181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    RefPtr<IDBDatabaseCallbacks> m_databaseCallbacks;
6281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch};
63f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
6481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen MurdochIDBDatabaseBackendImpl::IDBDatabaseBackendImpl(const String& name, IDBBackingStore* backingStore, IDBTransactionCoordinator* coordinator, IDBFactoryBackendImpl* factory, const String& uniqueIdentifier)
6581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    : m_backingStore(backingStore)
66e14391e94c850b8bd03680c23b38978db68687a8John Reck    , m_id(InvalidId)
67f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    , m_name(name)
68f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    , m_version("")
6928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    , m_identifier(uniqueIdentifier)
7028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    , m_factory(factory)
71e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    , m_transactionCoordinator(coordinator)
72f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick{
73f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    ASSERT(!m_name.isNull());
74f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
7581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    bool success = m_backingStore->extractIDBDatabaseMetaData(m_name, m_version, m_id);
76e14391e94c850b8bd03680c23b38978db68687a8John Reck    ASSERT_UNUSED(success, success == (m_id != InvalidId));
7781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (!m_backingStore->setIDBDatabaseMetaData(m_name, m_version, m_id, m_id == InvalidId))
78e14391e94c850b8bd03680c23b38978db68687a8John Reck        ASSERT_NOT_REACHED(); // FIXME: Need better error handling.
79e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    loadObjectStores();
805af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke}
815af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
82dd8bb3de4f353a81954234999f1fea748aee2ea9Ben MurdochIDBDatabaseBackendImpl::~IDBDatabaseBackendImpl()
835af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{
8428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    m_factory->removeIDBDatabaseBackend(m_identifier);
855af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke}
865af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
8781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen MurdochPassRefPtr<IDBBackingStore> IDBDatabaseBackendImpl::backingStore() const
88e14391e94c850b8bd03680c23b38978db68687a8John Reck{
8981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return m_backingStore;
90f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick}
91f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
924576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) WangPassRefPtr<DOMStringList> IDBDatabaseBackendImpl::objectStoreNames() const
935af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{
94545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    RefPtr<DOMStringList> objectStoreNames = DOMStringList::create();
95545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    for (ObjectStoreMap::const_iterator it = m_objectStores.begin(); it != m_objectStores.end(); ++it)
96545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        objectStoreNames->append(it->first);
97545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return objectStoreNames.release();
98545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch}
99545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
1002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben MurdochPassRefPtr<IDBObjectStoreBackendInterface> IDBDatabaseBackendImpl::createObjectStore(const String& name, const String& keyPath, bool autoIncrement, IDBTransactionBackendInterface* transactionPtr, ExceptionCode& ec)
101545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{
1024576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    ASSERT(transactionPtr->mode() == IDBTransaction::VERSION_CHANGE);
1034576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang
104545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (m_objectStores.contains(name)) {
1054576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        ec = IDBDatabaseException::CONSTRAINT_ERR;
106a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return 0;
107545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    }
108545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
1092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    RefPtr<IDBObjectStoreBackendImpl> objectStore = IDBObjectStoreBackendImpl::create(m_backingStore.get(), m_id, name, keyPath, autoIncrement);
110e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    ASSERT(objectStore->name() == name);
111a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
112a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    RefPtr<IDBDatabaseBackendImpl> database = this;
113a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    RefPtr<IDBTransactionBackendInterface> transaction = transactionPtr;
114a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!transaction->scheduleTask(createCallbackTask(&IDBDatabaseBackendImpl::createObjectStoreInternal, database, objectStore, transaction),
115a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                                   createCallbackTask(&IDBDatabaseBackendImpl::removeObjectStoreFromMap, database, objectStore))) {
1164576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        ec = IDBDatabaseException::NOT_ALLOWED_ERR;
117a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return 0;
118a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
119a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
120545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    m_objectStores.set(name, objectStore);
121a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return objectStore.release();
122545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch}
123545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
124a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid IDBDatabaseBackendImpl::createObjectStoreInternal(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendImpl> database, PassRefPtr<IDBObjectStoreBackendImpl> objectStore,  PassRefPtr<IDBTransactionBackendInterface> transaction)
125545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{
12681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    int64_t objectStoreId;
12781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
1282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (!database->m_backingStore->createObjectStore(database->id(), objectStore->name(), objectStore->keyPath(), objectStore->autoIncrement(), objectStoreId)) {
129a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        transaction->abort();
130a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return;
131a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
13281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
13381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    objectStore->setId(objectStoreId);
134a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    transaction->didCompleteTaskEvents();
135a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
136a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
137a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochPassRefPtr<IDBObjectStoreBackendInterface> IDBDatabaseBackendImpl::objectStore(const String& name)
138a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
139a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return m_objectStores.get(name);
140545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch}
141545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
1424576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wangvoid IDBDatabaseBackendImpl::deleteObjectStore(const String& name, IDBTransactionBackendInterface* transactionPtr, ExceptionCode& ec)
143545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{
144e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    RefPtr<IDBObjectStoreBackendImpl> objectStore = m_objectStores.get(name);
145e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    if (!objectStore) {
146a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        ec = IDBDatabaseException::NOT_FOUND_ERR;
147545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        return;
148545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    }
149a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    RefPtr<IDBDatabaseBackendImpl> database = this;
150a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    RefPtr<IDBTransactionBackendInterface> transaction = transactionPtr;
1514576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    if (!transaction->scheduleTask(createCallbackTask(&IDBDatabaseBackendImpl::deleteObjectStoreInternal, database, objectStore, transaction),
152a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                                   createCallbackTask(&IDBDatabaseBackendImpl::addObjectStoreToMap, database, objectStore))) {
153a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        ec = IDBDatabaseException::NOT_ALLOWED_ERR;
154a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return;
155a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
156a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_objectStores.remove(name);
157a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
158545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
1594576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wangvoid IDBDatabaseBackendImpl::deleteObjectStoreInternal(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendImpl> database, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBTransactionBackendInterface> transaction)
160a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
1612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    database->m_backingStore->deleteObjectStore(database->id(), objectStore->id());
162a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    transaction->didCompleteTaskEvents();
1635ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
1645ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
16581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid IDBDatabaseBackendImpl::setVersion(const String& version, PassRefPtr<IDBCallbacks> prpCallbacks, PassRefPtr<IDBDatabaseCallbacks> prpDatabaseCallbacks, ExceptionCode& ec)
1665ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
167a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    RefPtr<IDBCallbacks> callbacks = prpCallbacks;
16881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    RefPtr<IDBDatabaseCallbacks> databaseCallbacks = prpDatabaseCallbacks;
16981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (!m_databaseCallbacksSet.contains(databaseCallbacks)) {
17081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::ABORT_ERR, "Connection was closed before set version transaction was created"));
17181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return;
17281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
17381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    for (DatabaseCallbacksSet::const_iterator it = m_databaseCallbacksSet.begin(); it != m_databaseCallbacksSet.end(); ++it) {
17481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (*it != databaseCallbacks)
17581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            (*it)->onVersionChange(version);
17681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
17781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (m_databaseCallbacksSet.size() > 1) {
17881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        callbacks->onBlocked();
17981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        RefPtr<PendingSetVersionCall> pendingSetVersionCall = PendingSetVersionCall::create(version, callbacks, databaseCallbacks);
18081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_pendingSetVersionCalls.append(pendingSetVersionCall);
18181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return;
18281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
18381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
1844576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    RefPtr<DOMStringList> objectStoreNames = DOMStringList::create();
18581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    RefPtr<IDBDatabaseBackendImpl> database = this;
1862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    RefPtr<IDBTransactionBackendInterface> transaction = IDBTransactionBackendImpl::create(objectStoreNames.get(), IDBTransaction::VERSION_CHANGE, this);
187a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!transaction->scheduleTask(createCallbackTask(&IDBDatabaseBackendImpl::setVersionInternal, database, version, callbacks, transaction),
188a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                                   createCallbackTask(&IDBDatabaseBackendImpl::resetVersion, database, m_version))) {
189a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        ec = IDBDatabaseException::NOT_ALLOWED_ERR;
190a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
191a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
192a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
193a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid IDBDatabaseBackendImpl::setVersionInternal(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendImpl> database, const String& version, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBTransactionBackendInterface> transaction)
194a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
195e14391e94c850b8bd03680c23b38978db68687a8John Reck    int64_t databaseId = database->id();
196a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    database->m_version = version;
19781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (!database->m_backingStore->setIDBDatabaseMetaData(database->m_name, database->m_version, databaseId, databaseId == InvalidId)) {
198a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // FIXME: The Indexed Database specification does not have an error code dedicated to I/O errors.
199a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Error writing data to stable storage."));
200a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        transaction->abort();
201a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return;
202a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
203a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    callbacks->onSuccess(transaction);
2045af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke}
2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2062fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockPassRefPtr<IDBTransactionBackendInterface> IDBDatabaseBackendImpl::transaction(DOMStringList* objectStoreNames, unsigned short mode, ExceptionCode& ec)
207dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch{
2084576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    for (size_t i = 0; i < objectStoreNames->length(); ++i) {
2094576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        if (!m_objectStores.contains(objectStoreNames->item(i))) {
2104576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            ec = IDBDatabaseException::NOT_FOUND_ERR;
2114576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            return 0;
2124576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        }
2134576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    }
2144576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang
215a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // FIXME: Return not allowed err if close has been called.
2162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return IDBTransactionBackendImpl::create(objectStoreNames, mode, this);
217e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block}
218e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block
21981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid IDBDatabaseBackendImpl::open(PassRefPtr<IDBDatabaseCallbacks> callbacks)
220a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
22181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_databaseCallbacksSet.add(RefPtr<IDBDatabaseCallbacks>(callbacks));
222a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
223a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
22481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid IDBDatabaseBackendImpl::close(PassRefPtr<IDBDatabaseCallbacks> prpCallbacks)
225e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{
22681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    RefPtr<IDBDatabaseCallbacks> callbacks = prpCallbacks;
22781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ASSERT(m_databaseCallbacksSet.contains(callbacks));
22881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_databaseCallbacksSet.remove(callbacks);
22981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (m_databaseCallbacksSet.size() > 1)
23081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return;
231e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block
23281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    while (!m_pendingSetVersionCalls.isEmpty()) {
23381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        ExceptionCode ec = 0;
23481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        RefPtr<PendingSetVersionCall> pendingSetVersionCall = m_pendingSetVersionCalls.takeFirst();
23581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        setVersion(pendingSetVersionCall->version(), pendingSetVersionCall->callbacks(), pendingSetVersionCall->databaseCallbacks(), ec);
23681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        ASSERT(!ec);
237e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    }
238dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch}
239dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
24081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid IDBDatabaseBackendImpl::loadObjectStores()
24181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
24281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    Vector<int64_t> ids;
24381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    Vector<String> names;
24481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    Vector<String> keyPaths;
24581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    Vector<bool> autoIncrementFlags;
24681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_backingStore->getObjectStores(m_id, ids, names, keyPaths, autoIncrementFlags);
24781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
24881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ASSERT(names.size() == ids.size());
24981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ASSERT(keyPaths.size() == ids.size());
25081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ASSERT(autoIncrementFlags.size() == ids.size());
25181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
25281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    for (size_t i = 0; i < ids.size(); i++)
2532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        m_objectStores.set(names[i], IDBObjectStoreBackendImpl::create(m_backingStore.get(), m_id, ids[i], names[i], keyPaths[i], autoIncrementFlags[i]));
25481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
25581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
256a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid IDBDatabaseBackendImpl::removeObjectStoreFromMap(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendImpl> database, PassRefPtr<IDBObjectStoreBackendImpl> objectStore)
257a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
258a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ASSERT(database->m_objectStores.contains(objectStore->name()));
259a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    database->m_objectStores.remove(objectStore->name());
260a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
261a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
262a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid IDBDatabaseBackendImpl::addObjectStoreToMap(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendImpl> database, PassRefPtr<IDBObjectStoreBackendImpl> objectStore)
263a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
264a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    RefPtr<IDBObjectStoreBackendImpl> objectStorePtr = objectStore;
265a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ASSERT(!database->m_objectStores.contains(objectStorePtr->name()));
266a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    database->m_objectStores.set(objectStorePtr->name(), objectStorePtr);
267a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
268a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
269a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid IDBDatabaseBackendImpl::resetVersion(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendImpl> database, const String& version)
270a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
271a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    database->m_version = version;
272a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
273a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
274a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore
2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
277dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif // ENABLE(INDEXED_DATABASE)
278