Bumping gaia.json for 2 gaia revision(s) a=gaia-bump
[gecko.git] / storage / src / mozStorageStatementJSHelper.cpp
blob9d5c8b2c305ace300bd82c421bdf1dae99ad721b
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 namespace mozilla {
23 namespace storage {
25 ////////////////////////////////////////////////////////////////////////////////
26 //// Global Functions
28 static
29 bool
30 stepFunc(JSContext *aCtx,
31 uint32_t,
32 jsval *_vp)
34 nsCOMPtr<nsIXPConnect> xpc(Service::getXPConnect());
35 nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
36 JSObject *obj = JS_THIS_OBJECT(aCtx, _vp);
37 if (!obj) {
38 return false;
41 nsresult rv =
42 xpc->GetWrappedNativeOfJSObject(aCtx, obj, getter_AddRefs(wrapper));
43 if (NS_FAILED(rv)) {
44 ::JS_ReportError(aCtx, "mozIStorageStatement::step() could not obtain native statement");
45 return false;
48 #ifdef DEBUG
50 nsCOMPtr<mozIStorageStatement> isStatement(
51 do_QueryInterface(wrapper->Native())
53 NS_ASSERTION(isStatement, "How is this not a statement?!");
55 #endif
57 Statement *stmt = static_cast<Statement *>(
58 static_cast<mozIStorageStatement *>(wrapper->Native())
61 bool hasMore = false;
62 rv = stmt->ExecuteStep(&hasMore);
63 if (NS_SUCCEEDED(rv) && !hasMore) {
64 *_vp = JSVAL_FALSE;
65 (void)stmt->Reset();
66 return true;
69 if (NS_FAILED(rv)) {
70 ::JS_ReportError(aCtx, "mozIStorageStatement::step() returned an error");
71 return false;
74 *_vp = BOOLEAN_TO_JSVAL(hasMore);
75 return true;
78 ////////////////////////////////////////////////////////////////////////////////
79 //// StatementJSHelper
81 nsresult
82 StatementJSHelper::getRow(Statement *aStatement,
83 JSContext *aCtx,
84 JSObject *aScopeObj,
85 jsval *_row)
87 MOZ_ASSERT(NS_IsMainThread());
88 nsresult rv;
90 #ifdef DEBUG
91 int32_t state;
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!");
95 #endif
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(
105 aCtx,
106 ::JS_GetGlobalForObject(aCtx, scope),
107 row,
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);
122 return NS_OK;
125 nsresult
126 StatementJSHelper::getParams(Statement *aStatement,
127 JSContext *aCtx,
128 JSObject *aScopeObj,
129 jsval *_params)
131 MOZ_ASSERT(NS_IsMainThread());
132 nsresult rv;
134 #ifdef DEBUG
135 int32_t state;
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!");
139 #endif
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(
150 aCtx,
151 ::JS_GetGlobalForObject(aCtx, scope),
152 params,
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);
168 return NS_OK;
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)
176 NS_INTERFACE_MAP_END
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"
188 NS_IMETHODIMP
189 StatementJSHelper::GetProperty(nsIXPConnectWrappedNative *aWrapper,
190 JSContext *aCtx,
191 JSObject *aScopeObj,
192 jsid aId,
193 jsval *_result,
194 bool *_retval)
196 if (!JSID_IS_STRING(aId))
197 return NS_OK;
199 JS::Rooted<JSObject*> scope(aCtx, aScopeObj);
200 JS::Rooted<jsid> id(aCtx, aId);
202 #ifdef DEBUG
204 nsCOMPtr<mozIStorageStatement> isStatement(
205 do_QueryInterface(aWrapper->Native()));
206 NS_ASSERTION(isStatement, "How is this not a statement?!");
208 #endif
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);
221 return NS_OK;
225 NS_IMETHODIMP
226 StatementJSHelper::Resolve(nsIXPConnectWrappedNative *aWrapper,
227 JSContext *aCtx, JSObject *aScopeObj,
228 jsid aId, bool *aResolvedp,
229 bool *_retval)
231 if (!JSID_IS_STRING(aId))
232 return NS_OK;
234 JS::RootedObject scope(aCtx, aScopeObj);
235 if (::JS_FlatStringEqualsAscii(JSID_TO_FLAT_STRING(aId), "step")) {
236 *_retval = ::JS_DefineFunction(aCtx, scope, "step", stepFunc,
237 0, 0) != nullptr;
238 *aResolvedp = true;
239 return NS_OK;
241 return NS_OK;
244 ////////////////////////////////////////////////////////////////////////////////
245 //// StatementJSObjectHolder
247 NS_IMPL_ISUPPORTS(StatementJSObjectHolder, nsIXPConnectJSObjectHolder);
249 JSObject*
250 StatementJSObjectHolder::GetJSObject()
252 return mHolder->GetJSObject();
255 StatementJSObjectHolder::StatementJSObjectHolder(nsIXPConnectJSObjectHolder* aHolder)
256 : mHolder(aHolder)
258 MOZ_ASSERT(NS_IsMainThread());
259 MOZ_ASSERT(mHolder);
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