Fix DataSet memory leak
[platform/framework/native/appfw.git] / src / io / FIo_DataSetEnumeratorImpl.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file        FIo_DataSetEnumeratorImpl.cpp
20  * @brief       This is the implementation file for _DataSetEnumeratorImpl class.
21  */
22
23 #include <stdio.h>
24 #include <semaphore.h>
25 #include <errno.h>
26 #include <unique_ptr.h>
27
28 #include <FBaseInteger.h>
29 #include <FBaseDouble.h>
30 #include <FBaseString.h>
31 #include <FBaseByteBuffer.h>
32 #include <FBaseDateTime.h>
33 #include <FBaseUtilStringUtil.h>
34 #include <FBaseColLinkedList.h>
35 #include <FBaseColArrayList.h>
36 #include <FBaseColIEnumerator.h>
37 #include <FBaseSysLog.h>
38
39 #include <FIoDbTypes.h>
40 #include <FIo_DataSetEnumeratorImpl.h>
41 #include <FIo_DataRowImpl.h>
42
43 using namespace std;
44 using namespace Tizen::Base;
45 using namespace Tizen::Base::Utility;
46 using namespace Tizen::Base::Runtime;
47 using namespace Tizen::System;
48 using namespace Tizen::App;
49 using namespace Tizen::Base::Collection;
50
51 namespace Tizen { namespace Io
52 {
53
54 _DataSetEnumeratorImpl::_DataSetEnumeratorImpl(void)
55         : __pDataSet(null),
56         __pColumnList(null),
57         __pCurrentRow(null),
58         __columnCount(0),
59         __rowCount(0),
60         __currentRowIndex(-1)
61 {
62
63 }
64
65 _DataSetEnumeratorImpl::~_DataSetEnumeratorImpl(void)
66 {
67
68 }
69
70 result
71 _DataSetEnumeratorImpl::MoveNext(void)
72 {
73         SysTryReturnResult(NID_IO, __pDataSet != null, E_INVALID_STATE,
74                                 "The Object is not constructed or the dataset is already been deleted.");
75
76         if (__currentRowIndex +1  == __rowCount)
77                 return E_OUT_OF_RANGE;
78
79         ++__currentRowIndex;
80         __pCurrentRow = static_cast<ArrayList*>(__pDataSet->GetAt(__currentRowIndex));
81
82         if (__pCurrentRow == null)
83                 return E_INVALID_STATE;
84
85         return E_SUCCESS;
86 }
87
88 result
89 _DataSetEnumeratorImpl::MovePrevious(void)
90 {
91         SysTryReturnResult(NID_IO, __pDataSet != null, E_INVALID_STATE,
92                                 "The Object is not constructed or the dataset is already been deleted.");
93
94         if (__currentRowIndex == 0)
95                 return E_OUT_OF_RANGE;
96
97         --__currentRowIndex;
98         __pCurrentRow = static_cast<ArrayList*>(__pDataSet->GetAt(__currentRowIndex));
99
100         if (__pCurrentRow == null)
101                 return E_INVALID_STATE;
102
103         return E_SUCCESS;
104 }
105
106 result
107 _DataSetEnumeratorImpl::MoveFirst(void)
108 {
109         SysTryReturnResult(NID_IO, __pDataSet != null, E_INVALID_STATE,
110                                 "The Object is not constructed or the dataset is already been deleted.");
111
112         __currentRowIndex = 0;
113         __pCurrentRow = static_cast<ArrayList*>(__pDataSet->GetAt(__currentRowIndex));
114
115         if (__pCurrentRow == null)
116                 return E_INVALID_STATE;
117
118         return E_SUCCESS;
119 }
120
121 result
122 _DataSetEnumeratorImpl::MoveLast(void)
123 {
124         SysTryReturnResult(NID_IO, __pDataSet != null, E_INVALID_STATE,
125                                 "The Object is not constructed or the dataset is already been deleted.");
126
127         __currentRowIndex = __rowCount -1;
128         __pCurrentRow = static_cast<ArrayList*>(__pDataSet->GetAt(__currentRowIndex));
129
130         if (__pCurrentRow == null)
131                 return E_INVALID_STATE;
132
133         return E_SUCCESS;
134 }
135
136 result
137 _DataSetEnumeratorImpl::Reset(void)
138 {
139         SysTryReturnResult(NID_IO, __pDataSet != null, E_INVALID_STATE,
140                                 "The Object is not constructed or the dataset is already been deleted.");
141
142         __currentRowIndex = -1;
143         __pCurrentRow = null;
144
145         return E_SUCCESS;
146 }
147
148 result
149 _DataSetEnumeratorImpl::GetIntAt(int columnIndex, int& value) const
150 {
151         result r = E_SUCCESS;
152
153         SysTryReturnResult(NID_IO, __pDataSet != null, E_INVALID_STATE,
154                                 "The Object is not constructed or the dataset is already been deleted.");
155         SysTryReturnResult(NID_IO, columnIndex >= 0 && columnIndex < __columnCount, E_INVALID_ARG,
156                                 "Given column index is out of range.");
157         SysTryReturnResult(NID_IO, __pCurrentRow != null, E_INVALID_STATE,
158                                 "The method has tried to fetch the column data of a result set that is not activated.");
159
160         _DataItem* pDataItem = dynamic_cast < _DataItem* >(__pCurrentRow->GetAt(columnIndex));
161         if (pDataItem)
162         {
163                 if (pDataItem->type != DB_COLUMNTYPE_INT)
164                 {
165                         r = E_TYPE_MISMATCH;
166                         SysLog(NID_IO, "[E_TYPE_MISMATCH] Trying to access column of different type.");
167                         goto CATCH;
168                 }
169
170                 value = pDataItem->intValue;
171         }
172         return E_SUCCESS;
173
174         CATCH:
175                 return r;
176 }
177
178 result
179 _DataSetEnumeratorImpl::GetInt64At(int columnIndex, long long& value) const
180 {
181         result r = E_SUCCESS;
182
183         SysTryReturnResult(NID_IO, __pDataSet != null, E_INVALID_STATE,
184                                 "The Object is not constructed or the dataset is already been deleted.");
185         SysTryReturnResult(NID_IO, columnIndex >= 0 && columnIndex < __columnCount, E_INVALID_ARG,
186                                 "Given column index is out of range.");
187         SysTryReturnResult(NID_IO, __pCurrentRow != null, E_INVALID_STATE,
188                                 "The method has tried to fetch the column data of a result set that is not activated.");
189
190         _DataItem* pDataItem = dynamic_cast < _DataItem* >(__pCurrentRow->GetAt(columnIndex));
191         if (pDataItem)
192         {
193                 if (pDataItem->type != DB_COLUMNTYPE_INT64)
194                 {
195                         r = E_TYPE_MISMATCH;
196                         SysLog(NID_IO, "[E_TYPE_MISMATCH] Trying to access column of different type.");
197                         goto CATCH;
198                 }
199
200                 value = pDataItem->int64Value;
201         }
202         return E_SUCCESS;
203
204 CATCH:
205         return r;
206 }
207
208 result
209 _DataSetEnumeratorImpl::GetDoubleAt(int columnIndex, double& value) const
210 {
211         result r = E_SUCCESS;
212
213         SysTryReturnResult(NID_IO, __pDataSet != null, E_INVALID_STATE,
214                                 "The Object is not constructed or the dataset is already been deleted.");
215         SysTryReturnResult(NID_IO, columnIndex >= 0 && columnIndex < __columnCount, E_INVALID_ARG,
216                                 "Given column index is out of range.");
217         SysTryReturnResult(NID_IO, __pCurrentRow != null, E_INVALID_STATE,
218                                 "The method has tried to fetch the column data of a result set that is not activated.");
219
220         _DataItem* pDataItem = dynamic_cast < _DataItem* >(__pCurrentRow->GetAt(columnIndex));
221         if (pDataItem)
222         {
223                 if (pDataItem->type != DB_COLUMNTYPE_DOUBLE)
224                 {
225                         r = E_TYPE_MISMATCH;
226                         SysLog(NID_IO, "[E_TYPE_MISMATCH] Trying to access column of different type.");
227                         goto CATCH;
228                 }
229
230                 value = pDataItem->doubleValue;
231         }
232         return E_SUCCESS;
233
234 CATCH:
235         return r;
236 }
237
238 result
239 _DataSetEnumeratorImpl::GetStringAt(int columnIndex, String& value) const
240 {
241         result r = E_SUCCESS;
242
243         SysTryReturnResult(NID_IO, __pDataSet != null, E_INVALID_STATE,
244                                 "The Object is not constructed or the dataset is already been deleted.");
245         SysTryReturnResult(NID_IO, columnIndex >= 0 && columnIndex < __columnCount, E_INVALID_ARG,
246                                 "Given column index is out of range.");
247         SysTryReturnResult(NID_IO, __pCurrentRow != null, E_INVALID_STATE,
248                                 "The method has tried to fetch the column data of a result set that is not activated.");
249
250         _DataItem* pDataItem = dynamic_cast < _DataItem* >(__pCurrentRow->GetAt(columnIndex));
251         if (pDataItem)
252         {
253                 if (pDataItem->type != DB_COLUMNTYPE_TEXT)
254                 {
255                         r = E_TYPE_MISMATCH;
256                         SysLog(NID_IO, "[E_TYPE_MISMATCH] Trying to access column of different type.");
257                         goto CATCH;
258                 }
259
260                 value = *((String*)pDataItem->pObj);
261         }
262
263 CATCH:
264         return r;
265 }
266
267 result
268 _DataSetEnumeratorImpl::GetBlobAt(int columnIndex, ByteBuffer& value) const
269 {
270         result r = E_SUCCESS;
271         ByteBuffer* pBuffer = null;
272
273         SysTryReturnResult(NID_IO, __pDataSet != null, E_INVALID_STATE,
274                                 "The Object is not constructed or the dataset is already been deleted.");
275         SysTryReturnResult(NID_IO, columnIndex >= 0 && columnIndex < __columnCount, E_INVALID_ARG,
276                                 "Given column index is out of range.");
277         SysTryReturnResult(NID_IO, __pCurrentRow != null, E_INVALID_STATE,
278                                 "The method has tried to fetch the column data of a result set that is not activated.");
279
280         _DataItem* pDataItem = dynamic_cast < _DataItem* >(__pCurrentRow->GetAt(columnIndex));
281         if (pDataItem)
282         {
283                 if (pDataItem->type != DB_COLUMNTYPE_BLOB)
284                 {
285                         r = E_TYPE_MISMATCH;
286                         SysLog(NID_IO, "[E_TYPE_MISMATCH] Trying to access column of different type.");
287                         goto CATCH;
288                 }
289
290                 pBuffer = (ByteBuffer*)pDataItem->pObj;
291                 pBuffer->SetPosition(0);
292                 r = value.CopyFrom(*pBuffer);
293         }
294
295         // fall thru
296 CATCH:
297         return r;
298 }
299
300 result
301 _DataSetEnumeratorImpl::GetBlobAt(int columnIndex, void* buffer, int size) const
302 {
303         result r = E_SUCCESS;
304         int blobLen = 0;
305         ByteBuffer* pBuffer = null;
306
307         SysTryReturnResult(NID_IO, __pDataSet != null, E_INVALID_STATE,
308                                 "The Object is not constructed or the dataset is already been deleted.");
309         SysTryReturnResult(NID_IO, columnIndex >= 0 && columnIndex < __columnCount, E_INVALID_ARG,
310                                 "Given column index is out of range.");
311         SysTryReturnResult(NID_IO, __pCurrentRow != null, E_INVALID_STATE,
312                                 "The method has tried to fetch the column data of a result set that is not activated.");
313
314         _DataItem* pDataItem = dynamic_cast < _DataItem* >(__pCurrentRow->GetAt(columnIndex));
315         if (pDataItem)
316         {
317                 if (pDataItem->type != DB_COLUMNTYPE_BLOB)
318                 {
319                         r = E_TYPE_MISMATCH;
320                         SysLog(NID_IO, "[E_TYPE_MISMATCH] Trying to access column of different type.");
321                         goto CATCH;
322                 }
323
324                 pBuffer = (ByteBuffer*)pDataItem->pObj;
325                 pBuffer->SetPosition(0);
326                 blobLen = pBuffer->GetLimit();
327                 memcpy(buffer, pBuffer->GetPointer(), (blobLen < size) ? blobLen : size);
328         }
329
330         if (size < blobLen)
331         {
332                 r = E_OVERFLOW;
333         }
334
335         // fall thru
336 CATCH:
337         return r;
338 }
339
340 result
341 _DataSetEnumeratorImpl::GetDateTimeAt(int columnIndex, DateTime& value) const
342 {
343         result r = E_SUCCESS;
344         String* pStr = null;
345
346         SysTryReturnResult(NID_IO, __pDataSet != null, E_INVALID_STATE,
347                                 "The instance is not constructed or the dataset is already been deleted.");
348         SysTryReturnResult(NID_IO, columnIndex >= 0 && columnIndex < __columnCount, E_INVALID_ARG,
349                                 "Given column index is out of range.");
350         SysTryReturnResult(NID_IO, __pCurrentRow != null, E_INVALID_STATE,
351                                 "The method has tried to fetch the column data of a result set that is not activated.");
352
353         _DataItem* pDataItem = dynamic_cast < _DataItem* >(__pCurrentRow->GetAt(columnIndex));
354         if (pDataItem)
355         {
356                 if (pDataItem->type != DB_COLUMNTYPE_TEXT)
357                 {
358                         r = E_TYPE_MISMATCH;
359                         SysLog(NID_IO, "[E_TYPE_MISMATCH] Trying to access column of different type.");
360                         goto CATCH;
361                 }
362
363                 pStr = (String*)pDataItem->pObj;
364                 r = DateTime::Parse(*pStr, value);
365         }
366
367         // fall thru
368 CATCH:
369         return r;
370 }
371
372 int
373 _DataSetEnumeratorImpl::GetColumnCount(void) const
374 {
375         SysTryReturnResult(NID_IO, __pDataSet != null, E_INVALID_STATE,
376                                 "The Object is not constructed or the dataset is already been deleted.");
377
378         return __columnCount;
379 }
380
381 DbColumnType
382 _DataSetEnumeratorImpl::GetColumnType(int columnIndex) const
383 {
384         DbColumnType type = DB_COLUMNTYPE_UNDEFINED;
385
386         SysTryReturn(NID_IO, __pDataSet != null, DB_COLUMNTYPE_UNDEFINED, E_INVALID_STATE,
387                                 "[E_INVALID_STATE] The instance is not constructed or the dataset is already been deleted.");
388
389         SysTryReturn(NID_IO, columnIndex >= 0 && columnIndex < __columnCount, DB_COLUMNTYPE_UNDEFINED, E_INVALID_ARG,
390                                 "[E_INVALID_ARG] Given column index is out of range.");
391
392         if (__pCurrentRow)
393         {
394                 _DataItem* pDataItem = dynamic_cast < _DataItem* >(__pCurrentRow->GetAt(columnIndex));
395                 if (!pDataItem)
396                 {
397                         SetLastResult(E_INVALID_STATE);
398                         return DB_COLUMNTYPE_UNDEFINED;
399                 }
400
401                 switch (pDataItem->type)
402                 {
403                 case DB_COLUMNTYPE_INT:
404                 case DB_COLUMNTYPE_INT64:
405                 case DB_COLUMNTYPE_DOUBLE:
406                 case DB_COLUMNTYPE_TEXT:
407                 case DB_COLUMNTYPE_BLOB:
408                 case DB_COLUMNTYPE_NULL:
409                         type = pDataItem->type;
410                         break;
411
412                 default:
413                         SetLastResult(E_INVALID_STATE);
414                         break;
415                 }
416         }
417
418         return type;
419 }
420
421 String
422 _DataSetEnumeratorImpl::GetColumnName(int columnIndex) const
423 {
424         SysTryReturn(NID_IO, __pDataSet != null, null, E_INVALID_STATE,
425                                 "[E_INVALID_STATE] The instance is not constructed or the dataset is already been deleted.");
426
427         SysTryReturn(NID_IO, columnIndex >= 0 && columnIndex < __columnCount, null, E_INVALID_ARG,
428                                 "[E_INVALID_ARG] Given column index is out of range.");
429
430
431         String* pString = dynamic_cast <String *> (__pColumnList->GetAt(columnIndex));
432
433         if (!pString)
434         {
435                 SetLastResult(E_INVALID_STATE);
436                 return String("");
437         }
438
439         return String(pString->GetPointer());
440 }
441
442 int
443 _DataSetEnumeratorImpl::GetColumnSize(int columnIndex) const
444 {
445         int bytes = 0;
446
447         SysTryReturn(NID_IO, __pDataSet != null, -1, E_INVALID_STATE,
448                                 "[E_INVALID_STATE] The instance is not constructed or the dataset is already been deleted.");
449
450         SysTryReturn(NID_IO, columnIndex >= 0 && columnIndex < __columnCount, -1, E_INVALID_ARG,
451                                 "[E_INVALID_ARG] Given column index is out of range.");
452
453         SysTryReturn(NID_IO, __pCurrentRow != null, -1, E_INVALID_STATE,
454                                 "[E_INVALID_STATE] The method has tried to fetch the column data of a result set that is not activated.");
455
456         _DataItem* pDataItem = dynamic_cast < _DataItem* >(__pCurrentRow->GetAt(columnIndex));
457         if (!pDataItem)
458         {
459                 SetLastResult(E_INVALID_STATE);
460                 return 0;
461         }
462
463         bytes = pDataItem->size;
464         //SysLog(NID_IO, "Size is %d", bytes);
465
466         return bytes;
467 }
468
469 _DataSetEnumeratorImpl*
470 _DataSetEnumeratorImpl::GetInstance(DataSetEnumerator& dataSetEnumerator)
471 {
472         return dataSetEnumerator.__pDataSetEnumeratorImpl;
473 }
474
475 const _DataSetEnumeratorImpl*
476 _DataSetEnumeratorImpl::GetInstance(const DataSetEnumerator& dataSetEnumerator)
477 {
478         return dataSetEnumerator.__pDataSetEnumeratorImpl;
479 }
480
481 DataSetEnumerator*
482 _DataSetEnumeratorImpl::CreateDataSetEnumeratorInstanceN(void)
483 {
484         unique_ptr<DataSetEnumerator> pDataSetEnumerator(new (std::nothrow) DataSetEnumerator());
485         SysTryReturn(NID_IO, pDataSetEnumerator != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
486         return pDataSetEnumerator.release();
487 }
488
489 }} // Tizen::Io
490