PassRefPtr<IDBIndex> IDBObjectStore::createIndex(const String& name, PassRefPtr<DOMStringList> keyPath, const Dictionary& options, ExceptionCode& ec) { // FIXME: Binding code for DOMString[] should not match null. http://webkit.org/b/84217 if (!keyPath) return createIndex(name, IDBKeyPath("null"), options, ec); return createIndex(name, IDBKeyPath(*keyPath), options, ec); }
bool ArgumentCoder<IDBKeyPath>::decode(ArgumentDecoder& decoder, IDBKeyPath& keyPath) { IDBKeyPath::Type type; if (!decoder.decodeEnum(type)) return false; switch (type) { case IDBKeyPath::NullType: keyPath = IDBKeyPath(); return true; case IDBKeyPath::StringType: { String string; if (!decoder.decode(string)) return false; keyPath = IDBKeyPath(string); return true; } case IDBKeyPath::ArrayType: { Vector<String> array; if (!decoder.decode(array)) return false; keyPath = IDBKeyPath(array); return true; } default: return false; } }
IDBKeyPath idbKeyPathFromValue(ExecState* exec, JSValue keyPathValue) { IDBKeyPath keyPath; if (isJSArray(keyPathValue)) keyPath = IDBKeyPath(toNativeArray<String>(exec, keyPathValue)); else keyPath = IDBKeyPath(keyPathValue.toString(exec)->value(exec)); return keyPath; }
PassRefPtr<IDBObjectStore> IDBDatabase::createObjectStore(const String& name, const Dictionary& options, ExceptionCode& ec) { if (!m_versionChangeTransaction) { ec = IDBDatabaseException::IDB_INVALID_STATE_ERR; return 0; } if (!m_versionChangeTransaction->isActive()) { ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR; return 0; } IDBKeyPath keyPath; if (!options.isUndefinedOrNull()) { String keyPathString; Vector<String> keyPathArray; if (options.get("keyPath", keyPathArray)) keyPath = IDBKeyPath(keyPathArray); else if (options.getWithUndefinedOrNullCheck("keyPath", keyPathString)) keyPath = IDBKeyPath(keyPathString); } if (containsObjectStore(name)) { ec = IDBDatabaseException::CONSTRAINT_ERR; return 0; } if (!keyPath.isNull() && !keyPath.isValid()) { ec = IDBDatabaseException::IDB_SYNTAX_ERR; return 0; } bool autoIncrement = false; if (!options.isUndefinedOrNull()) options.get("autoIncrement", autoIncrement); if (autoIncrement && ((keyPath.type() == IDBKeyPath::StringType && keyPath.string().isEmpty()) || keyPath.type() == IDBKeyPath::ArrayType)) { ec = IDBDatabaseException::IDB_INVALID_ACCESS_ERR; return 0; } int64_t objectStoreId = m_metadata.maxObjectStoreId + 1; RefPtr<IDBObjectStoreBackendInterface> objectStoreBackend = m_backend->createObjectStore(objectStoreId, name, keyPath, autoIncrement, m_versionChangeTransaction->backend(), ec); if (!objectStoreBackend) { ASSERT(ec); return 0; } IDBObjectStoreMetadata metadata(name, objectStoreId, keyPath, autoIncrement, IDBObjectStoreBackendInterface::MinimumIndexId); RefPtr<IDBObjectStore> objectStore = IDBObjectStore::create(metadata, objectStoreBackend.release(), m_versionChangeTransaction.get()); m_metadata.objectStores.set(metadata.id, metadata); ++m_metadata.maxObjectStoreId; m_versionChangeTransaction->objectStoreCreated(name, objectStore); return objectStore.release(); }
WebIDBKeyPath WebIDBKeyPath::create(const WebVector<WebString>& keyPath) { Vector<String> strings; for (size_t i = 0; i < keyPath.size(); ++i) strings.append(keyPath[i]); return WebIDBKeyPath(IDBKeyPath(strings)); }
RefPtr<IDBObjectStore> LegacyDatabase::createObjectStore(const String& name, const Dictionary& options, ExceptionCode& ec) { IDBKeyPath keyPath; bool autoIncrement = false; if (!options.isUndefinedOrNull()) { String keyPathString; Vector<String> keyPathArray; if (options.get("keyPath", keyPathArray)) keyPath = IDBKeyPath(keyPathArray); else if (options.getWithUndefinedOrNullCheck("keyPath", keyPathString)) keyPath = IDBKeyPath(keyPathString); options.get("autoIncrement", autoIncrement); } return createObjectStore(name, keyPath, autoIncrement, ec); }
IDBKeyPath decodeIDBKeyPath(const char* p, const char* limit) { // May be typed, or may be a raw string. An invalid leading // byte sequence is used to identify typed coding. New records are // always written as typed. if (p == limit || (limit - p >= 2 && (*p != IDBKeyPathTypeCodedByte1 || *(p + 1) != IDBKeyPathTypeCodedByte2))) return IDBKeyPath(decodeString(p, limit)); p += 2; ASSERT(p != limit); IDBKeyPath::Type type = static_cast<IDBKeyPath::Type>(*p++); switch (type) { case IDBKeyPath::NullType: ASSERT(p == limit); return IDBKeyPath(); case IDBKeyPath::StringType: { String string; p = decodeStringWithLength(p, limit, string); ASSERT(p == limit); return IDBKeyPath(string); } case IDBKeyPath::ArrayType: { Vector<String> array; int64_t count; p = decodeVarInt(p, limit, count); ASSERT(p); ASSERT(count >= 0); while (count--) { String string; p = decodeStringWithLength(p, limit, string); ASSERT(p); array.append(string); } ASSERT(p == limit); return IDBKeyPath(array); } } ASSERT_NOT_REACHED(); return IDBKeyPath(); }
bool deserializeIDBKeyPath(const uint8_t* data, size_t size, Optional<IDBKeyPath>& result) { if (!data || !size) return false; auto decoder = KeyedDecoder::decoder(data, size); KeyPathType type; bool succeeded = decoder->decodeEnum("type", type, [](KeyPathType value) { return value == KeyPathType::Null || value == KeyPathType::String || value == KeyPathType::Array; }); if (!succeeded) return false; switch (type) { case KeyPathType::Null: break; case KeyPathType::String: { String string; if (!decoder->decodeString("string", string)) return false; result = IDBKeyPath(WTFMove(string)); break; } case KeyPathType::Array: { Vector<String> vector; succeeded = decoder->decodeObjects("array", vector, [](KeyedDecoder& decoder, String& result) { return decoder.decodeString("string", result); }); if (!succeeded) return false; result = IDBKeyPath(WTFMove(vector)); break; } } return true; }
IDBDatabaseMetadata::IDBDatabaseMetadata(const WebIDBMetadata& webMetadata) : name(webMetadata.name), id(webMetadata.id), version(webMetadata.version), maxObjectStoreId(webMetadata.maxObjectStoreId) { for (size_t i = 0; i < webMetadata.objectStores.size(); ++i) { const WebIDBMetadata::ObjectStore& webObjectStore = webMetadata.objectStores[i]; RefPtr<IDBObjectStoreMetadata> objectStore = adoptRef(new IDBObjectStoreMetadata( webObjectStore.name, webObjectStore.id, IDBKeyPath(webObjectStore.keyPath), webObjectStore.autoIncrement, webObjectStore.maxIndexId)); for (size_t j = 0; j < webObjectStore.indexes.size(); ++j) { const WebIDBMetadata::Index& webIndex = webObjectStore.indexes[j]; RefPtr<IDBIndexMetadata> index = adoptRef(new IDBIndexMetadata( webIndex.name, webIndex.id, IDBKeyPath(webIndex.keyPath), webIndex.unique, webIndex.multiEntry)); objectStore->indexes.set(webIndex.id, std::move(index)); } objectStores.set(webObjectStore.id, std::move(objectStore)); } }
PassRefPtr<IDBIndex> IDBObjectStore::createIndex(const String& name, const String& keyPath, const Dictionary& options, ExceptionCode& ec) { return createIndex(name, IDBKeyPath(keyPath), options, ec); }
WebIDBKeyPath WebIDBKeyPath::createNull() { return WebIDBKeyPath(IDBKeyPath()); }
WebIDBKeyPath WebIDBKeyPath::create(const WebString& keyPath) { return WebIDBKeyPath(IDBKeyPath(keyPath)); }