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 et
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 mozStorageStatementData_h
8 : #define mozStorageStatementData_h
9 :
10 : #include "sqlite3.h"
11 :
12 : #include "nsAutoPtr.h"
13 : #include "nsTArray.h"
14 : #include "nsIEventTarget.h"
15 : #include "MainThreadUtils.h"
16 :
17 : #include "mozStorageBindingParamsArray.h"
18 : #include "mozIStorageBaseStatement.h"
19 : #include "mozStorageConnection.h"
20 : #include "StorageBaseStatementInternal.h"
21 :
22 : struct sqlite3_stmt;
23 :
24 : namespace mozilla {
25 : namespace storage {
26 :
27 11 : class StatementData
28 : {
29 : public:
30 11 : StatementData(sqlite3_stmt *aStatement,
31 : already_AddRefed<BindingParamsArray> aParamsArray,
32 : StorageBaseStatementInternal *aStatementOwner)
33 11 : : mStatement(aStatement)
34 : , mParamsArray(aParamsArray)
35 11 : , mStatementOwner(aStatementOwner)
36 : {
37 11 : NS_PRECONDITION(mStatementOwner, "Must have a statement owner!");
38 11 : }
39 11 : StatementData(const StatementData &aSource)
40 11 : : mStatement(aSource.mStatement)
41 : , mParamsArray(aSource.mParamsArray)
42 11 : , mStatementOwner(aSource.mStatementOwner)
43 : {
44 11 : NS_PRECONDITION(mStatementOwner, "Must have a statement owner!");
45 11 : }
46 11 : StatementData()
47 11 : : mStatement(nullptr)
48 : {
49 11 : }
50 33 : ~StatementData()
51 33 : {
52 : // We need to ensure that mParamsArray is released on the main thread,
53 : // as the binding arguments may be XPConnect values, which are safe
54 : // to release only on the main thread.
55 33 : NS_ReleaseOnMainThread("StatementData::mParamsArray", mParamsArray.forget());
56 33 : }
57 :
58 : /**
59 : * Return the sqlite statement, fetching it from the storage statement. In
60 : * the case of AsyncStatements this may actually create the statement
61 : */
62 28 : inline int getSqliteStatement(sqlite3_stmt **_stmt)
63 : {
64 28 : if (!mStatement) {
65 11 : int rc = mStatementOwner->getAsyncStatement(&mStatement);
66 11 : NS_ENSURE_TRUE(rc == SQLITE_OK, rc);
67 : }
68 28 : *_stmt = mStatement;
69 28 : return SQLITE_OK;
70 : }
71 :
72 6 : operator BindingParamsArray *() const { return mParamsArray; }
73 :
74 : /**
75 : * NULLs out our sqlite3_stmt (it is held by the owner) after reseting it and
76 : * clear all bindings to it. This is expected to occur on the async thread.
77 : */
78 11 : inline void reset()
79 : {
80 11 : NS_PRECONDITION(mStatementOwner, "Must have a statement owner!");
81 : // In the AsyncStatement case we may never have populated mStatement if the
82 : // AsyncExecuteStatements got canceled or a failure occurred in constructing
83 : // the statement.
84 11 : if (mStatement) {
85 11 : (void)::sqlite3_reset(mStatement);
86 11 : (void)::sqlite3_clear_bindings(mStatement);
87 11 : mStatement = nullptr;
88 : }
89 11 : }
90 :
91 : /**
92 : * Indicates if this statement has parameters to be bound before it is
93 : * executed.
94 : *
95 : * @return true if the statement has parameters to bind against, false
96 : * otherwise.
97 : */
98 11 : inline bool hasParametersToBeBound() const { return !!mParamsArray; }
99 : /**
100 : * Indicates the number of implicit statements generated by this statement
101 : * requiring a transaction for execution. For example a single statement
102 : * with N BindingParams will execute N implicit staments.
103 : *
104 : * @return number of statements requiring a transaction for execution.
105 : *
106 : * @note In the case of AsyncStatements this may actually create the
107 : * statement.
108 : */
109 11 : inline uint32_t needsTransaction()
110 : {
111 11 : MOZ_ASSERT(!NS_IsMainThread());
112 : // Be sure to use the getSqliteStatement helper, since sqlite3_stmt_readonly
113 : // can only analyze prepared statements and AsyncStatements are prepared
114 : // lazily.
115 : sqlite3_stmt *stmt;
116 11 : int rc = getSqliteStatement(&stmt);
117 11 : if (SQLITE_OK != rc || ::sqlite3_stmt_readonly(stmt)) {
118 9 : return 0;
119 : }
120 2 : return mParamsArray ? mParamsArray->length() : 1;
121 : }
122 :
123 : private:
124 : sqlite3_stmt *mStatement;
125 : RefPtr<BindingParamsArray> mParamsArray;
126 :
127 : /**
128 : * We hold onto a reference of the statement's owner so it doesn't get
129 : * destroyed out from under us.
130 : */
131 : nsCOMPtr<StorageBaseStatementInternal> mStatementOwner;
132 : };
133 :
134 : } // namespace storage
135 : } // namespace mozilla
136 :
137 : #endif // mozStorageStatementData_h
|