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/. */
10 #include "mozStoragePrivateHelpers.h"
11 #include "mozStorageStatementParams.h"
12 #include "mozIStorageStatement.h"
17 ////////////////////////////////////////////////////////////////////////////////
20 StatementParams::StatementParams(mozIStorageStatement
*aStatement
) :
21 mStatement(aStatement
)
23 NS_ASSERTION(mStatement
!= nullptr, "mStatement is null");
24 (void)mStatement
->GetParameterCount(&mParamCount
);
29 mozIStorageStatementParams
,
33 ////////////////////////////////////////////////////////////////////////////////
36 #define XPC_MAP_CLASSNAME StatementParams
37 #define XPC_MAP_QUOTED_CLASSNAME "StatementParams"
38 #define XPC_MAP_WANT_SETPROPERTY
39 #define XPC_MAP_WANT_NEWENUMERATE
40 #define XPC_MAP_WANT_NEWRESOLVE
41 #define XPC_MAP_FLAGS nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE
42 #include "xpc_map_end.h"
45 StatementParams::SetProperty(nsIXPConnectWrappedNative
*aWrapper
,
52 NS_ENSURE_TRUE(mStatement
, NS_ERROR_NOT_INITIALIZED
);
54 if (JSID_IS_INT(aId
)) {
55 int idx
= JSID_TO_INT(aId
);
57 nsCOMPtr
<nsIVariant
> variant(convertJSValToVariant(aCtx
, *_vp
));
58 NS_ENSURE_TRUE(variant
, NS_ERROR_UNEXPECTED
);
59 nsresult rv
= mStatement
->BindByIndex(idx
, variant
);
60 NS_ENSURE_SUCCESS(rv
, rv
);
62 else if (JSID_IS_STRING(aId
)) {
63 JSString
*str
= JSID_TO_STRING(aId
);
65 const jschar
*chars
= JS_GetStringCharsAndLength(aCtx
, str
, &length
);
66 NS_ENSURE_TRUE(chars
, NS_ERROR_UNEXPECTED
);
67 NS_ConvertUTF16toUTF8
name(chars
, length
);
69 // check to see if there's a parameter with this name
70 nsCOMPtr
<nsIVariant
> variant(convertJSValToVariant(aCtx
, *_vp
));
71 NS_ENSURE_TRUE(variant
, NS_ERROR_UNEXPECTED
);
72 nsresult rv
= mStatement
->BindByName(name
, variant
);
73 NS_ENSURE_SUCCESS(rv
, rv
);
76 return NS_ERROR_INVALID_ARG
;
84 StatementParams::NewEnumerate(nsIXPConnectWrappedNative
*aWrapper
,
92 NS_ENSURE_TRUE(mStatement
, NS_ERROR_NOT_INITIALIZED
);
95 case JSENUMERATE_INIT
:
96 case JSENUMERATE_INIT_ALL
:
98 // Start our internal index at zero.
99 *_statep
= JSVAL_ZERO
;
101 // And set our length, if needed.
103 *_idp
= INT_TO_JSID(mParamCount
);
107 case JSENUMERATE_NEXT
:
109 NS_ASSERTION(*_statep
!= JSVAL_NULL
, "Internal state is null!");
111 // Make sure we are in range first.
112 uint32_t index
= static_cast<uint32_t>(JSVAL_TO_INT(*_statep
));
113 if (index
>= mParamCount
) {
114 *_statep
= JSVAL_NULL
;
118 // Get the name of our parameter.
120 nsresult rv
= mStatement
->GetParameterName(index
, name
);
121 NS_ENSURE_SUCCESS(rv
, rv
);
123 // But drop the first character, which is going to be a ':'.
124 JSString
*jsname
= ::JS_NewStringCopyN(aCtx
, &(name
.get()[1]),
126 NS_ENSURE_TRUE(jsname
, NS_ERROR_OUT_OF_MEMORY
);
129 if (!::JS_ValueToId(aCtx
, STRING_TO_JSVAL(jsname
), _idp
)) {
134 // And increment our index.
135 *_statep
= INT_TO_JSVAL(++index
);
139 case JSENUMERATE_DESTROY
:
142 *_statep
= JSVAL_NULL
;
152 StatementParams::NewResolve(nsIXPConnectWrappedNative
*aWrapper
,
160 NS_ENSURE_TRUE(mStatement
, NS_ERROR_NOT_INITIALIZED
);
161 // We do not throw at any point after this unless our index is out of range
162 // because we want to allow the prototype chain to be checked for the
165 JS::RootedObject
scope(aCtx
, aScopeObj
);
166 JS::RootedId
id(aCtx
, aId
);
167 bool resolved
= false;
169 if (JSID_IS_INT(id
)) {
170 uint32_t idx
= JSID_TO_INT(id
);
172 // Ensure that our index is within range. We do not care about the
173 // prototype chain being checked here.
174 if (idx
>= mParamCount
)
175 return NS_ERROR_INVALID_ARG
;
177 ok
= ::JS_DefineElement(aCtx
, scope
, idx
, JSVAL_VOID
, nullptr,
178 nullptr, JSPROP_ENUMERATE
);
181 else if (JSID_IS_STRING(id
)) {
182 JSString
*str
= JSID_TO_STRING(id
);
184 const jschar
*nameChars
= JS_GetStringCharsAndLength(aCtx
, str
, &nameLength
);
185 NS_ENSURE_TRUE(nameChars
, NS_ERROR_UNEXPECTED
);
187 // Check to see if there's a parameter with this name, and if not, let
188 // the rest of the prototype chain be checked.
189 NS_ConvertUTF16toUTF8
name(nameChars
, nameLength
);
191 nsresult rv
= mStatement
->GetParameterIndex(name
, &idx
);
192 if (NS_SUCCEEDED(rv
)) {
193 ok
= ::JS_DefinePropertyById(aCtx
, scope
, id
, JSVAL_VOID
, nullptr,
194 nullptr, JSPROP_ENUMERATE
);
200 *_objp
= resolved
&& ok
? scope
.get() : nullptr;
204 } // namespace storage
205 } // namespace mozilla