storage/mozStorageStatementData.h
author alwu <alwu@mozilla.com>
Mon, 07 Jan 2019 19:57:48 +0000
changeset 512757 0e229bbdaae5c8fa9f83796c628a4fdf88f057ba
parent 508163 6f3709b3878117466168c40affa7bca0b60cf75b
permissions -rw-r--r--
Bug 1513039 - part5 : log warning when autoplay is blocked. r=cpearce,karlt Wrap 'nsContentUtils::ReportToConsole()' to reduce necessary input parameters and call it when we need to log error or warning message. Show the warning when autoplay is blocked. For web audio, this restores the console messages removed in part4 and also reports the same message when the AudioContext is blocked in the constructor. Differential Revision: https://phabricator.services.mozilla.com/D14330

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * vim: sw=2 ts=2 sts=2 et
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef mozStorageStatementData_h
#define mozStorageStatementData_h

#include "sqlite3.h"

#include "nsAutoPtr.h"
#include "nsTArray.h"
#include "nsIEventTarget.h"
#include "MainThreadUtils.h"

#include "mozStorageBindingParamsArray.h"
#include "mozIStorageBaseStatement.h"
#include "mozStorageConnection.h"
#include "StorageBaseStatementInternal.h"

struct sqlite3_stmt;

namespace mozilla {
namespace storage {

class StatementData {
 public:
  StatementData(sqlite3_stmt *aStatement,
                already_AddRefed<BindingParamsArray> aParamsArray,
                StorageBaseStatementInternal *aStatementOwner)
      : mStatement(aStatement),
        mParamsArray(aParamsArray),
        mStatementOwner(aStatementOwner) {
    MOZ_ASSERT(mStatementOwner, "Must have a statement owner!");
  }
  StatementData(const StatementData &aSource)
      : mStatement(aSource.mStatement),
        mParamsArray(aSource.mParamsArray),
        mStatementOwner(aSource.mStatementOwner) {
    MOZ_ASSERT(mStatementOwner, "Must have a statement owner!");
  }
  StatementData() : mStatement(nullptr) {}
  ~StatementData() {
    // We need to ensure that mParamsArray is released on the main thread,
    // as the binding arguments may be XPConnect values, which are safe
    // to release only on the main thread.
    NS_ReleaseOnMainThreadSystemGroup("StatementData::mParamsArray",
                                      mParamsArray.forget());
  }

  /**
   * Return the sqlite statement, fetching it from the storage statement.  In
   * the case of AsyncStatements this may actually create the statement
   */
  inline int getSqliteStatement(sqlite3_stmt **_stmt) {
    if (!mStatement) {
      int rc = mStatementOwner->getAsyncStatement(&mStatement);
      NS_ENSURE_TRUE(rc == SQLITE_OK, rc);
    }
    *_stmt = mStatement;
    return SQLITE_OK;
  }

  operator BindingParamsArray *() const { return mParamsArray; }

  /**
   * NULLs out our sqlite3_stmt (it is held by the owner) after reseting it and
   * clear all bindings to it.  This is expected to occur on the async thread.
   */
  inline void reset() {
    MOZ_ASSERT(mStatementOwner, "Must have a statement owner!");
    // In the AsyncStatement case we may never have populated mStatement if the
    // AsyncExecuteStatements got canceled or a failure occurred in constructing
    // the statement.
    if (mStatement) {
      (void)::sqlite3_reset(mStatement);
      (void)::sqlite3_clear_bindings(mStatement);
      mStatement = nullptr;
    }
  }

  /**
   * Indicates if this statement has parameters to be bound before it is
   * executed.
   *
   * @return true if the statement has parameters to bind against, false
   *         otherwise.
   */
  inline bool hasParametersToBeBound() const { return !!mParamsArray; }
  /**
   * Indicates the number of implicit statements generated by this statement
   * requiring a transaction for execution.  For example a single statement
   * with N BindingParams will execute N implicit staments.
   *
   * @return number of statements requiring a transaction for execution.
   *
   * @note In the case of AsyncStatements this may actually create the
   *       statement.
   */
  inline uint32_t needsTransaction() {
    MOZ_ASSERT(!NS_IsMainThread());
    // Be sure to use the getSqliteStatement helper, since sqlite3_stmt_readonly
    // can only analyze prepared statements and AsyncStatements are prepared
    // lazily.
    sqlite3_stmt *stmt;
    int rc = getSqliteStatement(&stmt);
    if (SQLITE_OK != rc || ::sqlite3_stmt_readonly(stmt)) {
      return 0;
    }
    return mParamsArray ? mParamsArray->length() : 1;
  }

 private:
  sqlite3_stmt *mStatement;
  RefPtr<BindingParamsArray> mParamsArray;

  /**
   * We hold onto a reference of the statement's owner so it doesn't get
   * destroyed out from under us.
   */
  nsCOMPtr<StorageBaseStatementInternal> mStatementOwner;
};

}  // namespace storage
}  // namespace mozilla

#endif  // mozStorageStatementData_h