Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Modern IDB (Blob support): Support retrieving Blobs from IDB.
https://bugs.webkit.org/show_bug.cgi?id=156367

Reviewed by Alex Christensen.

Source/WebCore:

No new tests (No testable change in behavior yet, current tests pass).

This patch does the following:
- Pulls BlobURLs and stored filenames out of IDB whenever an IDB record is fetched.
- Adds those URLs and filenames to IDBValue.
- Uses IDBValue in more places instead of SharedBuffer/ThreadSafeBuffer.
- Teaches SerializedScriptValue, Blob, and File how to read the URLs and filenames when they exist.
- Teaches the Blob registry to register a new type of Blob that is not a "File" but is backed by one.

* Modules/indexeddb/IDBCursor.cpp:
(WebCore::IDBCursor::setGetResult):

* Modules/indexeddb/IDBGetResult.h:
(WebCore::IDBGetResult::IDBGetResult):

* Modules/indexeddb/IDBRequest.cpp:
(WebCore::IDBRequest::setResultToStructuredClone):
* Modules/indexeddb/IDBRequest.h:

* Modules/indexeddb/IDBTransaction.cpp:
(WebCore::IDBTransaction::didGetRecordOnServer):

* Modules/indexeddb/IDBValue.cpp:
(WebCore::IDBValue::IDBValue):
* Modules/indexeddb/IDBValue.h:

* Modules/indexeddb/server/MemoryIndexCursor.cpp:
(WebCore::IDBServer::MemoryIndexCursor::currentData):

* Modules/indexeddb/server/MemoryObjectStoreCursor.cpp:
(WebCore::IDBServer::MemoryObjectStoreCursor::currentData):

* Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:
(WebCore::IDBServer::SQLiteIDBBackingStore::createIndex):
(WebCore::IDBServer::SQLiteIDBBackingStore::getBlobRecordsForObjectStoreRecord):
(WebCore::IDBServer::SQLiteIDBBackingStore::getRecord):
(WebCore::IDBServer::SQLiteIDBBackingStore::getIndexRecord):
* Modules/indexeddb/server/SQLiteIDBBackingStore.h:

* Modules/indexeddb/server/SQLiteIDBCursor.cpp:
(WebCore::IDBServer::SQLiteIDBCursor::currentData):
(WebCore::IDBServer::SQLiteIDBCursor::internalAdvanceOnce):
* Modules/indexeddb/server/SQLiteIDBCursor.h:
(WebCore::IDBServer::SQLiteIDBCursor::currentValue):
(WebCore::IDBServer::SQLiteIDBCursor::currentValueBuffer): Deleted.

* Modules/indexeddb/server/SQLiteIDBTransaction.h:
(WebCore::IDBServer::SQLiteIDBTransaction::backingStore):

* Modules/websockets/WorkerThreadableWebSocketChannel.cpp:
(WebCore::WorkerThreadableWebSocketChannel::Bridge::send):

* bindings/js/IDBBindingUtilities.cpp:
(WebCore::deserializeIDBValueDataToJSValue):
(WebCore::deserializeIDBValueData):
(WebCore::deserializeIDBValue):
* bindings/js/IDBBindingUtilities.h:

* bindings/js/SerializedScriptValue.cpp:
(WebCore::CloneDeserializer::deserialize):
(WebCore::CloneDeserializer::CloneDeserializer):
(WebCore::CloneDeserializer::readFile):
(WebCore::CloneDeserializer::readTerminal):
(WebCore::CloneDeserializer::blobFilePathForBlobURL):
(WebCore::SerializedScriptValue::deserialize):
* bindings/js/SerializedScriptValue.h:

* fileapi/Blob.cpp:
(WebCore::Blob::Blob):
* fileapi/Blob.h:
(WebCore::Blob::deserialize):

* fileapi/File.cpp:
(WebCore::File::File):

* fileapi/ThreadableBlobRegistry.cpp:
(WebCore::threadableQueue):
(WebCore::ThreadableBlobRegistry::registerBlobURLOptionallyFileBacked):
* fileapi/ThreadableBlobRegistry.h:

* platform/CrossThreadTask.h:
(WebCore::createCrossThreadTask):

* platform/network/BlobRegistry.h:

