Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/storage/StorageBaseStatementInternal.h
Line
Count
Source (jump to first uncovered line)
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
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
  Connection *getOwner()
52
0
  {
53
0
    return mDBConnection;
54
0
  }
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
0
  {                                                                       \
170
0
    _optionalGuard                                                        \
171
0
    return StorageBaseStatementInternal::_method _invokeArgs;             \
172
0
  }
Unexecuted instantiation: mozilla::storage::AsyncStatement::NewBindingParamsArray(mozIStorageBindingParamsArray**)
Unexecuted instantiation: mozilla::storage::AsyncStatement::ExecuteAsync(mozIStorageStatementCallback*, mozIStoragePendingStatement**)
Unexecuted instantiation: mozilla::storage::AsyncStatement::EscapeStringForLIKE(nsTSubstring<char16_t> const&, char16_t, nsTSubstring<char16_t>&)
Unexecuted instantiation: mozilla::storage::Statement::NewBindingParamsArray(mozIStorageBindingParamsArray**)
Unexecuted instantiation: mozilla::storage::Statement::ExecuteAsync(mozIStorageStatementCallback*, mozIStoragePendingStatement**)
Unexecuted instantiation: mozilla::storage::Statement::EscapeStringForLIKE(nsTSubstring<char16_t> const&, char16_t, nsTSubstring<char16_t>&)
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
0
  Bind##_nameBit##_concatBit
