2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
8 // http://www.apache.org/licenses/LICENSE-2.0
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.
18 * @file FIo_DbEnumeratorImpl.cpp
19 * @brief This is the implementation file for _DbEnumeratorImpl class.
23 #include <semaphore.h>
25 #include <unique_ptr.h>
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>
39 #include <FBase_NativeError.h>
40 #include <FApp_AppInfo.h>
41 #include <FSys_RuntimeInfoImpl.h>
42 #include <FIo_DbEnumeratorImpl.h>
45 using namespace Tizen::Base;
46 using namespace Tizen::Base::Utility;
47 using namespace Tizen::Base::Runtime;
48 using namespace Tizen::System;
49 using namespace Tizen::App;
50 using namespace Tizen::Base::Collection;
52 namespace Tizen { namespace Io
54 static const unsigned int _MAX_DB_CACHE_SIZE = 2 * 1024 * 1024; // default cache size is 2MB
62 LinkedList dbValuesList;
75 if (this->hasData == true)
77 dbValuesList.RemoveAll(true);
89 unique_ptr<char[]> pData;
92 _DbColumn::_DbColumn(void)
99 _DbColumn::~_DbColumn(void)
103 class _DbEnumeratorCache
108 * This is the default constructor for this class.
110 _DbEnumeratorCache(void);
111 ~_DbEnumeratorCache(void);
113 unsigned int __currentUsedMemory;
114 _DbRow* __pCurrentDbRow;
115 LinkedList __dbColumnNameList;
116 LinkedList __dbRowList;
118 friend class _DbEnumeratorImpl;
122 _DbEnumeratorCache::_DbEnumeratorCache(void)
123 : __currentUsedMemory(0)
124 , __pCurrentDbRow(null)
128 _DbEnumeratorCache::~_DbEnumeratorCache(void)
130 __dbColumnNameList.RemoveAll(true);
131 __dbRowList.RemoveAll(true);
134 _DbEnumeratorImpl::_DbEnumeratorImpl(void)
135 : __shouldReleaseResource(false)
140 , __currentRowIndex(-1)
141 , __pDbEnumeratorCache(null)
145 _DbEnumeratorImpl::~_DbEnumeratorImpl(void)
147 result r = E_SUCCESS;
150 if (__shouldReleaseResource && __pEnum)
152 ret = sqlite3_finalize(static_cast <sqlite3_stmt*>(__pEnum));
153 if (ret != SQLITE_OK)
155 r = __ConvertNativeSqliteErrorToResult(ret);
156 SysLog(NID_IO, "[%s] Failed to finalize SQL statement (%d, %s).", GetErrorMessage(
157 r), ret, sqlite3_errmsg((sqlite3*) __pDatabase));
161 delete __pDbEnumeratorCache;
165 _DbEnumeratorImpl::CacheRow(bool cacheColumnNamesToo)
167 SysTryReturnResult(NID_IO, __pEnum != null, E_INVALID_STATE,
168 "The Object is not constructed or the database is already been closed.");
169 SysTryReturnResult(NID_IO, __pDbEnumeratorCache != null, E_INVALID_STATE,
170 "The Object is not constructed or the database is already been closed.");
173 result r = E_SUCCESS;
175 // check if all the rows are been cached already
178 SysTryReturnResult(NID_IO, __currentRowIndex < (__rowCount - 1), E_OUT_OF_RANGE,
179 "Reached to the end of the result set.");
182 ret = sqlite3_step((sqlite3_stmt*) __pEnum);
187 // set max rows in the result set
188 if (__currentRowIndex >= 0)
190 __rowCount = __currentRowIndex + 1;
192 return E_OUT_OF_RANGE;
197 unique_ptr<_DbRow> pDbRow(new (std::nothrow) _DbRow);
198 SysTryReturnResult(NID_IO, pDbRow != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
200 for (int i = 0; i < __columnCount; i++)
202 // prepare column name list only once
203 if (cacheColumnNamesToo == true)
206 const char* pName = sqlite3_column_name((sqlite3_stmt*) __pEnum, i);
208 r = __pDbEnumeratorCache->__dbColumnNameList.Add(* new (std::nothrow) String(pName));
209 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Propagated.", GetErrorMessage(r));
212 unique_ptr<_DbColumn> pDbColumn(new (std::nothrow) _DbColumn);
213 SysTryReturnResult(NID_IO, pDbColumn != null, E_OUT_OF_MEMORY,
214 "The memory is insufficient.");
216 int columnType = sqlite3_column_type((sqlite3_stmt*) __pEnum, i);
218 pDbColumn->type = columnType;
224 int size = sizeof(long long);
225 unique_ptr<char[]> pData(new (std::nothrow) char[size + 1]);
226 SysTryReturnResult(NID_IO, pData != null, E_OUT_OF_MEMORY,
227 "The memory is insufficient.");
228 memset(pData.get(), 0, size + 1);
229 long long value = sqlite3_column_int64((sqlite3_stmt*) __pEnum, i);
230 memcpy(pData.get(), &value, size);
231 pDbColumn->size = size;
232 pDbColumn->pData = move(pData);
237 int size = sizeof(double);
238 unique_ptr<char[]> pData(new (std::nothrow) char[size + 1]);
239 SysTryReturnResult(NID_IO, pData != null, E_OUT_OF_MEMORY,
240 "The memory is insufficient.");
241 memset(pData.get(), 0, size + 1);
242 double doubleValue = sqlite3_column_double((sqlite3_stmt*) __pEnum, i);
243 memcpy(pData.get(), &doubleValue, size);
244 pDbColumn->size = size;
245 pDbColumn->pData = move(pData);
250 int size = sqlite3_column_bytes((sqlite3_stmt*) __pEnum, i);
251 unique_ptr<char[]> pData(new (std::nothrow) char[size + 1]);
252 SysTryReturnResult(NID_IO, pData != null, E_OUT_OF_MEMORY,
253 "The memory is insufficient.");
254 memset(pData.get(), 0, size + 1);
255 char* pTextData = (char*) sqlite3_column_text((sqlite3_stmt*) __pEnum, i);
256 memcpy(pData.get(), pTextData, size);
257 pDbColumn->size = size;
258 pDbColumn->pData = move(pData);
263 int size = sqlite3_column_bytes((sqlite3_stmt*) __pEnum, i);
264 unique_ptr<char[]> pData(new (std::nothrow) char[size + 1]);
265 SysTryReturnResult(NID_IO, pData != null, E_OUT_OF_MEMORY,
266 "The memory is insufficient.");
267 memset(pData.get(), 0, size + 1);
268 char* pBlobData = (char*) sqlite3_column_blob((sqlite3_stmt*) __pEnum, i);
269 memcpy(pData.get(), pBlobData, size);
270 pDbColumn->size = size;
271 pDbColumn->pData = move(pData);
276 int size = sqlite3_column_bytes((sqlite3_stmt*) __pEnum, i);
277 pDbColumn->size = size;
282 SysTryReturnResult(NID_IO, false, E_DATABASE, "The column type is invalid.");
286 dbRowSize += pDbColumn->size;
287 r = pDbRow->dbValuesList.Add(*pDbColumn.release());
288 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Propagated.", GetErrorMessage(r));
291 __pDbEnumeratorCache->__currentUsedMemory += dbRowSize;
293 if (__pDbEnumeratorCache->__currentUsedMemory > _MAX_DB_CACHE_SIZE)
295 // remove old rows in FIFO manner till there is enough space for the current row.
296 for (int i = 0; i < __pDbEnumeratorCache->__dbRowList.GetCount(); i++)
298 _DbRow* pTmpDbRow = dynamic_cast< _DbRow* >(__pDbEnumeratorCache->__dbRowList.GetAt(i));
299 SysTryReturn(NID_IO, pTmpDbRow != null, GetLastResult(), GetLastResult(), "[%s] Propagated.", GetErrorMessage(GetLastResult()));
300 if (pTmpDbRow->hasData == true)
302 pTmpDbRow->dbValuesList.RemoveAll(true);
303 pTmpDbRow->hasData = false;
304 __pDbEnumeratorCache->__currentUsedMemory -= pTmpDbRow->dataSize;
305 pTmpDbRow->dataSize = 0;
307 if (__pDbEnumeratorCache->__currentUsedMemory <= _MAX_DB_CACHE_SIZE)
315 pDbRow->hasData = true;
316 pDbRow->dataSize = dbRowSize;
317 _DbRow* pTmpDbRow = pDbRow.release();
318 r = __pDbEnumeratorCache->__dbRowList.Add(*pTmpDbRow);
321 pTmpDbRow->dbValuesList.RemoveAll(true);
323 SysLog(NID_IO, "[%s] Propagated.", GetErrorMessage(r));
329 // set current cursor
330 __pDbEnumeratorCache->__pCurrentDbRow = pTmpDbRow;
336 if (!_AppInfo::IsOspCompat())
338 r = __ConvertNativeSqliteErrorToDetailResult(ret);
342 case E_ILLEGAL_ACCESS:
344 case E_INVALID_OPERATION:
352 r = __ConvertNativeSqliteErrorToResult(ret);
355 SysLog(NID_IO, "[%s] Failed to move row index. (%d, %s).", GetErrorMessage(r), ret,
356 sqlite3_errmsg(static_cast< sqlite3* >(__pDatabase)));
366 _DbEnumeratorImpl::CacheRow(_DbRow& dbRow, int rowIndex)
368 result r = E_SUCCESS;
371 SysTryReturnResult(NID_IO, __pEnum != null, E_INVALID_STATE,
372 "The Object is not constructed or the database is already been closed.");
374 SysTryReturnResult(NID_IO, __pDbEnumeratorCache != null, E_INVALID_STATE,
375 "The Object is not constructed or the database is already been closed.");
377 // reset sqlite result set.
378 ret = sqlite3_reset((sqlite3_stmt*) __pEnum);
379 if (ret != SQLITE_OK)
381 if (!_AppInfo::IsOspCompat())
383 r = __ConvertNativeSqliteErrorToDetailResult(ret);
387 case E_ILLEGAL_ACCESS:
389 case E_INVALID_FORMAT:
391 case E_INVALID_OPERATION:
399 r = __ConvertNativeSqliteErrorToResult(ret);
402 SysLog(NID_IO, "[%s] Failed to reset SQL statement. (%d, %s).", GetErrorMessage(r),
403 ret, sqlite3_errmsg(static_cast< sqlite3* >(__pDatabase)));
407 // move cursor to desired position.
408 for (int i = 0; i <= rowIndex; i++)
410 ret = sqlite3_step((sqlite3_stmt*) __pEnum);
411 if (ret != SQLITE_ROW)
413 SysLog(NID_IO, "Did not yield any result row");
418 // ret == SQLITE_ROW, cache the row.
421 for (int i = 0; i < __columnCount; i++)
423 unique_ptr<_DbColumn> pDbColumn(new (std::nothrow) _DbColumn);
424 SysTryReturnResult(NID_IO, pDbColumn != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
426 int columnType = sqlite3_column_type((sqlite3_stmt*) __pEnum, i);
428 pDbColumn->type = columnType;
434 int size = sizeof(long long);
435 unique_ptr<char[]> pData(new (std::nothrow) char[size + 1]);
436 SysTryReturnResult(NID_IO, pData != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
437 memset(pData.get(), 0, size + 1);
438 long long value = sqlite3_column_int64((sqlite3_stmt*) __pEnum, i);
439 memcpy(pData.get(), &value, size);
440 pDbColumn->size = size;
441 pDbColumn->pData = move(pData);
446 int size = sizeof(double);
447 unique_ptr<char[]> pData(new (std::nothrow) char[size + 1]);
448 SysTryReturnResult(NID_IO, pData != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
449 memset(pData.get(), 0, size + 1);
450 double doubleValue = sqlite3_column_double((sqlite3_stmt*) __pEnum, i);
451 memcpy(pData.get(), &doubleValue, size);
452 pDbColumn->size = size;
453 pDbColumn->pData = move(pData);
458 int size = sqlite3_column_bytes((sqlite3_stmt*) __pEnum, i);
459 unique_ptr<char[]> pData(new (std::nothrow) char[size + 1]);
460 SysTryReturnResult(NID_IO, pData != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
461 memset(pData.get(), 0, size + 1);
462 char* pTextData = (char*) sqlite3_column_text((sqlite3_stmt*) __pEnum, i);
463 memcpy(pData.get(), pTextData, size);
464 pDbColumn->size = size;
465 pDbColumn->pData = move(pData);
470 int size = sqlite3_column_bytes((sqlite3_stmt*) __pEnum, i);
471 unique_ptr<char[]> pData(new (std::nothrow) char[size + 1]);
472 SysTryReturnResult(NID_IO, pData != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
473 memset(pData.get(), 0, size + 1);
474 char* pBlobData = (char*) sqlite3_column_blob((sqlite3_stmt*) __pEnum, i);
475 memcpy(pData.get(), pBlobData, size);
476 pDbColumn->size = size;
477 pDbColumn->pData = move(pData);
482 int size = sqlite3_column_bytes((sqlite3_stmt*) __pEnum, i);
483 pDbColumn->size = size;
488 SysTryReturnResult(NID_IO, false, E_DATABASE, "The column type is invalid.");
493 dbRowSize += pDbColumn->size;
494 r = dbRow.dbValuesList.Add(*pDbColumn.release());
495 SysTryCatch(NID_IO, !IsFailed(r), , r, "[%s] Propagated.", GetErrorMessage(r));
498 __pDbEnumeratorCache->__currentUsedMemory += dbRowSize;
500 if (__pDbEnumeratorCache->__currentUsedMemory > _MAX_DB_CACHE_SIZE)
502 // In this case remove old rows in LIFO manner till there is enough space for the current row.
503 for (int i = __pDbEnumeratorCache->__dbRowList.GetCount() - 1; i >= 0; i--)
505 _DbRow* pTmpDbRow = dynamic_cast< _DbRow* >(__pDbEnumeratorCache->__dbRowList.GetAt(i));
506 SysTryCatch(NID_IO, pTmpDbRow != null, r = GetLastResult(), GetLastResult(), "[%s] Propagated.", GetErrorMessage(GetLastResult()));
507 if (pTmpDbRow->hasData == true)
509 pTmpDbRow->dbValuesList.RemoveAll(true);
510 pTmpDbRow->hasData = false;
511 __pDbEnumeratorCache->__currentUsedMemory -= pTmpDbRow->dataSize;
512 pTmpDbRow->dataSize = 0;
514 if (__pDbEnumeratorCache->__currentUsedMemory <= _MAX_DB_CACHE_SIZE)
516 break; // found enough space.
522 dbRow.hasData = true;
523 dbRow.dataSize = dbRowSize;
524 __currentRowIndex = rowIndex;
526 // set current cursor
527 __pDbEnumeratorCache->__pCurrentDbRow = &dbRow;
533 dbRow.dbValuesList.RemoveAll(true);
534 dbRow.hasData = false;
540 _DbEnumeratorImpl::MoveNext(void)
542 SysTryReturnResult(NID_IO, __pEnum != null, E_INVALID_STATE,
543 "The Object is not constructed or the database is already been closed.");
545 _DbRow* pDbRow = null;
546 result r = E_SUCCESS;
548 if (__pDbEnumeratorCache == null) // called for the first time
550 __pDbEnumeratorCache = new (std::nothrow) _DbEnumeratorCache; // allocate only once
551 SysTryReturnResult(NID_IO, __pDbEnumeratorCache != null, E_OUT_OF_MEMORY,
552 "The memory is insufficient.");
554 __columnCount = sqlite3_column_count((sqlite3_stmt*) __pEnum);
556 SysLog(NID_IO, "__columnCount: %d", __columnCount);
558 return this->CacheRow(true);
562 SysLog(NID_IO, "current used memory:%d", __pDbEnumeratorCache->__currentUsedMemory);
563 if ((__currentRowIndex + 1 <= __pDbEnumeratorCache->__dbRowList.GetCount() - 1))
565 pDbRow = dynamic_cast <_DbRow*>(__pDbEnumeratorCache->__dbRowList.GetAt(__currentRowIndex + 1));
566 SysTryReturnResult(NID_IO, pDbRow != null, E_SYSTEM, "The method cannot proceed due to a severe system error.");
568 if (pDbRow->hasData == true)
571 __pDbEnumeratorCache->__pCurrentDbRow = pDbRow;
575 return CacheRow(*pDbRow, __currentRowIndex + 1);
580 return this->CacheRow();
588 _DbEnumeratorImpl::MovePrevious(void)
590 result r = E_SUCCESS;
592 SysTryReturnResult(NID_IO, __pEnum != null, E_INVALID_STATE,
593 "The Object is not constructed or the database is already been closed.");
594 SysTryReturn(NID_IO, __pDbEnumeratorCache != null, E_INVALID_STATE, E_INVALID_STATE,
595 "[E_INVALID_STATE] The method has tried to fetch the column data of a result set that is not activated.");
596 SysTryReturnResult(NID_IO, __currentRowIndex > 0, E_OUT_OF_RANGE,
597 "The Method has reached out of the result set.");
599 // since no restriction on window size, this case should work all the times.
600 __pDbEnumeratorCache->__pCurrentDbRow = dynamic_cast< _DbRow* >(__pDbEnumeratorCache->__dbRowList.GetAt(__currentRowIndex - 1));
602 if (__pDbEnumeratorCache->__pCurrentDbRow)
604 if (__pDbEnumeratorCache->__pCurrentDbRow->hasData == true)
610 return CacheRow(*(__pDbEnumeratorCache->__pCurrentDbRow), __currentRowIndex - 1);
618 _DbEnumeratorImpl::MoveFirst(void)
620 SysTryReturnResult(NID_IO, __pEnum != null, E_INVALID_STATE,
621 "The Object is not constructed or the database is already been closed.");
623 if (__pDbEnumeratorCache == null) // if called for the first time
625 return this->MoveNext();
629 if (__currentRowIndex == 0)
631 return E_SUCCESS; // __pCurrentDbRow cursor is pointing to first row
635 __pDbEnumeratorCache->__pCurrentDbRow = dynamic_cast< _DbRow* >(__pDbEnumeratorCache->__dbRowList.GetAt(0));
636 if (__pDbEnumeratorCache->__pCurrentDbRow)
638 if (__pDbEnumeratorCache->__pCurrentDbRow->hasData == true)
640 __currentRowIndex = 0;
644 return CacheRow(*(__pDbEnumeratorCache->__pCurrentDbRow), 0);
647 else // this should not happen!!
649 // reset and do MoveNext()
650 delete __pDbEnumeratorCache;
651 __pDbEnumeratorCache = null;
652 __currentRowIndex = -1;
655 result r = this->Reset(); // to call sqlite3_reset()
656 SysTryReturnResult(NID_IO, r == E_SUCCESS, r, "Propagated.");
658 return this->MoveNext();
667 _DbEnumeratorImpl::MoveLast(void)
669 result r = E_SUCCESS;
670 _DbRow* pDbRow = null;
672 SysTryReturnResult(NID_IO, __pEnum != null, E_INVALID_STATE,
673 "The Object is not constructed or the database is already been closed.");
675 if (__pDbEnumeratorCache == null) // if called for the first time
678 r = this->MoveNext();
679 SysTryReturnResult(NID_IO, r == E_SUCCESS, r, "Propagated.");
681 // cache all the rows
684 r = this->CacheRow();
685 if (r == E_OUT_OF_RANGE)
694 if (__rowCount > 0 && __currentRowIndex == (__rowCount - 1))
696 return E_SUCCESS; // already @last row.
699 // move cursor from __currentRowIndex + 1 to the end of the row list.
700 for (int i = __currentRowIndex + 1; i < __pDbEnumeratorCache->__dbRowList.GetCount(); i++)
702 // find the missing row index
703 pDbRow = dynamic_cast< _DbRow* >(__pDbEnumeratorCache->__dbRowList.GetAt(i));
706 if (pDbRow->hasData == true)
708 __pDbEnumeratorCache->__pCurrentDbRow = pDbRow;
709 __currentRowIndex = i;
713 r = this->CacheRow(*pDbRow, i);
714 SysTryReturn(NID_IO, !(IsFailed(r)), r, r, "[%s] Propagated.", GetErrorMessage(r));
723 if (__rowCount > 0 && __currentRowIndex == (__rowCount - 1))
725 return E_SUCCESS; // __dbRowList contains all the rows and __currentRowIndex is @last row.
729 // cache remaining rows
732 r = this->CacheRow();
733 if (r == E_OUT_OF_RANGE)
746 _DbEnumeratorImpl::Reset(void)
748 SysTryReturnResult(NID_IO, __pEnum != null, E_INVALID_STATE,
749 "The Object is not constructed or the database is already been closed.");
752 result r = E_SUCCESS;
754 if (__pDbEnumeratorCache != null)
756 // by resetting row offset and current row, can re-use the cache for later purpose.
757 __pDbEnumeratorCache->__pCurrentDbRow = null;
758 __currentRowIndex = -1;
762 ret = sqlite3_reset((sqlite3_stmt*) __pEnum);
763 if (ret != SQLITE_OK)
765 if (!_AppInfo::IsOspCompat())
767 r = __ConvertNativeSqliteErrorToDetailResult(ret);
771 case E_ILLEGAL_ACCESS:
773 case E_INVALID_FORMAT:
775 case E_INVALID_OPERATION:
783 r = __ConvertNativeSqliteErrorToResult(ret);
786 SysLog(NID_IO, "[%s] Failed to reset SQL statement. (%d, %s).", GetErrorMessage(r),
787 ret, sqlite3_errmsg(static_cast< sqlite3* >(__pDatabase)));
795 _DbEnumeratorImpl::GetIntAt(int columnIndex, int& value) const
797 SysTryReturnResult(NID_IO, __pEnum != null, E_INVALID_STATE,
798 "The Object is not constructed or the database is already been closed.");
799 SysTryReturnResult(NID_IO, columnIndex >= 0 && columnIndex < __columnCount, E_INVALID_ARG,
800 "Given column index is out of range.");
801 SysTryReturnResult(NID_IO, __pDbEnumeratorCache != null, E_INVALID_STATE,
802 "The method has tried to fetch the column data of a result set that is not activated.");
803 SysTryReturnResult(NID_IO, __pDbEnumeratorCache->__pCurrentDbRow != null, E_SYSTEM,
804 "Result row is not activated.");
806 _DbColumn* pDbColumn = dynamic_cast < _DbColumn* >(__pDbEnumeratorCache->__pCurrentDbRow->dbValuesList.GetAt(columnIndex));
807 SysTryReturnResult(NID_IO, pDbColumn != null, E_SYSTEM, "The specified column at index %d is not found from the result set.", columnIndex);
809 SysTryReturnResult(NID_IO, pDbColumn->type == SQLITE_INTEGER, E_TYPE_MISMATCH,
810 "Trying to access column of different type.");
812 SysTryReturnResult(NID_IO, pDbColumn->pData != null, E_SYSTEM, "Data for specified column does not exist.");
814 value = *((int *)pDbColumn->pData.get());
820 _DbEnumeratorImpl::GetInt64At(int columnIndex, long long& value) const
822 SysTryReturnResult(NID_IO, __pEnum != null, E_INVALID_STATE,
823 "The Object is not constructed or the database is already been closed.");
824 SysTryReturnResult(NID_IO, columnIndex >= 0 && columnIndex < __columnCount, E_INVALID_ARG,
825 "Given column index is out of range.");
826 SysTryReturnResult(NID_IO, __pDbEnumeratorCache != null, E_INVALID_STATE,
827 "The method has tried to fetch the column data of a result set that is not activated.");
828 SysTryReturnResult(NID_IO, __pDbEnumeratorCache->__pCurrentDbRow != null, E_SYSTEM,
829 "Result row is not activated.");
831 _DbColumn* pDbColumn = dynamic_cast < _DbColumn* >(__pDbEnumeratorCache->__pCurrentDbRow->dbValuesList.GetAt(columnIndex));
832 SysTryReturnResult(NID_IO, pDbColumn != null, E_SYSTEM, "The specified column at index %d is not found from the result set.", columnIndex);
834 SysTryReturnResult(NID_IO, pDbColumn->type == SQLITE_INTEGER, E_TYPE_MISMATCH,
835 "Trying to access column of different type.");
836 SysTryReturnResult(NID_IO, pDbColumn->pData != null, E_SYSTEM, "Data for specified column does not exist.");
838 value = *((long long *)pDbColumn->pData.get());
844 _DbEnumeratorImpl::GetDoubleAt(int columnIndex, double& value) const
846 SysTryReturnResult(NID_IO, __pEnum != null, E_INVALID_STATE,
847 "The Object is not constructed or the database is already been closed.");
848 SysTryReturnResult(NID_IO, columnIndex >= 0 && columnIndex < __columnCount, E_INVALID_ARG,
849 "Given column index is out of range.");
850 SysTryReturnResult(NID_IO, __pDbEnumeratorCache != null, E_INVALID_STATE,
851 "The method has tried to fetch the column data of a result set that is not activated.");
852 SysTryReturnResult(NID_IO, __pDbEnumeratorCache->__pCurrentDbRow != null, E_SYSTEM,
853 "Result row is not activated.");
855 _DbColumn* pDbColumn = dynamic_cast < _DbColumn* >(__pDbEnumeratorCache->__pCurrentDbRow->dbValuesList.GetAt(columnIndex));
856 SysTryReturnResult(NID_IO, pDbColumn != null, E_SYSTEM, "The specified column at index %d is not found from the result set.", columnIndex);
857 SysTryReturnResult(NID_IO, pDbColumn->type == SQLITE_FLOAT, E_TYPE_MISMATCH, "Trying to access column of different type.");
858 SysTryReturnResult(NID_IO, pDbColumn->pData != null, E_SYSTEM, "Data for specified column does not exist.");
860 value = *((double *)pDbColumn->pData.get());
866 _DbEnumeratorImpl::GetStringAt(int columnIndex, String& value) const
868 SysTryReturnResult(NID_IO, __pEnum != null, E_INVALID_STATE,
869 "The Object is not constructed or the database is already been closed.");
870 SysTryReturnResult(NID_IO, columnIndex >= 0 && columnIndex < __columnCount, E_INVALID_ARG,
871 "Given column index is out of range.");
872 SysTryReturnResult(NID_IO, __pDbEnumeratorCache != null, E_INVALID_STATE,
873 "The method has tried to fetch the column data of a result set that is not activated.");
874 SysTryReturnResult(NID_IO, __pDbEnumeratorCache->__pCurrentDbRow != null, E_SYSTEM,
875 "Result row is not activated.");
877 _DbColumn* pDbColumn = dynamic_cast < _DbColumn* >(__pDbEnumeratorCache->__pCurrentDbRow->dbValuesList.GetAt(columnIndex));
878 SysTryReturnResult(NID_IO, pDbColumn != null, E_SYSTEM, "The specified column at index %d is not found from the result set.", columnIndex);
879 SysTryReturnResult(NID_IO, pDbColumn->type == SQLITE_TEXT, E_TYPE_MISMATCH, "Trying to access column of different type.");
880 SysTryReturnResult(NID_IO, pDbColumn->pData != null, E_SYSTEM, "Data for specified column does not exist.");
882 result r = StringUtil::Utf8ToString(const_cast< char* >(pDbColumn->pData.get()), value);
883 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] Propagating to caller...", GetErrorMessage(r));
889 _DbEnumeratorImpl::GetBlobAt(int columnIndex, ByteBuffer& value) const
891 SysTryReturnResult(NID_IO, __pEnum != null, E_INVALID_STATE,
892 "The Object is not constructed or the database is already been closed.");
893 SysTryReturnResult(NID_IO, columnIndex >= 0 && columnIndex < __columnCount, E_INVALID_ARG,
894 "Given column index is out of range.");
895 SysTryReturnResult(NID_IO, __pDbEnumeratorCache != null, E_INVALID_STATE,
896 "The method has tried to fetch the column data of a result set that is not activated.");
897 SysTryReturnResult(NID_IO, __pDbEnumeratorCache->__pCurrentDbRow != null, E_SYSTEM,
898 "Result row is not activated.");
900 _DbColumn* pDbColumn = dynamic_cast < _DbColumn* >(__pDbEnumeratorCache->__pCurrentDbRow->dbValuesList.GetAt(columnIndex));
901 SysTryReturnResult(NID_IO, pDbColumn != null, E_SYSTEM, "The specified column at index %d is not found from the result set.", columnIndex);
902 SysTryReturnResult(NID_IO, pDbColumn->type == SQLITE_BLOB, E_TYPE_MISMATCH, "Trying to access column of different type.");
904 int blobLen = pDbColumn->size;
905 SysTryReturnResult(NID_IO, pDbColumn->pData != null, E_SYSTEM, "Data for specified column does not exist.");
907 const byte* pBlob = reinterpret_cast< const byte* >(pDbColumn->pData.get());
908 result r = value.SetArray(pBlob, 0, blobLen);
909 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] Propagating to caller...", GetErrorMessage(r));
915 _DbEnumeratorImpl::GetBlobAt(int columnIndex, void* buffer, int size) const
917 SysTryReturnResult(NID_IO, __pEnum != null, E_INVALID_STATE,
918 "The Object is not constructed or the database is already been closed.");
919 SysTryReturnResult(NID_IO, columnIndex >= 0 && columnIndex < __columnCount, E_INVALID_ARG,
920 "Given column index is out of range.");
921 SysTryReturnResult(NID_IO, buffer != null, E_INVALID_ARG, "Null pointer was passed.");
922 SysTryReturnResult(NID_IO, size > 0, E_INVALID_ARG, "Invalid size was passed.");
923 SysTryReturnResult(NID_IO, __pDbEnumeratorCache != null, E_INVALID_STATE,
924 "The method has tried to fetch the column data of a result set that is not activated.");
925 SysTryReturnResult(NID_IO, __pDbEnumeratorCache->__pCurrentDbRow != null, E_SYSTEM,
926 "Result row is not activated.");
928 _DbColumn* pDbColumn = dynamic_cast < _DbColumn* >(__pDbEnumeratorCache->__pCurrentDbRow->dbValuesList.GetAt(columnIndex));
929 SysTryReturnResult(NID_IO, pDbColumn != null, E_SYSTEM, "The specified column at index %d is not found from the result set.", columnIndex);
930 SysTryReturnResult(NID_IO, pDbColumn->type == SQLITE_BLOB, E_TYPE_MISMATCH, "Trying to access column of different type.");
932 int blobLen = pDbColumn->size;
933 SysTryReturnResult(NID_IO, pDbColumn->pData != null, E_SYSTEM, "Data for specified column does not exist.");
935 const byte* pBlob = reinterpret_cast< const byte* >(pDbColumn->pData.get());
936 memcpy(buffer, pBlob, (blobLen < size) ? blobLen : size);
947 _DbEnumeratorImpl::GetDateTimeAt(int columnIndex, DateTime& value) const
949 SysTryReturnResult(NID_IO, __pEnum != null, E_INVALID_STATE,
950 "The Object is not constructed or the database is already been closed.");
951 SysTryReturnResult(NID_IO, columnIndex >= 0 && columnIndex < __columnCount, E_INVALID_ARG,
952 "Given column index is out of range.");
953 SysTryReturnResult(NID_IO, __pDbEnumeratorCache != null, E_INVALID_STATE,
954 "The method has tried to fetch the column data of a result set that is not activated.");
955 SysTryReturnResult(NID_IO, __pDbEnumeratorCache->__pCurrentDbRow != null, E_SYSTEM,
956 "Result row is not activated.");
958 _DbColumn* pDbColumn = dynamic_cast < _DbColumn* >(__pDbEnumeratorCache->__pCurrentDbRow->dbValuesList.GetAt(columnIndex));
959 SysTryReturnResult(NID_IO, pDbColumn != null, E_SYSTEM, "The specified column at index %d is not found from the result set.", columnIndex);
960 SysTryReturnResult(NID_IO, pDbColumn->type == SQLITE_TEXT, E_TYPE_MISMATCH, "Trying to access column of different type.");
961 SysTryReturnResult(NID_IO, pDbColumn->pData != null, E_SYSTEM, "Data for specified column does not exist.");
963 const char* pStr = const_cast< char* >(pDbColumn->pData.get());
965 result r = DateTime::Parse(pStr, value);
966 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] Propagating to caller...", GetErrorMessage(r));
972 _DbEnumeratorImpl::GetColumnCount(void) const
974 SysTryReturn(NID_IO, __pEnum != null, -1, E_INVALID_STATE,
975 "[E_INVALID_STATE] This instance has not been properly constructed yet or has already been finalized.");
976 SysTryReturn(NID_IO, __pDbEnumeratorCache != null, -1, E_INVALID_STATE,
977 "[E_INVALID_STATE] The method has tried to fetch the column data of a result set that is not activated.");
979 return __columnCount;
983 _DbEnumeratorImpl::GetColumnType(int columnIndex) const
985 DbColumnType type = DB_COLUMNTYPE_UNDEFINED;
987 SysTryReturn(NID_IO, __pEnum != null, DB_COLUMNTYPE_UNDEFINED, E_INVALID_STATE,
988 "[E_INVALID_STATE] This instance has not been properly constructed yet or has already been finalized.");
990 SysTryReturn(NID_IO, columnIndex >= 0 && columnIndex < __columnCount, DB_COLUMNTYPE_UNDEFINED, E_INVALID_ARG,
991 "[E_INVALID_ARG] Given column index is out of range.");
993 SysTryReturn(NID_IO, __pDbEnumeratorCache != null, DB_COLUMNTYPE_UNDEFINED, E_INVALID_STATE,
994 "[E_INVALID_STATE] The method has tried to fetch the column data of a result set that is not activated.");
996 if (__pDbEnumeratorCache->__pCurrentDbRow)
998 _DbColumn* pDbColumn = dynamic_cast < _DbColumn* >(__pDbEnumeratorCache->__pCurrentDbRow->dbValuesList.GetAt(columnIndex));
1001 SetLastResult(E_INVALID_STATE);
1002 return DB_COLUMNTYPE_UNDEFINED;
1004 switch (pDbColumn->type)
1006 case SQLITE_INTEGER:
1007 type = DB_COLUMNTYPE_INT;
1011 type = DB_COLUMNTYPE_DOUBLE;
1015 type = DB_COLUMNTYPE_TEXT;
1019 type = DB_COLUMNTYPE_BLOB;
1023 type = DB_COLUMNTYPE_NULL;
1027 SetLastResult(E_INVALID_STATE);
1036 _DbEnumeratorImpl::GetColumnName(int columnIndex) const
1038 SysTryReturn(NID_IO, __pEnum != null, null, E_INVALID_STATE,
1039 "[E_INVALID_STATE] This instance has not been properly constructed yet or has already been finalized.");
1041 SysTryReturn(NID_IO, columnIndex >= 0 && columnIndex < __columnCount, null, E_INVALID_ARG,
1042 "[E_INVALID_ARG] Given column index is out of range.");
1044 SysTryReturn(NID_IO, __pDbEnumeratorCache != null, null, E_INVALID_STATE,
1045 "[E_INVALID_STATE] The method has tried to fetch the column data of a result set that is not activated.");
1047 String* pString = dynamic_cast <String *> (__pDbEnumeratorCache->__dbColumnNameList.GetAt(columnIndex));
1051 SetLastResult(E_INVALID_STATE);
1055 return String(pString->GetPointer());
1059 _DbEnumeratorImpl::GetColumnSize(int columnIndex) const
1063 SysTryReturn(NID_IO, __pEnum != null, 0, E_INVALID_STATE,
1064 "[E_INVALID_STATE] This instance has not been properly constructed yet or has already been finalized.");
1066 SysTryReturn(NID_IO, columnIndex >= 0 && columnIndex < __columnCount, 0, E_INVALID_ARG,
1067 "[E_INVALID_ARG] Given column index is out of range.");
1069 SysTryReturn(NID_IO, __pDbEnumeratorCache != null, 0, E_INVALID_STATE,
1070 "[E_INVALID_STATE] The method has tried to fetch the column data of a result set that is not activated.");
1072 if (__pDbEnumeratorCache->__pCurrentDbRow)
1074 _DbColumn* pDbColumn = dynamic_cast < _DbColumn* >(__pDbEnumeratorCache->__pCurrentDbRow->dbValuesList.GetAt(columnIndex));
1077 SetLastResult(E_INVALID_STATE);
1080 int columnType = pDbColumn->type;
1084 case SQLITE_INTEGER:
1085 if (_AppInfo::IsOspCompat())
1087 bytes = sizeof(int); // for 2.0 compatibility
1091 bytes = sizeof(long long);
1096 bytes = sizeof(double);
1102 bytes = pDbColumn->size;
1106 SetLastResult(E_INVALID_STATE);
1115 _DbEnumeratorImpl::GetInstance(DbEnumerator& dbEnumerator)
1117 return dbEnumerator.__pDbEnumeratorImpl;
1120 const _DbEnumeratorImpl*
1121 _DbEnumeratorImpl::GetInstance(const DbEnumerator& dbEnumerator)
1123 return dbEnumerator.__pDbEnumeratorImpl;
1127 _DbEnumeratorImpl::CreateDbEnumeratorInstanceN(void)
1129 unique_ptr<DbEnumerator> pDbEnumerator(new (std::nothrow) DbEnumerator());
1130 SysTryReturn(NID_IO, pDbEnumerator != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
1131 return pDbEnumerator.release();