Fix the boiler plate codes
[platform/framework/native/appfw.git] / src / io / FIo_DataControlResultSetImpl.cpp
1 //
2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
3 //
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
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
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.
15 //
16
17 /**
18  * @file        FIo_DataControlResultSetImpl.cpp
19  * @brief       This is the implementation for the %_DataControlResultSetImpl class.
20  */
21
22 #include <unistd.h>
23 #include <fcntl.h>
24 #include <sys/types.h>
25 #include <new>
26 #include <unique_ptr.h>
27
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>
39
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>
46
47 using namespace Tizen::Base;
48 using namespace Tizen::Base::Utility;
49 using namespace Tizen::Base::Collection;
50 using namespace Tizen::App;
51
52 const char* _DATACONTROL_RESULT_DIR = "/tmp/osp/DataControlResult/\0";
53
54 namespace Tizen { namespace Io
55 {
56
57 static const int _DATACONTROL_PACKET_INDEX_COLUMNCOUNT = 1;
58
59 _DataControlResultSetImpl::_DataControlResultSetImpl(RequestId reqId)
60         : __constructed(true)
61         , __pageNo(1)
62         , __countPerPage(0)
63         , __result(E_SUCCESS)
64         , __tmpPath(L"")
65         , __reqId(reqId)
66 {
67 }
68
69 _DataControlResultSetImpl::~_DataControlResultSetImpl(void)
70 {
71         __constructed = false;
72 }
73
74 // header
75 // [sizeof(int)] row count
76 // [sizeof(int)] column count
77 // [sieeof(int)] total size of column names
78 //
79 // column info.
80 // [sizeof(int)] column type x N
81 // [  variant  ] column name x N
82 //
83 // column elements
84 // [sizeof(int)] type
85 // [sizeof(int)] size
86 // [  varient  ] content
87 result
88 _DataControlResultSetImpl::FillWith(IDbEnumerator* pDbEnum)
89 {
90         String tempFilePath(_DATACONTROL_RESULT_DIR);
91         String columnName;
92         String appId;
93         String reqType;
94         String callerReqId;
95         String* pNo = null;
96         String* pCount = null;
97         String* pColumnCount = null;
98         result r = E_SUCCESS;
99         _DataControlRequestType requestType = _DATACONTROL_REQUEST_TYPE_UNDEFINED;
100         int columnCount = 0;
101         int rowCount = 0;
102         int totalSizeOfColumnTypes = 0;
103         int totalSizeOfColumnNames = 0;
104         int cursorOffset = 0;
105         int pageNo = 0;
106         int countPerPage = 0;
107         int type = 0;
108         int i = 0;
109         int pageNoIndex = 0;
110
111         SysAssertf(__constructed == true, "Not yet constructed. Construct() should be called before use.\n\n");
112
113         _AppControlManager* pAppMgr = _AppControlManager::GetInstance();
114         SysTryReturnResult(NID_IO, pAppMgr, E_SYSTEM, "Failed to get instance.");
115
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);
119
120         const _AppArg& arg = pResultInfo->arg;
121
122         // key-based request
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.");
128
129         appId = arg.GetCallerAppId();
130         callerReqId = arg.GetValue(OSP_K_REQUEST_ID);
131
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.");
135
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);
139
140         pageNoIndex = _DATACONTROL_PACKET_INDEX_COLUMNCOUNT + columnCount + 2 + 1;
141
142         pNo = dynamic_cast< String* >(pList->GetAt(pageNoIndex));
143         SysTryReturnResult(NID_IO, pNo, E_SYSTEM, "Invalid result object.");
144         Integer::Parse(*pNo, pageNo);
145
146         pCount = dynamic_cast< String* >(pList->GetAt(pageNoIndex + 1));
147         SysTryReturnResult(NID_IO, pCount, E_SYSTEM, "Invalid result object.");
148         Integer::Parse(*pCount, countPerPage);
149
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());
155
156         // initialize
157         r = pDbEnum->Reset();
158         SysTryReturnResult(NID_IO, r == E_SUCCESS, E_DATABASE,
159                         "The database engine has failed to execute reset.");
160
161         cursorOffset = (__pageNo - 1) * __countPerPage;
162         for (i = 0; i < cursorOffset; i++) // move cursor to the specific page to be requested
163         {
164                 r = pDbEnum->MoveNext();
165                 if (r == E_OUT_OF_RANGE) // the previous pages do not exist
166                 {
167                         __result = E_OUT_OF_RANGE;
168                         SysTryReturnResult(NID_IO, false, E_SUCCESS, "Out of range error.");
169                 }
170                 SysTryReturnResult(NID_IO, !IsFailed(r), E_DATABASE,
171                                    "The database engine has failed to enumerator result set.");
172         }
173
174         // XXX: must call MoveNext() before calling GetColumnCount()
175         r = pDbEnum->MoveNext();
176         if (r == E_OUT_OF_RANGE) // the specific page is empty
177         {
178                 __result = E_OUT_OF_RANGE;
179                 SysTryReturnResult(NID_IO, false, E_SUCCESS, "Out of range error.");
180         }
181         SysTryReturnResult(NID_IO, !IsFailed(r), E_DATABASE,
182                            "The database engine has failed to enumerate the result set.");
183
184         // if has the result set
185         std::unique_ptr<File> pFile(new (std::nothrow) File());
186
187         SysTryReturnResult(NID_IO, pFile != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
188
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());
192
193         columnCount = pDbEnum->GetColumnCount();
194         SysSecureLog(NID_IO, "column count is %d.\n", columnCount);
195
196         r = pFile->Seek(FILESEEKPOSITION_BEGIN, sizeof(int));
197         SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
198
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));
201
202         r = pFile->Seek(FILESEEKPOSITION_CURRENT, sizeof(int));
203         SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
204
205         // pack column type
206         for (i = 0; i < columnCount; i++)
207         {
208                 int type = -1;
209                 DbColumnType columnType = pDbEnum->GetColumnType(i);
210                 switch (columnType)
211                 {
212                 case DB_COLUMNTYPE_INT:
213                 {
214                         type = 1; // int64 type
215                         break;
216                 }
217
218                 case DB_COLUMNTYPE_DOUBLE:
219                 {
220                         type = 2; // double type
221                         break;
222                 }
223
224                 case DB_COLUMNTYPE_TEXT:
225                 {
226                         type = 3; // text type
227                         break;
228                 }
229
230                 case DB_COLUMNTYPE_BLOB:
231                 {
232                         type = 4; // blob type
233                         break;
234                 }
235
236                 case DB_COLUMNTYPE_NULL:
237                 {
238                         type = 5; // null type
239                         break;
240                 }
241
242                 default:
243                         SysLog(NID_IO, "type: UNDEFINED (%d)", type);
244                         break;
245                 }
246                 r = pFile->Write(&type, sizeof(int));
247                 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
248
249                 totalSizeOfColumnTypes += sizeof(int);
250         }
251         //totalSizeOfColumnTypes = columnCount * sizeof(int);
252
253         totalSizeOfColumnNames = 0;
254         for (i = 0; i < columnCount; i++)
255         {
256                 char* pColumnName = null;
257                 int byte = 0;
258
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));
263
264                 pColumnName = _StringConverter::CopyToCharArrayN(columnName);
265                 byte = strlen(pColumnName);
266                 totalSizeOfColumnNames += byte;
267
268                 SysSecureLog(NID_IO, "[%d] column name: %s", i, pColumnName);
269                 delete[] pColumnName;
270         }
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));
273
274         r = pFile->Write(&totalSizeOfColumnNames, sizeof(int)); // pack
275         SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
276
277         r = pFile->Seek(FILESEEKPOSITION_CURRENT, totalSizeOfColumnTypes + totalSizeOfColumnNames);
278         SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
279
280         do
281         {
282                 for (i = 0; i < columnCount; i++)
283                 {
284                         DbColumnType columnType = pDbEnum->GetColumnType(i);
285                         switch (columnType)
286                         {
287                         case DB_COLUMNTYPE_INT:
288                         {
289                                 long long int64Value = 0;
290                                 int type = 1; // int64
291                                 int size = 0;
292
293                                 r = pDbEnum->GetInt64At(i, int64Value);
294                                 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
295
296                                 size = sizeof(long long);
297
298                                 r = pFile->Write(&type, sizeof(int));
299                                 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
300
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));
305                                 break;
306                         }
307
308                         case DB_COLUMNTYPE_DOUBLE:
309                         {
310                                 double doubleValue = 0;
311                                 int type = 2; // double
312                                 int size = 0;
313
314                                 r = pDbEnum->GetDoubleAt(i, doubleValue);
315                                 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
316
317                                 size = sizeof(double);
318
319                                 r = pFile->Write(&type, sizeof(int));
320                                 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
321
322                                 r = pFile->Write(&size, sizeof(int));
323                                 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
324
325                                 r = pFile->Write(&doubleValue, sizeof(double));
326                                 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
327                                 break;
328                         }
329
330                         case DB_COLUMNTYPE_TEXT:
331                         {
332                                 String textValue;
333                                 int type = 3; // text
334                                 int size = 0;
335
336                                 r = pDbEnum->GetStringAt(i, textValue);
337                                 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
338
339                                 std::unique_ptr<char[]> pContent(_StringConverter::CopyToCharArrayN(textValue));
340                                 size = strlen(pContent.get());
341
342                                 r = pFile->Write(&type, sizeof(int));
343                                 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
344
345                                 r = pFile->Write(&size, sizeof(int));
346                                 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
347
348                                 if (size > 0)
349                                 {
350                                         r = pFile->Write(pContent.get(), size);
351                                         SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
352                                 }
353                                 break;
354                         }
355
356                         case DB_COLUMNTYPE_BLOB: // XXX: need test !!
357                         {
358                                 ByteBuffer blobValue;
359                                 int type = 4; // blob
360                                 int size = 0;
361
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));
365
366                                 r = pDbEnum->GetBlobAt(i, blobValue);
367                                 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
368
369                                 r = pFile->Write(&type, sizeof(int));
370                                 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
371
372                                 r = pFile->Write(&size, sizeof(int));
373                                 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
374
375                                 if (size > 0)
376                                 {
377                                         r = pFile->Write(blobValue);
378                                         SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
379                                 }
380                                 break;
381                         }
382
383                         case DB_COLUMNTYPE_NULL:
384                         {
385                                 int type = 5; // null
386                                 int size = 0;
387
388                                 r = pFile->Write(&type, sizeof(int));
389                                 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
390
391                                 r = pFile->Write(&size, sizeof(int));
392                                 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] System error was occurred.", GetErrorMessage(r));
393                                 break;
394                         }
395
396                         default:
397                                 SysTryReturnResult(NID_IO, false, E_DATABASE,
398                                                    "The column type is invalid.");
399                                 break;
400                         }
401                 }
402                 rowCount++;
403         }
404         while (pDbEnum->MoveNext() == E_SUCCESS && rowCount < __countPerPage);
405
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));
409
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));
412
413         return r;
414 }
415
416 result
417 _DataControlResultSetImpl::SetCapacity(int pageNo, int countPerPage)
418 {
419         result r = E_SUCCESS;
420
421         SysAssertf(__constructed == true, "Not yet constructed. Construct() should be called before use.\n\n");
422
423         __pageNo = pageNo;
424         __countPerPage = countPerPage;
425
426         return r;
427 }
428
429 }} // Tizen::Io
430