Modern IDB: Possible crash deallocating IDBDatabaseInfo/IDBObjectStoreInfo/IDBIndexInfo.
[WebKit-https.git] / Source / WebCore / Modules / indexeddb / shared / IDBDatabaseInfo.cpp
index 39b4604..23ce920 100644 (file)
@@ -40,15 +40,120 @@ IDBDatabaseInfo::IDBDatabaseInfo(const String& name, uint64_t version)
 {
 }
 
+IDBDatabaseInfo::IDBDatabaseInfo(const IDBDatabaseInfo& other, IsolatedCopyTag)
+    : m_name(other.m_name.isolatedCopy())
+    , m_version(other.m_version)
+    , m_maxObjectStoreID(other.m_maxObjectStoreID)
+{
+    for (auto entry : other.m_objectStoreMap)
+        m_objectStoreMap.set(entry.key, entry.value.isolatedCopy());
+}
+
 IDBDatabaseInfo IDBDatabaseInfo::isolatedCopy() const
 {
-    IDBDatabaseInfo info;
+    return { *this, IDBDatabaseInfo::IsolatedCopy };
+}
+
+bool IDBDatabaseInfo::hasObjectStore(const String& name) const
+{
+    for (auto& objectStore : m_objectStoreMap.values()) {
+        if (objectStore.name() == name)
+            return true;
+    }
+
+    return false;
+}
+
+IDBObjectStoreInfo IDBDatabaseInfo::createNewObjectStore(const String& name, const IDBKeyPath& keyPath, bool autoIncrement)
+{
+    IDBObjectStoreInfo info(++m_maxObjectStoreID, name, keyPath, autoIncrement);
+    m_objectStoreMap.set(info.identifier(), info);
+    return info;
+}
+
+void IDBDatabaseInfo::addExistingObjectStore(const IDBObjectStoreInfo& info)
+{
+    ASSERT(!m_objectStoreMap.contains(info.identifier()));
+
+    if (info.identifier() > m_maxObjectStoreID)
+        m_maxObjectStoreID = info.identifier();
+
+    m_objectStoreMap.set(info.identifier(), info);
+}
+
+IDBObjectStoreInfo* IDBDatabaseInfo::getInfoForExistingObjectStore(uint64_t objectStoreIdentifier)
+{
+    auto iterator = m_objectStoreMap.find(objectStoreIdentifier);
+    if (iterator == m_objectStoreMap.end())
+        return nullptr;
+
+    return &iterator->value;
+}
+
+IDBObjectStoreInfo* IDBDatabaseInfo::getInfoForExistingObjectStore(const String& name)
+{
+    for (auto& objectStore : m_objectStoreMap.values()) {
+        if (objectStore.name() == name)
+            return &objectStore;
+    }
+
+    return nullptr;
+}
+
+const IDBObjectStoreInfo* IDBDatabaseInfo::infoForExistingObjectStore(uint64_t objectStoreIdentifier) const
+{
+    return const_cast<IDBDatabaseInfo*>(this)->getInfoForExistingObjectStore(objectStoreIdentifier);
+}
+
+IDBObjectStoreInfo* IDBDatabaseInfo::infoForExistingObjectStore(uint64_t objectStoreIdentifier)
+{
+    return getInfoForExistingObjectStore(objectStoreIdentifier);
+}
+
+const IDBObjectStoreInfo* IDBDatabaseInfo::infoForExistingObjectStore(const String& name) const
+{
+    return const_cast<IDBDatabaseInfo*>(this)->getInfoForExistingObjectStore(name);
+}
+
+IDBObjectStoreInfo* IDBDatabaseInfo::infoForExistingObjectStore(const String& name)
+{
+    return getInfoForExistingObjectStore(name);
+}
+
+Vector<String> IDBDatabaseInfo::objectStoreNames() const
+{
+    Vector<String> names;
+    names.reserveCapacity(m_objectStoreMap.size());
+    for (auto& objectStore : m_objectStoreMap.values())
+        names.uncheckedAppend(objectStore.name());
+
+    return names;
+}
+
+void IDBDatabaseInfo::deleteObjectStore(const String& objectStoreName)
+{
+    auto* info = infoForExistingObjectStore(objectStoreName);
+    if (!info)
+        return;
 
-    info.m_name = m_name.isolatedCopy();
-    info.m_version = m_version;
+    m_objectStoreMap.remove(info->identifier());
+}
+
+void IDBDatabaseInfo::deleteObjectStore(uint64_t objectStoreIdentifier)
+{
+    m_objectStoreMap.remove(objectStoreIdentifier);
+}
+
+#ifndef NDEBUG
+String IDBDatabaseInfo::loggingString() const
+{
+    String top = makeString("Database: ", m_name, " version ", String::number(m_version), "\n");
+    for (auto objectStore : m_objectStoreMap.values())
+        top.append(makeString(objectStore.loggingString(1), "\n"));
 
-    return WTF::move(info);
+    return top; 
 }
+#endif
 
 } // namespace WebCore