mozStorageStatementRow.cpp (4493B)
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 "nsString.h" 8 9 #include "mozilla/ErrorResult.h" 10 #include "mozilla/dom/MozStorageStatementRowBinding.h" 11 #include "mozStorageStatementRow.h" 12 #include "mozStorageStatement.h" 13 14 #include "jsapi.h" 15 #include "js/Array.h" // JS::NewArrayObject 16 #include "js/PropertyAndElement.h" // JS_DefineElement 17 #include "js/Value.h" 18 19 #include "xpc_make_class.h" 20 21 namespace mozilla { 22 namespace storage { 23 24 //////////////////////////////////////////////////////////////////////////////// 25 //// StatementRow 26 27 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(StatementRow, mWindow) 28 29 NS_INTERFACE_TABLE_HEAD(StatementRow) 30 NS_WRAPPERCACHE_INTERFACE_TABLE_ENTRY 31 NS_INTERFACE_TABLE(StatementRow, nsISupports) 32 NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(StatementRow) 33 NS_INTERFACE_MAP_END 34 35 NS_IMPL_CYCLE_COLLECTING_ADDREF(StatementRow) 36 NS_IMPL_CYCLE_COLLECTING_RELEASE(StatementRow) 37 38 StatementRow::StatementRow(nsPIDOMWindowInner* aWindow, Statement* aStatement) 39 : mWindow(aWindow), mStatement(aStatement) {} 40 41 JSObject* StatementRow::WrapObject(JSContext* aCx, 42 JS::Handle<JSObject*> aGivenProto) { 43 return dom::MozStorageStatementRow_Binding::Wrap(aCx, this, aGivenProto); 44 } 45 46 void StatementRow::NamedGetter(JSContext* aCx, const nsAString& aName, 47 bool& aFound, 48 JS::MutableHandle<JS::Value> aResult, 49 mozilla::ErrorResult& aRv) { 50 if (!mStatement) { 51 aRv.Throw(NS_ERROR_NOT_INITIALIZED); 52 return; 53 } 54 55 nsCString name = NS_ConvertUTF16toUTF8(aName); 56 57 uint32_t idx; 58 { 59 nsresult rv = mStatement->GetColumnIndex(name, &idx); 60 if (NS_FAILED(rv)) { 61 // It's highly likely that the name doesn't exist, so let the JS engine 62 // check the prototype chain and throw if that doesn't have the property 63 // either. 64 aFound = false; 65 return; 66 } 67 } 68 69 int32_t type; 70 aRv = mStatement->GetTypeOfIndex(idx, &type); 71 if (aRv.Failed()) { 72 return; 73 } 74 75 switch (type) { 76 case mozIStorageValueArray::VALUE_TYPE_INTEGER: 77 case mozIStorageValueArray::VALUE_TYPE_FLOAT: { 78 double dval; 79 aRv = mStatement->GetDouble(idx, &dval); 80 if (aRv.Failed()) { 81 return; 82 } 83 aResult.set(::JS_NumberValue(dval)); 84 break; 85 } 86 case mozIStorageValueArray::VALUE_TYPE_TEXT: { 87 uint32_t bytes; 88 const char16_t* sval = reinterpret_cast<const char16_t*>( 89 static_cast<mozIStorageStatement*>(mStatement) 90 ->AsSharedWString(idx, &bytes)); 91 JSString* str = 92 ::JS_NewUCStringCopyN(aCx, sval, bytes / sizeof(char16_t)); 93 if (!str) { 94 aRv.Throw(NS_ERROR_UNEXPECTED); 95 return; 96 } 97 aResult.setString(str); 98 break; 99 } 100 case mozIStorageValueArray::VALUE_TYPE_BLOB: { 101 uint32_t length; 102 const uint8_t* blob = static_cast<mozIStorageStatement*>(mStatement) 103 ->AsSharedBlob(idx, &length); 104 JS::Rooted<JSObject*> obj(aCx, JS::NewArrayObject(aCx, length)); 105 if (!obj) { 106 aRv.Throw(NS_ERROR_UNEXPECTED); 107 return; 108 } 109 aResult.setObject(*obj); 110 111 // Copy the blob over to the JS array. 112 for (uint32_t i = 0; i < length; i++) { 113 if (!::JS_DefineElement(aCx, obj, i, blob[i], JSPROP_ENUMERATE)) { 114 aRv.Throw(NS_ERROR_UNEXPECTED); 115 return; 116 } 117 } 118 break; 119 } 120 case mozIStorageValueArray::VALUE_TYPE_NULL: 121 aResult.setNull(); 122 break; 123 default: 124 NS_ERROR("unknown column type returned, what's going on?"); 125 break; 126 } 127 aFound = true; 128 } 129 130 void StatementRow::GetSupportedNames(nsTArray<nsString>& aNames) { 131 if (!mStatement) { 132 return; 133 } 134 135 uint32_t columnCount; 136 nsresult rv = mStatement->GetColumnCount(&columnCount); 137 if (NS_WARN_IF(NS_FAILED(rv))) { 138 return; 139 } 140 141 for (uint32_t i = 0; i < columnCount; i++) { 142 nsAutoCString name; 143 nsresult rv = mStatement->GetColumnName(i, name); 144 if (NS_WARN_IF(NS_FAILED(rv))) { 145 return; 146 } 147 aNames.AppendElement(NS_ConvertUTF8toUTF16(name)); 148 } 149 } 150 151 } // namespace storage 152 } // namespace mozilla