* platform/network/BlobRegistryImpl.cpp:
(WebCore::BlobRegistryImpl::registerBlobURL):
(WebCore::BlobRegistryImpl::registerBlobURLOptionallyFileBacked):
* platform/network/BlobRegistryImpl.h:

Source/WebKit2:

* NetworkProcess/FileAPI/NetworkBlobRegistry.cpp:
(WebKit::NetworkBlobRegistry::registerBlobURLOptionallyFileBacked):
* NetworkProcess/FileAPI/NetworkBlobRegistry.h:

* NetworkProcess/NetworkConnectionToWebProcess.cpp:
(WebKit::NetworkConnectionToWebProcess::registerBlobURLOptionallyFileBacked):
* NetworkProcess/NetworkConnectionToWebProcess.h:
* NetworkProcess/NetworkConnectionToWebProcess.messages.in:

* WebProcess/FileAPI/BlobRegistryProxy.cpp:
(WebKit::BlobRegistryProxy::registerBlobURLOptionallyFileBacked):
* WebProcess/FileAPI/BlobRegistryProxy.h:


Canonical link: https://commits.webkit.org/174668@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@199524 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
beidson committed Apr 14, 2016
1 parent d88a732 commit 80ac2b5
Show file tree
Hide file tree
Showing 37 changed files with 454 additions and 68 deletions.
97 changes: 97 additions & 0 deletions Source/WebCore/ChangeLog
@@ -1,3 +1,100 @@
2016-04-13 Brady Eidson <beidson@apple.com>

Modern IDB (Blob support): Support retrieving Blobs from IDB.
https://bugs.webkit.org/show_bug.cgi?id=156367

Reviewed by Alex Christensen.

No new tests (No testable change in behavior yet, current tests pass).

This patch does the following:
- Pulls BlobURLs and stored filenames out of IDB whenever an IDB record is fetched.
- Adds those URLs and filenames to IDBValue.
- Uses IDBValue in more places instead of SharedBuffer/ThreadSafeBuffer.
- Teaches SerializedScriptValue, Blob, and File how to read the URLs and filenames when they exist.
- Teaches the Blob registry to register a new type of Blob that is not a "File" but is backed by one.

* Modules/indexeddb/IDBCursor.cpp:
(WebCore::IDBCursor::setGetResult):

* Modules/indexeddb/IDBGetResult.h:
(WebCore::IDBGetResult::IDBGetResult):

* Modules/indexeddb/IDBRequest.cpp:
(WebCore::IDBRequest::setResultToStructuredClone):
* Modules/indexeddb/IDBRequest.h:

* Modules/indexeddb/IDBTransaction.cpp:
(WebCore::IDBTransaction::didGetRecordOnServer):

* Modules/indexeddb/IDBValue.cpp:
(WebCore::IDBValue::IDBValue):
* Modules/indexeddb/IDBValue.h:

* Modules/indexeddb/server/MemoryIndexCursor.cpp:
(WebCore::IDBServer::MemoryIndexCursor::currentData):

* Modules/indexeddb/server/MemoryObjectStoreCursor.cpp:
(WebCore::IDBServer::MemoryObjectStoreCursor::currentData):

* Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:
(WebCore::IDBServer::SQLiteIDBBackingStore::createIndex):
(WebCore::IDBServer::SQLiteIDBBackingStore::getBlobRecordsForObjectStoreRecord):
(WebCore::IDBServer::SQLiteIDBBackingStore::getRecord):
(WebCore::IDBServer::SQLiteIDBBackingStore::getIndexRecord):
* Modules/indexeddb/server/SQLiteIDBBackingStore.h:

* Modules/indexeddb/server/SQLiteIDBCursor.cpp:
(WebCore::IDBServer::SQLiteIDBCursor::currentData):
(WebCore::IDBServer::SQLiteIDBCursor::internalAdvanceOnce):
* Modules/indexeddb/server/SQLiteIDBCursor.h:
(WebCore::IDBServer::SQLiteIDBCursor::currentValue):
(WebCore::IDBServer::SQLiteIDBCursor::currentValueBuffer): Deleted.

* Modules/indexeddb/server/SQLiteIDBTransaction.h:
(WebCore::IDBServer::SQLiteIDBTransaction::backingStore):

* Modules/websockets/WorkerThreadableWebSocketChannel.cpp:
(WebCore::WorkerThreadableWebSocketChannel::Bridge::send):

