|
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 { |
|
23 // Get the number of results |
|
24 mNumCols = ::sqlite3_column_count(aStatement); |
|
25 |
|
26 // Start copying over values |
|
27 for (uint32_t i = 0; i < mNumCols; i++) { |
|
28 // Store the value |
|
29 nsIVariant *variant = nullptr; |
|
30 int type = ::sqlite3_column_type(aStatement, i); |
|
31 switch (type) { |
|
32 case SQLITE_INTEGER: |
|
33 variant = new IntegerVariant(::sqlite3_column_int64(aStatement, i)); |
|
34 break; |
|
35 case SQLITE_FLOAT: |
|
36 variant = new FloatVariant(::sqlite3_column_double(aStatement, i)); |
|
37 break; |
|
38 case SQLITE_TEXT: |
|
39 { |
|
40 nsDependentString str( |
|
41 static_cast<const char16_t *>(::sqlite3_column_text16(aStatement, i)) |
|
42 ); |
|
43 variant = new TextVariant(str); |
|
44 break; |
|
45 } |
|
46 case SQLITE_NULL: |
|
47 variant = new NullVariant(); |
|
48 break; |
|
49 case SQLITE_BLOB: |
|
50 { |
|
51 int size = ::sqlite3_column_bytes(aStatement, i); |
|
52 const void *data = ::sqlite3_column_blob(aStatement, i); |
|
53 variant = new BlobVariant(std::pair<const void *, int>(data, size)); |
|
54 break; |
|
55 } |
|
56 default: |
|
57 return NS_ERROR_UNEXPECTED; |
|
58 } |
|
59 NS_ENSURE_TRUE(variant, NS_ERROR_OUT_OF_MEMORY); |
|
60 |
|
61 // Insert into our storage array |
|
62 NS_ENSURE_TRUE(mData.InsertObjectAt(variant, i), NS_ERROR_OUT_OF_MEMORY); |
|
63 |
|
64 // Associate the name (if any) with the index |
|
65 const char *name = ::sqlite3_column_name(aStatement, i); |
|
66 if (!name) break; |
|
67 nsAutoCString colName(name); |
|
68 mNameHashtable.Put(colName, i); |
|
69 } |
|
70 |
|
71 return NS_OK; |
|
72 } |
|
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 { |
|
91 ENSURE_INDEX_VALUE(aIndex, mNumCols); |
|
92 NS_ADDREF(*_result = mData.ObjectAt(aIndex)); |
|
93 return NS_OK; |
|
94 } |
|
95 |
|
96 NS_IMETHODIMP |
|
97 Row::GetResultByName(const nsACString &aName, |
|
98 nsIVariant **_result) |
|
99 { |
|
100 uint32_t index; |
|
101 NS_ENSURE_TRUE(mNameHashtable.Get(aName, &index), NS_ERROR_NOT_AVAILABLE); |
|
102 return GetResultByIndex(index, _result); |
|
103 } |
|
104 |
|
105 //////////////////////////////////////////////////////////////////////////////// |
|
106 //// mozIStorageValueArray |
|
107 |
|
108 NS_IMETHODIMP |
|
109 Row::GetNumEntries(uint32_t *_entries) |
|
110 { |
|
111 *_entries = mNumCols; |
|
112 return NS_OK; |
|
113 } |
|
114 |
|
115 NS_IMETHODIMP |
|
116 Row::GetTypeOfIndex(uint32_t aIndex, |
|
117 int32_t *_type) |
|
118 { |
|
119 ENSURE_INDEX_VALUE(aIndex, mNumCols); |
|
120 |
|
121 uint16_t type; |
|
122 (void)mData.ObjectAt(aIndex)->GetDataType(&type); |
|
123 switch (type) { |
|
124 case nsIDataType::VTYPE_INT32: |
|
125 case nsIDataType::VTYPE_INT64: |
|
126 *_type = mozIStorageValueArray::VALUE_TYPE_INTEGER; |
|
127 break; |
|
128 case nsIDataType::VTYPE_DOUBLE: |
|
129 *_type = mozIStorageValueArray::VALUE_TYPE_FLOAT; |
|
130 break; |
|
131 case nsIDataType::VTYPE_ASTRING: |
|
132 *_type = mozIStorageValueArray::VALUE_TYPE_TEXT; |
|
133 break; |
|
134 case nsIDataType::VTYPE_ARRAY: |
|
135 *_type = mozIStorageValueArray::VALUE_TYPE_BLOB; |
|
136 break; |
|
137 default: |
|
138 *_type = mozIStorageValueArray::VALUE_TYPE_NULL; |
|
139 break; |
|
140 } |
|
141 return NS_OK; |
|
142 } |
|
143 |
|
144 NS_IMETHODIMP |
|
145 Row::GetInt32(uint32_t aIndex, |
|
146 int32_t *_value) |
|
147 { |
|
148 ENSURE_INDEX_VALUE(aIndex, mNumCols); |
|
149 return mData.ObjectAt(aIndex)->GetAsInt32(_value); |
|
150 } |
|
151 |
|
152 NS_IMETHODIMP |
|
153 Row::GetInt64(uint32_t aIndex, |
|
154 int64_t *_value) |
|
155 { |
|
156 ENSURE_INDEX_VALUE(aIndex, mNumCols); |
|
157 return mData.ObjectAt(aIndex)->GetAsInt64(_value); |
|
158 } |
|
159 |
|
160 NS_IMETHODIMP |
|
161 Row::GetDouble(uint32_t aIndex, |
|
162 double *_value) |
|
163 { |
|
164 ENSURE_INDEX_VALUE(aIndex, mNumCols); |
|
165 return mData.ObjectAt(aIndex)->GetAsDouble(_value); |
|
166 } |
|
167 |
|
168 NS_IMETHODIMP |
|
169 Row::GetUTF8String(uint32_t aIndex, |
|
170 nsACString &_value) |
|
171 { |
|
172 ENSURE_INDEX_VALUE(aIndex, mNumCols); |
|
173 return mData.ObjectAt(aIndex)->GetAsAUTF8String(_value); |
|
174 } |
|
175 |
|
176 NS_IMETHODIMP |
|
177 Row::GetString(uint32_t aIndex, |
|
178 nsAString &_value) |
|
179 { |
|
180 ENSURE_INDEX_VALUE(aIndex, mNumCols); |
|
181 return mData.ObjectAt(aIndex)->GetAsAString(_value); |
|
182 } |
|
183 |
|
184 NS_IMETHODIMP |
|
185 Row::GetBlob(uint32_t aIndex, |
|
186 uint32_t *_size, |
|
187 uint8_t **_blob) |
|
188 { |
|
189 ENSURE_INDEX_VALUE(aIndex, mNumCols); |
|
190 |
|
191 uint16_t type; |
|
192 nsIID interfaceIID; |
|
193 return mData.ObjectAt(aIndex)->GetAsArray(&type, &interfaceIID, _size, |
|
194 reinterpret_cast<void **>(_blob)); |
|
195 } |
|
196 |
|
197 NS_IMETHODIMP |
|
198 Row::GetIsNull(uint32_t aIndex, |
|
199 bool *_isNull) |
|
200 { |
|
201 ENSURE_INDEX_VALUE(aIndex, mNumCols); |
|
202 NS_ENSURE_ARG_POINTER(_isNull); |
|
203 |
|
204 uint16_t type; |
|
205 (void)mData.ObjectAt(aIndex)->GetDataType(&type); |
|
206 *_isNull = type == nsIDataType::VTYPE_EMPTY; |
|
207 return NS_OK; |
|
208 } |
|
209 |
|
210 NS_IMETHODIMP |
|
211 Row::GetSharedUTF8String(uint32_t, |
|
212 uint32_t *, |
|
213 char const **) |
|
214 { |
|
215 return NS_ERROR_NOT_IMPLEMENTED; |
|
216 } |
|
217 |
|
218 NS_IMETHODIMP |
|
219 Row::GetSharedString(uint32_t, |
|
220 uint32_t *, |
|
221 const char16_t **) |
|
222 { |
|
223 return NS_ERROR_NOT_IMPLEMENTED; |
|
224 } |
|
225 |
|
226 NS_IMETHODIMP |
|
227 Row::GetSharedBlob(uint32_t, |
|
228 uint32_t *, |
|
229 const uint8_t **) |
|
230 { |
|
231 return NS_ERROR_NOT_IMPLEMENTED; |
|
232 } |
|
233 |
|
234 } // namespace storage |
|
235 } // namespace mozilla |