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_DataControlResultSetImpl.cpp
19 * @brief This is the implementation for the %_DataControlResultSetImpl class.
24 #include <sys/types.h>
26 #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 <FBaseResult.h>
35 #include <FIoDatabase.h>
36 #include <FIoDbEnumerator.h>
37 #include <FBaseColAllElementsDeleter.h>
38 #include <FBaseSysLog.h>
40 #include <FBase_StringConverter.h>
41 #include <FBase_NativeError.h>
42 #include <FApp_AppControlManager.h>
43 #include <FApp_AppArg.h>
44 #include <FIo_FileImpl.h>
45 #include <FIo_DataControlResultSetImpl.h>
47 using namespace Tizen::Base;
48 using namespace Tizen::Base::Utility;
49 using namespace Tizen::Base::Collection;
50 using namespace Tizen::App;
52 const char* _DATACONTROL_RESULT_DIR = "/tmp/osp/DataControlResult/\0";
54 namespace Tizen { namespace Io
57 static const int _DATACONTROL_PACKET_INDEX_COLUMNCOUNT = 1;
59 _DataControlResultSetImpl::_DataControlResultSetImpl(RequestId reqId)
69 _DataControlResultSetImpl::~_DataControlResultSetImpl(void)
71 __constructed = false;
75 // [sizeof(int)] row count
76 // [sizeof(int)] column count
77 // [sieeof(int)] total size of column names
80 // [sizeof(int)] column type x N
81 // [ variant ] column name x N
86 // [ varient ] content
88 _DataControlResultSetImpl::FillWith(IDbEnumerator* pDbEnum)
90 String tempFilePath(_DATACONTROL_RESULT_DIR);
96 String* pCount = null;
97 String* pColumnCount = null;
99 _DataControlRequestType requestType = _DATACONTROL_REQUEST_TYPE_UNDEFINED;
102 int totalSizeOfColumnTypes = 0;
103 int totalSizeOfColumnNames = 0;
104 int cursorOffset = 0;
106 int countPerPage = 0;
111 SysAssertf(__constructed == true, "Not yet constructed. Construct() should be called before use.\n\n");
113 _AppControlManager* pAppMgr = _AppControlManager::GetInstance();
114 SysTryReturnResult(NID_IO, pAppMgr, E_SYSTEM, "Failed to get instance.");
116 _ResultInfo* pResultInfo = pAppMgr->__resultManager.FindItem(static_cast< int >(__reqId)); // provider reqId
117 SysTryReturnResult(NID_IO, pResultInfo, E_OBJ_NOT_FOUND,
118 "The data control request specified with the req (%ld) did not exist.", __reqId);
120 const _AppArg& arg = pResultInfo->arg;
123 reqType = arg.GetValue(OSP_K_DATACONTROL_REQUEST_TYPE);
124 Integer::Parse(reqType, type);
125 requestType = static_cast< _DataControlRequestType >(type);
126 SysTryReturnResult(NID_IO, requestType == _DATACONTROL_REQUEST_TYPE_SQL_QUERY, E_INVALID_ARG,
127 "The reqId should be for the data control query request.");
129 appId = arg.GetCallerAppId();
130 callerReqId = arg.GetValue(OSP_K_REQUEST_ID);
132 // list-based request
133 std::unique_ptr< ArrayList, AllElementsDeleter > pList(_AppArg::GetListN(arg.GetBundle(), OSP_K_ARG));
134 SysTryReturnResult(NID_IO, pList, E_SYSTEM, "Invalid result object.");
136 pColumnCount = dynamic_cast< String* >(pList->GetAt(_DATACONTROL_PACKET_INDEX_COLUMNCOUNT));
137 SysTryReturnResult(NID_IO, pColumnCount, E_SYSTEM, "Invalid result object.");
138 Integer::Parse(*pColumnCount, columnCount);
140 pageNoIndex = _DATACONTROL_PACKET_INDEX_COLUMNCOUNT + columnCount + 2 + 1;
142 pNo = dynamic_cast< String* >(pList->GetAt(pageNoIndex));
143 SysTryReturnResult(NID_IO, pNo, E_SYSTEM, "Invalid result object.");
144 Integer::Parse(*pNo, pageNo);
146 pCount = dynamic_cast< String* >(pList->GetAt(pageNoIndex + 1));
147 SysTryReturnResult(NID_IO, pCount, E_SYSTEM, "Invalid result object.");
148 Integer::Parse(*pCount, countPerPage);
150 this->SetCapacity(pageNo, countPerPage);
151 tempFilePath.Append(appId);
152 tempFilePath.Append(callerReqId);
153 __tmpPath = tempFilePath;
154 SysSecureLog(NID_IO, "[DC_PROV_SEND] temp file path: %ls", tempFilePath.GetPointer());
157 r = pDbEnum->Reset();
158 SysTryReturnResult(NID_IO, r == E_SUCCESS, E_DATABASE,
159 "The database engine has failed to execute reset.");
161 cursorOffset = (__pageNo - 1) * __countPerPage;
162 for (i = 0; i < cursorOffset; i++) // move cursor to the specific page to be requested
164 r = pDbEnum->MoveNext();
165 if (r == E_OUT_OF_RANGE) // the previous pages do not exist
167 __result = E_OUT_OF_RANGE;
168 SysTryReturnResult(NID_IO, false, E_SUCCESS, "Out of range error.");
170 SysTryReturnResult(NID_IO, !IsFailed(r), E_DATABASE,
171 "The database engine has failed to enumerator result set.");
174 // XXX: must call MoveNext() before calling GetColumnCount()
175 r = pDbEnum->MoveNext();
176 if (r == E_OUT_OF_RANGE) // the specific page is empty
178 __result = E_OUT_OF_RANGE;
179 SysTryReturnResult(NID_IO, false, E_SUCCESS, "Out of range error.");
181 SysTryReturnResult(NID_IO, !IsFailed(r), E_DATABASE,
182 "The database engine has failed to enumerate the result set.");
184 // if has the result set
185 std::unique_ptr<File> pFile(new (std::nothrow) File());
187 SysTryReturnResult(NID_IO, pFile != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
189 r = pFile->Construct(__tmpPath, L"w+", true);
190 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] Failed to create temp file (%ls) for result set.",
191 GetErrorMessage(r), __tmpPath.GetPointer());
193 columnCount = pDbEnum->GetColumnCount();
194 SysSecureLog(NID_IO, "column count is %d.\n", columnCount);
196 r = pFile->Seek(FILESEEKPOSITION_BEGIN, sizeof(int));
197 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
199 r = pFile->Write(&columnCount, sizeof(int)); // pack column count
200 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
202 r = pFile->Seek(FILESEEKPOSITION_CURRENT, sizeof(int));
203 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
206 for (i = 0; i < columnCount; i++)
209 DbColumnType columnType = pDbEnum->GetColumnType(i);
212 case DB_COLUMNTYPE_INT:
214 type = 1; // int64 type
218 case DB_COLUMNTYPE_DOUBLE:
220 type = 2; // double type
224 case DB_COLUMNTYPE_TEXT:
226 type = 3; // text type
230 case DB_COLUMNTYPE_BLOB:
232 type = 4; // blob type
236 case DB_COLUMNTYPE_NULL:
238 type = 5; // null type
243 SysLog(NID_IO, "type: UNDEFINED (%d)", type);
246 r = pFile->Write(&type, sizeof(int));
247 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
249 totalSizeOfColumnTypes += sizeof(int);
251 //totalSizeOfColumnTypes = columnCount * sizeof(int);
253 totalSizeOfColumnNames = 0;
254 for (i = 0; i < columnCount; i++)
256 char* pColumnName = null;
259 columnName = pDbEnum->GetColumnName(i);
260 columnName.Append('\n');
261 r = pFile->Write(columnName);
262 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
264 pColumnName = _StringConverter::CopyToCharArrayN(columnName);
265 byte = strlen(pColumnName);
266 totalSizeOfColumnNames += byte;
268 SysSecureLog(NID_IO, "[%d] column name: %s", i, pColumnName);
269 delete[] pColumnName;
271 r = pFile->Seek(FILESEEKPOSITION_BEGIN, sizeof(int) * 2);
272 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
274 r = pFile->Write(&totalSizeOfColumnNames, sizeof(int)); // pack
275 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
277 r = pFile->Seek(FILESEEKPOSITION_CURRENT, totalSizeOfColumnTypes + totalSizeOfColumnNames);
278 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
282 for (i = 0; i < columnCount; i++)
284 DbColumnType columnType = pDbEnum->GetColumnType(i);
287 case DB_COLUMNTYPE_INT:
289 long long int64Value = 0;
290 int type = 1; // int64
293 r = pDbEnum->GetInt64At(i, int64Value);
294 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
296 size = sizeof(long long);
298 r = pFile->Write(&type, sizeof(int));
299 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
301 r = pFile->Write(&size, sizeof(int));
302 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
303 r = pFile->Write(&int64Value, sizeof(long long));
304 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
308 case DB_COLUMNTYPE_DOUBLE:
310 double doubleValue = 0;
311 int type = 2; // double
314 r = pDbEnum->GetDoubleAt(i, doubleValue);
315 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
317 size = sizeof(double);
319 r = pFile->Write(&type, sizeof(int));
320 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
322 r = pFile->Write(&size, sizeof(int));
323 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
325 r = pFile->Write(&doubleValue, sizeof(double));
326 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
330 case DB_COLUMNTYPE_TEXT:
333 int type = 3; // text
336 r = pDbEnum->GetStringAt(i, textValue);
337 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
339 std::unique_ptr<char[]> pContent(_StringConverter::CopyToCharArrayN(textValue));
340 size = strlen(pContent.get());
342 r = pFile->Write(&type, sizeof(int));
343 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
345 r = pFile->Write(&size, sizeof(int));
346 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
350 r = pFile->Write(pContent.get(), size);
351 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
356 case DB_COLUMNTYPE_BLOB: // XXX: need test !!
358 ByteBuffer blobValue;
359 int type = 4; // blob
362 size = pDbEnum->GetColumnSize(i);
363 r = blobValue.Construct(size);
364 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
366 r = pDbEnum->GetBlobAt(i, blobValue);
367 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
369 r = pFile->Write(&type, sizeof(int));
370 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
372 r = pFile->Write(&size, sizeof(int));
373 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
377 r = pFile->Write(blobValue);
378 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
383 case DB_COLUMNTYPE_NULL:
385 int type = 5; // null
388 r = pFile->Write(&type, sizeof(int));
389 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
391 r = pFile->Write(&size, sizeof(int));
392 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
397 SysTryReturnResult(NID_IO, false, E_DATABASE,
398 "The column type is invalid.");
404 while (pDbEnum->MoveNext() == E_SUCCESS && rowCount < __countPerPage);
406 SysLog(NID_IO, "row count is %d.\n", rowCount);
407 r = pFile->Seek(FILESEEKPOSITION_BEGIN, 0);
408 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
410 r = pFile->Write(&rowCount, sizeof(int)); // pack row count
411 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
417 _DataControlResultSetImpl::SetCapacity(int pageNo, int countPerPage)
419 result r = E_SUCCESS;
421 SysAssertf(__constructed == true, "Not yet constructed. Construct() should be called before use.\n\n");
424 __countPerPage = countPerPage;