Line data Source code
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/. */
6 :
7 : #include "nsIXPConnect.h"
8 : #include "mozStorageAsyncStatement.h"
9 : #include "mozStorageService.h"
10 :
11 : #include "nsMemory.h"
12 : #include "nsString.h"
13 : #include "nsServiceManagerUtils.h"
14 :
15 : #include "mozStorageAsyncStatementJSHelper.h"
16 :
17 : #include "mozStorageAsyncStatementParams.h"
18 :
19 : #include "jsapi.h"
20 :
21 : #include "xpc_make_class.h"
22 :
23 : namespace mozilla {
24 : namespace storage {
25 :
26 : ////////////////////////////////////////////////////////////////////////////////
27 : //// AsyncStatementJSHelper
28 :
29 : nsresult
30 6 : AsyncStatementJSHelper::getParams(AsyncStatement *aStatement,
31 : JSContext *aCtx,
32 : JSObject *aScopeObj,
33 : JS::Value *_params)
34 : {
35 6 : MOZ_ASSERT(NS_IsMainThread());
36 : nsresult rv;
37 :
38 : #ifdef DEBUG
39 : int32_t state;
40 6 : (void)aStatement->GetState(&state);
41 6 : NS_ASSERTION(state == mozIStorageAsyncStatement::MOZ_STORAGE_STATEMENT_READY,
42 : "Invalid state to get the params object - all calls will fail!");
43 : #endif
44 :
45 6 : if (!aStatement->mStatementParamsHolder) {
46 : nsCOMPtr<mozIStorageStatementParams> params =
47 4 : new AsyncStatementParams(aStatement);
48 2 : NS_ENSURE_TRUE(params, NS_ERROR_OUT_OF_MEMORY);
49 :
50 4 : JS::RootedObject scope(aCtx, aScopeObj);
51 4 : nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
52 4 : nsCOMPtr<nsIXPConnect> xpc(Service::getXPConnect());
53 6 : rv = xpc->WrapNativeHolder(
54 : aCtx,
55 2 : ::JS_GetGlobalForObject(aCtx, scope),
56 : params,
57 : NS_GET_IID(mozIStorageStatementParams),
58 4 : getter_AddRefs(holder)
59 6 : );
60 2 : NS_ENSURE_SUCCESS(rv, rv);
61 : RefPtr<AsyncStatementParamsHolder> paramsHolder =
62 6 : new AsyncStatementParamsHolder(holder);
63 : aStatement->mStatementParamsHolder =
64 : new nsMainThreadPtrHolder<nsIXPConnectJSObjectHolder>(
65 4 : "AsyncStatement::mStatementParamsHolder", paramsHolder);
66 : }
67 :
68 12 : JS::Rooted<JSObject*> obj(aCtx);
69 6 : obj = aStatement->mStatementParamsHolder->GetJSObject();
70 6 : NS_ENSURE_STATE(obj);
71 :
72 6 : _params->setObject(*obj);
73 6 : return NS_OK;
74 : }
75 :
76 232 : NS_IMETHODIMP_(MozExternalRefCountType) AsyncStatementJSHelper::AddRef() { return 2; }
77 229 : NS_IMETHODIMP_(MozExternalRefCountType) AsyncStatementJSHelper::Release() { return 1; }
78 129 : NS_INTERFACE_MAP_BEGIN(AsyncStatementJSHelper)
79 129 : NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
80 6 : NS_INTERFACE_MAP_ENTRY(nsISupports)
81 6 : NS_INTERFACE_MAP_END
82 :
83 : ////////////////////////////////////////////////////////////////////////////////
84 : //// nsIXPCScriptable
85 :
86 : #define XPC_MAP_CLASSNAME AsyncStatementJSHelper
87 : #define XPC_MAP_QUOTED_CLASSNAME "AsyncStatementJSHelper"
88 : #define XPC_MAP_FLAGS (XPC_SCRIPTABLE_WANT_GETPROPERTY | \
89 : XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE)
90 : #include "xpc_map_end.h"
91 :
92 : NS_IMETHODIMP
93 6 : AsyncStatementJSHelper::GetProperty(nsIXPConnectWrappedNative *aWrapper,
94 : JSContext *aCtx,
95 : JSObject *aScopeObj,
96 : jsid aId,
97 : JS::Value *_result,
98 : bool *_retval)
99 : {
100 6 : if (!JSID_IS_STRING(aId))
101 0 : return NS_OK;
102 :
103 : // Cast to async via mozI* since direct from nsISupports is ambiguous.
104 12 : JS::RootedObject scope(aCtx, aScopeObj);
105 12 : JS::RootedId id(aCtx, aId);
106 : mozIStorageAsyncStatement *iAsyncStmt =
107 6 : static_cast<mozIStorageAsyncStatement *>(aWrapper->Native());
108 6 : AsyncStatement *stmt = static_cast<AsyncStatement *>(iAsyncStmt);
109 :
110 : #ifdef DEBUG
111 : {
112 6 : nsISupports *supp = aWrapper->Native();
113 12 : nsCOMPtr<mozIStorageAsyncStatement> isStatement(do_QueryInterface(supp));
114 6 : NS_ASSERTION(isStatement, "How is this not an async statement?!");
115 : }
116 : #endif
117 :
118 6 : if (::JS_FlatStringEqualsAscii(JSID_TO_FLAT_STRING(id), "params"))
119 6 : return getParams(stmt, aCtx, scope, _result);
120 :
121 0 : return NS_OK;
122 : }
123 :
124 : ////////////////////////////////////////////////////////////////////////////////
125 : //// AsyncStatementParamsHolder
126 :
127 6 : NS_IMPL_ISUPPORTS(AsyncStatementParamsHolder, nsIXPConnectJSObjectHolder);
128 :
129 : JSObject*
130 6 : AsyncStatementParamsHolder::GetJSObject()
131 : {
132 6 : return mHolder->GetJSObject();
133 : }
134 :
135 2 : AsyncStatementParamsHolder::AsyncStatementParamsHolder(nsIXPConnectJSObjectHolder* aHolder)
136 2 : : mHolder(aHolder)
137 : {
138 2 : MOZ_ASSERT(NS_IsMainThread());
139 2 : MOZ_ASSERT(mHolder);
140 2 : }
141 :
142 0 : AsyncStatementParamsHolder::~AsyncStatementParamsHolder()
143 : {
144 0 : MOZ_ASSERT(NS_IsMainThread());
145 : // We are considered dead at this point, so any wrappers for row or params
146 : // need to lose their reference to the statement.
147 0 : nsCOMPtr<nsIXPConnectWrappedNative> wrapper = do_QueryInterface(mHolder);
148 0 : nsCOMPtr<mozIStorageStatementParams> iObj = do_QueryWrappedNative(wrapper);
149 0 : AsyncStatementParams *obj = static_cast<AsyncStatementParams *>(iObj.get());
150 0 : obj->mStatement = nullptr;
151 0 : }
152 :
153 : } // namespace storage
154 : } // namespace mozilla
|