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 static const int _DATACONTROL_PACKET_INDEX_COLUMNCOUNT = 1;
60 _DataControlResultSetImpl::_DataControlResultSetImpl(RequestId reqId)
70 _DataControlResultSetImpl::~_DataControlResultSetImpl(void)
72 __constructed = false;
76 // [sizeof(int)] row count
77 // [sizeof(int)] column count
78 // [sieeof(int)] total size of column names
81 // [sizeof(int)] column type x N
82 // [ variant ] column name x N
87 // [ varient ] content
89 _DataControlResultSetImpl::FillWith(IDbEnumerator* pDbEnum)
91 String tempFilePath(_DATACONTROL_RESULTSET_DIR);
97 String* pCount = null;
98 String* pColumnCount = null;
100 _DataControlRequestType requestType = _DATACONTROL_REQUEST_TYPE_UNDEFINED;
103 int totalSizeOfColumnTypes = 0;
104 int totalSizeOfColumnNames = 0;
105 int cursorOffset = 0;
107 int countPerPage = 0;
112 SysAssertf(__constructed == true, "Not yet constructed. Construct() should be called before use.\n\n");
114 _AppControlManager* pAppMgr = _AppControlManager::GetInstance();
115 SysTryReturnResult(NID_IO, pAppMgr, E_SYSTEM, "Failed to get instance.");
117 _ResultInfo* pResultInfo = pAppMgr->__resultManager.FindItem(static_cast< int >(__reqId)); // provider reqId
118 SysTryReturnResult(NID_IO, pResultInfo, E_OBJ_NOT_FOUND,
119 "The data control request specified with the req (%ld) did not exist.", __reqId);
121 const _AppArg& arg = pResultInfo->arg;
124 reqType = arg.GetValue(OSP_K_DATACONTROL_REQUEST_TYPE);
125 Integer::Parse(reqType, type);
126 requestType = static_cast< _DataControlRequestType >(type);
127 SysTryReturnResult(NID_IO, requestType == _DATACONTROL_REQUEST_TYPE_SQL_QUERY, E_INVALID_ARG,
128 "The reqId should be for the data control query request.");
130 appId = arg.GetCallerAppId();
131 callerReqId = arg.GetValue(OSP_K_REQUEST_ID);
133 // list-based request
134 std::unique_ptr< ArrayList, AllElementsDeleter > pList(_AppArg::GetListN(arg.GetBundle(), OSP_K_ARG));
135 SysTryReturnResult(NID_IO, pList, E_SYSTEM, "Invalid result object.");
137 pColumnCount = dynamic_cast< String* >(pList->GetAt(_DATACONTROL_PACKET_INDEX_COLUMNCOUNT));
138 SysTryReturnResult(NID_IO, pColumnCount, E_SYSTEM, "Invalid result object.");
139 Integer::Parse(*pColumnCount, columnCount);
141 pageNoIndex = _DATACONTROL_PACKET_INDEX_COLUMNCOUNT + columnCount + 2 + 1;
143 pNo = dynamic_cast< String* >(pList->GetAt(pageNoIndex));
144 SysTryReturnResult(NID_IO, pNo, E_SYSTEM, "Invalid result object.");
145 Integer::Parse(*pNo, pageNo);
147 pCount = dynamic_cast< String* >(pList->GetAt(pageNoIndex + 1));
148 SysTryReturnResult(NID_IO, pCount, E_SYSTEM, "Invalid result object.");
149 Integer::Parse(*pCount, countPerPage);
151 this->SetCapacity(pageNo, countPerPage);
152 tempFilePath.Append(appId);
153 tempFilePath.Append(callerReqId);
154 __tmpPath = tempFilePath;
155 SysSecureLog(NID_IO, "[DC_PROV_SEND] temp file path: %ls", tempFilePath.GetPointer());
158 r = pDbEnum->Reset();
159 SysTryReturnResult(NID_IO, r == E_SUCCESS, E_DATABASE,
160 "The database engine has failed to execute reset.");
162 cursorOffset = (__pageNo - 1) * __countPerPage;
163 for (i = 0; i < cursorOffset; i++) // move cursor to the specific page to be requested
165 r = pDbEnum->MoveNext();
166 if (r == E_OUT_OF_RANGE) // the previous pages do not exist
168 __result = E_OUT_OF_RANGE;
169 SysTryReturnResult(NID_IO, false, E_SUCCESS, "Out of range error.");
171 SysTryReturnResult(NID_IO, !IsFailed(r), E_DATABASE,
172 "The database engine has failed to enumerator result set.");
175 // XXX: must call MoveNext() before calling GetColumnCount()
176 r = pDbEnum->MoveNext();
177 if (r == E_OUT_OF_RANGE) // the specific page is empty
179 __result = E_OUT_OF_RANGE;
180 SysTryReturnResult(NID_IO, false, E_SUCCESS, "Out of range error.");
182 SysTryReturnResult(NID_IO, !IsFailed(r), E_DATABASE,
183 "The database engine has failed to enumerate the result set.");
185 // if has the result set
186 std::unique_ptr<File> pFile(new (std::nothrow) File());
188 SysTryReturnResult(NID_IO, pFile != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
190 r = pFile->Construct(__tmpPath, L"w+", true);
191 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] Failed to create temp file (%ls) for result set.",
192 GetErrorMessage(r), __tmpPath.GetPointer());
194 columnCount = pDbEnum->GetColumnCount();
195 SysSecureLog(NID_IO, "column count is %d.\n", columnCount);
197 r = pFile->Seek(FILESEEKPOSITION_BEGIN, sizeof(int));
198 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
200 r = pFile->Write(&columnCount, sizeof(int)); // pack column count
201 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
203 r = pFile->Seek(FILESEEKPOSITION_CURRENT, sizeof(int));
204 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
207 for (i = 0; i < columnCount; i++)
210 DbColumnType columnType = pDbEnum->GetColumnType(i);
213 case DB_COLUMNTYPE_INT:
215 type = 1; // int64 type
219 case DB_COLUMNTYPE_DOUBLE:
221 type = 2; // double type
225 case DB_COLUMNTYPE_TEXT:
227 type = 3; // text type
231 case DB_COLUMNTYPE_BLOB:
233 type = 4; // blob type
237 case DB_COLUMNTYPE_NULL:
239 type = 5; // null type
244 SysLog(NID_IO, "type: UNDEFINED (%d)", type);
247 r = pFile->Write(&type, sizeof(int));
248 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
250 totalSizeOfColumnTypes += sizeof(int);
252 //totalSizeOfColumnTypes = columnCount * sizeof(int);
254 totalSizeOfColumnNames = 0;
255 for (i = 0; i < columnCount; i++)
257 char* pColumnName = null;
260 columnName = pDbEnum->GetColumnName(i);
261 columnName.Append('\n');
262 r = pFile->Write(columnName);
263 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
265 pColumnName = _StringConverter::CopyToCharArrayN(columnName);
266 byte = strlen(pColumnName);
267 totalSizeOfColumnNames += byte;
269 SysSecureLog(NID_IO, "[%d] column name: %s", i, pColumnName);
270 delete[] pColumnName;
272 r = pFile->Seek(FILESEEKPOSITION_BEGIN, sizeof(int) * 2);
273 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
275 r = pFile->Write(&totalSizeOfColumnNames, sizeof(int)); // pack
276 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
278 r = pFile->Seek(FILESEEKPOSITION_CURRENT, totalSizeOfColumnTypes + totalSizeOfColumnNames);
279 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
283 for (i = 0; i < columnCount; i++)
285 DbColumnType columnType = pDbEnum->GetColumnType(i);
288 case DB_COLUMNTYPE_INT:
290 long long int64Value = 0;
291 int type = 1; // int64
294 r = pDbEnum->GetInt64At(i, int64Value);
295 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
297 size = sizeof(long long);
299 r = pFile->Write(&type, sizeof(int));
300 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
302 r = pFile->Write(&size, sizeof(int));
303 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
304 r = pFile->Write(&int64Value, sizeof(long long));
305 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
309 case DB_COLUMNTYPE_DOUBLE:
311 double doubleValue = 0;
312 int type = 2; // double
315 r = pDbEnum->GetDoubleAt(i, doubleValue);
316 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
318 size = sizeof(double);
320 r = pFile->Write(&type, sizeof(int));
321 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
323 r = pFile->Write(&size, sizeof(int));
324 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
326 r = pFile->Write(&doubleValue, sizeof(double));
327 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
331 case DB_COLUMNTYPE_TEXT:
334 int type = 3; // text
337 r = pDbEnum->GetStringAt(i, textValue);
338 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
340 std::unique_ptr<char[]> pContent(_StringConverter::CopyToCharArrayN(textValue));
341 size = strlen(pContent.get());
343 r = pFile->Write(&type, sizeof(int));
344 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
346 r = pFile->Write(&size, sizeof(int));
347 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
351 r = pFile->Write(pContent.get(), size);
352 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
357 case DB_COLUMNTYPE_BLOB: // XXX: need test !!
359 ByteBuffer blobValue;
360 int type = 4; // blob
363 size = pDbEnum->GetColumnSize(i);
364 r = blobValue.Construct(size);
365 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
367 r = pDbEnum->GetBlobAt(i, blobValue);
368 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
370 r = pFile->Write(&type, sizeof(int));
371 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
373 r = pFile->Write(&size, sizeof(int));
374 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
378 r = pFile->Write(blobValue);
379 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
384 case DB_COLUMNTYPE_NULL:
386 int type = 5; // null
389 r = pFile->Write(&type, sizeof(int));
390 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
392 r = pFile->Write(&size, sizeof(int));
393 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
398 SysTryReturnResult(NID_IO, false, E_DATABASE,
399 "The column type is invalid.");
405 while (pDbEnum->MoveNext() == E_SUCCESS && rowCount < __countPerPage);
407 SysLog(NID_IO, "row count is %d.\n", rowCount);
408 r = pFile->Seek(FILESEEKPOSITION_BEGIN, 0);
409 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
411 r = pFile->Write(&rowCount, sizeof(int)); // pack row count
412 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
418 _DataControlResultSetImpl::SetCapacity(int pageNo, int countPerPage)
420 result r = E_SUCCESS;
422 SysAssertf(__constructed == true, "Not yet constructed. Construct() should be called before use.\n\n");
425 __countPerPage = countPerPage;