201
202
/**
203
 * We have type-specific convenience methods for C++ implementations in
204
 * two different forms; by index and 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 ByIndex 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
0
  {                                                                           \
226
0
    _guard                                                                    \
227
0
    mozIStorageBindingParams *params = getParams();                           \
228
0
    NS_ENSURE_TRUE(params, NS_ERROR_OUT_OF_MEMORY);                           \
229
0
    return params->BIND_NAME_CONCAT(_name, ByName) _invArgs;                  \
230
0
  }                                                                           \
Unexecuted instantiation: mozilla::storage::AsyncStatement::BindUTF8StringByName(nsTSubstring<char> const&, nsTSubstring<char> const&)
Unexecuted instantiation: mozilla::storage::AsyncStatement::BindStringByName(nsTSubstring<char> const&, nsTSubstring<char16_t> const&)
Unexecuted instantiation: mozilla::storage::AsyncStatement::BindDoubleByName(nsTSubstring<char> const&, double)
Unexecuted instantiation: mozilla::storage::AsyncStatement::BindInt32ByName(nsTSubstring<char> const&, int)
Unexecuted instantiation: mozilla::storage::AsyncStatement::BindInt64ByName(nsTSubstring<char> const&, long)
Unexecuted instantiation: mozilla::storage::AsyncStatement::BindNullByName(nsTSubstring<char> const&)
Unexecuted instantiation: mozilla::storage::AsyncStatement::BindBlobByName(nsTSubstring<char> const&, unsigned char const*, unsigned int)
Unexecuted instantiation: mozilla::storage::AsyncStatement::BindStringAsBlobByName(nsTSubstring<char> const&, nsTSubstring<char16_t> const&)
Unexecuted instantiation: mozilla::storage::AsyncStatement::BindUTF8StringAsBlobByName(nsTSubstring<char> const&, nsTSubstring<char> const&)
Unexecuted instantiation: mozilla::storage::AsyncStatement::BindAdoptedBlobByName(nsTSubstring<char> const&, unsigned char*, unsigned int)
Unexecuted instantiation: mozilla::storage::Statement::BindUTF8StringByName(nsTSubstring<char> const&, nsTSubstring<char> const&)
Unexecuted instantiation: mozilla::storage::Statement::BindStringByName(nsTSubstring<char> const&, nsTSubstring<char16_t> const&)
Unexecuted instantiation: mozilla::storage::Statement::BindDoubleByName(nsTSubstring<char> const&, double)
Unexecuted instantiation: mozilla::storage::Statement::BindInt32ByName(nsTSubstring<char> const&, int)
Unexecuted instantiation: mozilla::storage::Statement::BindInt64ByName(nsTSubstring<char> const&, long)
Unexecuted instantiation: mozilla::storage::Statement::BindNullByName(nsTSubstring<char> const&)
Unexecuted instantiation: mozilla::storage::Statement::BindBlobByName(nsTSubstring<char> const&, unsigned char const*, unsigned int)
Unexecuted instantiation: mozilla::storage::Statement::BindStringAsBlobByName(nsTSubstring<char> const&, nsTSubstring<char16_t> const&)
Unexecuted instantiation: mozilla::storage::Statement::BindUTF8StringAsBlobByName(nsTSubstring<char> const&, nsTSubstring<char> const&)
Unexecuted instantiation: mozilla::storage::Statement::BindAdoptedBlobByName(nsTSubstring<char> const&, unsigned char*, unsigned int)
231
  NS_IMETHODIMP _class::BIND_NAME_CONCAT(_name, ByIndex) _declIndex           \
232
0
  {                                                                           \
233
0
    _guard                                                                    \
234
0
    mozIStorageBindingParams *params = getParams();                           \
235
0
    NS_ENSURE_TRUE(params, NS_ERROR_OUT_OF_MEMORY);                           \
236
0
    return params->BIND_NAME_CONCAT(_name, ByIndex) _invArgs;                 \
237
0
  }
Unexecuted instantiation: mozilla::storage::AsyncStatement::BindUTF8StringByIndex(unsigned int, nsTSubstring<char> const&)
Unexecuted instantiation: mozilla::storage::AsyncStatement::BindStringByIndex(unsigned int, nsTSubstring<char16_t> const&)
Unexecuted instantiation: mozilla::storage::AsyncStatement::BindDoubleByIndex(unsigned int, double)
Unexecuted instantiation: mozilla::storage::AsyncStatement::BindInt32ByIndex(unsigned int, int)
Unexecuted instantiation: mozilla::storage::AsyncStatement::BindInt64ByIndex(unsigned int, long)
Unexecuted instantiation: mozilla::storage::AsyncStatement::BindNullByIndex(unsigned int)
Unexecuted instantiation: mozilla::storage::AsyncStatement::BindBlobByIndex(unsigned int, unsigned char const*, unsigned int)
Unexecuted instantiation: mozilla::storage::AsyncStatement::BindStringAsBlobByIndex(unsigned int, nsTSubstring<char16_t> const&)
Unexecuted instantiation: mozilla::storage::AsyncStatement::BindUTF8StringAsBlobByIndex(unsigned int, nsTSubstring<char> const&)
Unexecuted instantiation: mozilla::storage::AsyncStatement::BindAdoptedBlobByIndex(unsigned int, unsigned char*, unsigned int)
Unexecuted instantiation: mozilla::storage::Statement::BindUTF8StringByIndex(unsigned int, nsTSubstring<char> const&)
Unexecuted instantiation: mozilla::storage::Statement::BindStringByIndex(unsigned int, nsTSubstring<char16_t> const&)
Unexecuted instantiation: mozilla::storage::Statement::BindDoubleByIndex(unsigned int, double)
Unexecuted instantiation: mozilla::storage::Statement::BindInt32ByIndex(unsigned int, int)
Unexecuted instantiation: mozilla::storage::Statement::BindInt64ByIndex(unsigned int, long)
Unexecuted instantiation: mozilla::storage::Statement::BindNullByIndex(unsigned int)
Unexecuted instantiation: mozilla::storage::Statement::BindBlobByIndex(unsigned int, unsigned char const*, unsigned int)
Unexecuted instantiation: mozilla::storage::Statement::BindStringAsBlobByIndex(unsigned int, nsTSubstring<char16_t> const&)
Unexecuted instantiation: mozilla::storage::Statement::BindUTF8StringAsBlobByIndex(unsigned int, nsTSubstring<char> const&)
Unexecuted instantiation: mozilla::storage::Statement::BindAdoptedBlobByIndex(unsigned int, unsigned char*, unsigned int)
238
239
/**
240
 * Implement BindByName/BindByIndex for the given class.
241
 *
242
 * @param _class The class name.
243
 * @param _optionalGuard The guard clause to inject.
244
 */
245
#define BIND_BASE_IMPLS(_class, _optionalGuard)             \
246
  NS_IMETHODIMP _class::BindByName(const nsACString &aName, \
247
                                   nsIVariant *aValue)      \
248
0
  {                                                         \
249
0
    _optionalGuard                                          \
250
0
    mozIStorageBindingParams *params = getParams();         \
251
0
    NS_ENSURE_TRUE(params, NS_ERROR_OUT_OF_MEMORY);         \
252
0
    return params->BindByName(aName, aValue);               \
253
0
  }                                                         \
Unexecuted instantiation: mozilla::storage::AsyncStatement::BindByName(nsTSubstring<char> const&, nsIVariant*)
Unexecuted instantiation: mozilla::storage::Statement::BindByName(nsTSubstring<char> const&, nsIVariant*)
254
  NS_IMETHODIMP _class::BindByIndex(uint32_t aIndex,        \
255
                                    nsIVariant *aValue)     \
