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"
25 ////////////////////////////////////////////////////////////////////////////////
30 stepFunc(JSContext
*aCtx
,
34 nsCOMPtr
<nsIXPConnect
> xpc(Service::getXPConnect());
35 nsCOMPtr
<nsIXPConnectWrappedNative
> wrapper
;
36 JSObject
*obj
= JS_THIS_OBJECT(aCtx
, _vp
);
42 xpc
->GetWrappedNativeOfJSObject(aCtx
, obj
, getter_AddRefs(wrapper
));
44 ::JS_ReportError(aCtx
, "mozIStorageStatement::step() could not obtain native statement");
50 nsCOMPtr
<mozIStorageStatement
> isStatement(
51 do_QueryInterface(wrapper
->Native())
53 NS_ASSERTION(isStatement
, "How is this not a statement?!");
57 Statement
*stmt
= static_cast<Statement
*>(
58 static_cast<mozIStorageStatement
*>(wrapper
->Native())
62 rv
= stmt
->ExecuteStep(&hasMore
);
63 if (NS_SUCCEEDED(rv
) && !hasMore
) {
70 ::JS_ReportError(aCtx
, "mozIStorageStatement::step() returned an error");
74 *_vp
= BOOLEAN_TO_JSVAL(hasMore
);
78 ////////////////////////////////////////////////////////////////////////////////
79 //// StatementJSHelper
82 StatementJSHelper::getRow(Statement
*aStatement
,
87 MOZ_ASSERT(NS_IsMainThread());
92 (void)aStatement
->GetState(&state
);
93 NS_ASSERTION(state
== mozIStorageStatement::MOZ_STORAGE_STATEMENT_EXECUTING
,
94 "Invalid state to get the row object - all calls will fail!");
97 if (!aStatement
->mStatementRowHolder
) {
98 JS::RootedObject
scope(aCtx
, aScopeObj
);
99 nsCOMPtr
<mozIStorageStatementRow
> row(new StatementRow(aStatement
));
100 NS_ENSURE_TRUE(row
, NS_ERROR_OUT_OF_MEMORY
);
102 nsCOMPtr
<nsIXPConnectJSObjectHolder
> holder
;
103 nsCOMPtr
<nsIXPConnect
> xpc(Service::getXPConnect());
104 rv
= xpc
->WrapNative(
106 ::JS_GetGlobalForObject(aCtx
, scope
),
108 NS_GET_IID(mozIStorageStatementRow
),
109 getter_AddRefs(holder
)
111 NS_ENSURE_SUCCESS(rv
, rv
);
112 nsRefPtr
<StatementRowHolder
> rowHolder
= new StatementRowHolder(holder
);
113 aStatement
->mStatementRowHolder
=
114 new nsMainThreadPtrHolder
<nsIXPConnectJSObjectHolder
>(rowHolder
);
117 JS::Rooted
<JSObject
*> obj(aCtx
);
118 obj
= aStatement
->mStatementRowHolder
->GetJSObject();
119 NS_ENSURE_STATE(obj
);
121 *_row
= OBJECT_TO_JSVAL(obj
);
126 StatementJSHelper::getParams(Statement
*aStatement
,
131 MOZ_ASSERT(NS_IsMainThread());
136 (void)aStatement
->GetState(&state
);
137 NS_ASSERTION(state
== mozIStorageStatement::MOZ_STORAGE_STATEMENT_READY
,
138 "Invalid state to get the params object - all calls will fail!");
141 if (!aStatement
->mStatementParamsHolder
) {
142 JS::RootedObject
scope(aCtx
, aScopeObj
);
143 nsCOMPtr
<mozIStorageStatementParams
> params
=
144 new StatementParams(aStatement
);
145 NS_ENSURE_TRUE(params
, NS_ERROR_OUT_OF_MEMORY
);
147 nsCOMPtr
<nsIXPConnectJSObjectHolder
> holder
;
148 nsCOMPtr
<nsIXPConnect
> xpc(Service::getXPConnect());
149 rv
= xpc
->WrapNative(
151 ::JS_GetGlobalForObject(aCtx
, scope
),
153 NS_GET_IID(mozIStorageStatementParams
),
154 getter_AddRefs(holder
)
156 NS_ENSURE_SUCCESS(rv
, rv
);
157 nsRefPtr
<StatementParamsHolder
> paramsHolder
=
158 new StatementParamsHolder(holder
);
159 aStatement
->mStatementParamsHolder
=
160 new nsMainThreadPtrHolder
<nsIXPConnectJSObjectHolder
>(paramsHolder
);
163 JS::Rooted
<JSObject
*> obj(aCtx
);
164 obj
= aStatement
->mStatementParamsHolder
->GetJSObject();
165 NS_ENSURE_STATE(obj
);
167 *_params
= OBJECT_TO_JSVAL(obj
);
171 NS_IMETHODIMP_(MozExternalRefCountType
) StatementJSHelper::AddRef() { return 2; }
172 NS_IMETHODIMP_(MozExternalRefCountType
) StatementJSHelper::Release() { return 1; }
173 NS_INTERFACE_MAP_BEGIN(StatementJSHelper
)
174 NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable
)
175 NS_INTERFACE_MAP_ENTRY(nsISupports
)
178 ////////////////////////////////////////////////////////////////////////////////
179 //// nsIXPCScriptable
181 #define XPC_MAP_CLASSNAME StatementJSHelper
182 #define XPC_MAP_QUOTED_CLASSNAME "StatementJSHelper"
183 #define XPC_MAP_WANT_GETPROPERTY
184 #define XPC_MAP_WANT_RESOLVE
185 #define XPC_MAP_FLAGS nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE
186 #include "xpc_map_end.h"
189 StatementJSHelper::GetProperty(nsIXPConnectWrappedNative
*aWrapper
,
196 if (!JSID_IS_STRING(aId
))
199 JS::Rooted
<JSObject
*> scope(aCtx
, aScopeObj
);
200 JS::Rooted
<jsid
> id(aCtx
, aId
);
204 nsCOMPtr
<mozIStorageStatement
> isStatement(
205 do_QueryInterface(aWrapper
->Native()));
206 NS_ASSERTION(isStatement
, "How is this not a statement?!");
210 Statement
*stmt
= static_cast<Statement
*>(
211 static_cast<mozIStorageStatement
*>(aWrapper
->Native())
214 JSFlatString
*str
= JSID_TO_FLAT_STRING(id
);
215 if (::JS_FlatStringEqualsAscii(str
, "row"))
216 return getRow(stmt
, aCtx
, scope
, _result
);
218 if (::JS_FlatStringEqualsAscii(str
, "params"))
219 return getParams(stmt
, aCtx
, scope
, _result
);
226 StatementJSHelper::Resolve(nsIXPConnectWrappedNative
*aWrapper
,
227 JSContext
*aCtx
, JSObject
*aScopeObj
,
228 jsid aId
, bool *aResolvedp
,
231 if (!JSID_IS_STRING(aId
))
234 JS::RootedObject
scope(aCtx
, aScopeObj
);
235 if (::JS_FlatStringEqualsAscii(JSID_TO_FLAT_STRING(aId
), "step")) {
236 *_retval
= ::JS_DefineFunction(aCtx
, scope
, "step", stepFunc
,
244 ////////////////////////////////////////////////////////////////////////////////
245 //// StatementJSObjectHolder
247 NS_IMPL_ISUPPORTS(StatementJSObjectHolder
, nsIXPConnectJSObjectHolder
);
250 StatementJSObjectHolder::GetJSObject()
252 return mHolder
->GetJSObject();
255 StatementJSObjectHolder::StatementJSObjectHolder(nsIXPConnectJSObjectHolder
* aHolder
)
258 MOZ_ASSERT(NS_IsMainThread());
262 StatementParamsHolder::~StatementParamsHolder()
264 MOZ_ASSERT(NS_IsMainThread());
265 // We are considered dead at this point, so any wrappers for row or params
266 // need to lose their reference to the statement.
267 nsCOMPtr
<nsIXPConnectWrappedNative
> wrapper
= do_QueryInterface(mHolder
);
268 nsCOMPtr
<mozIStorageStatementParams
> iObj
= do_QueryWrappedNative(wrapper
);
269 StatementParams
*obj
= static_cast<StatementParams
*>(iObj
.get());
270 obj
->mStatement
= nullptr;
273 StatementRowHolder::~StatementRowHolder()
275 MOZ_ASSERT(NS_IsMainThread());
276 // We are considered dead at this point, so any wrappers for row or params
277 // need to lose their reference to the statement.
278 nsCOMPtr
<nsIXPConnectWrappedNative
> wrapper
= do_QueryInterface(mHolder
);
279 nsCOMPtr
<mozIStorageStatementRow
> iObj
= do_QueryWrappedNative(wrapper
);
280 StatementRow
*obj
= static_cast<StatementRow
*>(iObj
.get());
281 obj
->mStatement
= nullptr;
284 } // namespace storage
285 } // namespace mozilla