2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
9 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 * @file FIo_DataControlResultSetImpl.cpp
20 * @brief This is the implementation for the %_DataControlResultSetImpl class.
25 #include <sys/types.h>
27 #include <unique_ptr.h>
29 #include <FBaseInteger.h>
30 #include <FBaseDouble.h>
31 #include <FBaseString.h>
32 #include <FBaseByteBuffer.h>
33 #include <FBaseDateTime.h>
34 #include <FBaseUtilStringUtil.h>
35 #include <FBaseResult.h>
36 #include <FIoDatabase.h>
37 #include <FIoDbEnumerator.h>
38 #include <FBaseColAllElementsDeleter.h>
39 #include <FBaseSysLog.h>
41 #include <FBase_StringConverter.h>
42 #include <FBase_NativeError.h>
43 #include <FApp_AppControlManager.h>
44 #include <FApp_AppArg.h>
45 #include <FIo_FileImpl.h>
46 #include <FIo_DataControlResultSetImpl.h>
48 using namespace Tizen::Base;
49 using namespace Tizen::Base::Utility;
50 using namespace Tizen::Base::Collection;
51 using namespace Tizen::App;
53 const char* _DATACONTROL_RESULTSET_DIR = "/tmp/osp/DataControlResultSet/\0";
55 namespace Tizen { namespace Io
58 _DataControlResultSetImpl::_DataControlResultSetImpl(RequestId reqId)
68 _DataControlResultSetImpl::~_DataControlResultSetImpl(void)
70 __constructed = false;
74 // [sizeof(int)] row count
75 // [sizeof(int)] column count
76 // [sieeof(int)] total size of column names
79 // [sizeof(int)] column type x N
80 // [ variant ] column name x N
85 // [ varient ] content
87 _DataControlResultSetImpl::FillWith(IDbEnumerator* pDbEnum)
89 String tempFilePath(_DATACONTROL_RESULTSET_DIR);
91 String* pAppId = null;
92 String* pRequestType = null;
93 String* pReqId = null;
95 String* pCount = null;
96 String* pColumnCount = null;
98 _DataControlRequestType requestType = _DATACONTROL_REQUEST_TYPE_UNDEFINED;
101 int totalSizeOfColumnTypes = 0;
102 int totalSizeOfColumnNames = 0;
103 int cursorOffset = 0;
105 int countPerPage = 0;
110 SysAssertf(__constructed == true, "Not yet constructed. Construct() should be called before use.\n\n");
112 _AppControlManager* pAppMgr = _AppControlManager::GetInstance();
113 SysTryReturnResult(NID_APP, pAppMgr, E_SYSTEM, "Failed to get instance.");
115 _ResultInfo* pResultInfo = pAppMgr->__resultManager.FindItem(static_cast< int >(__reqId));
116 SysTryReturnResult(NID_APP, pResultInfo, E_OBJ_NOT_FOUND,
117 "The data control request specified with the reqId (%ld) did not exist.", __reqId);
119 const _AppArg& arg = pResultInfo->arg;
121 std::unique_ptr<ArrayList, AllElementsDeleter> pList(arg.GetArgListN(0));
122 SysTryReturnResult(NID_APP, pList, E_SYSTEM, "Invalid result object.");
125 pAppId = dynamic_cast< String* >(pList->GetAt(0)); // key[0]
126 SysTryReturnResult(NID_APP, pAppId, E_SYSTEM, "Invalid request.");
128 pRequestType = dynamic_cast< String* >(pList->GetAt(1)); // key[1]
129 SysTryReturnResult(NID_APP, pRequestType, E_SYSTEM, "Invalid request.");
130 Integer::Parse(*pRequestType, type);
131 requestType = static_cast< _DataControlRequestType >(type);
132 SysTryReturnResult(NID_APP, requestType == _DATACONTROL_REQUEST_TYPE_SQL_QUERY, E_INVALID_ARG,
133 "The reqId should be for the data control query request.");
135 pReqId = dynamic_cast< String* >(pList->GetAt(2)); // key[2]
136 SysTryReturnResult(NID_APP, pReqId, E_SYSTEM, "Invalid request.");
138 // list-based request
139 pColumnCount = dynamic_cast< String* >(pList->GetAt(5));
140 SysTryReturnResult(NID_APP, pColumnCount, E_SYSTEM, "Invalid result object.");
141 Integer::Parse(*pColumnCount, columnCount);
143 pageNoIndex = 5 + columnCount + 2 + 1;
145 pNo = dynamic_cast< String* >(pList->GetAt(pageNoIndex));
146 SysTryReturnResult(NID_APP, pNo, E_SYSTEM, "Invalid result object.");
147 Integer::Parse(*pNo, pageNo);
149 pCount = dynamic_cast< String* >(pList->GetAt(pageNoIndex + 1));
150 SysTryReturnResult(NID_APP, pCount, E_SYSTEM, "Invalid result object.");
151 Integer::Parse(*pCount, countPerPage);
153 this->SetCapacity(pageNo, countPerPage);
154 tempFilePath.Append(*pAppId);
155 tempFilePath.Append(*pReqId);
156 __tmpPath = tempFilePath;
159 r = pDbEnum->Reset();
160 SysTryReturnResult(NID_IO, r == E_SUCCESS, E_DATABASE,
161 "The database engine has failed to execute reset.");
163 cursorOffset = (__pageNo - 1) * __countPerPage;
164 for (i = 0; i < cursorOffset; i++) // move cursor to the specific page to be requested
166 r = pDbEnum->MoveNext();
167 if (r == E_OUT_OF_RANGE) // the previous pages do not exist
169 __result = E_OUT_OF_RANGE;
170 SysTryReturnResult(NID_APP, false, E_SUCCESS, "Out of range error.");
172 SysTryReturnResult(NID_IO, !IsFailed(r), E_DATABASE,
173 "The database engine has failed to enumerator result set.");
176 // XXX: must call MoveNext() before calling GetColumnCount()
177 r = pDbEnum->MoveNext();
178 if (r == E_OUT_OF_RANGE) // the specific page is empty
180 __result = E_OUT_OF_RANGE;
181 SysTryReturnResult(NID_APP, false, E_SUCCESS, "Out of range error.");
183 SysTryReturnResult(NID_IO, !IsFailed(r), E_DATABASE,
184 "The database engine has failed to enumerate the result set.");
186 // if has the result set
187 std::unique_ptr<File> pFile(new (std::nothrow) File());
189 SysTryReturnResult(NID_IO, pFile != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
191 r = pFile->Construct(__tmpPath, "w+", true);
192 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] Failed to create temp file (%ls) for result set.",
193 GetErrorMessage(r), __tmpPath.GetPointer());
195 columnCount = pDbEnum->GetColumnCount();
196 SysLog(NID_IO, "column count is %d.\n", columnCount);
198 r = pFile->Seek(FILESEEKPOSITION_BEGIN, sizeof(int));
199 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
201 r = pFile->Write(&columnCount, sizeof(int)); // pack column count
202 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
204 r = pFile->Seek(FILESEEKPOSITION_CURRENT, sizeof(int));
205 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
208 for (i = 0; i < columnCount; i++)
211 DbColumnType columnType = pDbEnum->GetColumnType(i);
214 case DB_COLUMNTYPE_INT:
216 type = 1; // int64 type
220 case DB_COLUMNTYPE_DOUBLE:
222 type = 2; // double type
226 case DB_COLUMNTYPE_TEXT:
228 type = 3; // text type
232 case DB_COLUMNTYPE_BLOB:
234 type = 4; // blob type
239 SysLog(NID_IO, "type: UNDEFINDE (%d)", type);
242 r = pFile->Write(&type, sizeof(int));
243 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
245 totalSizeOfColumnTypes += sizeof(int);
247 //totalSizeOfColumnTypes = columnCount * sizeof(int);
249 totalSizeOfColumnNames = 0;
250 for (i = 0; i < columnCount; i++)
252 char* pColumnName = null;
255 columnName = pDbEnum->GetColumnName(i);
256 columnName.Append('\n');
257 r = pFile->Write(columnName);
258 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
260 pColumnName = _StringConverter::CopyToCharArrayN(columnName);
261 byte = strlen(pColumnName);
262 totalSizeOfColumnNames += byte;
264 SysLog(NID_IO, "[%d] column name: %s", i, pColumnName);
265 delete[] pColumnName;
267 r = pFile->Seek(FILESEEKPOSITION_BEGIN, sizeof(int) * 2);
268 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
270 r = pFile->Write(&totalSizeOfColumnNames, sizeof(int)); // pack
271 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
273 r = pFile->Seek(FILESEEKPOSITION_CURRENT, totalSizeOfColumnTypes + totalSizeOfColumnNames);
274 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
278 for (i = 0; i < columnCount; i++)
280 DbColumnType columnType = pDbEnum->GetColumnType(i);
283 case DB_COLUMNTYPE_INT:
285 long long int64Value = 0;
286 int type = 1; // int64
289 r = pDbEnum->GetInt64At(i, int64Value);
290 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
292 size = sizeof(long long);
294 r = pFile->Write(&type, sizeof(int));
295 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
297 r = pFile->Write(&size, sizeof(int));
298 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
300 r = pFile->Write(&int64Value, sizeof(long long));
301 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
305 case DB_COLUMNTYPE_DOUBLE:
307 double doubleValue = 0;
308 int type = 2; // double
311 r = pDbEnum->GetDoubleAt(i, doubleValue);
312 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
314 size = sizeof(double);
316 r = pFile->Write(&type, sizeof(int));
317 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
319 r = pFile->Write(&size, sizeof(int));
320 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
322 r = pFile->Write(&doubleValue, sizeof(double));
323 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
327 case DB_COLUMNTYPE_TEXT:
330 int type = 3; // text
333 r = pDbEnum->GetStringAt(i, textValue);
334 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
336 std::unique_ptr<char[]> pContent(_StringConverter::CopyToCharArrayN(textValue));
337 size = strlen(pContent.get());
339 r = pFile->Write(&type, sizeof(int));
340 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
342 r = pFile->Write(&size, sizeof(int));
343 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
345 r = pFile->Write(pContent.get(), size);
346 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
351 case DB_COLUMNTYPE_BLOB: // XXX: need test !!
353 ByteBuffer blobValue;
354 int type = 4; // blob
357 size = pDbEnum->GetColumnSize(i);
358 r = blobValue.Construct(size);
359 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
361 r = pDbEnum->GetBlobAt(i, blobValue);
362 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
364 r = pFile->Write(&type, sizeof(int));
365 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
367 r = pFile->Write(&size, sizeof(int));
368 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
370 r = pFile->Write(blobValue);
371 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
376 SysTryReturnResult(NID_IO, false, E_DATABASE,
377 "The column type is invalid.");
383 while (pDbEnum->MoveNext() == E_SUCCESS && rowCount < __countPerPage);
385 SysLog(NID_IO, "row count is %d.\n", rowCount);
386 r = pFile->Seek(FILESEEKPOSITION_BEGIN, 0);
387 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
389 r = pFile->Write(&rowCount, sizeof(int)); // pack row count
390 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
396 _DataControlResultSetImpl::SetCapacity(int pageNo, int countPerPage)
398 result r = E_SUCCESS;
400 SysAssertf(__constructed == true, "Not yet constructed. Construct() should be called before use.\n\n");
403 __countPerPage = countPerPage;