Bug 1625482 [wpt PR 22496] - [ScrollTimeline] Do not show scrollbar to bypass flakine...
[gecko.git] / storage / mozStorageStatementJSHelper.cpp
blobf51659329461f9705ed57934933db08d48d19181
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
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 #include "nsIXPConnect.h"
8 #include "mozStorageStatement.h"
9 #include "mozStorageService.h"
11 #include "nsMemory.h"
12 #include "nsString.h"
13 #include "nsServiceManagerUtils.h"
15 #include "mozStorageStatementJSHelper.h"
17 #include "mozStorageStatementRow.h"
18 #include "mozStorageStatementParams.h"
20 #include "jsapi.h"
22 #include "xpc_make_class.h"
24 namespace mozilla {
25 namespace storage {
27 ////////////////////////////////////////////////////////////////////////////////
28 //// Global Functions
30 static bool stepFunc(JSContext* aCtx, uint32_t argc, JS::Value* _vp) {
31 JS::CallArgs args = CallArgsFromVp(argc, _vp);
33 nsCOMPtr<nsIXPConnect> xpc(nsIXPConnect::XPConnect());
34 nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
36 if (!args.thisv().isObject()) {
37 ::JS_ReportErrorASCII(aCtx, "mozIStorageStatement::step() requires object");
38 return false;
41 JS::RootedObject obj(aCtx, &args.thisv().toObject());
42 nsresult rv =
43 xpc->GetWrappedNativeOfJSObject(aCtx, obj, getter_AddRefs(wrapper));
44 if (NS_FAILED(rv)) {
45 ::JS_ReportErrorASCII(
46 aCtx, "mozIStorageStatement::step() could not obtain native statement");
47 return false;
50 #ifdef DEBUG
52 nsCOMPtr<mozIStorageStatement> isStatement(
53 do_QueryInterface(wrapper->Native()));
54 NS_ASSERTION(isStatement, "How is this not a statement?!");
56 #endif
58 Statement* stmt = static_cast<Statement*>(
59 static_cast<mozIStorageStatement*>(wrapper->Native()));
61 bool hasMore = false;
62 rv = stmt->ExecuteStep(&hasMore);
63 if (NS_SUCCEEDED(rv) && !hasMore) {
64 args.rval().setBoolean(false);
65 (void)stmt->Reset();
66 return true;
69 if (NS_FAILED(rv)) {
70 ::JS_ReportErrorASCII(aCtx,
71 "mozIStorageStatement::step() returned an error");
72 return false;
75 args.rval().setBoolean(hasMore);
76 return true;
79 ////////////////////////////////////////////////////////////////////////////////
80 //// StatementJSHelper
82 nsresult StatementJSHelper::getRow(Statement* aStatement, JSContext* aCtx,
83 JSObject* aScopeObj, JS::Value* _row) {
84 MOZ_ASSERT(NS_IsMainThread());
86 #ifdef DEBUG
87 int32_t state;
88 (void)aStatement->GetState(&state);
89 NS_ASSERTION(state == mozIStorageStatement::MOZ_STORAGE_STATEMENT_EXECUTING,
90 "Invalid state to get the row object - all calls will fail!");
91 #endif
93 JS::RootedObject scope(aCtx, aScopeObj);
95 if (!aStatement->mStatementRowHolder) {
96 dom::GlobalObject global(aCtx, scope);
97 if (global.Failed()) {
98 return NS_ERROR_UNEXPECTED;
101 nsCOMPtr<nsPIDOMWindowInner> window =
102 do_QueryInterface(global.GetAsSupports());
104 RefPtr<StatementRow> row(new StatementRow(window, aStatement));
105 NS_ENSURE_TRUE(row, NS_ERROR_OUT_OF_MEMORY);
107 RefPtr<StatementRowHolder> rowHolder = new StatementRowHolder(row);
108 NS_ENSURE_TRUE(rowHolder, NS_ERROR_OUT_OF_MEMORY);
110 aStatement->mStatementRowHolder =
111 new nsMainThreadPtrHolder<StatementRowHolder>(
112 "Statement::mStatementRowHolder", rowHolder);
115 RefPtr<StatementRow> row(aStatement->mStatementRowHolder->Get());
116 JSObject* obj = row->WrapObject(aCtx, nullptr);
117 if (!obj) {
118 return NS_ERROR_UNEXPECTED;
121 _row->setObject(*obj);
122 return NS_OK;
125 nsresult StatementJSHelper::getParams(Statement* aStatement, JSContext* aCtx,
126 JSObject* aScopeObj, JS::Value* _params) {
127 MOZ_ASSERT(NS_IsMainThread());
129 #ifdef DEBUG
130 int32_t state;
131 (void)aStatement->GetState(&state);
132 NS_ASSERTION(state == mozIStorageStatement::MOZ_STORAGE_STATEMENT_READY,
133 "Invalid state to get the params object - all calls will fail!");
134 #endif
136 JS::RootedObject scope(aCtx, aScopeObj);
138 if (!aStatement->mStatementParamsHolder) {
139 dom::GlobalObject global(aCtx, scope);
140 if (global.Failed()) {
141 return NS_ERROR_UNEXPECTED;
144 nsCOMPtr<nsPIDOMWindowInner> window =
145 do_QueryInterface(global.GetAsSupports());
147 RefPtr<StatementParams> params(new StatementParams(window, aStatement));
148 NS_ENSURE_TRUE(params, NS_ERROR_OUT_OF_MEMORY);
150 RefPtr<StatementParamsHolder> paramsHolder =
151 new StatementParamsHolder(params);
152 NS_ENSURE_TRUE(paramsHolder, NS_ERROR_OUT_OF_MEMORY);
154 aStatement->mStatementParamsHolder =
155 new nsMainThreadPtrHolder<StatementParamsHolder>(
156 "Statement::mStatementParamsHolder", paramsHolder);
159 RefPtr<StatementParams> params(aStatement->mStatementParamsHolder->Get());
160 JSObject* obj = params->WrapObject(aCtx, nullptr);
161 if (!obj) {
162 return NS_ERROR_UNEXPECTED;
165 _params->setObject(*obj);
166 return NS_OK;
169 NS_IMETHODIMP_(MozExternalRefCountType) StatementJSHelper::AddRef() {
170 return 2;
172 NS_IMETHODIMP_(MozExternalRefCountType) StatementJSHelper::Release() {
173 return 1;
175 NS_INTERFACE_MAP_BEGIN(StatementJSHelper)
176 NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
177 NS_INTERFACE_MAP_ENTRY(nsISupports)
178 NS_INTERFACE_MAP_END
180 ////////////////////////////////////////////////////////////////////////////////
181 //// nsIXPCScriptable
183 #define XPC_MAP_CLASSNAME StatementJSHelper
184 #define XPC_MAP_QUOTED_CLASSNAME "StatementJSHelper"
185 #define XPC_MAP_FLAGS \
186 (XPC_SCRIPTABLE_WANT_RESOLVE | XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE)
187 #include "xpc_map_end.h"
189 NS_IMETHODIMP
190 StatementJSHelper::Resolve(nsIXPConnectWrappedNative* aWrapper, JSContext* aCtx,
191 JSObject* aScopeObj, jsid aId, bool* aResolvedp,
192 bool* _retval) {
193 if (!JSID_IS_STRING(aId)) return NS_OK;
195 JS::Rooted<JSObject*> scope(aCtx, aScopeObj);
196 JS::Rooted<jsid> id(aCtx, aId);
198 #ifdef DEBUG
200 nsCOMPtr<mozIStorageStatement> isStatement(
201 do_QueryInterface(aWrapper->Native()));
202 NS_ASSERTION(isStatement, "How is this not a statement?!");
204 #endif
206 Statement* stmt = static_cast<Statement*>(
207 static_cast<mozIStorageStatement*>(aWrapper->Native()));
209 JSLinearString* str = JSID_TO_LINEAR_STRING(id);
210 if (::JS_LinearStringEqualsLiteral(str, "step")) {
211 *_retval = ::JS_DefineFunction(aCtx, scope, "step", stepFunc, 0,
212 JSPROP_RESOLVING) != nullptr;
213 *aResolvedp = true;
214 return NS_OK;
217 JS::RootedValue val(aCtx);
219 if (::JS_LinearStringEqualsLiteral(str, "row")) {
220 nsresult rv = getRow(stmt, aCtx, scope, val.address());
221 NS_ENSURE_SUCCESS(rv, rv);
222 *_retval = ::JS_DefinePropertyById(aCtx, scope, id, val, JSPROP_RESOLVING);
223 *aResolvedp = true;
224 return NS_OK;
227 if (::JS_LinearStringEqualsLiteral(str, "params")) {
228 nsresult rv = getParams(stmt, aCtx, scope, val.address());
229 NS_ENSURE_SUCCESS(rv, rv);
230 *_retval = ::JS_DefinePropertyById(aCtx, scope, id, val, JSPROP_RESOLVING);
231 *aResolvedp = true;
232 return NS_OK;
235 return NS_OK;
238 NS_IMPL_ISUPPORTS0(StatementParamsHolder);
240 StatementParamsHolder::~StatementParamsHolder() {
241 MOZ_ASSERT(NS_IsMainThread());
242 // We are considered dead at this point, so any wrappers for row or params
243 // need to lose their reference to the statement.
244 mParams->mStatement = nullptr;
247 NS_IMPL_ISUPPORTS0(StatementRowHolder);
249 StatementRowHolder::~StatementRowHolder() {
250 MOZ_ASSERT(NS_IsMainThread());
251 // We are considered dead at this point, so any wrappers for row or params
252 // need to lose their reference to the statement.
253 mRow->mStatement = nullptr;
256 } // namespace storage
257 } // namespace mozilla