/src/mozilla-central/storage/mozStorageRow.cpp
Line | Count | Source (jump to first uncovered line) |
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 "sqlite3.h" |
10 | | #include "mozStoragePrivateHelpers.h" |
11 | | #include "Variant.h" |
12 | | #include "mozStorageRow.h" |
13 | | |
14 | | namespace mozilla { |
15 | | namespace storage { |
16 | | |
17 | | //////////////////////////////////////////////////////////////////////////////// |
18 | | //// Row |
19 | | |
20 | | nsresult |
21 | | Row::initialize(sqlite3_stmt *aStatement) |
22 | 0 | { |
23 | 0 | // Get the number of results |
24 | 0 | mNumCols = ::sqlite3_column_count(aStatement); |
25 | 0 |
|
26 | 0 | // Start copying over values |
27 | 0 | for (uint32_t i = 0; i < mNumCols; i++) { |
28 | 0 | // Store the value |
29 | 0 | nsIVariant *variant = nullptr; |
30 | 0 | int type = ::sqlite3_column_type(aStatement, i); |
31 | 0 | switch (type) { |
32 | 0 | case SQLITE_INTEGER: |
33 | 0 | variant = new IntegerVariant(::sqlite3_column_int64(aStatement, i)); |
34 | 0 | break; |
35 | 0 | case SQLITE_FLOAT: |
36 | 0 | variant = new FloatVariant(::sqlite3_column_double(aStatement, i)); |
37 | 0 | break; |
38 | 0 | case SQLITE_TEXT: |
39 | 0 | { |
40 | 0 | nsDependentString str( |
41 | 0 | static_cast<const char16_t *>(::sqlite3_column_text16(aStatement, i)) |
42 | 0 | ); |
43 | 0 | variant = new TextVariant(str); |
44 | 0 | break; |
45 | 0 | } |
46 | 0 | case SQLITE_NULL: |
47 | 0 | variant = new NullVariant(); |
48 | 0 | break; |
49 | 0 | case SQLITE_BLOB: |
50 | 0 | { |
51 | 0 | int size = ::sqlite3_column_bytes(aStatement, i); |
52 | 0 | const void *data = ::sqlite3_column_blob(aStatement, i); |
53 | 0 | variant = new BlobVariant(std::pair<const void *, int>(data, size)); |
54 | 0 | break; |
55 | 0 | } |
56 | 0 | default: |
57 | 0 | return NS_ERROR_UNEXPECTED; |
58 | 0 | } |
59 | 0 | NS_ENSURE_TRUE(variant, NS_ERROR_OUT_OF_MEMORY); |
60 | 0 |
|
61 | 0 | // Insert into our storage array |
62 | 0 | NS_ENSURE_TRUE(mData.InsertObjectAt(variant, i), NS_ERROR_OUT_OF_MEMORY); |
63 | 0 |
|
64 | 0 | // Associate the name (if any) with the index |
65 | 0 | const char *name = ::sqlite3_column_name(aStatement, i); |
66 | 0 | if (!name) break; |
67 | 0 | nsAutoCString colName(name); |
68 | 0 | mNameHashtable.Put(colName, i); |
69 | 0 | } |
70 | 0 |
|
71 | 0 | return NS_OK; |
72 | 0 | } |
73 | | |
74 | | /** |
75 | | * Note: This object is only ever accessed on one thread at a time. It it not |
76 | | * threadsafe, but it does need threadsafe AddRef and Release. |
77 | | */ |
78 | | NS_IMPL_ISUPPORTS( |
79 | | Row, |
80 | | mozIStorageRow, |
81 | | mozIStorageValueArray |
82 | | ) |
83 | | |
84 | | //////////////////////////////////////////////////////////////////////////////// |
85 | | //// mozIStorageRow |
86 | | |
87 | | NS_IMETHODIMP |
88 | | Row::GetResultByIndex(uint32_t aIndex, |
89 | | nsIVariant **_result) |
90 | 0 | { |
91 | 0 | ENSURE_INDEX_VALUE(aIndex, mNumCols); |
92 | 0 | NS_ADDREF(*_result = mData.ObjectAt(aIndex)); |
93 | 0 | return NS_OK; |
94 | 0 | } |
95 | | |
96 | | NS_IMETHODIMP |
97 | | Row::GetResultByName(const nsACString &aName, |
98 | | nsIVariant **_result) |
99 | 0 | { |
100 | 0 | uint32_t index; |
101 | 0 | NS_ENSURE_TRUE(mNameHashtable.Get(aName, &index), NS_ERROR_NOT_AVAILABLE); |
102 | 0 | return GetResultByIndex(index, _result); |
103 | 0 | } |
104 | | |
105 | | //////////////////////////////////////////////////////////////////////////////// |
106 | | //// mozIStorageValueArray |
107 | | |
108 | | NS_IMETHODIMP |
109 | | Row::GetNumEntries(uint32_t *_entries) |
110 | 0 | { |
111 | 0 | *_entries = mNumCols; |
112 | 0 | return NS_OK; |
113 | 0 | } |
114 | | |
115 | | NS_IMETHODIMP |
116 | | Row::GetTypeOfIndex(uint32_t aIndex, |
117 | | int32_t *_type) |
118 | 0 | { |
119 | 0 | ENSURE_INDEX_VALUE(aIndex, mNumCols); |
120 | 0 |
|
121 | 0 | uint16_t type; |
122 | 0 | (void)mData.ObjectAt(aIndex)->GetDataType(&type); |
123 | 0 | switch (type) { |
124 | 0 | case nsIDataType::VTYPE_INT32: |
125 | 0 | case nsIDataType::VTYPE_INT64: |
126 | 0 | *_type = mozIStorageValueArray::VALUE_TYPE_INTEGER; |
127 | 0 | break; |
128 | 0 | case nsIDataType::VTYPE_DOUBLE: |
129 | 0 | *_type = mozIStorageValueArray::VALUE_TYPE_FLOAT; |
130 | 0 | break; |
131 | 0 | case nsIDataType::VTYPE_ASTRING: |
132 | 0 | *_type = mozIStorageValueArray::VALUE_TYPE_TEXT; |
133 | 0 | break; |
134 | 0 | case nsIDataType::VTYPE_ARRAY: |
135 | 0 | *_type = mozIStorageValueArray::VALUE_TYPE_BLOB; |
136 | 0 | break; |
137 | 0 | default: |
138 | 0 | *_type = mozIStorageValueArray::VALUE_TYPE_NULL; |
139 | 0 | break; |
140 | 0 | } |
141 | 0 | return NS_OK; |
142 | 0 | } |
143 | | |
144 | | NS_IMETHODIMP |
145 | | Row::GetInt32(uint32_t aIndex, |
146 | | int32_t *_value) |
147 | 0 | { |
148 | 0 | ENSURE_INDEX_VALUE(aIndex, mNumCols); |
149 | 0 | return mData.ObjectAt(aIndex)->GetAsInt32(_value); |
150 | 0 | } |
151 | | |
152 | | NS_IMETHODIMP |
153 | | Row::GetInt64(uint32_t aIndex, |
154 | | int64_t *_value) |
155 | 0 | { |
156 | 0 | ENSURE_INDEX_VALUE(aIndex, mNumCols); |
157 | 0 | return mData.ObjectAt(aIndex)->GetAsInt64(_value); |
158 | 0 | } |
159 | | |
160 | | NS_IMETHODIMP |
161 | | Row::GetDouble(uint32_t aIndex, |
162 | | double *_value) |
163 | 0 | { |
164 | 0 | ENSURE_INDEX_VALUE(aIndex, mNumCols); |
165 | 0 | return mData.ObjectAt(aIndex)->GetAsDouble(_value); |
166 | 0 | } |
167 | | |
168 | | NS_IMETHODIMP |
169 | | Row::GetUTF8String(uint32_t aIndex, |
170 | | nsACString &_value) |
171 | 0 | { |
172 | 0 | ENSURE_INDEX_VALUE(aIndex, mNumCols); |
173 | 0 | return mData.ObjectAt(aIndex)->GetAsAUTF8String(_value); |
174 | 0 | } |
175 | | |
176 | | NS_IMETHODIMP |
177 | | Row::GetString(uint32_t aIndex, |
178 | | nsAString &_value) |
179 | 0 | { |
180 | 0 | ENSURE_INDEX_VALUE(aIndex, mNumCols); |
181 | 0 | return mData.ObjectAt(aIndex)->GetAsAString(_value); |
182 | 0 | } |
183 | | |
184 | | NS_IMETHODIMP |
185 | | Row::GetBlob(uint32_t aIndex, |
186 | | uint32_t *_size, |
187 | | uint8_t **_blob) |
188 | 0 | { |
189 | 0 | ENSURE_INDEX_VALUE(aIndex, mNumCols); |
190 | 0 |
|
191 | 0 | uint16_t type; |
192 | 0 | nsIID interfaceIID; |
193 | 0 | return mData.ObjectAt(aIndex)->GetAsArray(&type, &interfaceIID, _size, |
194 | 0 | reinterpret_cast<void **>(_blob)); |
195 | 0 | } |
196 | | |
197 | | NS_IMETHODIMP |
198 | | Row::GetBlobAsString(uint32_t aIndex, nsAString& aValue) |
199 | 0 | { |
200 | 0 | return DoGetBlobAsString(this, aIndex, aValue); |
201 | 0 | } |
202 | | |
203 | | NS_IMETHODIMP |
204 | | Row::GetBlobAsUTF8String(uint32_t aIndex, nsACString& aValue) |
205 | 0 | { |
206 | 0 | return DoGetBlobAsString(this, aIndex, aValue); |
207 | 0 | } |
208 | | |
209 | | NS_IMETHODIMP |
210 | | Row::GetIsNull(uint32_t aIndex, |
211 | | bool *_isNull) |
212 | 0 | { |
213 | 0 | ENSURE_INDEX_VALUE(aIndex, mNumCols); |
214 | 0 | NS_ENSURE_ARG_POINTER(_isNull); |
215 | 0 |
|
216 | 0 | uint16_t type; |
217 | 0 | (void)mData.ObjectAt(aIndex)->GetDataType(&type); |
218 | 0 | *_isNull = type == nsIDataType::VTYPE_EMPTY; |
219 | 0 | return NS_OK; |
220 | 0 | } |
221 | | |
222 | | NS_IMETHODIMP |
223 | | Row::GetSharedUTF8String(uint32_t, |
224 | | uint32_t *, |
225 | | char const **) |
226 | 0 | { |
227 | 0 | return NS_ERROR_NOT_IMPLEMENTED; |
228 | 0 | } |
229 | | |
230 | | NS_IMETHODIMP |
231 | | Row::GetSharedString(uint32_t, |
232 | | uint32_t *, |
233 | | const char16_t **) |
234 | 0 | { |
235 | 0 | return NS_ERROR_NOT_IMPLEMENTED; |
236 | 0 | } |
237 | | |
238 | | NS_IMETHODIMP |
239 | | Row::GetSharedBlob(uint32_t, |
240 | | uint32_t *, |
241 | | const uint8_t **) |
242 | 0 | { |
243 | 0 | return NS_ERROR_NOT_IMPLEMENTED; |
244 | 0 | } |
245 | | |
246 | | } // namespace storage |
247 | | } // namespace mozilla |