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"
13 #include "nsServiceManagerUtils.h"
15 #include "mozStorageStatementJSHelper.h"
17 #include "mozStorageStatementRow.h"
18 #include "mozStorageStatementParams.h"
22 #include "xpc_make_class.h"
27 ////////////////////////////////////////////////////////////////////////////////
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");
41 JS::RootedObject
obj(aCtx
, &args
.thisv().toObject());
43 xpc
->GetWrappedNativeOfJSObject(aCtx
, obj
, getter_AddRefs(wrapper
));
45 ::JS_ReportErrorASCII(
46 aCtx
, "mozIStorageStatement::step() could not obtain native statement");
52 nsCOMPtr
<mozIStorageStatement
> isStatement(
53 do_QueryInterface(wrapper
->Native()));
54 NS_ASSERTION(isStatement
, "How is this not a statement?!");
58 Statement
* stmt
= static_cast<Statement
*>(
59 static_cast<mozIStorageStatement
*>(wrapper
->Native()));
62 rv
= stmt
->ExecuteStep(&hasMore
);
63 if (NS_SUCCEEDED(rv
) && !hasMore
) {
64 args
.rval().setBoolean(false);
70 ::JS_ReportErrorASCII(aCtx
,
71 "mozIStorageStatement::step() returned an error");
75 args
.rval().setBoolean(hasMore
);
79 ////////////////////////////////////////////////////////////////////////////////
80 //// StatementJSHelper
82 nsresult
StatementJSHelper::getRow(Statement
* aStatement
, JSContext
* aCtx
,
83 JSObject
* aScopeObj
, JS::Value
* _row
) {
84 MOZ_ASSERT(NS_IsMainThread());
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!");
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);
118 return NS_ERROR_UNEXPECTED
;
121 _row
->setObject(*obj
);
125 nsresult
StatementJSHelper::getParams(Statement
* aStatement
, JSContext
* aCtx
,
126 JSObject
* aScopeObj
, JS::Value
* _params
) {
127 MOZ_ASSERT(NS_IsMainThread());
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!");
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);
162 return NS_ERROR_UNEXPECTED
;
165 _params
->setObject(*obj
);
169 NS_IMETHODIMP_(MozExternalRefCountType
) StatementJSHelper::AddRef() {
172 NS_IMETHODIMP_(MozExternalRefCountType
) StatementJSHelper::Release() {
175 NS_INTERFACE_MAP_BEGIN(StatementJSHelper
)
176 NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable
)
177 NS_INTERFACE_MAP_ENTRY(nsISupports
)
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"
190 StatementJSHelper::Resolve(nsIXPConnectWrappedNative
* aWrapper
, JSContext
* aCtx
,
191 JSObject
* aScopeObj
, jsid aId
, bool* aResolvedp
,
193 if (!JSID_IS_STRING(aId
)) return NS_OK
;
195 JS::Rooted
<JSObject
*> scope(aCtx
, aScopeObj
);
196 JS::Rooted
<jsid
> id(aCtx
, aId
);
200 nsCOMPtr
<mozIStorageStatement
> isStatement(
201 do_QueryInterface(aWrapper
->Native()));
202 NS_ASSERTION(isStatement
, "How is this not a statement?!");
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;
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
);
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
);
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