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