256
0
  {                                                         \
257
0
    _optionalGuard                                          \
258
0
    mozIStorageBindingParams *params = getParams();         \
259
0
    NS_ENSURE_TRUE(params, NS_ERROR_OUT_OF_MEMORY);         \
260
0
    return params->BindByIndex(aIndex, aValue);             \
261
0
  }
Unexecuted instantiation: mozilla::storage::AsyncStatement::BindByIndex(unsigned int, nsIVariant*)
Unexecuted instantiation: mozilla::storage::Statement::BindByIndex(unsigned int, nsIVariant*)
262
263
/**
264
 * Define the various Bind*ByIndex, Bind*ByName stubs that just end up proxying
265
 * to the params object.
266
 */
267
#define BOILERPLATE_BIND_PROXIES(_class, _optionalGuard) \
268
  BIND_BASE_IMPLS(_class, _optionalGuard)                \
269
  BIND_GEN_IMPL(_class, _optionalGuard,                  \
270
                UTF8String,                              \
271
                (const nsACString &aWhere,               \
272
                 const nsACString &aValue),              \
273
                (uint32_t aWhere,                        \
274
                 const nsACString &aValue),              \
275
                (aWhere, aValue))                        \
276
  BIND_GEN_IMPL(_class, _optionalGuard,                  \
277
                String,                                  \
278
                (const nsACString &aWhere,               \
279
                 const nsAString  &aValue),              \
280
                (uint32_t aWhere,                        \
281
                 const nsAString  &aValue),              \
282
                (aWhere, aValue))                        \
283
  BIND_GEN_IMPL(_class, _optionalGuard,                  \
284
                Double,                                  \
285
                (const nsACString &aWhere,               \
286
                 double aValue),                         \
287
                (uint32_t aWhere,                        \
288
                 double aValue),                         \
289
                (aWhere, aValue))                        \
290
  BIND_GEN_IMPL(_class, _optionalGuard,                  \
291
                Int32,                                   \
292
                (const nsACString &aWhere,               \
293
                 int32_t aValue),                        \
294
                (uint32_t aWhere,                        \
295
                 int32_t aValue),                        \
296
                (aWhere, aValue))                        \
297
  BIND_GEN_IMPL(_class, _optionalGuard,                  \
298
                Int64,                                   \
299
                (const nsACString &aWhere,               \
300
                 int64_t aValue),                        \
301
                (uint32_t aWhere,                        \
302
                 int64_t aValue),                        \
303
                (aWhere, aValue))                        \
304
  BIND_GEN_IMPL(_class, _optionalGuard,                  \
305
                Null,                                    \
306
                (const nsACString &aWhere),              \
307
                (uint32_t aWhere),                       \
308
                (aWhere))                                \
309
  BIND_GEN_IMPL(_class, _optionalGuard,                  \
310
                Blob,                                    \
311
                (const nsACString &aWhere,               \
312
                 const uint8_t *aValue,                  \
313
                 uint32_t aValueSize),                   \
314
                (uint32_t aWhere,                        \
315
                 const uint8_t *aValue,                  \
316
                 uint32_t aValueSize),                   \
317
                (aWhere, aValue, aValueSize))            \
318
  BIND_GEN_IMPL(_class, _optionalGuard,                  \
319
                StringAsBlob,                            \
320
                (const nsACString &aWhere,               \
321
                 const nsAString& aValue),               \
322
                (uint32_t aWhere,                        \
323
                 const nsAString& aValue),               \
324
                (aWhere, aValue))                        \
325
  BIND_GEN_IMPL(_class, _optionalGuard,                  \
326
                UTF8StringAsBlob,                        \
327
                (const nsACString &aWhere,               \
328
                 const nsACString& aValue),              \
329
                (uint32_t aWhere,                        \
330
                 const nsACString& aValue),              \
331
                (aWhere, aValue))                        \
332
  BIND_GEN_IMPL(_class, _optionalGuard,                  \
333
                AdoptedBlob,                             \
334
                (const nsACString &aWhere,               \
335
                 uint8_t *aValue,                        \
336
                 uint32_t aValueSize),                   \
337
                (uint32_t aWhere,                        \
338
                 uint8_t *aValue,                        \
339
                 uint32_t aValueSize),                   \
340
                (aWhere, aValue, aValueSize))
341
342
343
344
} // namespace storage
345
} // namespace mozilla
346
347
#endif // mozilla_storage_StorageBaseStatementInternal_h_