bool isIDBKeyPathValid(const IDBKeyPath& keyPath) { auto visitor = WTF::makeVisitor([](const String& string) { return IDBIsValidKeyPath(string); }, [](const Vector<String>& vector) { if (vector.isEmpty()) return false; for (auto& key : vector) { if (!IDBIsValidKeyPath(key)) return false; } return true; }); return WTF::visit(visitor, keyPath); }
PassRefPtr<IDBObjectStore> IDBDatabase::createObjectStore(const String& name, const OptionsObject& options, ExceptionCode& ec) { if (!m_setVersionTransaction) { ec = IDBDatabaseException::NOT_ALLOWED_ERR; return 0; } String keyPath; bool keyPathExists = options.getKeyStringWithUndefinedOrNullCheck("keyPath", keyPath); if (keyPathExists && !IDBIsValidKeyPath(keyPath)) { ec = IDBDatabaseException::NON_TRANSIENT_ERR; return 0; } bool autoIncrement = false; options.getKeyBool("autoIncrement", autoIncrement); // FIXME: Look up evictable and pass that on as well. RefPtr<IDBObjectStoreBackendInterface> objectStore = m_backend->createObjectStore(name, keyPath, autoIncrement, m_setVersionTransaction->backend(), ec); if (!objectStore) { ASSERT(ec); return 0; } return IDBObjectStore::create(objectStore.release(), m_setVersionTransaction.get()); }
bool IDBKeyPath::isValid() const { switch (m_type) { case NullType: return false; case StringType: return IDBIsValidKeyPath(m_string); case ArrayType: if (m_array.isEmpty()) return false; for (size_t i = 0; i < m_array.size(); ++i) { if (!IDBIsValidKeyPath(m_array[i])) return false; } return true; } ASSERT_NOT_REACHED(); return false; }
PassRefPtr<IDBIndex> IDBObjectStore::createIndex(const String& name, const String& keyPath, const OptionsObject& options, ExceptionCode& ec) { if (!IDBIsValidKeyPath(keyPath)) { ec = IDBDatabaseException::NON_TRANSIENT_ERR; return 0; } bool unique = false; options.getKeyBool("unique", unique); RefPtr<IDBIndexBackendInterface> index = m_objectStore->createIndex(name, keyPath, unique, m_transaction->backend(), ec); ASSERT(!index != !ec); // If we didn't get an index, we should have gotten an exception code. And vice versa. if (!index) return 0; return IDBIndex::create(index.release(), this, m_transaction.get()); }