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