author Matthew Noorenberghe <>
Fri, 21 Dec 2018 16:56:15 +0000
changeset 508848 443b0e20be2216655fcd4c0ab32287282014c697
parent 505383 6f3709b3878117466168c40affa7bca0b60cf75b
permissions -rw-r--r--
Bug 1330228 - Use hasBeenTypePassword in FormData.jsm to not save former password fields. r=Felipe Differential Revision:

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
 * 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 */

#ifndef mozilla_storage_StatementCache_h
#define mozilla_storage_StatementCache_h

#include "mozIStorageConnection.h"
#include "mozIStorageStatement.h"
#include "mozIStorageAsyncStatement.h"

#include "nsAutoPtr.h"
#include "nsHashKeys.h"
#include "nsInterfaceHashtable.h"

namespace mozilla {
namespace storage {

 * Class used to cache statements (mozIStorageStatement or
 * mozIStorageAsyncStatement).
template <typename StatementType>
class StatementCache {
   * Constructor for the cache.
   * @note a connection can have more than one cache.
   * @param aConnection
   *        A reference to the nsCOMPtr for the connection this cache is to be
   *        used for.  This nsCOMPtr must at least live as long as this class,
   *        otherwise crashes will happen.
  explicit StatementCache(nsCOMPtr<mozIStorageConnection>& aConnection)
      : mConnection(aConnection) {}

   * Obtains a cached statement.  If this statement is not yet created, it will
   * be created and stored for later use.
   * @param aQuery
   *        The SQL string (either a const char [] or nsACString) to get a
   *        cached query for.
   * @return the cached statement, or null upon error.
  inline already_AddRefed<StatementType> GetCachedStatement(
      const nsACString& aQuery) {
    nsCOMPtr<StatementType> stmt;
    if (!mCachedStatements.Get(aQuery, getter_AddRefs(stmt))) {
      stmt = CreateStatement(aQuery);
      NS_ENSURE_TRUE(stmt, nullptr);

      mCachedStatements.Put(aQuery, stmt);
    return stmt.forget();

  template <int N>
  MOZ_ALWAYS_INLINE already_AddRefed<StatementType> GetCachedStatement(
      const char (&aQuery)[N]) {
    nsDependentCString query(aQuery, N - 1);
    return GetCachedStatement(query);

   * Finalizes all cached statements so the database can be safely closed.  The
   * behavior of this cache is unspecified after this method is called.
  inline void FinalizeStatements() {
    for (auto iter = mCachedStatements.Iter(); !iter.Done(); iter.Next()) {

    // Clear the cache at this time too!

  inline already_AddRefed<StatementType> CreateStatement(
      const nsACString& aQuery);

  nsInterfaceHashtable<nsCStringHashKey, StatementType> mCachedStatements;
  nsCOMPtr<mozIStorageConnection>& mConnection;

template <>
inline already_AddRefed<mozIStorageStatement>
    const nsACString& aQuery) {
  NS_ENSURE_TRUE(mConnection, nullptr);

  nsCOMPtr<mozIStorageStatement> stmt;
  nsresult rv = mConnection->CreateStatement(aQuery, getter_AddRefs(stmt));
  if (NS_FAILED(rv)) {
    nsCString error;
    error.AppendLiteral("The statement '");
    error.AppendLiteral("' failed to compile with the error message '");
    nsCString msg;
  NS_ENSURE_SUCCESS(rv, nullptr);

  return stmt.forget();

template <>
inline already_AddRefed<mozIStorageAsyncStatement>
    const nsACString& aQuery) {
  NS_ENSURE_TRUE(mConnection, nullptr);

  nsCOMPtr<mozIStorageAsyncStatement> stmt;
  nsresult rv = mConnection->CreateAsyncStatement(aQuery, getter_AddRefs(stmt));
  NS_ENSURE_SUCCESS(rv, nullptr);

  return stmt.forget();

}  // namespace storage
}  // namespace mozilla

#endif  // mozilla_storage_StatementCache_h