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();
}
IDBObjectStore* IDBDatabase::createObjectStore(const String& name, const IDBKeyPath& keyPath, bool autoIncrement, ExceptionState& exceptionState)
{
    IDB_TRACE("IDBDatabase::createObjectStore");
    Platform::current()->histogramEnumeration("WebCore.IndexedDB.FrontEndAPICalls", IDBCreateObjectStoreCall, IDBMethodsMax);
    if (!m_versionChangeTransaction) {
        exceptionState.throwDOMException(InvalidStateError, IDBDatabase::notVersionChangeTransactionErrorMessage);
        return nullptr;
    }
    if (m_versionChangeTransaction->isFinished() || m_versionChangeTransaction->isFinishing()) {
        exceptionState.throwDOMException(TransactionInactiveError, IDBDatabase::transactionFinishedErrorMessage);
        return nullptr;
    }
    if (!m_versionChangeTransaction->isActive()) {
        exceptionState.throwDOMException(TransactionInactiveError, IDBDatabase::transactionInactiveErrorMessage);
        return nullptr;
    }

    if (containsObjectStore(name)) {
        exceptionState.throwDOMException(ConstraintError, "An object store with the specified name already exists.");
        return nullptr;
    }

    if (!keyPath.isNull() && !keyPath.isValid()) {
        exceptionState.throwDOMException(SyntaxError, "The keyPath option is not a valid key path.");
        return nullptr;
    }

    if (autoIncrement && ((keyPath.type() == IDBKeyPath::StringType && keyPath.string().isEmpty()) || keyPath.type() == IDBKeyPath::ArrayType)) {
        exceptionState.throwDOMException(InvalidAccessError, "The autoIncrement option was set but the keyPath option was empty or an array.");
        return nullptr;
    }

    if (!m_backend) {
        exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databaseClosedErrorMessage);
        return nullptr;
    }

    int64_t objectStoreId = m_metadata.maxObjectStoreId + 1;
    m_backend->createObjectStore(m_versionChangeTransaction->id(), objectStoreId, name, keyPath, autoIncrement);

    IDBObjectStoreMetadata metadata(name, objectStoreId, keyPath, autoIncrement, WebIDBDatabase::minimumIndexId);
    IDBObjectStore* objectStore = IDBObjectStore::create(metadata, m_versionChangeTransaction.get());
    m_metadata.objectStores.set(metadata.id, metadata);
    ++m_metadata.maxObjectStoreId;

    m_versionChangeTransaction->objectStoreCreated(name, objectStore);
    return objectStore;
}
Example #3
0
PassRefPtr<IDBObjectStore> IDBDatabase::createObjectStore(const String& name, const IDBKeyPath& keyPath, bool autoIncrement, ExceptionCode& ec)
{
    IDB_TRACE("IDBDatabase::createObjectStore");
    HistogramSupport::histogramEnumeration("WebCore.IndexedDB.FrontEndAPICalls", IDBCreateObjectStoreCall, IDBMethodsMax);
    if (!m_versionChangeTransaction) {
        ec = IDBDatabaseException::InvalidStateError;
        return 0;
    }
    if (!m_versionChangeTransaction->isActive()) {
        ec = IDBDatabaseException::TransactionInactiveError;
        return 0;
    }

    if (containsObjectStore(name)) {
        ec = IDBDatabaseException::ConstraintError;
        return 0;
    }

    if (!keyPath.isNull() && !keyPath.isValid()) {
        ec = IDBDatabaseException::SyntaxError;
        return 0;
    }

    if (autoIncrement && ((keyPath.type() == IDBKeyPath::StringType && keyPath.string().isEmpty()) || keyPath.type() == IDBKeyPath::ArrayType)) {
        ec = IDBDatabaseException::InvalidAccessError;
        return 0;
    }

    int64_t objectStoreId = m_metadata.maxObjectStoreId + 1;
    m_backend->createObjectStore(m_versionChangeTransaction->id(), objectStoreId, name, keyPath, autoIncrement);

    IDBObjectStoreMetadata metadata(name, objectStoreId, keyPath, autoIncrement, IDBDatabaseBackendInterface::MinimumIndexId);
    RefPtr<IDBObjectStore> objectStore = IDBObjectStore::create(metadata, m_versionChangeTransaction.get());
    m_metadata.objectStores.set(metadata.id, metadata);
    ++m_metadata.maxObjectStoreId;

    m_versionChangeTransaction->objectStoreCreated(name, objectStore);
    return objectStore.release();
}
RefPtr<IDBObjectStore> LegacyDatabase::createObjectStore(const String& name, const IDBKeyPath& keyPath, bool autoIncrement, ExceptionCode& ec)
{
    LOG(StorageAPI, "LegacyDatabase::createObjectStore");
    if (!m_versionChangeTransaction) {
        ec = IDBDatabaseException::InvalidStateError;
        return 0;
    }
    if (!m_versionChangeTransaction->isActive()) {
        ec = IDBDatabaseException::TransactionInactiveError;
        return 0;
    }

    if (containsObjectStore(name)) {
        ec = IDBDatabaseException::ConstraintError;
        return 0;
    }

    if (!keyPath.isNull() && !keyPath.isValid()) {
        ec = IDBDatabaseException::SyntaxError;
        return 0;
    }

    if (autoIncrement && ((keyPath.type() == IDBKeyPath::StringType && keyPath.string().isEmpty()) || keyPath.type() == IDBKeyPath::ArrayType)) {
        ec = IDBDatabaseException::InvalidAccessError;
        return 0;
    }

    int64_t objectStoreId = m_metadata.maxObjectStoreId + 1;
    m_backend->createObjectStore(m_versionChangeTransaction->id(), objectStoreId, name, keyPath, autoIncrement);

    IDBObjectStoreMetadata metadata(name, objectStoreId, keyPath, autoIncrement, IDBDatabaseBackend::MinimumIndexId);
    RefPtr<LegacyObjectStore> objectStore = LegacyObjectStore::create(metadata, m_versionChangeTransaction.get());
    m_metadata.objectStores.set(metadata.id, metadata);
    ++m_metadata.maxObjectStoreId;

    m_versionChangeTransaction->objectStoreCreated(name, objectStore);
    return objectStore.release();
}
Example #5
0
IDBObjectStore* IDBDatabase::createObjectStore(const String& name,
                                               const IDBKeyPath& keyPath,
                                               bool autoIncrement,
                                               ExceptionState& exceptionState) {
  IDB_TRACE("IDBDatabase::createObjectStore");
  recordApiCallsHistogram(IDBCreateObjectStoreCall);

  if (!m_versionChangeTransaction) {
    exceptionState.throwDOMException(
        InvalidStateError,
        IDBDatabase::notVersionChangeTransactionErrorMessage);
    return nullptr;
  }
  if (m_versionChangeTransaction->isFinished() ||
      m_versionChangeTransaction->isFinishing()) {
    exceptionState.throwDOMException(
        TransactionInactiveError, IDBDatabase::transactionFinishedErrorMessage);
    return nullptr;
  }
  if (!m_versionChangeTransaction->isActive()) {
    exceptionState.throwDOMException(
        TransactionInactiveError, IDBDatabase::transactionInactiveErrorMessage);
    return nullptr;
  }

  if (!keyPath.isNull() && !keyPath.isValid()) {
    exceptionState.throwDOMException(
        SyntaxError, "The keyPath option is not a valid key path.");
    return nullptr;
  }

  if (containsObjectStore(name)) {
    exceptionState.throwDOMException(
        ConstraintError, IDBDatabase::objectStoreNameTakenErrorMessage);
    return nullptr;
  }

  if (autoIncrement && ((keyPath.getType() == IDBKeyPath::StringType &&
                         keyPath.string().isEmpty()) ||
                        keyPath.getType() == IDBKeyPath::ArrayType)) {
    exceptionState.throwDOMException(InvalidAccessError,
                                     "The autoIncrement option was set but the "
                                     "keyPath option was empty or an array.");
    return nullptr;
  }

  if (!m_backend) {
    exceptionState.throwDOMException(InvalidStateError,
                                     IDBDatabase::databaseClosedErrorMessage);
    return nullptr;
  }

  int64_t objectStoreId = m_metadata.maxObjectStoreId + 1;
  DCHECK_NE(objectStoreId, IDBObjectStoreMetadata::InvalidId);
  m_backend->createObjectStore(m_versionChangeTransaction->id(), objectStoreId,
                               name, keyPath, autoIncrement);

  RefPtr<IDBObjectStoreMetadata> storeMetadata = adoptRef(
      new IDBObjectStoreMetadata(name, objectStoreId, keyPath, autoIncrement,
                                 WebIDBDatabase::minimumIndexId));
  IDBObjectStore* objectStore =
      IDBObjectStore::create(storeMetadata, m_versionChangeTransaction.get());
  m_versionChangeTransaction->objectStoreCreated(name, objectStore);
  m_metadata.objectStores.set(objectStoreId, std::move(storeMetadata));
  ++m_metadata.maxObjectStoreId;

  return objectStore;
}