* bindings/js/IDBBindingUtilities.cpp:
(WebCore::deserializeIDBValueDataToJSValue):
(WebCore::deserializeIDBValueData):
(WebCore::deserializeIDBValue):
* bindings/js/IDBBindingUtilities.h:

* bindings/js/SerializedScriptValue.cpp:
(WebCore::CloneDeserializer::deserialize):
(WebCore::CloneDeserializer::CloneDeserializer):
(WebCore::CloneDeserializer::readFile):
(WebCore::CloneDeserializer::readTerminal):
(WebCore::CloneDeserializer::blobFilePathForBlobURL):
(WebCore::SerializedScriptValue::deserialize):
* bindings/js/SerializedScriptValue.h:

* fileapi/Blob.cpp:
(WebCore::Blob::Blob):
* fileapi/Blob.h:
(WebCore::Blob::deserialize):

* fileapi/File.cpp:
(WebCore::File::File):

* fileapi/ThreadableBlobRegistry.cpp:
(WebCore::threadableQueue):
(WebCore::ThreadableBlobRegistry::registerBlobURLOptionallyFileBacked):
* fileapi/ThreadableBlobRegistry.h:

* platform/CrossThreadTask.h:
(WebCore::createCrossThreadTask):

* platform/network/BlobRegistry.h:

* platform/network/BlobRegistryImpl.cpp:
(WebCore::BlobRegistryImpl::registerBlobURL):
(WebCore::BlobRegistryImpl::registerBlobURLOptionallyFileBacked):
* platform/network/BlobRegistryImpl.h:

2016-04-13 Zalan Bujtas <zalan@apple.com>

Text on compositing layer with negative letter-spacing is truncated.
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/Modules/indexeddb/IDBCursor.cpp
Expand Up @@ -418,7 +418,7 @@ void IDBCursor::setGetResult(IDBRequest& request, const IDBGetResult& getResult)
if (isKeyCursor())
m_deprecatedCurrentValue = { };
else
m_deprecatedCurrentValue = deserializeIDBValueData(*context, getResult.value().data());
m_deprecatedCurrentValue = deserializeIDBValue(*context, getResult.value());

