storage/src/StorageBaseStatementInternal.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     2  * vim: sw=2 ts=2 sts=2 expandtab
     3  * This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #ifndef mozilla_storage_StorageBaseStatementInternal_h_
     8 #define mozilla_storage_StorageBaseStatementInternal_h_
    10 #include "nsISupports.h"
    11 #include "nsCOMPtr.h"
    12 #include "nsAutoPtr.h"
    14 struct sqlite3;
    15 struct sqlite3_stmt;
    16 class mozIStorageError;
    17 class mozIStorageBindingParamsArray;
    18 class mozIStorageBindingParams;
    19 class mozIStorageStatementCallback;
    20 class mozIStoragePendingStatement;
    22 namespace mozilla {
    23 namespace storage {
    25 #define STORAGEBASESTATEMENTINTERNAL_IID \
    26   {0xd18856c9, 0xbf07, 0x4ae2, {0x94, 0x5b, 0x1a, 0xdd, 0x49, 0x19, 0x55, 0x2a}}
    28 class Connection;
    29 class StatementData;
    31 class AsyncStatementFinalizer;
    33 /**
    34  * Implementation-only interface and shared logix mix-in corresponding to
    35  * mozIStorageBaseStatement.  Both Statement and AsyncStatement inherit from
    36  * this. The interface aspect makes them look the same to implementation innards
    37  * that aren't publicly accessible.  The mix-in avoids code duplication in
    38  * common implementations of mozIStorageBaseStatement, albeit with some minor
    39  * performance/space overhead because we have to use defines to officially
    40  * implement the methods on Statement/AsyncStatement (and proxy to this base
    41  * class.)
    42  */
    43 class StorageBaseStatementInternal : public nsISupports
    44 {
    45 public:
    46   NS_DECLARE_STATIC_IID_ACCESSOR(STORAGEBASESTATEMENTINTERNAL_IID)
    48   /**
    49    * @return the connection that this statement belongs to.
    50    */
    51   Connection *getOwner()
    52   {
    53     return mDBConnection;
    54   }
    56   /**
    57    * Return the asynchronous statement, creating it if required.
    58    *
    59    * This is for use by the asynchronous execution code for StatementData
    60    * created by AsyncStatements.  Statement internally uses this method to
    61    * prepopulate StatementData with the sqlite3_stmt.
    62    *
    63    * @param[out] stmt
    64    *             The sqlite3_stmt for asynchronous use.
    65    * @return The SQLite result code for creating the statement if created,
    66    *         SQLITE_OK if creation was not required.
    67    */
    68   virtual int getAsyncStatement(sqlite3_stmt **_stmt) = 0;
    70   /**
    71    * Obtains the StatementData needed for asynchronous execution.
    72    *
    73    * This is for use by Connection to retrieve StatementData from statements
    74    * when executeAsync is invoked.
    75    *
    76    * @param[out] _data
    77    *             A reference to a StatementData object that will be populated
    78    *             upon successful execution of this method.
    79    * @return NS_OK if we were able to assemble the data, failure otherwise.
    80    */
    81   virtual nsresult getAsynchronousStatementData(StatementData &_data) = 0;
    83   /**
    84    * Construct a new BindingParams to be owned by the provided binding params
    85    * array.  This method exists so that BindingParamsArray does not need
    86    * factory logic to determine what type of BindingParams to instantiate.
    87    *
    88    * @param aOwner
    89    *        The binding params array to own the newly created binding params.
    90    * @return The new mozIStorageBindingParams instance appropriate to the
    91    *         underlying statement type.
    92    */
    93   virtual already_AddRefed<mozIStorageBindingParams> newBindingParams(
    94     mozIStorageBindingParamsArray *aOwner
    95   ) = 0;
    97 protected: // mix-in bits are protected
    98   StorageBaseStatementInternal();
   100   nsRefPtr<Connection> mDBConnection;
   101   sqlite3 *mNativeConnection;
   103   /**
   104    * Our asynchronous statement.
   105    *
   106    * For Statement this is populated by the first invocation to
   107    * getAsyncStatement.
   108    *
   109    * For AsyncStatement, this is null at creation time and initialized by the
   110    * async thread when it calls getAsyncStatement the first time the statement
   111    * is executed.  (Or in the event of badly formed SQL, every time.)
   112    */
   113   sqlite3_stmt *mAsyncStatement;
   115   /**
   116    * Initiate asynchronous finalization by dispatching an event to the
   117    * asynchronous thread to finalize mAsyncStatement.  This acquires a reference
   118    * to this statement and proxies it back to the connection's owning thread
   119    * for release purposes.
   120    *
   121    * In the event the asynchronous thread is already gone or we otherwise fail
   122    * to dispatch an event to it we failover to invoking internalAsyncFinalize
   123    * directly.  (That's what the asynchronous finalizer would have called.)
   124    *
   125    * @note You must not call this method from your destructor because its
   126    *       operation assumes we are still alive.  Call internalAsyncFinalize
   127    *       directly in that case.
   128    */
   129   void asyncFinalize();
   131   /**
   132    * Cleanup the async sqlite3_stmt stored in mAsyncStatement if it exists by
   133    * attempting to dispatch to the asynchronous thread if available, finalizing
   134    * on this thread if it is not.
   135    *
   136    * @note Call this from your destructor, call asyncFinalize otherwise.
   137    */
   138   void destructorAsyncFinalize();
   140   NS_IMETHOD NewBindingParamsArray(mozIStorageBindingParamsArray **_array);
   141   NS_IMETHOD ExecuteAsync(mozIStorageStatementCallback *aCallback,
   142                           mozIStoragePendingStatement **_stmt);
   143   NS_IMETHOD EscapeStringForLIKE(const nsAString &aValue,
   144                                  const char16_t aEscapeChar,
   145                                  nsAString &_escapedString);
   147   // Needs access to internalAsyncFinalize
   148   friend class AsyncStatementFinalizer;
   149 };
   151 NS_DEFINE_STATIC_IID_ACCESSOR(StorageBaseStatementInternal,
   152                               STORAGEBASESTATEMENTINTERNAL_IID)
   154 #define NS_DECL_STORAGEBASESTATEMENTINTERNAL \
   155   virtual Connection *getOwner(); \
   156   virtual int getAsyncStatement(sqlite3_stmt **_stmt); \
   157   virtual nsresult getAsynchronousStatementData(StatementData &_data); \
   158   virtual already_AddRefed<mozIStorageBindingParams> newBindingParams( \
   159     mozIStorageBindingParamsArray *aOwner);
   161 /**
   162  * Helper macro to implement the proxying implementations.  Because we are
   163  * implementing methods that are part of mozIStorageBaseStatement and the
   164  * implementation classes already use NS_DECL_MOZISTORAGEBASESTATEMENT we don't
   165  * need to provide declaration support.
   166  */
   167 #define MIX_IMPL(_class, _optionalGuard, _method, _declArgs, _invokeArgs) \
   168   NS_IMETHODIMP _class::_method _declArgs                                 \
   169   {                                                                       \
   170     _optionalGuard                                                        \
   171     return StorageBaseStatementInternal::_method _invokeArgs;             \
   172   }
   175 /**
   176  * Define proxying implementation for the given _class.  If a state invariant
   177  * needs to be checked and an early return possibly performed, pass the clause
   178  * to use as _optionalGuard.
   179  */
   180 #define MIXIN_IMPL_STORAGEBASESTATEMENTINTERNAL(_class, _optionalGuard) \
   181   MIX_IMPL(_class, _optionalGuard,                                      \
   182            NewBindingParamsArray,                                       \
   183            (mozIStorageBindingParamsArray **_array),                    \
   184            (_array))                                                    \
   185   MIX_IMPL(_class, _optionalGuard,                                      \
   186            ExecuteAsync,                                                \
   187            (mozIStorageStatementCallback *aCallback,                    \
   188             mozIStoragePendingStatement **_stmt),                       \
   189            (aCallback, _stmt))                                          \
   190   MIX_IMPL(_class, _optionalGuard,                                      \
   191            EscapeStringForLIKE,                                         \
   192            (const nsAString &aValue, const char16_t aEscapeChar,       \
   193             nsAString &_escapedString),                                 \
   194            (aValue, aEscapeChar, _escapedString))
   196 /**
   197  * Name-building helper for BIND_GEN_IMPL.
   198  */
   199 #define BIND_NAME_CONCAT(_nameBit, _concatBit) \
   200   Bind##_nameBit##_concatBit
   202 /**
   203  * We have type-specific convenience methods for C++ implementations in
   204  * 3 different forms; 2 by index, 1 by name.  The following macro allows
   205  * us to avoid having to define repetitive things by hand.
   206  *
   207  * Because of limitations of macros and our desire to avoid requiring special
   208  * permutations for the null and blob cases (whose argument count varies),
   209  * we require that the argument declarations and corresponding invocation
   210  * usages are passed in.
   211  *
   212  * @param _class
   213  *        The class name.
   214  * @param _guard
   215  *        The guard clause to inject.
   216  * @param _declName
   217  *        The argument list (with parens) for the ByName variants.
   218  * @param _declIndex
   219  *        The argument list (with parens) for the index variants.
   220  * @param _invArgs
   221  *        The invocation argumment list.
   222  */
   223 #define BIND_GEN_IMPL(_class, _guard, _name, _declName, _declIndex, _invArgs) \
   224   NS_IMETHODIMP _class::BIND_NAME_CONCAT(_name, ByName) _declName             \
   225   {                                                                           \
   226     _guard                                                                    \
   227     mozIStorageBindingParams *params = getParams();                           \
   228     NS_ENSURE_TRUE(params, NS_ERROR_OUT_OF_MEMORY);                           \
   229     return params->BIND_NAME_CONCAT(_name, ByName) _invArgs;                  \
   230   }                                                                           \
   231   NS_IMETHODIMP _class::BIND_NAME_CONCAT(_name, ByIndex) _declIndex           \
   232   {                                                                           \
   233     _guard                                                                    \
   234     mozIStorageBindingParams *params = getParams();                           \
   235     NS_ENSURE_TRUE(params, NS_ERROR_OUT_OF_MEMORY);                           \
   236     return params->BIND_NAME_CONCAT(_name, ByIndex) _invArgs;                 \
   237   }                                                                           \
   238   NS_IMETHODIMP _class::BIND_NAME_CONCAT(_name, Parameter) _declIndex         \
   239   {                                                                           \
   240     _guard                                                                    \
   241     mozIStorageBindingParams *params = getParams();                           \
   242     NS_ENSURE_TRUE(params, NS_ERROR_OUT_OF_MEMORY);                           \
   243     return params->BIND_NAME_CONCAT(_name, ByIndex) _invArgs;                 \
   244   }
   246 /**
   247  * Implement BindByName/BindByIndex for the given class.
   248  *
   249  * @param _class The class name.
   250  * @param _optionalGuard The guard clause to inject.
   251  */
   252 #define BIND_BASE_IMPLS(_class, _optionalGuard)             \
   253   NS_IMETHODIMP _class::BindByName(const nsACString &aName, \
   254                                    nsIVariant *aValue)      \
   255   {                                                         \
   256     _optionalGuard                                          \
   257     mozIStorageBindingParams *params = getParams();         \
   258     NS_ENSURE_TRUE(params, NS_ERROR_OUT_OF_MEMORY);         \
   259     return params->BindByName(aName, aValue);               \
   260   }                                                         \
   261   NS_IMETHODIMP _class::BindByIndex(uint32_t aIndex,        \
   262                                     nsIVariant *aValue)     \
   263   {                                                         \
   264     _optionalGuard                                          \
   265     mozIStorageBindingParams *params = getParams();         \
   266     NS_ENSURE_TRUE(params, NS_ERROR_OUT_OF_MEMORY);         \
   267     return params->BindByIndex(aIndex, aValue);             \
   268   }
   270 /**
   271  * Define the various Bind*Parameter, Bind*ByIndex, Bind*ByName stubs that just
   272  * end up proxying to the params object.
   273  */
   274 #define BOILERPLATE_BIND_PROXIES(_class, _optionalGuard) \
   275   BIND_BASE_IMPLS(_class, _optionalGuard)                \
   276   BIND_GEN_IMPL(_class, _optionalGuard,                  \
   277                 UTF8String,                              \
   278                 (const nsACString &aWhere,               \
   279                  const nsACString &aValue),              \
   280                 (uint32_t aWhere,                        \
   281                  const nsACString &aValue),              \
   282                 (aWhere, aValue))                        \
   283   BIND_GEN_IMPL(_class, _optionalGuard,                  \
   284                 String,                                  \
   285                 (const nsACString &aWhere,               \
   286                  const nsAString  &aValue),              \
   287                 (uint32_t aWhere,                        \
   288                  const nsAString  &aValue),              \
   289                 (aWhere, aValue))                        \
   290   BIND_GEN_IMPL(_class, _optionalGuard,                  \
   291                 Double,                                  \
   292                 (const nsACString &aWhere,               \
   293                  double aValue),                         \
   294                 (uint32_t aWhere,                        \
   295                  double aValue),                         \
   296                 (aWhere, aValue))                        \
   297   BIND_GEN_IMPL(_class, _optionalGuard,                  \
   298                 Int32,                                   \
   299                 (const nsACString &aWhere,               \
   300                  int32_t aValue),                        \
   301                 (uint32_t aWhere,                        \
   302                  int32_t aValue),                        \
   303                 (aWhere, aValue))                        \
   304   BIND_GEN_IMPL(_class, _optionalGuard,                  \
   305                 Int64,                                   \
   306                 (const nsACString &aWhere,               \
   307                  int64_t aValue),                        \
   308                 (uint32_t aWhere,                        \
   309                  int64_t aValue),                        \
   310                 (aWhere, aValue))                        \
   311   BIND_GEN_IMPL(_class, _optionalGuard,                  \
   312                 Null,                                    \
   313                 (const nsACString &aWhere),              \
   314                 (uint32_t aWhere),                       \
   315                 (aWhere))                                \
   316   BIND_GEN_IMPL(_class, _optionalGuard,                  \
   317                 Blob,                                    \
   318                 (const nsACString &aWhere,               \
   319                  const uint8_t *aValue,                  \
   320                  uint32_t aValueSize),                   \
   321                 (uint32_t aWhere,                        \
   322                  const uint8_t *aValue,                  \
   323                  uint32_t aValueSize),                   \
   324                 (aWhere, aValue, aValueSize))            \
   325   BIND_GEN_IMPL(_class, _optionalGuard,                  \
   326                 AdoptedBlob,                             \
   327                 (const nsACString &aWhere,               \
   328                  uint8_t *aValue,                        \
   329                  uint32_t aValueSize),                   \
   330                 (uint32_t aWhere,                        \
   331                  uint8_t *aValue,                        \
   332                  uint32_t aValueSize),                   \
   333                 (aWhere, aValue, aValueSize))
   337 } // storage
   338 } // mozilla
   340 #endif // mozilla_storage_StorageBaseStatementInternal_h_

mercurial