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
238 case DB_COLUMNTYPE_NULL:
240 type = 5; // null type
245 SysLog(NID_IO, "type: UNDEFINED (%d)", type);
248 r = pFile->Write(&type, sizeof(int));
249 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
251 totalSizeOfColumnTypes += sizeof(int);
253 //totalSizeOfColumnTypes = columnCount * sizeof(int);
255 totalSizeOfColumnNames = 0;
256 for (i = 0; i < columnCount; i++)
258 char* pColumnName = null;
261 columnName = pDbEnum->GetColumnName(i);
262 columnName.Append('\n');
263 r = pFile->Write(columnName);
264 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
266 pColumnName = _StringConverter::CopyToCharArrayN(columnName);
267 byte = strlen(pColumnName);
268 totalSizeOfColumnNames += byte;
270 SysLog(NID_IO, "[%d] column name: %s", i, pColumnName);
271 delete[] pColumnName;
273 r = pFile->Seek(FILESEEKPOSITION_BEGIN, sizeof(int) * 2);
274 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
276 r = pFile->Write(&totalSizeOfColumnNames, sizeof(int)); // pack
277 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
279 r = pFile->Seek(FILESEEKPOSITION_CURRENT, totalSizeOfColumnTypes + totalSizeOfColumnNames);
280 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
284 for (i = 0; i < columnCount; i++)
286 DbColumnType columnType = pDbEnum->GetColumnType(i);
289 case DB_COLUMNTYPE_INT:
291 long long int64Value = 0;
292 int type = 1; // int64
295 r = pDbEnum->GetInt64At(i, int64Value);
296 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
298 size = sizeof(long long);
300 r = pFile->Write(&type, sizeof(int));
301 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
303 r = pFile->Write(&size, sizeof(int));
304 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
305 r = pFile->Write(&int64Value, sizeof(long long));
306 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
310 case DB_COLUMNTYPE_DOUBLE:
312 double doubleValue = 0;
313 int type = 2; // double
316 r = pDbEnum->GetDoubleAt(i, doubleValue);
317 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
319 size = sizeof(double);
321 r = pFile->Write(&type, sizeof(int));
322 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
324 r = pFile->Write(&size, sizeof(int));
325 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
327 r = pFile->Write(&doubleValue, sizeof(double));
328 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
332 case DB_COLUMNTYPE_TEXT:
335 int type = 3; // text
338 r = pDbEnum->GetStringAt(i, textValue);
339 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
341 std::unique_ptr<char[]> pContent(_StringConverter::CopyToCharArrayN(textValue));
342 size = strlen(pContent.get());
344 r = pFile->Write(&type, sizeof(int));
345 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
347 r = pFile->Write(&size, sizeof(int));
348 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
352 r = pFile->Write(pContent.get(), size);
353 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
358 case DB_COLUMNTYPE_BLOB: // XXX: need test !!
360 ByteBuffer blobValue;
361 int type = 4; // blob
364 size = pDbEnum->GetColumnSize(i);
365 r = blobValue.Construct(size);
366 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
368 r = pDbEnum->GetBlobAt(i, blobValue);
369 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
371 r = pFile->Write(&type, sizeof(int));
372 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
374 r = pFile->Write(&size, sizeof(int));
375 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
379 r = pFile->Write(blobValue);
380 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
385 case DB_COLUMNTYPE_NULL:
387 int type = 5; // null
390 r = pFile->Write(&type, sizeof(int));
391 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
393 r = pFile->Write(&size, sizeof(int));
394 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
399 SysTryReturnResult(NID_IO, false, E_DATABASE,
400 "The column type is invalid.");
406 while (pDbEnum->MoveNext() == E_SUCCESS && rowCount < __countPerPage);
408 SysLog(NID_IO, "row count is %d.\n", rowCount);
409 r = pFile->Seek(FILESEEKPOSITION_BEGIN, 0);
410 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
412 r = pFile->Write(&rowCount, sizeof(int)); // pack row count
413 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
419 _DataControlResultSetImpl::SetCapacity(int pageNo, int countPerPage)
421 result r = E_SUCCESS;
423 SysAssertf(__constructed == true, "Not yet constructed. Construct() should be called before use.\n\n");
426 __countPerPage = countPerPage;