void IDBIndexBackendImpl::getInternal(ScriptExecutionContext*, PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBTransactionBackendImpl> transaction) { IDB_TRACE("IDBIndexBackendImpl::getInternal"); RefPtr<IDBKey> key; if (keyRange->isOnlyKey()) key = keyRange->lower(); else { RefPtr<IDBBackingStore::Cursor> backingStoreCursor = index->backingStore()->openIndexCursor(transaction->backingStoreTransaction(), index->databaseId(), index->m_objectStoreBackend->id(), index->id(), keyRange.get(), IDBCursor::NEXT); if (!backingStoreCursor) { callbacks->onSuccess(); return; } key = backingStoreCursor->key(); } RefPtr<IDBKey> primaryKey = index->backingStore()->getPrimaryKeyViaIndex(transaction->backingStoreTransaction(), index->databaseId(), index->m_objectStoreBackend->id(), index->id(), *key); String value = index->backingStore()->getRecord(transaction->backingStoreTransaction(), index->databaseId(), index->m_objectStoreBackend->id(), *primaryKey); if (value.isNull()) { callbacks->onSuccess(); return; } if (index->m_objectStoreBackend->autoIncrement() && !index->m_objectStoreBackend->keyPath().isNull()) { callbacks->onSuccess(SerializedScriptValue::createFromWire(value), primaryKey, index->m_objectStoreBackend->keyPath()); return; } callbacks->onSuccess(SerializedScriptValue::createFromWire(value)); }
void IDBIndexBackendImpl::openCursorInternal(ScriptExecutionContext*, PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBKeyRange> range, unsigned short untypedDirection, IDBCursorBackendInterface::CursorType cursorType, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBTransactionBackendImpl> transaction) { IDB_TRACE("IDBIndexBackendImpl::openCursorInternal"); IDBCursor::Direction direction = static_cast<IDBCursor::Direction>(untypedDirection); RefPtr<IDBBackingStore::Cursor> backingStoreCursor; switch (cursorType) { case IDBCursorBackendInterface::IndexKeyCursor: backingStoreCursor = index->backingStore()->openIndexKeyCursor(transaction->backingStoreTransaction(), index->databaseId(), index->m_objectStoreBackend->id(), index->id(), range.get(), direction); break; case IDBCursorBackendInterface::IndexCursor: backingStoreCursor = index->backingStore()->openIndexCursor(transaction->backingStoreTransaction(), index->databaseId(), index->m_objectStoreBackend->id(), index->id(), range.get(), direction); break; case IDBCursorBackendInterface::ObjectStoreCursor: case IDBCursorBackendInterface::InvalidCursorType: ASSERT_NOT_REACHED(); break; } if (!backingStoreCursor) { callbacks->onSuccess(static_cast<SerializedScriptValue*>(0)); return; } RefPtr<IDBCursorBackendImpl> cursor = IDBCursorBackendImpl::create(backingStoreCursor.get(), cursorType, transaction.get(), index->m_objectStoreBackend); callbacks->onSuccess(cursor, cursor->key(), cursor->primaryKey(), cursor->value()); }
void IDBDatabaseBackendImpl::createObjectStoreInternal(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendImpl> database, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBTransactionBackendImpl> transaction) { if (!database->m_backingStore->createObjectStore(transaction->backingStoreTransaction(), database->id(), objectStore->id(), objectStore->name(), objectStore->keyPath(), objectStore->autoIncrement())) { transaction->abort(); return; } }
bool IDBObjectStoreBackendLevelDB::makeIndexWriters(PassRefPtr<IDBTransactionBackendLevelDB> transaction, IDBBackingStore* backingStore, int64_t databaseId, const IDBObjectStoreMetadata& objectStore, PassRefPtr<IDBKey> primaryKey, bool keyWasGenerated, const Vector<int64_t>& indexIds, const Vector<IDBDatabaseBackendInterface::IndexKeys>& indexKeys, Vector<OwnPtr<IndexWriter> >* indexWriters, String* errorMessage, bool& completed) { ASSERT(indexIds.size() == indexKeys.size()); completed = false; HashMap<int64_t, IDBDatabaseBackendInterface::IndexKeys> indexKeyMap; for (size_t i = 0; i < indexIds.size(); ++i) indexKeyMap.add(indexIds[i], indexKeys[i]); for (IDBObjectStoreMetadata::IndexMap::const_iterator it = objectStore.indexes.begin(); it != objectStore.indexes.end(); ++it) { const IDBIndexMetadata& index = it->value; IDBDatabaseBackendInterface::IndexKeys keys = indexKeyMap.get(it->key); // If the objectStore is using autoIncrement, then any indexes with an identical keyPath need to also use the primary (generated) key as a key. if (keyWasGenerated && (index.keyPath == objectStore.keyPath)) keys.append(primaryKey); OwnPtr<IndexWriter> indexWriter(adoptPtr(new IndexWriter(index, keys))); bool canAddKeys = false; bool backingStoreSuccess = indexWriter->verifyIndexKeys(*backingStore, transaction->backingStoreTransaction(), databaseId, objectStore.id, index.id, canAddKeys, primaryKey.get(), errorMessage); if (!backingStoreSuccess) return false; if (!canAddKeys) return true; indexWriters->append(indexWriter.release()); } completed = true; return true; }
void IDBIndexBackendImpl::getKeyInternal(ScriptExecutionContext* context, PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBTransactionBackendImpl> transaction) { IDB_TRACE("IDBIndexBackendImpl::getInternal"); RefPtr<IDBBackingStore::Cursor> backingStoreCursor = index->backingStore()->openIndexKeyCursor(transaction->backingStoreTransaction(), index->databaseId(), index->m_objectStoreBackend->id(), index->id(), keyRange.get(), IDBCursor::NEXT); if (!backingStoreCursor) { callbacks->onSuccess(static_cast<IDBKey*>(0)); return; } RefPtr<IDBKey> keyResult = index->backingStore()->getPrimaryKeyViaIndex(transaction->backingStoreTransaction(), index->databaseId(), index->m_objectStoreBackend->id(), index->id(), *backingStoreCursor->key()); if (!keyResult) { callbacks->onSuccess(static_cast<IDBKey*>(0)); return; } callbacks->onSuccess(keyResult.get()); }
PassRefPtr<IDBKey> IDBObjectStoreBackendLevelDB::generateKey(PassRefPtr<IDBBackingStore> backingStore, PassRefPtr<IDBTransactionBackendLevelDB> transaction, int64_t databaseId, int64_t objectStoreId) { const int64_t maxGeneratorValue = 9007199254740992LL; // Maximum integer storable as ECMAScript number. int64_t currentNumber; bool ok = backingStore->getKeyGeneratorCurrentNumber(transaction->backingStoreTransaction(), databaseId, objectStoreId, currentNumber); if (!ok) { LOG_ERROR("Failed to getKeyGeneratorCurrentNumber"); return IDBKey::createInvalid(); } if (currentNumber < 0 || currentNumber > maxGeneratorValue) return IDBKey::createInvalid(); return IDBKey::createNumber(currentNumber); }
void IDBDatabaseBackendImpl::setIntVersionInternal(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendImpl> database, int64_t version, PassRefPtr<IDBCallbacks> prpCallbacks, PassRefPtr<IDBDatabaseCallbacks> databaseCallbacks, PassRefPtr<IDBTransactionBackendImpl> transaction) { RefPtr<IDBCallbacks> callbacks(prpCallbacks); int64_t databaseId = database->id(); int64_t oldVersion = database->m_metadata.intVersion; ASSERT(version > oldVersion); database->m_metadata.intVersion = version; if (!database->m_backingStore->updateIDBDatabaseIntVersion(transaction->backingStoreTransaction(), databaseId, database->m_metadata.intVersion)) { RefPtr<IDBDatabaseError> error = IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Error writing data to stable storage."); callbacks->onError(error); transaction->abort(error); return; } ASSERT(!database->m_pendingSecondHalfOpenWithVersion); database->m_pendingSecondHalfOpenWithVersion = PendingOpenWithVersionCall::create(callbacks, databaseCallbacks, version); callbacks->onUpgradeNeeded(oldVersion, transaction, database); }
void IDBDatabaseBackendImpl::deleteObjectStoreInternal(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendImpl> database, PassRefPtr<IDBObjectStoreBackendImpl> objectStore, PassRefPtr<IDBTransactionBackendImpl> transaction) { database->m_backingStore->deleteObjectStore(transaction->backingStoreTransaction(), database->id(), objectStore->id()); }
void IDBIndexBackendImpl::countInternal(ScriptExecutionContext*, PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBKeyRange> range, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBTransactionBackendImpl> transaction) { IDB_TRACE("IDBIndexBackendImpl::countInternal"); uint32_t count = 0; RefPtr<IDBBackingStore::Cursor> backingStoreCursor = index->backingStore()->openIndexKeyCursor(transaction->backingStoreTransaction(), index->databaseId(), index->m_objectStoreBackend->id(), index->id(), range.get(), IDBCursor::NEXT); if (!backingStoreCursor) { callbacks->onSuccess(count); return; } do { ++count; } while (backingStoreCursor->continueFunction(0)); callbacks->onSuccess(count); }
bool IDBObjectStoreBackendLevelDB::updateKeyGenerator(PassRefPtr<IDBBackingStore> backingStore, PassRefPtr<IDBTransactionBackendLevelDB> transaction, int64_t databaseId, int64_t objectStoreId, const IDBKey* key, bool checkCurrent) { ASSERT(key && key->type() == IDBKey::NumberType); return backingStore->maybeUpdateKeyGeneratorCurrentNumber(transaction->backingStoreTransaction(), databaseId, objectStoreId, static_cast<int64_t>(floor(key->number())) + 1, checkCurrent); }