1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/storage/src/mozStorageStatementJSHelper.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,236 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ : 1.6 + * This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#include "nsIXPConnect.h" 1.11 +#include "mozStorageStatement.h" 1.12 +#include "mozStorageService.h" 1.13 + 1.14 +#include "nsMemory.h" 1.15 +#include "nsString.h" 1.16 +#include "nsServiceManagerUtils.h" 1.17 + 1.18 +#include "mozStorageStatementJSHelper.h" 1.19 + 1.20 +#include "mozStorageStatementRow.h" 1.21 +#include "mozStorageStatementParams.h" 1.22 + 1.23 +#include "jsapi.h" 1.24 + 1.25 +namespace mozilla { 1.26 +namespace storage { 1.27 + 1.28 +//////////////////////////////////////////////////////////////////////////////// 1.29 +//// Global Functions 1.30 + 1.31 +static 1.32 +bool 1.33 +stepFunc(JSContext *aCtx, 1.34 + uint32_t, 1.35 + jsval *_vp) 1.36 +{ 1.37 + nsCOMPtr<nsIXPConnect> xpc(Service::getXPConnect()); 1.38 + nsCOMPtr<nsIXPConnectWrappedNative> wrapper; 1.39 + JSObject *obj = JS_THIS_OBJECT(aCtx, _vp); 1.40 + if (!obj) { 1.41 + return false; 1.42 + } 1.43 + 1.44 + nsresult rv = 1.45 + xpc->GetWrappedNativeOfJSObject(aCtx, obj, getter_AddRefs(wrapper)); 1.46 + if (NS_FAILED(rv)) { 1.47 + ::JS_ReportError(aCtx, "mozIStorageStatement::step() could not obtain native statement"); 1.48 + return false; 1.49 + } 1.50 + 1.51 +#ifdef DEBUG 1.52 + { 1.53 + nsCOMPtr<mozIStorageStatement> isStatement( 1.54 + do_QueryInterface(wrapper->Native()) 1.55 + ); 1.56 + NS_ASSERTION(isStatement, "How is this not a statement?!"); 1.57 + } 1.58 +#endif 1.59 + 1.60 + Statement *stmt = static_cast<Statement *>( 1.61 + static_cast<mozIStorageStatement *>(wrapper->Native()) 1.62 + ); 1.63 + 1.64 + bool hasMore = false; 1.65 + rv = stmt->ExecuteStep(&hasMore); 1.66 + if (NS_SUCCEEDED(rv) && !hasMore) { 1.67 + *_vp = JSVAL_FALSE; 1.68 + (void)stmt->Reset(); 1.69 + return true; 1.70 + } 1.71 + 1.72 + if (NS_FAILED(rv)) { 1.73 + ::JS_ReportError(aCtx, "mozIStorageStatement::step() returned an error"); 1.74 + return false; 1.75 + } 1.76 + 1.77 + *_vp = BOOLEAN_TO_JSVAL(hasMore); 1.78 + return true; 1.79 +} 1.80 + 1.81 +//////////////////////////////////////////////////////////////////////////////// 1.82 +//// StatementJSHelper 1.83 + 1.84 +nsresult 1.85 +StatementJSHelper::getRow(Statement *aStatement, 1.86 + JSContext *aCtx, 1.87 + JSObject *aScopeObj, 1.88 + jsval *_row) 1.89 +{ 1.90 + nsresult rv; 1.91 + 1.92 +#ifdef DEBUG 1.93 + int32_t state; 1.94 + (void)aStatement->GetState(&state); 1.95 + NS_ASSERTION(state == mozIStorageStatement::MOZ_STORAGE_STATEMENT_EXECUTING, 1.96 + "Invalid state to get the row object - all calls will fail!"); 1.97 +#endif 1.98 + 1.99 + if (!aStatement->mStatementRowHolder) { 1.100 + JS::RootedObject scope(aCtx, aScopeObj); 1.101 + nsCOMPtr<mozIStorageStatementRow> row(new StatementRow(aStatement)); 1.102 + NS_ENSURE_TRUE(row, NS_ERROR_OUT_OF_MEMORY); 1.103 + 1.104 + nsCOMPtr<nsIXPConnect> xpc(Service::getXPConnect()); 1.105 + rv = xpc->WrapNative( 1.106 + aCtx, 1.107 + ::JS_GetGlobalForObject(aCtx, scope), 1.108 + row, 1.109 + NS_GET_IID(mozIStorageStatementRow), 1.110 + getter_AddRefs(aStatement->mStatementRowHolder) 1.111 + ); 1.112 + NS_ENSURE_SUCCESS(rv, rv); 1.113 + } 1.114 + 1.115 + JS::Rooted<JSObject*> obj(aCtx); 1.116 + obj = aStatement->mStatementRowHolder->GetJSObject(); 1.117 + NS_ENSURE_STATE(obj); 1.118 + 1.119 + *_row = OBJECT_TO_JSVAL(obj); 1.120 + return NS_OK; 1.121 +} 1.122 + 1.123 +nsresult 1.124 +StatementJSHelper::getParams(Statement *aStatement, 1.125 + JSContext *aCtx, 1.126 + JSObject *aScopeObj, 1.127 + jsval *_params) 1.128 +{ 1.129 + nsresult rv; 1.130 + 1.131 +#ifdef DEBUG 1.132 + int32_t state; 1.133 + (void)aStatement->GetState(&state); 1.134 + NS_ASSERTION(state == mozIStorageStatement::MOZ_STORAGE_STATEMENT_READY, 1.135 + "Invalid state to get the params object - all calls will fail!"); 1.136 +#endif 1.137 + 1.138 + if (!aStatement->mStatementParamsHolder) { 1.139 + JS::RootedObject scope(aCtx, aScopeObj); 1.140 + nsCOMPtr<mozIStorageStatementParams> params = 1.141 + new StatementParams(aStatement); 1.142 + NS_ENSURE_TRUE(params, NS_ERROR_OUT_OF_MEMORY); 1.143 + 1.144 + nsCOMPtr<nsIXPConnect> xpc(Service::getXPConnect()); 1.145 + rv = xpc->WrapNative( 1.146 + aCtx, 1.147 + ::JS_GetGlobalForObject(aCtx, scope), 1.148 + params, 1.149 + NS_GET_IID(mozIStorageStatementParams), 1.150 + getter_AddRefs(aStatement->mStatementParamsHolder) 1.151 + ); 1.152 + NS_ENSURE_SUCCESS(rv, rv); 1.153 + } 1.154 + 1.155 + JS::Rooted<JSObject*> obj(aCtx); 1.156 + obj = aStatement->mStatementParamsHolder->GetJSObject(); 1.157 + NS_ENSURE_STATE(obj); 1.158 + 1.159 + *_params = OBJECT_TO_JSVAL(obj); 1.160 + return NS_OK; 1.161 +} 1.162 + 1.163 +NS_IMETHODIMP_(MozExternalRefCountType) StatementJSHelper::AddRef() { return 2; } 1.164 +NS_IMETHODIMP_(MozExternalRefCountType) StatementJSHelper::Release() { return 1; } 1.165 +NS_INTERFACE_MAP_BEGIN(StatementJSHelper) 1.166 + NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable) 1.167 + NS_INTERFACE_MAP_ENTRY(nsISupports) 1.168 +NS_INTERFACE_MAP_END 1.169 + 1.170 +//////////////////////////////////////////////////////////////////////////////// 1.171 +//// nsIXPCScriptable 1.172 + 1.173 +#define XPC_MAP_CLASSNAME StatementJSHelper 1.174 +#define XPC_MAP_QUOTED_CLASSNAME "StatementJSHelper" 1.175 +#define XPC_MAP_WANT_GETPROPERTY 1.176 +#define XPC_MAP_WANT_NEWRESOLVE 1.177 +#define XPC_MAP_FLAGS nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE 1.178 +#include "xpc_map_end.h" 1.179 + 1.180 +NS_IMETHODIMP 1.181 +StatementJSHelper::GetProperty(nsIXPConnectWrappedNative *aWrapper, 1.182 + JSContext *aCtx, 1.183 + JSObject *aScopeObj, 1.184 + jsid aId, 1.185 + jsval *_result, 1.186 + bool *_retval) 1.187 +{ 1.188 + if (!JSID_IS_STRING(aId)) 1.189 + return NS_OK; 1.190 + 1.191 + JS::Rooted<JSObject*> scope(aCtx, aScopeObj); 1.192 + JS::Rooted<jsid> id(aCtx, aId); 1.193 + 1.194 +#ifdef DEBUG 1.195 + { 1.196 + nsCOMPtr<mozIStorageStatement> isStatement( 1.197 + do_QueryInterface(aWrapper->Native())); 1.198 + NS_ASSERTION(isStatement, "How is this not a statement?!"); 1.199 + } 1.200 +#endif 1.201 + 1.202 + Statement *stmt = static_cast<Statement *>( 1.203 + static_cast<mozIStorageStatement *>(aWrapper->Native()) 1.204 + ); 1.205 + 1.206 + JSFlatString *str = JSID_TO_FLAT_STRING(id); 1.207 + if (::JS_FlatStringEqualsAscii(str, "row")) 1.208 + return getRow(stmt, aCtx, scope, _result); 1.209 + 1.210 + if (::JS_FlatStringEqualsAscii(str, "params")) 1.211 + return getParams(stmt, aCtx, scope, _result); 1.212 + 1.213 + return NS_OK; 1.214 +} 1.215 + 1.216 + 1.217 +NS_IMETHODIMP 1.218 +StatementJSHelper::NewResolve(nsIXPConnectWrappedNative *aWrapper, 1.219 + JSContext *aCtx, 1.220 + JSObject *aScopeObj, 1.221 + jsid aId, 1.222 + JSObject **_objp, 1.223 + bool *_retval) 1.224 +{ 1.225 + if (!JSID_IS_STRING(aId)) 1.226 + return NS_OK; 1.227 + 1.228 + JS::RootedObject scope(aCtx, aScopeObj); 1.229 + if (::JS_FlatStringEqualsAscii(JSID_TO_FLAT_STRING(aId), "step")) { 1.230 + *_retval = ::JS_DefineFunction(aCtx, scope, "step", stepFunc, 1.231 + 0, 0) != nullptr; 1.232 + *_objp = scope.get(); 1.233 + return NS_OK; 1.234 + } 1.235 + return NS_OK; 1.236 +} 1.237 + 1.238 +} // namespace storage 1.239 +} // namespace mozilla