LCOV - code coverage report
Current view: top level - storage - StorageBaseStatementInternal.h (source / functions) Hit Total Coverage
Test: output.info Lines: 3 3 100.0 %
Date: 2017-07-14 16:53:18 Functions: 2 2 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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/. */
       6             : 
       7             : #ifndef mozilla_storage_StorageBaseStatementInternal_h_
       8             : #define mozilla_storage_StorageBaseStatementInternal_h_
       9             : 
      10             : #include "nsISupports.h"
      11             : #include "nsCOMPtr.h"
      12             : #include "nsAutoPtr.h"
      13             : #include "mozStorageHelper.h"
      14             : 
      15             : struct sqlite3;
      16             : struct sqlite3_stmt;
      17             : class mozIStorageBindingParamsArray;
      18             : class mozIStorageBindingParams;
      19             : class mozIStorageStatementCallback;
      20             : class mozIStoragePendingStatement;
      21             : 
      22             : namespace mozilla {
      23             : namespace storage {
      24             : 
      25             : #define STORAGEBASESTATEMENTINTERNAL_IID \
      26             :   {0xd18856c9, 0xbf07, 0x4ae2, {0x94, 0x5b, 0x1a, 0xdd, 0x49, 0x19, 0x55, 0x2a}}
      27             : 
      28             : class Connection;
      29             : class StatementData;
      30             : 
      31             : class AsyncStatementFinalizer;
      32             : 
      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          22 : class StorageBaseStatementInternal : public nsISupports
      44             : {
      45             : public:
      46             :   NS_DECLARE_STATIC_IID_ACCESSOR(STORAGEBASESTATEMENTINTERNAL_IID)
      47             : 
      48             :   /**
      49             :    * @return the connection that this statement belongs to.
      50             :    */
      51           3 :   Connection *getOwner()
      52             :   {
      53           3 :     return mDBConnection;
      54             :   }
      55             : 
      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;
      69             : 
      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;
      82             : 
      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;
      96             : 
      97             : protected: // mix-in bits are protected
      98             :   StorageBaseStatementInternal();
      99             : 
     100             :   RefPtr<Connection> mDBConnection;
     101             :   sqlite3 *mNativeConnection;
     102             : 
     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;
     114             : 
     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();
     130             : 
     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();
     139             : 
     140             :   NS_IMETHOD NewBindingParamsArray(mozIStorageBindingParamsArray **_array);
     141             :   NS_IMETHOD ExecuteAsync(mozIStorageStatementCallback *aCallback,
     142             :                           mozIStoragePendingStatement **_stmt);
     143             :   NS_IMETHOD EscapeStringForLIKE(const nsAString &aValue,
     144             :                                  char16_t aEscapeChar,
     145             :                                  nsAString &_escapedString);
     146             : 
     147             :   // Needs access to internalAsyncFinalize
     148             :   friend class AsyncStatementFinalizer;
     149             : };
     150             : 
     151             : NS_DEFINE_STATIC_IID_ACCESSOR(StorageBaseStatementInternal,
     152             :                               STORAGEBASESTATEMENTINTERNAL_IID)
     153             : 
     154             : #define NS_DECL_STORAGEBASESTATEMENTINTERNAL \
     155             :   virtual Connection *getOwner(); \
     156             :   virtual int getAsyncStatement(sqlite3_stmt **_stmt) override; \
     157             :   virtual nsresult getAsynchronousStatementData(StatementData &_data) override; \
     158             :   virtual already_AddRefed<mozIStorageBindingParams> newBindingParams( \
     159             :     mozIStorageBindingParamsArray *aOwner) override;
     160             : 
     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             :   }
     173             : 
     174             : 
     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, char16_t aEscapeChar,              \
     193             :             nsAString &_escapedString),                                 \
     194             :            (aValue, aEscapeChar, _escapedString))
     195             : 
     196             : /**
     197             :  * Name-building helper for BIND_GEN_IMPL.
     198             :  */
     199             : #define BIND_NAME_CONCAT(_nameBit, _concatBit) \
     200             :   Bind##_nameBit##_concatBit
     201             : 
     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             :     WARN_DEPRECATED();                                                        \
     241             :     _guard                                                                    \
     242             :     mozIStorageBindingParams *params = getParams();                           \
     243             :     NS_ENSURE_TRUE(params, NS_ERROR_OUT_OF_MEMORY);                           \
     244             :     return params->BIND_NAME_CONCAT(_name, ByIndex) _invArgs;                 \
     245             :   }
     246             : 
     247             : /**
     248             :  * Implement BindByName/BindByIndex for the given class.
     249             :  *
     250             :  * @param _class The class name.
     251             :  * @param _optionalGuard The guard clause to inject.
     252             :  */
     253             : #define BIND_BASE_IMPLS(_class, _optionalGuard)             \
     254             :   NS_IMETHODIMP _class::BindByName(const nsACString &aName, \
     255             :                                    nsIVariant *aValue)      \
     256             :   {                                                         \
     257             :     _optionalGuard                                          \
     258             :     mozIStorageBindingParams *params = getParams();         \
     259             :     NS_ENSURE_TRUE(params, NS_ERROR_OUT_OF_MEMORY);         \
     260             :     return params->BindByName(aName, aValue);               \
     261             :   }                                                         \
     262             :   NS_IMETHODIMP _class::BindByIndex(uint32_t aIndex,        \
     263             :                                     nsIVariant *aValue)     \
     264             :   {                                                         \
     265             :     _optionalGuard                                          \
     266             :     mozIStorageBindingParams *params = getParams();         \
     267             :     NS_ENSURE_TRUE(params, NS_ERROR_OUT_OF_MEMORY);         \
     268             :     return params->BindByIndex(aIndex, aValue);             \
     269             :   }
     270             : 
     271             : /**
     272             :  * Define the various Bind*Parameter, Bind*ByIndex, Bind*ByName stubs that just
     273             :  * end up proxying to the params object.
     274             :  */
     275             : #define BOILERPLATE_BIND_PROXIES(_class, _optionalGuard) \
     276             :   BIND_BASE_IMPLS(_class, _optionalGuard)                \
     277             :   BIND_GEN_IMPL(_class, _optionalGuard,                  \
     278             :                 UTF8String,                              \
     279             :                 (const nsACString &aWhere,               \
     280             :                  const nsACString &aValue),              \
     281             :                 (uint32_t aWhere,                        \
     282             :                  const nsACString &aValue),              \
     283             :                 (aWhere, aValue))                        \
     284             :   BIND_GEN_IMPL(_class, _optionalGuard,                  \
     285             :                 String,                                  \
     286             :                 (const nsACString &aWhere,               \
     287             :                  const nsAString  &aValue),              \
     288             :                 (uint32_t aWhere,                        \
     289             :                  const nsAString  &aValue),              \
     290             :                 (aWhere, aValue))                        \
     291             :   BIND_GEN_IMPL(_class, _optionalGuard,                  \
     292             :                 Double,                                  \
     293             :                 (const nsACString &aWhere,               \
     294             :                  double aValue),                         \
     295             :                 (uint32_t aWhere,                        \
     296             :                  double aValue),                         \
     297             :                 (aWhere, aValue))                        \
     298             :   BIND_GEN_IMPL(_class, _optionalGuard,                  \
     299             :                 Int32,                                   \
     300             :                 (const nsACString &aWhere,               \
     301             :                  int32_t aValue),                        \
     302             :                 (uint32_t aWhere,                        \
     303             :                  int32_t aValue),                        \
     304             :                 (aWhere, aValue))                        \
     305             :   BIND_GEN_IMPL(_class, _optionalGuard,                  \
     306             :                 Int64,                                   \
     307             :                 (const nsACString &aWhere,               \
     308             :                  int64_t aValue),                        \
     309             :                 (uint32_t aWhere,                        \
     310             :                  int64_t aValue),                        \
     311             :                 (aWhere, aValue))                        \
     312             :   BIND_GEN_IMPL(_class, _optionalGuard,                  \
     313             :                 Null,                                    \
     314             :                 (const nsACString &aWhere),              \
     315             :                 (uint32_t aWhere),                       \
     316             :                 (aWhere))                                \
     317             :   BIND_GEN_IMPL(_class, _optionalGuard,                  \
     318             :                 Blob,                                    \
     319             :                 (const nsACString &aWhere,               \
     320             :                  const uint8_t *aValue,                  \
     321             :                  uint32_t aValueSize),                   \
     322             :                 (uint32_t aWhere,                        \
     323             :                  const uint8_t *aValue,                  \
     324             :                  uint32_t aValueSize),                   \
     325             :                 (aWhere, aValue, aValueSize))            \
     326             :   BIND_GEN_IMPL(_class, _optionalGuard,                  \
     327             :                 StringAsBlob,                            \
     328             :                 (const nsACString &aWhere,               \
     329             :                  const nsAString& aValue),               \
     330             :                 (uint32_t aWhere,                        \
     331             :                  const nsAString& aValue),               \
     332             :                 (aWhere, aValue))                        \
     333             :   BIND_GEN_IMPL(_class, _optionalGuard,                  \
     334             :                 UTF8StringAsBlob,                        \
     335             :                 (const nsACString &aWhere,               \
     336             :                  const nsACString& aValue),              \
     337             :                 (uint32_t aWhere,                        \
     338             :                  const nsACString& aValue),              \
     339             :                 (aWhere, aValue))                        \
     340             :   BIND_GEN_IMPL(_class, _optionalGuard,                  \
     341             :                 AdoptedBlob,                             \
     342             :                 (const nsACString &aWhere,               \
     343             :                  uint8_t *aValue,                        \
     344             :                  uint32_t aValueSize),                   \
     345             :                 (uint32_t aWhere,                        \
     346             :                  uint8_t *aValue,                        \
     347             :                  uint32_t aValueSize),                   \
     348             :                 (aWhere, aValue, aValueSize))
     349             : 
     350             : 
     351             : 
     352             : } // namespace storage
     353             : } // namespace mozilla
     354             : 
     355             : #endif // mozilla_storage_StorageBaseStatementInternal_h_

Generated by: LCOV version 1.13