m_gotValue = true;
}
Expand Down
24 changes: 18 additions & 6 deletions Source/WebCore/Modules/indexeddb/IDBGetResult.h
Expand Up @@ -43,17 +43,22 @@ class IDBGetResult {
{
}

IDBGetResult(Ref<SharedBuffer>&& buffer, const IDBKeyData& currentPrimaryKey)
: m_primaryKeyData(currentPrimaryKey)
IDBGetResult(const IDBValue& value, const IDBKeyData& currentPrimaryKey)
: m_value(value)
, m_primaryKeyData(currentPrimaryKey)
{
dataFromBuffer(buffer.get());
}

IDBGetResult(const ThreadSafeDataBuffer& buffer)
: m_value(buffer)
{
}

IDBGetResult(IDBValue&& buffer)
: m_value(WTFMove(buffer))
{
}

IDBGetResult(PassRefPtr<IDBKey> key)
: m_keyData(key.get())
{
Expand All @@ -78,8 +83,15 @@ class IDBGetResult {
{
}

IDBGetResult(const IDBKeyData& keyData, const IDBKeyData& primaryKeyData, const ThreadSafeDataBuffer& valueBuffer)
: m_value(valueBuffer)
IDBGetResult(const IDBKeyData& keyData, const IDBKeyData& primaryKeyData, IDBValue&& value)
: m_value(WTFMove(value))
, m_keyData(keyData)
, m_primaryKeyData(primaryKeyData)
{
}

IDBGetResult(const IDBKeyData& keyData, const IDBKeyData& primaryKeyData, const IDBValue& value)
: m_value(value)
, m_keyData(keyData)
, m_primaryKeyData(primaryKeyData)
{
Expand All @@ -97,7 +109,7 @@ class IDBGetResult {
template<class Decoder> static bool decode(Decoder&, IDBGetResult&);

private:
WEBCORE_EXPORT void dataFromBuffer(SharedBuffer&);
void dataFromBuffer(SharedBuffer&);

IDBValue m_value;
IDBKeyData m_keyData;
Expand Down
6 changes: 3 additions & 3 deletions Source/WebCore/Modules/indexeddb/IDBRequest.cpp
Expand Up @@ -341,16 +341,16 @@ void IDBRequest::setResult(uint64_t number)
m_result = IDBAny::create(Deprecated::ScriptValue(scriptExecutionContext()->vm(), JSC::JSValue(number)));
}

void IDBRequest::setResultToStructuredClone(const ThreadSafeDataBuffer& valueData)
void IDBRequest::setResultToStructuredClone(const IDBValue& value)
{
LOG(IndexedDB, "IDBRequest::setResultToStructuredClone");

auto context = scriptExecutionContext();
if (!context)
return;

Deprecated::ScriptValue value = deserializeIDBValueData(*context, valueData);
m_result = IDBAny::create(WTFMove(value));
Deprecated::ScriptValue scriptValue = deserializeIDBValue(*context, value);
m_result = IDBAny::create(WTFMove(scriptValue));
}

void IDBRequest::setResultToUndefined()
Expand Down
3 changes: 2 additions & 1 deletion Source/WebCore/Modules/indexeddb/IDBRequest.h
Expand Up @@ -44,6 +44,7 @@ class IDBIndex;
class IDBKeyData;
class IDBObjectStore;
class IDBResultData;
class IDBValue;
class ThreadSafeDataBuffer;

namespace IDBClient {
Expand Down Expand Up @@ -98,7 +99,7 @@ class IDBRequest : public EventTargetWithInlineData, public ActiveDOMObject, pub

void setResult(const IDBKeyData*);
void setResult(uint64_t);
void setResultToStructuredClone(const ThreadSafeDataBuffer&);
void setResultToStructuredClone(const IDBValue&);
void setResultToUndefined();

IDBAny* modernResult() { return m_result.get(); }
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/Modules/indexeddb/IDBTransaction.cpp
Expand Up @@ -738,7 +738,7 @@ void IDBTransaction::didGetRecordOnServer(IDBRequest& request, const IDBResultDa
request.setResultToUndefined();
} else {
if (resultData.getResult().value().data().data())
request.setResultToStructuredClone(resultData.getResult().value().data());
request.setResultToStructuredClone(resultData.getResult().value());
else
request.setResultToUndefined();
}
Expand Down
7 changes: 7 additions & 0 deletions Source/WebCore/Modules/indexeddb/IDBValue.cpp
Expand Up @@ -54,6 +54,13 @@ IDBValue::IDBValue(const SerializedScriptValue& scriptValue, const Vector<String
{
}

IDBValue::IDBValue(const ThreadSafeDataBuffer& value, Vector<String>&& blobURLs, Vector<String>&& blobFilePaths)
: m_data(value)
, m_blobURLs(WTFMove(blobURLs))
, m_blobFilePaths(WTFMove(blobFilePaths))
{
}

IDBValue::IDBValue(const ThreadSafeDataBuffer& value, const Vector<String>& blobURLs, const Vector<String>& blobFilePaths)
: m_data(value)
, m_blobURLs(blobURLs)
Expand Down
1 change: 1 addition & 0 deletions Source/WebCore/Modules/indexeddb/IDBValue.h
Expand Up @@ -39,6 +39,7 @@ class IDBValue {
IDBValue(const SerializedScriptValue&);
IDBValue(const ThreadSafeDataBuffer&);
IDBValue(const SerializedScriptValue&, const Vector<String>& blobURLs, const Vector<String>& blobFilePaths);
IDBValue(const ThreadSafeDataBuffer&, Vector<String>&& blobURLs, Vector<String>&& blobFilePaths);
IDBValue(const ThreadSafeDataBuffer&, const Vector<String>& blobURLs, const Vector<String>& blobFilePaths);

IDBValue isolatedCopy() const;
Expand Down
6 changes: 4 additions & 2 deletions Source/WebCore/Modules/indexeddb/server/MemoryIndexCursor.cpp
Expand Up @@ -74,8 +74,10 @@ void MemoryIndexCursor::currentData(IDBGetResult& getResult)

if (m_info.cursorType() == IndexedDB::CursorType::KeyOnly)
getResult = { m_currentKey, m_currentPrimaryKey };
else
getResult = { m_currentKey, m_currentPrimaryKey, m_index.objectStore().valueForKey(m_currentPrimaryKey) };
else {
IDBValue value = { m_index.objectStore().valueForKey(m_currentPrimaryKey), { }, { } };
getResult = { m_currentKey, m_currentPrimaryKey, WTFMove(value) };
}
}

void MemoryIndexCursor::iterate(const IDBKeyData& key, uint32_t count, IDBGetResult& getResult)
Expand Down
Expand Up @@ -189,7 +189,8 @@ void MemoryObjectStoreCursor::currentData(IDBGetResult& data)
}

m_currentPositionKey = **m_iterator;
data = { m_currentPositionKey, m_currentPositionKey, m_objectStore.valueForKeyRange(m_currentPositionKey) };
IDBValue value = { m_objectStore.valueForKeyRange(m_currentPositionKey), { }, { } };
data = { m_currentPositionKey, m_currentPositionKey, WTFMove(value) };
}

void MemoryObjectStoreCursor::incrementForwardIterator(std::set<IDBKeyData>& set, const IDBKeyData& key, uint32_t count)
Expand Down
82 changes: 75 additions & 7 deletions Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp
Expand Up @@ -1049,7 +1049,8 @@ IDBError SQLiteIDBBackingStore::createIndex(const IDBResourceIdentifier& transac

while (!cursor->currentKey().isNull()) {
auto& key = cursor->currentKey();
auto valueBuffer = ThreadSafeDataBuffer::copyVector(cursor->currentValueBuffer());
auto* value = cursor->currentValue();
ThreadSafeDataBuffer valueBuffer = value ? value->data() : ThreadSafeDataBuffer();

IDBError error = updateOneIndexForAddRecord(info, key, valueBuffer);
if (!error.isNull()) {
Expand Down Expand Up @@ -1627,6 +1628,60 @@ IDBError SQLiteIDBBackingStore::addRecord(const IDBResourceIdentifier& transacti
return error;
}

IDBError SQLiteIDBBackingStore::getBlobRecordsForObjectStoreRecord(int64_t objectStoreRecord, Vector<String>& blobURLs, Vector<String>& blobFilePaths)
{
ASSERT(objectStoreRecord);

HashSet<String> blobURLSet;
{
SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT blobURL FROM BlobRecords WHERE objectStoreRow = ?"));
if (sql.prepare() != SQLITE_OK
|| sql.bindInt64(1, objectStoreRecord) != SQLITE_OK) {
LOG_ERROR("Could not prepare statement to fetch blob URLs for object store record (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to look up blobURL records in object store by key range") };
}

int sqlResult = sql.step();
if (sqlResult == SQLITE_OK || sqlResult == SQLITE_DONE) {
// There are no blobURLs in the database for this object store record.
return { };
}

while (sqlResult == SQLITE_ROW) {
blobURLSet.add(sql.getColumnText(0));
sqlResult = sql.step();
}

if (sqlResult != SQLITE_DONE) {
LOG_ERROR("Could not fetch blob URLs for object store record (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to look up blobURL records in object store by key range") };
}
}

ASSERT(!blobURLSet.isEmpty());
String databaseDirectory = fullDatabaseDirectory();
for (auto& blobURL : blobURLSet) {
SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT fileName FROM BlobFiles WHERE blobURL = ?"));
if (sql.prepare() != SQLITE_OK
|| sql.bindText(1, blobURL) != SQLITE_OK) {
LOG_ERROR("Could not prepare statement to fetch blob filename for object store record (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to look up blobURL records in object store by key range") };
}

if (sql.step() != SQLITE_ROW) {
LOG_ERROR("Entry for blob filename for blob url %s does not exist (%i) - %s", blobURL.utf8().data(), m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to look up blobURL records in object store by key range") };
}

blobURLs.append(blobURL);

String fileName = sql.getColumnText(0);
blobFilePaths.append(pathByAppendingComponent(databaseDirectory, fileName));
}

return { };
}

IDBError SQLiteIDBBackingStore::getRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreID, const IDBKeyRangeData& keyRange, IDBGetResult& resultValue)
{
LOG(IndexedDB, "SQLiteIDBBackingStore::getRecord - key range %s, object store %" PRIu64, keyRange.loggingString().utf8().data(), objectStoreID);
Expand Down Expand Up @@ -1658,11 +1713,13 @@ IDBError SQLiteIDBBackingStore::getRecord(const IDBResourceIdentifier& transacti
return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize upper IDBKey in lookup range") };
}

int64_t recordID = 0;
ThreadSafeDataBuffer resultBuffer;
{
static NeverDestroyed<const ASCIILiteral> lowerOpenUpperOpen("SELECT value FROM Records WHERE objectStoreID = ? AND key > CAST(? AS TEXT) AND key < CAST(? AS TEXT) ORDER BY key;");
static NeverDestroyed<const ASCIILiteral> lowerOpenUpperClosed("SELECT value FROM Records WHERE objectStoreID = ? AND key > CAST(? AS TEXT) AND key <= CAST(? AS TEXT) ORDER BY key;");
static NeverDestroyed<const ASCIILiteral> lowerClosedUpperOpen("SELECT value FROM Records WHERE objectStoreID = ? AND key >= CAST(? AS TEXT) AND key < CAST(? AS TEXT) ORDER BY key;");
static NeverDestroyed<const ASCIILiteral> lowerClosedUpperClosed("SELECT value FROM Records WHERE objectStoreID = ? AND key >= CAST(? AS TEXT) AND key <= CAST(? AS TEXT) ORDER BY key;");
static NeverDestroyed<const ASCIILiteral> lowerOpenUpperOpen("SELECT value, ROWID FROM Records WHERE objectStoreID = ? AND key > CAST(? AS TEXT) AND key < CAST(? AS TEXT) ORDER BY key;");
static NeverDestroyed<const ASCIILiteral> lowerOpenUpperClosed("SELECT value, ROWID FROM Records WHERE objectStoreID = ? AND key > CAST(? AS TEXT) AND key <= CAST(? AS TEXT) ORDER BY key;");
static NeverDestroyed<const ASCIILiteral> lowerClosedUpperOpen("SELECT value, ROWID FROM Records WHERE objectStoreID = ? AND key >= CAST(? AS TEXT) AND key < CAST(? AS TEXT) ORDER BY key;");
static NeverDestroyed<const ASCIILiteral> lowerClosedUpperClosed("SELECT value, ROWID FROM Records WHERE objectStoreID = ? AND key >= CAST(? AS TEXT) AND key <= CAST(? AS TEXT) ORDER BY key;");

const ASCIILiteral* query = nullptr;

Expand Down Expand Up @@ -1703,9 +1760,20 @@ IDBError SQLiteIDBBackingStore::getRecord(const IDBResourceIdentifier& transacti

Vector<uint8_t> buffer;
sql.getColumnBlobAsVector(0, buffer);
resultValue = ThreadSafeDataBuffer::adoptVector(buffer);
resultBuffer = ThreadSafeDataBuffer::adoptVector(buffer);

recordID = sql.getColumnInt64(1);
}

ASSERT(recordID);
Vector<String> blobURLs, blobFilePaths;
auto error = getBlobRecordsForObjectStoreRecord(recordID, blobURLs, blobFilePaths);
ASSERT(blobURLs.size() == blobFilePaths.size());

if (!error.isNull())
return error;

resultValue = { { resultBuffer, WTFMove(blobURLs), WTFMove(blobFilePaths) } };
return { };
}

Expand Down Expand Up @@ -1739,7 +1807,7 @@ IDBError SQLiteIDBBackingStore::getIndexRecord(const IDBResourceIdentifier& tran
if (type == IndexedDB::IndexRecordType::Key)
getResult = { cursor->currentPrimaryKey() };
else
getResult = { SharedBuffer::create(cursor->currentValueBuffer().data(), cursor->currentValueBuffer().size()), cursor->currentPrimaryKey() };
getResult = { cursor->currentValue() ? *cursor->currentValue() : IDBValue(), cursor->currentPrimaryKey() };
}

return { };
Expand Down
Expand Up @@ -85,6 +85,8 @@ class SQLiteIDBBackingStore : public IDBBackingStore {

IDBBackingStoreTemporaryFileHandler& temporaryFileHandler() const { return m_temporaryFileHandler; }

IDBError getBlobRecordsForObjectStoreRecord(int64_t objectStoreRecord, Vector<String>& blobURLs, Vector<String>& blobFilePaths);

private:
String filenameForDatabaseName() const;
String fullDatabasePath() const;
Expand Down

0 comments on commit 80ac2b5

Please sign in to comment.