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 : * ***** BEGIN LICENSE BLOCK *****
4 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 : *
6 : * The contents of this file are subject to the Mozilla Public License Version
7 : * 1.1 (the "License"); you may not use this file except in compliance with
8 : * the License. You may obtain a copy of the License at
9 : * http://www.mozilla.org/MPL/
10 : *
11 : * Software distributed under the License is distributed on an "AS IS" basis,
12 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 : * for the specific language governing rights and limitations under the
14 : * License.
15 : *
16 : * The Original Code is mozilla.org code.
17 : *
18 : * The Initial Developer of the Original Code is
19 : * Mozilla Corporation
20 : * Portions created by the Initial Developer are Copyright (C) 2008
21 : * the Initial Developer. All Rights Reserved.
22 : *
23 : * Contributor(s):
24 : * Shawn Wilsher <me@shawnwilsher.com> (Original Author)
25 : *
26 : * Alternatively, the contents of this file may be used under the terms of
27 : * either the GNU General Public License Version 2 or later (the "GPL"), or
28 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 : * in which case the provisions of the GPL or the LGPL are applicable instead
30 : * of those above. If you wish to allow use of your version of this file only
31 : * under the terms of either the GPL or the LGPL, and not to allow others to
32 : * use your version of this file under the terms of the MPL, indicate your
33 : * decision by deleting the provisions above and replace them with the notice
34 : * and other provisions required by the GPL or the LGPL. If you do not delete
35 : * the provisions above, a recipient may use your version of this file under
36 : * the terms of any one of the MPL, the GPL or the LGPL.
37 : *
38 : * ***** END LICENSE BLOCK ***** */
39 :
40 : #include "nsString.h"
41 :
42 : #include "sqlite3.h"
43 : #include "mozStoragePrivateHelpers.h"
44 : #include "Variant.h"
45 : #include "mozStorageRow.h"
46 :
47 : namespace mozilla {
48 : namespace storage {
49 :
50 : ////////////////////////////////////////////////////////////////////////////////
51 : //// Row
52 :
53 : nsresult
54 24433 : Row::initialize(sqlite3_stmt *aStatement)
55 : {
56 : // Initialize the hash table
57 24433 : NS_ENSURE_TRUE(mNameHashtable.Init(), NS_ERROR_OUT_OF_MEMORY);
58 :
59 : // Get the number of results
60 24433 : mNumCols = ::sqlite3_column_count(aStatement);
61 :
62 : // Start copying over values
63 311198 : for (PRUint32 i = 0; i < mNumCols; i++) {
64 : // Store the value
65 286765 : nsIVariant *variant = nsnull;
66 286765 : int type = ::sqlite3_column_type(aStatement, i);
67 286765 : switch (type) {
68 : case SQLITE_INTEGER:
69 274112 : variant = new IntegerVariant(::sqlite3_column_int64(aStatement, i));
70 137056 : break;
71 : case SQLITE_FLOAT:
72 68 : variant = new FloatVariant(::sqlite3_column_double(aStatement, i));
73 34 : break;
74 : case SQLITE_TEXT:
75 : {
76 : nsDependentString str(
77 106644 : static_cast<const PRUnichar *>(::sqlite3_column_text16(aStatement, i))
78 213288 : );
79 106644 : variant = new TextVariant(str);
80 : break;
81 : }
82 : case SQLITE_NULL:
83 43002 : variant = new NullVariant();
84 43002 : break;
85 : case SQLITE_BLOB:
86 : {
87 29 : int size = ::sqlite3_column_bytes(aStatement, i);
88 29 : const void *data = ::sqlite3_column_blob(aStatement, i);
89 58 : variant = new BlobVariant(std::pair<const void *, int>(data, size));
90 29 : break;
91 : }
92 : default:
93 0 : return NS_ERROR_UNEXPECTED;
94 : }
95 286765 : NS_ENSURE_TRUE(variant, NS_ERROR_OUT_OF_MEMORY);
96 :
97 : // Insert into our storage array
98 286765 : NS_ENSURE_TRUE(mData.InsertObjectAt(variant, i), NS_ERROR_OUT_OF_MEMORY);
99 :
100 : // Associate the name (if any) with the index
101 286765 : const char *name = ::sqlite3_column_name(aStatement, i);
102 286765 : if (!name) break;
103 573530 : nsCAutoString colName(name);
104 286765 : mNameHashtable.Put(colName, i);
105 : }
106 :
107 24433 : return NS_OK;
108 : }
109 :
110 : /**
111 : * Note: This object is only ever accessed on one thread at a time. It it not
112 : * threadsafe, but it does need threadsafe AddRef and Release.
113 : */
114 342021 : NS_IMPL_THREADSAFE_ISUPPORTS2(
115 : Row,
116 : mozIStorageRow,
117 : mozIStorageValueArray
118 : )
119 :
120 : ////////////////////////////////////////////////////////////////////////////////
121 : //// mozIStorageRow
122 :
123 : NS_IMETHODIMP
124 112188 : Row::GetResultByIndex(PRUint32 aIndex,
125 : nsIVariant **_result)
126 : {
127 112188 : ENSURE_INDEX_VALUE(aIndex, mNumCols);
128 112188 : NS_ADDREF(*_result = mData.ObjectAt(aIndex));
129 112188 : return NS_OK;
130 : }
131 :
132 : NS_IMETHODIMP
133 106807 : Row::GetResultByName(const nsACString &aName,
134 : nsIVariant **_result)
135 : {
136 : PRUint32 index;
137 106807 : NS_ENSURE_TRUE(mNameHashtable.Get(aName, &index), NS_ERROR_NOT_AVAILABLE);
138 106807 : return GetResultByIndex(index, _result);
139 : }
140 :
141 : ////////////////////////////////////////////////////////////////////////////////
142 : //// mozIStorageValueArray
143 :
144 : NS_IMETHODIMP
145 16 : Row::GetNumEntries(PRUint32 *_entries)
146 : {
147 16 : *_entries = mNumCols;
148 16 : return NS_OK;
149 : }
150 :
151 : NS_IMETHODIMP
152 12 : Row::GetTypeOfIndex(PRUint32 aIndex,
153 : PRInt32 *_type)
154 : {
155 12 : ENSURE_INDEX_VALUE(aIndex, mNumCols);
156 :
157 : PRUint16 type;
158 10 : (void)mData.ObjectAt(aIndex)->GetDataType(&type);
159 10 : switch (type) {
160 : case nsIDataType::VTYPE_INT32:
161 : case nsIDataType::VTYPE_INT64:
162 2 : *_type = mozIStorageValueArray::VALUE_TYPE_INTEGER;
163 2 : break;
164 : case nsIDataType::VTYPE_DOUBLE:
165 2 : *_type = mozIStorageValueArray::VALUE_TYPE_FLOAT;
166 2 : break;
167 : case nsIDataType::VTYPE_ASTRING:
168 2 : *_type = mozIStorageValueArray::VALUE_TYPE_TEXT;
169 2 : break;
170 : case nsIDataType::VTYPE_ARRAY:
171 2 : *_type = mozIStorageValueArray::VALUE_TYPE_BLOB;
172 2 : break;
173 : default:
174 2 : *_type = mozIStorageValueArray::VALUE_TYPE_NULL;
175 2 : break;
176 : }
177 10 : return NS_OK;
178 : }
179 :
180 : NS_IMETHODIMP
181 22652 : Row::GetInt32(PRUint32 aIndex,
182 : PRInt32 *_value)
183 : {
184 22652 : ENSURE_INDEX_VALUE(aIndex, mNumCols);
185 22650 : return mData.ObjectAt(aIndex)->GetAsInt32(_value);
186 : }
187 :
188 : NS_IMETHODIMP
189 34418 : Row::GetInt64(PRUint32 aIndex,
190 : PRInt64 *_value)
191 : {
192 34418 : ENSURE_INDEX_VALUE(aIndex, mNumCols);
193 34416 : return mData.ObjectAt(aIndex)->GetAsInt64(_value);
194 : }
195 :
196 : NS_IMETHODIMP
197 2 : Row::GetDouble(PRUint32 aIndex,
198 : double *_value)
199 : {
200 2 : ENSURE_INDEX_VALUE(aIndex, mNumCols);
201 0 : return mData.ObjectAt(aIndex)->GetAsDouble(_value);
202 : }
203 :
204 : NS_IMETHODIMP
205 56888 : Row::GetUTF8String(PRUint32 aIndex,
206 : nsACString &_value)
207 : {
208 56888 : ENSURE_INDEX_VALUE(aIndex, mNumCols);
209 56886 : return mData.ObjectAt(aIndex)->GetAsAUTF8String(_value);
210 : }
211 :
212 : NS_IMETHODIMP
213 4 : Row::GetString(PRUint32 aIndex,
214 : nsAString &_value)
215 : {
216 4 : ENSURE_INDEX_VALUE(aIndex, mNumCols);
217 2 : return mData.ObjectAt(aIndex)->GetAsAString(_value);
218 : }
219 :
220 : NS_IMETHODIMP
221 5 : Row::GetBlob(PRUint32 aIndex,
222 : PRUint32 *_size,
223 : PRUint8 **_blob)
224 : {
225 5 : ENSURE_INDEX_VALUE(aIndex, mNumCols);
226 :
227 : PRUint16 type;
228 : nsIID interfaceIID;
229 3 : return mData.ObjectAt(aIndex)->GetAsArray(&type, &interfaceIID, _size,
230 3 : reinterpret_cast<void **>(_blob));
231 : }
232 :
233 : NS_IMETHODIMP
234 36 : Row::GetIsNull(PRUint32 aIndex,
235 : bool *_isNull)
236 : {
237 36 : ENSURE_INDEX_VALUE(aIndex, mNumCols);
238 34 : NS_ENSURE_ARG_POINTER(_isNull);
239 :
240 : PRUint16 type;
241 34 : (void)mData.ObjectAt(aIndex)->GetDataType(&type);
242 34 : *_isNull = type == nsIDataType::VTYPE_EMPTY;
243 34 : return NS_OK;
244 : }
245 :
246 : NS_IMETHODIMP
247 0 : Row::GetSharedUTF8String(PRUint32,
248 : PRUint32 *,
249 : char const **)
250 : {
251 0 : return NS_ERROR_NOT_IMPLEMENTED;
252 : }
253 :
254 : NS_IMETHODIMP
255 0 : Row::GetSharedString(PRUint32,
256 : PRUint32 *,
257 : const PRUnichar **)
258 : {
259 0 : return NS_ERROR_NOT_IMPLEMENTED;
260 : }
261 :
262 : NS_IMETHODIMP
263 0 : Row::GetSharedBlob(PRUint32,
264 : PRUint32 *,
265 : const PRUint8 **)
266 : {
267 0 : return NS_ERROR_NOT_IMPLEMENTED;
268 : }
269 :
270 : } // namespace storage
271 : } // namespace mozilla
|