Diff
Modified: trunk/Source/WebCore/ChangeLog (163169 => 163170)
--- trunk/Source/WebCore/ChangeLog 2014-01-31 15:11:05 UTC (rev 163169)
+++ trunk/Source/WebCore/ChangeLog 2014-01-31 15:55:28 UTC (rev 163170)
@@ -1,3 +1,21 @@
+2014-01-31 Brady Eidson <[email protected]>
+
+ IDB: Index writing
+ <rdar://problem/15899973> and https://bugs.webkit.org/show_bug.cgi?id=127868
+
+ Reviewed by Anders Carlsson.
+
+ * Modules/indexeddb/IDBDatabaseBackend.cpp:
+ (WebCore::IDBDatabaseBackend::openConnectionInternal): Remove outdated comment and ASSERT.
+
+ * Modules/indexeddb/IDBObjectStore.cpp:
+ (WebCore::IDBObjectStore::createIndex): Conditionalize a block of code that is LevelDB-only.
+
+ Remove getColumnBlob(). Nobody used it, and it was dangerous because it reset the statement:
+ * platform/sql/SQLiteStatement.cpp:
+ * platform/sql/SQLiteStatement.h:
+ * WebCore.exp.in:
+
2014-01-30 László Langó <[email protected]>
[CSS Grid Layout] Do log(n) search in the named line vectors when positioning named line spans.
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseBackend.cpp (163169 => 163170)
--- trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseBackend.cpp 2014-01-31 15:11:05 UTC (rev 163169)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseBackend.cpp 2014-01-31 15:55:28 UTC (rev 163170)
@@ -467,9 +467,6 @@
bool isNewDatabase = m_metadata.version == IDBDatabaseMetadata::NoIntVersion;
if (version == IDBDatabaseMetadata::DefaultIntVersion) {
- // FIXME: this comments was related to Chromium code. It may be incorrect
- // For unit tests only - skip upgrade steps. Calling from script with DefaultIntVersion throws exception.
- ASSERT(isNewDatabase);
m_databaseCallbacksSet.add(databaseCallbacks);
callbacks->onSuccess(this, this->metadata());
return;
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp (163169 => 163170)
--- trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp 2014-01-31 15:11:05 UTC (rev 163169)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp 2014-01-31 15:55:28 UTC (rev 163170)
@@ -415,6 +415,7 @@
if (ec)
return 0;
+#if USE(LEVELDB)
RefPtr<IDBRequest> indexRequest = openCursor(context, static_cast<IDBKeyRange*>(0), IDBCursor::directionNext(), IDBDatabaseBackend::PreemptiveTask, ec);
ASSERT(!ec);
if (ec)
@@ -424,6 +425,9 @@
// This is kept alive by being the success handler of the request, which is in turn kept alive by the owning transaction.
RefPtr<IndexPopulator> indexPopulator = IndexPopulator::create(backendDB(), m_transaction->id(), id(), metadata);
indexRequest->setOnsuccess(indexPopulator);
+#else
+ ASSERT_UNUSED(context, context);
+#endif
return index.release();
}
Modified: trunk/Source/WebCore/WebCore.exp.in (163169 => 163170)
--- trunk/Source/WebCore/WebCore.exp.in 2014-01-31 15:11:05 UTC (rev 163169)
+++ trunk/Source/WebCore/WebCore.exp.in 2014-01-31 15:55:28 UTC (rev 163170)
@@ -82,7 +82,6 @@
__ZN7WebCore10Pasteboard14writePlainTextERKN3WTF6StringENS0_18SmartReplaceOptionE
__ZN7WebCore10RenderView10compositorEv
__ZN7WebCore10RenderView7hitTestERKNS_14HitTestRequestERNS_13HitTestResultE
-__ZN7WebCore15SQLiteStatement13getColumnBlobEiRi
__ZN7WebCore15SQLiteStatement14getColumnInt64Ei
__ZN7WebCore15SQLiteStatement21getColumnBlobAsVectorEiRN3WTF6VectorIcLm0ENS1_15CrashOnOverflowEEE
__ZN7WebCore10ScrollView16setParentVisibleEb
Modified: trunk/Source/WebCore/platform/sql/SQLiteStatement.cpp (163169 => 163170)
--- trunk/Source/WebCore/platform/sql/SQLiteStatement.cpp 2014-01-31 15:11:05 UTC (rev 163169)
+++ trunk/Source/WebCore/platform/sql/SQLiteStatement.cpp 2014-01-31 15:55:28 UTC (rev 163170)
@@ -428,34 +428,6 @@
result[i] = (static_cast<const unsigned char*>(blob))[i];
}
-const void* SQLiteStatement::getColumnBlob(int col, int& size)
-{
- ASSERT(col >= 0);
-
- size = 0;
-
- if (finalize() != SQLITE_OK)
- LOG(SQLDatabase, "Finalize failed");
- if (prepare() != SQLITE_OK) {
- LOG(SQLDatabase, "Prepare failed");
- return 0;
- }
- if (step() != SQLITE_ROW) {
- LOG(SQLDatabase, "Step wasn't a row");
- return 0;
- }
-
- if (columnCount() <= col)
- return 0;
-
- const void* blob = sqlite3_column_blob(m_statement, col);
- if (!blob)
- return 0;
-
- size = sqlite3_column_bytes(m_statement, col);
- return blob;
-}
-
bool SQLiteStatement::returnTextResults(int col, Vector<String>& v)
{
ASSERT(col >= 0);
Modified: trunk/Source/WebCore/platform/sql/SQLiteStatement.h (163169 => 163170)
--- trunk/Source/WebCore/platform/sql/SQLiteStatement.h 2014-01-31 15:11:05 UTC (rev 163169)
+++ trunk/Source/WebCore/platform/sql/SQLiteStatement.h 2014-01-31 15:55:28 UTC (rev 163170)
@@ -81,7 +81,6 @@
double getColumnDouble(int col);
int getColumnInt(int col);
int64_t getColumnInt64(int col);
- const void* getColumnBlob(int col, int& size);
String getColumnBlobAsString(int col);
void getColumnBlobAsVector(int col, Vector<char>&);
Modified: trunk/Source/WebKit2/ChangeLog (163169 => 163170)
--- trunk/Source/WebKit2/ChangeLog 2014-01-31 15:11:05 UTC (rev 163169)
+++ trunk/Source/WebKit2/ChangeLog 2014-01-31 15:55:28 UTC (rev 163170)
@@ -1,3 +1,23 @@
+2014-01-31 Brady Eidson <[email protected]>
+
+ IDB: Index writing
+ <rdar://problem/15899973> and https://bugs.webkit.org/show_bug.cgi?id=127868
+
+ Reviewed by Anders Carlsson.
+
+ * DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp:
+ (WebKit::UniqueIDBDatabase::putRecordInBackingStore): Handle writing index records, as well.
+
+ * DatabaseProcess/IndexedDB/UniqueIDBDatabaseBackingStore.h:
+ * DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp:
+ (WebKit::UniqueIDBDatabaseBackingStoreSQLite::createAndPopulateInitialMetadata): Create a table
+ for index records
+ (WebKit::UniqueIDBDatabaseBackingStoreSQLite::extractExistingMetadata): Extract IDBIndexMetadata
+ (WebKit::UniqueIDBDatabaseBackingStoreSQLite::deleteObjectStore):
+ (WebKit::UniqueIDBDatabaseBackingStoreSQLite::deleteIndex):
+ (WebKit::UniqueIDBDatabaseBackingStoreSQLite::putIndexRecord): Store in the IndexRecords table.
+ * DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.h:
+
2014-01-30 Jinwoo Song <[email protected]>
[EFL][WK2] Unreviewed EFL WebKit2 build fix after r163116.
Modified: trunk/Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp (163169 => 163170)
--- trunk/Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp 2014-01-31 15:11:05 UTC (rev 163169)
+++ trunk/Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp 2014-01-31 15:55:28 UTC (rev 163170)
@@ -800,14 +800,20 @@
}
}
- // FIXME: The LevelDB port performs "makeIndexWriters" here. Necessary?
-
if (!m_backingStore->putRecord(transaction, objectStoreMetadata.id, *key, value.data(), value.size())) {
postMainThreadTask(createAsyncTask(*this, &UniqueIDBDatabase::didPutRecordInBackingStore, requestID, IDBKeyData(), IDBDatabaseException::UnknownError, ASCIILiteral("Internal backing store error putting a record")));
return;
}
- // FIXME: The LevelDB port updates index keys here. Necessary?
+ ASSERT(indexIDs.size() == indexKeys.size());
+ for (size_t i = 0; i < indexIDs.size(); ++i) {
+ for (size_t j = 0; j < indexKeys[i].size(); ++j) {
+ if (!m_backingStore->putIndexRecord(transaction, objectStoreMetadata.id, indexIDs[i], keyData, indexKeys[i][j])) {
+ postMainThreadTask(createAsyncTask(*this, &UniqueIDBDatabase::didPutRecordInBackingStore, requestID, IDBKeyData(), IDBDatabaseException::UnknownError, ASCIILiteral("Internal backing store error writing index key")));
+ return;
+ }
+ }
+ }
if (putMode != IDBDatabaseBackend::CursorUpdate && objectStoreMetadata.autoIncrement && key->type() == IDBKey::NumberType) {
if (!m_backingStore->updateKeyGeneratorNumber(transaction, objectStoreMetadata.id, keyNumber, keyWasGenerated)) {
Modified: trunk/Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabaseBackingStore.h (163169 => 163170)
--- trunk/Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabaseBackingStore.h 2014-01-31 15:11:05 UTC (rev 163169)
+++ trunk/Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabaseBackingStore.h 2014-01-31 15:55:28 UTC (rev 163170)
@@ -68,6 +68,7 @@
virtual bool keyExistsInObjectStore(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKey&, bool& keyExists) = 0;
virtual bool putRecord(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKey&, const uint8_t* valueBuffer, size_t valueSize) = 0;
+ virtual bool putIndexRecord(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, const WebCore::IDBKeyData&, const WebCore::IDBKeyData& indexKey) = 0;
virtual bool getKeyRecordFromObjectStore(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKey&, RefPtr<WebCore::SharedBuffer>& result) = 0;
virtual bool getKeyRangeRecordFromObjectStore(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKeyRange&, RefPtr<WebCore::SharedBuffer>& result, RefPtr<WebCore::IDBKey>& resultKey) = 0;
Modified: trunk/Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp (163169 => 163170)
--- trunk/Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp 2014-01-31 15:11:05 UTC (rev 163169)
+++ trunk/Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp 2014-01-31 15:55:28 UTC (rev 163170)
@@ -99,6 +99,12 @@
return nullptr;
}
+ if (!m_sqliteDB->executeCommand("CREATE TABLE IndexRecords (indexID INTEGER NOT NULL ON CONFLICT FAIL, objectStoreID INTEGER NOT NULL ON CONFLICT FAIL, key TEXT COLLATE IDBKEY NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE, value NOT NULL ON CONFLICT FAIL);")) {
+ LOG_ERROR("Could not create Records table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
+ m_sqliteDB = nullptr;
+ return nullptr;
+ }
+
if (!m_sqliteDB->executeCommand("CREATE TABLE KeyGenerators (objectStoreID INTEGER NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE, currentKey INTEGER NOT NULL ON CONFLICT FAIL);")) {
LOG_ERROR("Could not create KeyGenerators table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
m_sqliteDB = nullptr;
@@ -202,11 +208,10 @@
osMetadata.id = sql.getColumnInt64(0);
osMetadata.name = sql.getColumnText(1);
- int keyPathSize;
- const uint8_t* keyPathBuffer = static_cast<const uint8_t*>(sql.getColumnBlob(2, keyPathSize));
+ Vector<char> keyPathBuffer;
+ sql.getColumnBlobAsVector(2, keyPathBuffer);
-
- if (!deserializeIDBKeyPath(keyPathBuffer, keyPathSize, osMetadata.keyPath)) {
+ if (!deserializeIDBKeyPath(reinterpret_cast<const uint8_t*>(keyPathBuffer.data()), keyPathBuffer.size(), osMetadata.keyPath)) {
LOG_ERROR("Unable to extract key path metadata from database");
return nullptr;
}
@@ -224,8 +229,47 @@
}
}
- // FIXME: Once we save indexes we need to extract their metadata, also.
+ {
+ SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT id, name, objectStoreID, keyPath, isUnique, multiEntry FROM IndexInfo;"));
+ if (sql.prepare() != SQLResultOk)
+ return nullptr;
+ int result = sql.step();
+ while (result == SQLResultRow) {
+ IDBIndexMetadata indexMetadata;
+
+ indexMetadata.id = sql.getColumnInt64(0);
+ indexMetadata.name = sql.getColumnText(1);
+ int64_t objectStoreID = sql.getColumnInt64(2);
+
+ Vector<char> keyPathBuffer;
+ sql.getColumnBlobAsVector(3, keyPathBuffer);
+
+ if (!deserializeIDBKeyPath(reinterpret_cast<const uint8_t*>(keyPathBuffer.data()), keyPathBuffer.size(), indexMetadata.keyPath)) {
+ LOG_ERROR("Unable to extract key path metadata from database");
+ return nullptr;
+ }
+
+ indexMetadata.unique = sql.getColumnInt(4);
+ indexMetadata.multiEntry = sql.getColumnInt(5);
+
+ auto objectStoreMetadataIt = metadata->objectStores.find(objectStoreID);
+ if (objectStoreMetadataIt == metadata->objectStores.end()) {
+ LOG_ERROR("Found index referring to a non-existant object store");
+ return nullptr;
+ }
+
+ objectStoreMetadataIt->value.indexes.set(indexMetadata.id, indexMetadata);
+
+ result = sql.step();
+ }
+
+ if (result != SQLResultDone) {
+ LOG_ERROR("Error fetching index metadata from database on disk");
+ return nullptr;
+ }
+ }
+
return metadata;
}
@@ -452,33 +496,37 @@
}
}
- // Delete all associated Index records
+ // Delete all associated records
{
- Vector<int64_t> indexIDs;
- SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT id FROM IndexInfo WHERE objectStoreID = ?;"));
+ SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM Records WHERE objectStoreID = ?;"));
if (sql.prepare() != SQLResultOk
- || sql.bindInt64(1, objectStoreID) != SQLResultOk) {
- LOG_ERROR("Error fetching index ID records for object store id %lli from IndexInfo table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
+ || sql.bindInt64(1, objectStoreID) != SQLResultOk
+ || sql.step() != SQLResultDone) {
+ LOG_ERROR("Could not delete records for object store %lli (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
return false;
}
+ }
- int resultCode;
- while ((resultCode = sql.step()) == SQLResultRow)
- indexIDs.append(sql.getColumnInt64(0));
-
- if (resultCode != SQLResultDone) {
- LOG_ERROR("Error fetching index ID records for object store id %lli from IndexInfo table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
+ // Delete all associated Indexes
+ {
+ SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexInfo WHERE objectStoreID = ?;"));
+ if (sql.prepare() != SQLResultOk
+ || sql.bindInt64(1, objectStoreID) != SQLResultOk
+ || sql.step() != SQLResultDone) {
+ LOG_ERROR("Could not delete index from IndexInfo table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
return false;
}
-
- for (auto indexID : indexIDs) {
- if (!deleteIndex(transactionIdentifier, objectStoreID, indexID))
- return false;
- }
}
+ // Delete all associated Index records
{
- // FIXME: Execute SQL here to drop all records related to this object store.
+ SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexRecords WHERE objectStoreID = ?;"));
+ if (sql.prepare() != SQLResultOk
+ || sql.bindInt64(1, objectStoreID) != SQLResultOk
+ || sql.step() != SQLResultDone) {
+ LOG_ERROR("Could not delete index records(%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
+ return false;
+ }
}
return true;
@@ -579,7 +627,17 @@
}
}
- // FIXME (<rdar://problem/15905293>) - Once we store records against indexes, delete them here.
+ {
+ SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexRecords WHERE indexID = ? AND objectStoreID = ?;"));
+ if (sql.prepare() != SQLResultOk
+ || sql.bindInt64(1, indexID) != SQLResultOk
+ || sql.bindInt64(2, objectStoreID) != SQLResultOk
+ || sql.step() != SQLResultDone) {
+ LOG_ERROR("Could not delete index records for index id %lli from IndexRecords table (%i) - %s", indexID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
+ return false;
+ }
+ }
+
return true;
}
@@ -698,6 +756,49 @@
return true;
}
+bool UniqueIDBDatabaseBackingStoreSQLite::putIndexRecord(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, const IDBKeyData& keyValue, const IDBKeyData& indexKey)
+{
+ ASSERT(!isMainThread());
+ ASSERT(m_sqliteDB);
+ ASSERT(m_sqliteDB->isOpen());
+
+ SQLiteIDBTransaction* transaction = m_transactions.get(transactionIdentifier);
+ if (!transaction || !transaction->inProgress()) {
+ LOG_ERROR("Attempt to put index record into database without an established, in-progress transaction");
+ return false;
+ }
+ if (transaction->mode() == IndexedDB::TransactionMode::ReadOnly) {
+ LOG_ERROR("Attempt to put index record into database during read-only transaction");
+ return false;
+ }
+
+ RefPtr<SharedBuffer> indexKeyBuffer = serializeIDBKeyData(indexKey);
+ if (!indexKeyBuffer) {
+ LOG_ERROR("Unable to serialize index key to be stored in the database");
+ return false;
+ }
+
+ RefPtr<SharedBuffer> valueBuffer = serializeIDBKeyData(keyValue);
+ if (!valueBuffer) {
+ LOG_ERROR("Unable to serialize the value to be stored in the database");
+ return false;
+ }
+ {
+ SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO IndexRecords VALUES (?, ?, CAST(? AS TEXT), ?);"));
+ if (sql.prepare() != SQLResultOk
+ || sql.bindInt64(1, indexID) != SQLResultOk
+ || sql.bindInt64(2, objectStoreID) != SQLResultOk
+ || sql.bindBlob(3, indexKeyBuffer->data(), indexKeyBuffer->size()) != SQLResultOk
+ || sql.bindBlob(4, valueBuffer->data(), valueBuffer->size()) != SQLResultOk
+ || sql.step() != SQLResultDone) {
+ LOG_ERROR("Could not put index record for index %lli in object store %lli in Records table (%i) - %s", indexID, objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
+ return false;
+ }
+ }
+
+ return true;
+}
+
bool UniqueIDBDatabaseBackingStoreSQLite::getKeyRecordFromObjectStore(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const IDBKey& key, RefPtr<SharedBuffer>& result)
{
ASSERT(!isMainThread());
Modified: trunk/Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.h (163169 => 163170)
--- trunk/Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.h 2014-01-31 15:11:05 UTC (rev 163169)
+++ trunk/Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.h 2014-01-31 15:55:28 UTC (rev 163170)
@@ -73,7 +73,9 @@
virtual bool keyExistsInObjectStore(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKey&, bool& keyExists) override;
virtual bool putRecord(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKey&, const uint8_t* valueBuffer, size_t valueSize) override;
+ virtual bool putIndexRecord(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, const WebCore::IDBKeyData& keyValue, const WebCore::IDBKeyData& indexKey) override;
+
virtual bool getKeyRecordFromObjectStore(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKey&, RefPtr<WebCore::SharedBuffer>& result) override;
virtual bool getKeyRangeRecordFromObjectStore(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKeyRange&, RefPtr<WebCore::SharedBuffer>& result, RefPtr<WebCore::IDBKey>& resultKey) override;
virtual bool count(const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, const WebCore::IDBKeyRangeData&, int64_t& count) override;