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 FApp_SqlDataControlImpl.cpp
19 * @brief This is the implementation for the %_SqlDataControlImpl class.
23 #include <unique_ptr.h>
25 #include <appsvc/appsvc.h>
27 #include <FBaseInteger.h>
28 #include <FBaseString.h>
29 #include <FBaseLongLong.h>
30 #include <FBaseColLinkedList.h>
31 #include <FBaseColIList.h>
32 #include <FBaseColIMap.h>
33 #include <FBaseColIMapEnumerator.h>
34 #include <FBaseRtIEventArg.h>
35 #include <FBaseSysLog.h>
38 #include <FAppSqlDataControl.h>
39 #include <FAppISqlDataControlResponseListener.h>
41 #include <FBase_StringConverter.h>
42 #include <FIo_DataControlResultSetEnumerator.h>
44 #include "FApp_AppControlManager.h"
45 #include "FApp_SqlDataControlImpl.h"
46 #include "FApp_AppArg.h"
47 #include "FApp_DataControlManager.h"
48 #include "FAppPkg_PackageManagerImpl.h"
50 #define DATACONTROL_PROTOCOL_VER_2_1_0_2 // ver_2.1.0.2
51 #define DATACONTROL_PROTOCOL_VER_2_1_0_3 // ver_2.1.0.3
55 using namespace Tizen::Base;
56 using namespace Tizen::Base::Collection;
57 using namespace Tizen::Base::Runtime;
58 using namespace Tizen::Io;
59 using namespace Tizen::App;
60 using namespace Tizen::App::Package;
62 namespace Tizen { namespace App
65 static const int MAX_REQUEST_COUNT = 128;
66 static const int REQUEST_THRESHOLD = 100;
67 static const int _MAX_ARGUMENT_SIZE = 16384; // 16KB
68 static const int _MAX_REQUEST_ARGUMENT_SIZE = 1048576; // 1MB
69 //static const char* _DATACONTROL_REQUEST_DIR = "/tmp/osp/DataControlRequest/\0";
70 static const char* _DATACONTROL_REQUEST_DIR = "/tmp/osp/data-control/request/\0";
72 class _SqlDataControlEventArg
76 _SqlDataControlEventArg(_DataControlRequestType requestType, RequestId reqId, String providerId, String dataId,
77 _DataControlResultSetEnumerator* pResultSetEnum, long long insertRowId, bool providerResult, String* pErrorMsg)
78 : __requestType(requestType)
80 , __providerId(providerId)
82 , __pResultSetEnum(pResultSetEnum)
83 , __insertRowId(insertRowId)
84 , __providerResult(providerResult)
85 , __pErrorMsg(pErrorMsg)
88 ~_SqlDataControlEventArg(void)
90 delete __pResultSetEnum;
94 _DataControlRequestType __requestType;
98 _DataControlResultSetEnumerator* __pResultSetEnum;
99 long long __insertRowId;
100 bool __providerResult;
104 class _SqlDataControlEvent
108 virtual void FireImpl(IEventListener& listener, const IEventArg& arg);
112 _SqlDataControlEvent::FireImpl(IEventListener& listener, const IEventArg& arg)
114 const _SqlDataControlEventArg* pArg = dynamic_cast<const _SqlDataControlEventArg*>(&arg);
117 ISqlDataControlResponseListener* pListener = dynamic_cast<ISqlDataControlResponseListener*> (&listener);
118 if (pListener != null)
120 switch (pArg->__requestType)
122 case _DATACONTROL_REQUEST_TYPE_SQL_QUERY:
123 pListener->OnSqlDataControlSelectResponseReceived(pArg->__reqId, pArg->__providerId, pArg->__dataId,
124 *(pArg->__pResultSetEnum), pArg->__providerResult, pArg->__pErrorMsg);
126 case _DATACONTROL_REQUEST_TYPE_SQL_INSERT:
127 pListener->OnSqlDataControlInsertResponseReceived(pArg->__reqId, pArg->__providerId, pArg->__dataId,
128 pArg->__insertRowId, pArg->__providerResult, pArg->__pErrorMsg);
130 case _DATACONTROL_REQUEST_TYPE_SQL_UPDATE:
131 pListener->OnSqlDataControlUpdateResponseReceived(pArg->__reqId, pArg->__providerId, pArg->__dataId,
132 pArg->__providerResult, pArg->__pErrorMsg);
134 case _DATACONTROL_REQUEST_TYPE_SQL_DELETE:
135 pListener->OnSqlDataControlDeleteResponseReceived(pArg->__reqId, pArg->__providerId, pArg->__dataId,
136 pArg->__providerResult, pArg->__pErrorMsg);
146 _SqlDataControlImpl::_SqlDataControlImpl(void)
147 : __access(_DATACONTROL_ACCESS_UNDEFINED)
148 , __pPreviousListener(null)
149 , __pSqlDataControlEvent(null)
153 _SqlDataControlImpl::~_SqlDataControlImpl(void)
155 delete __pSqlDataControlEvent;
157 _DataControlManager* pDcMgr = _DataControlManager::GetInstance();
159 IEnumerator* pEnum = __pRequestList->GetEnumeratorN();
160 while (pEnum->MoveNext() == E_SUCCESS)
162 Integer* pReqId = dynamic_cast< Integer* >(pEnum->GetCurrent());
163 if (pReqId != null && pDcMgr != null)
165 pDcMgr->RemoveRequestInfo(*pReqId);
168 delete __pRequestList;
172 _SqlDataControlImpl::GetInstance(SqlDataControl& dc)
174 return dc.__pSqlDataControlImpl;
177 const _SqlDataControlImpl*
178 _SqlDataControlImpl::GetInstance(const SqlDataControl& dc)
180 return dc.__pSqlDataControlImpl;
184 _SqlDataControlImpl::StartSqlDataControl(int type, const IList* pDataList, int* pReq)
186 Integer* pReqId = null;
187 _DataControlRequestInfo* pReqInfo = null;
188 result r = E_SUCCESS;
191 _DataControlManager* pDcMgr = _DataControlManager::GetInstance();
192 SysTryReturnResult(NID_APP, pDcMgr != null, E_SYSTEM, "Getting _DataControlManager instance failed.");
194 // Check the request count of DataControl operation
195 int count = pDcMgr->GetRequestCount();
196 SysLog(NID_APP, "Current launch request count: %d", count);
198 if (count > REQUEST_THRESHOLD)
200 _AppManagerImpl* pImpl = _AppManagerImpl::GetInstance();
202 // Clear the request queue if the provider is terminated
203 if (!pImpl->IsRunning(__appId))
205 SysLog(NID_APP, "The request queue is cleared due to the invalid provider.");
207 pDcMgr->RemoveAllRequests();
211 SysTryReturnResult(NID_APP, count < MAX_REQUEST_COUNT, E_MAX_EXCEEDED, "The number of requests has exceeded the maximum limit.");
213 _AppArg* pArg = new (std::nothrow) _AppArg; // XXX: pArg will be released in _AppManagerImpl::LaunchApp().
214 SysTryReturnResult(NID_APP, pArg != null, E_OUT_OF_MEMORY, "insufficient memory");
216 pArg->Construct(*this, static_cast <_DataControlRequestType>(type), pDataList);
218 _AppControlManager* pAppManagerImpl = _AppControlManager::GetInstance();
220 if (__pSqlDataControlEvent)
222 // reqId is system-wide id because the bundle is system-wide.
224 _AppControlManager::_RequestGuard reqObj = _AppControlManager::_RequestGuard(*pAppManagerImpl, pArg, SqlDataControlCallback, __pSqlDataControlEvent, -1);
225 req = reqObj.GetRequestNumber();
227 _AppControlManager::_RequestGuard reqObj = _AppControlManager::_RequestGuard(*pAppManagerImpl, pArg, SqlDataControlCallback, pDcMgr, -1);
228 req = reqObj.GetRequestNumber();
230 pReqId = new (std::nothrow) Integer(req);
231 SysTryCatch(NID_APP, pReqId != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
232 "[E_OUT_OF_MEMORY] The memory is insufficient");
234 pReqInfo = new (std::nothrow) _DataControlRequestInfo(__pSqlDataControlEvent);
235 SysTryCatch(NID_APP, pReqInfo != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
236 "[E_OUT_OF_MEMORY] The memory is insufficient");
237 pReqInfo->SetSqlDataControlImpl(this);
239 r = pDcMgr->AddRequestInfo(pReqId, pReqInfo);
240 SysTryCatch(NID_APP, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[%s] Failed to add request info", GetErrorMessage(r));
242 r = pAppManagerImpl->LaunchApp(__appId, pArg, req);
245 SysPropagate(NID_APP, r);
247 pDcMgr->RemoveRequestInfo(*pReqId);
251 __pRequestList->Add(new (std::nothrow) Integer(req));
260 r = pAppManagerImpl->LaunchApp(__appId, pArg);
261 SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Propagating to caller...", GetErrorMessage(r));
275 _SqlDataControlImpl::Select(const String& dataId, const IList* pColumnList, const String* pWhere,
276 const String *pOrder, RequestId& reqId, int pageNo, int countPerPage)
278 SysTryReturnResult(NID_APP, pageNo > 0, E_INVALID_ARG, "The specified pageNo parameter is less than 1");
279 SysTryReturnResult(NID_APP, countPerPage > 0, E_INVALID_ARG, "The specified countPerPage parameter is less than 1");
280 SysTryReturnResult(NID_APP, (__access & _DATACONTROL_ACCESS_READ) > 0, E_ILLEGAL_ACCESS,
281 "The SELECT query is not permitted by DataControl provider.");
283 const String* pColumn = null;
285 result r = E_SUCCESS;
286 SysLog(NID_APP, "[DC_CALLER_SEND] SqlDataControl SELECT");
288 ArrayList* pArgList = new ArrayList();
289 pArgList->Construct();
291 pArgList->Add(*(new String(dataId))); // list(0): data ID
292 long long argSize = dataId.GetLength() * sizeof(wchar_t);
294 if (pColumnList != null)
296 int columnCount = pColumnList->GetCount();
297 SysTryCatch(NID_APP, columnCount > 0, r = E_INVALID_ARG, E_INVALID_ARG,
298 "[E_INVALID_ARG] The specified pColumnList parameter is empty.");
300 pArgList->Add(*(new String(Integer::ToString(columnCount)))); // list(1): selected column count
301 SysLog(NID_APP, "[DC_CALLER_SEND] selected column count: %d", columnCount);
304 while (i < columnCount) // list(2): column list
306 pColumn = dynamic_cast< const String* >(pColumnList->GetAt(i));
307 SysTryCatch(NID_APP, pColumn != null, r = E_INVALID_ARG, E_INVALID_ARG,
308 "[E_INVALID_ARG] The object is not String class.");
310 pArgList->Add(*(new String(*pColumn)));
311 argSize += pColumn->GetLength() * sizeof(wchar_t);
312 SysLog(NID_APP, "[DC_CALLER_SEND] column[%d]: %ls", i, pColumn->GetPointer());
318 pArgList->Add(*(new String(L"NULL")));
321 if (pWhere != null) // list(3): where clause
323 pArgList->Add(*(new String(*pWhere)));
324 argSize += pWhere->GetLength() * sizeof(wchar_t);
325 SysLog(NID_APP, "[DC_CALLER_SEND] pWhere: %ls", pWhere->GetPointer());
329 pArgList->Add(*(new String(L"NULL")));
332 if (pOrder != null) // list(4): order clause
334 pArgList->Add(*(new String(*pOrder)));
335 argSize += pOrder->GetLength() * sizeof(wchar_t);
336 SysLog(NID_APP, "[DC_CALLER_SEND] pOrder: %ls", pOrder->GetPointer());
340 pArgList->Add(*(new String(L"NULL")));
342 SysTryCatch(NID_APP, argSize <= _MAX_ARGUMENT_SIZE, r = E_MAX_EXCEEDED, E_MAX_EXCEEDED,
343 "[E_MAX_EXCEEDED] The size of sending argument (%lld) exceeds the maximum limit.", argSize);
345 pArgList->Add(*(new String(Integer::ToString(pageNo)))); // list(5): page number
347 pArgList->Add(*(new String(Integer::ToString(countPerPage)))); // list(6): count per page
349 r = StartSqlDataControl(_DATACONTROL_REQUEST_TYPE_SQL_QUERY, pArgList, &id);
350 SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Propagating to caller...", GetErrorMessage(r));
352 reqId = static_cast< RequestId >(id);
354 SysLog(NID_APP, "[DC_CALLER_SEND] data: %ls, pColumnList: 0x%x, pWhere: 0x%x, pOrder: 0x%x, req: %d, pageNo: %d, countPerPage: %d",
355 dataId.GetPointer(), pColumnList, pWhere, pOrder, reqId, pageNo, countPerPage);
359 pArgList->RemoveAll(true);
366 _SqlDataControlImpl::SqlDataControlCallback(void* data, _AppArg* pArg, _AppArg* pResArg, service_result_e res, int prop, int option)
368 ArrayList* pResultList = null;
369 String* pResult = null;
370 String* pProviderId = null;
371 String* pDataId = null;
372 String* pErrorMessage = null;
373 String* pErrorMsg = null;
374 String* pTmpPath = null;
375 String* pInsertRowId = null;
376 _DataControlResultSetEnumerator* pResultSetEnum = null;
381 bool providerResult = true;
382 //bundle* origBundle = null;
383 bundle* resBundle = null;
384 _SqlDataControlEventArg* pEventArg = null;
385 const char* p = null;
386 result r = E_SUCCESS;
388 SysTryReturnResult(NID_APP, pResArg != null, E_INVALID_ARG, "Empty result callback.");
389 SysLog(NID_APP, "appsvc result value: %d", res);
391 resBundle = pResArg->GetBundle();
394 p = appsvc_get_data(resBundle, OSP_K_REQUEST_ID);
395 SysTryCatch(NID_APP, p, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid bundle");
399 _DataControlManager* pDcMgr = static_cast< _DataControlManager* >(data);
400 SysTryReturnResult(NID_APP, pDcMgr != null, E_SYSTEM, "Getting _DataControlManager instance failed.");
402 _DataControlRequestInfo* pReqInfo = pDcMgr->GetRequestInfo(key);
403 if (pReqInfo == null)
405 SysLog(NID_APP, "No request info of reqId %d", reqId);
409 _SqlDataControlEvent* pSqlDataControlEvent = dynamic_cast< _SqlDataControlEvent* >(pReqInfo->GetEvent());
410 SysTryCatch(NID_APP, pSqlDataControlEvent != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid request info");
412 _SqlDataControlImpl* pDcImpl = pReqInfo->GetSqlDataControlImpl();
413 SysTryCatch(NID_APP, pDcImpl != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid request info");
415 pDcImpl->__pRequestList->Remove(key);
416 pDcMgr->RemoveRequestInfo(key);
418 // Remove the request from the queue
419 SysLog(NID_APP, "Remove the request, req: %d", reqId);
421 if (pSqlDataControlEvent != null && typeid(pSqlDataControlEvent) == typeid(_SqlDataControlEvent*))
424 pResultList = _AppArg::GetListN(resBundle, OSP_K_ARG);
425 SysTryCatch(NID_APP, pResultList, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid result");
427 pResult = dynamic_cast <String*>(pResultList->GetAt(0)); // result list[0]
428 SysTryCatch(NID_APP, pResult, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid result");
429 Integer::Parse(*pResult, providerRes);
430 providerResult = static_cast< bool >(providerRes);
432 pErrorMessage = dynamic_cast< String* >(pResultList->GetAt(1)); // result list[1]
433 SysTryCatch(NID_APP, pErrorMessage, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid result");
434 pErrorMsg = new (std::nothrow) String(*pErrorMessage);
435 SysTryCatch(NID_APP, pErrorMsg, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
436 "[E_OUT_OF_MEMORY] The memory is insufficient.");
439 //origBundle = pArg->GetBundle();
441 p = appsvc_get_data(resBundle, OSP_K_DATACONTROL_REQUEST_TYPE);
442 SysTryCatch(NID_APP, p, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid bundle");
443 requestType = atoi(p);
445 p = appsvc_get_data(resBundle, OSP_K_DATACONTROL_PROVIDER);
446 SysTryCatch(NID_APP, p, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid bundle");
447 pProviderId = new (std::nothrow) String(p);
448 SysTryCatch(NID_APP, pProviderId, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
449 "[E_OUT_OF_MEMORY] The memory is insufficient.");
451 p = appsvc_get_data(resBundle, OSP_K_DATACONTROL_DATA);
452 SysTryCatch(NID_APP, p, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid bundle");
453 pDataId = new (std::nothrow) String(p);
454 SysTryCatch(NID_APP, pDataId, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
455 "[E_OUT_OF_MEMORY] The memory is insufficient.");
457 SysSecureLog(NID_APP, "[DC_CALLER_RECV] provider result: %ld, requestType: %d, req: %d, provider: %ls, data: %ls, errorMsg: %ls ",
458 providerRes, requestType, reqId, pProviderId->GetPointer(), pDataId->GetPointer(), pErrorMsg->GetPointer());
460 switch (static_cast <_DataControlRequestType>(requestType))
462 case _DATACONTROL_REQUEST_TYPE_SQL_QUERY:
464 pResultSetEnum = new (std::nothrow) _DataControlResultSetEnumerator;
465 SysTryCatch(NID_APP, pResultSetEnum, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
466 "[E_OUT_OF_MEMORY] The memory is insufficient.");
468 if (providerResult == true)
470 pTmpPath = dynamic_cast< String* >(pResultList->GetAt(2)); // result list[2]
471 if (pTmpPath == null)
473 SysLogException(NID_APP, E_SYSTEM, "[E_SYSTEM] invalid result");
474 delete pResultSetEnum;
478 SysLog(NID_APP, "[DC_CALLER_RECV] tempPath: %ls", pTmpPath->GetPointer());
479 if (pTmpPath->Equals(L"NoResultSet", true) == false) // Result set exists
481 pResultSetEnum->SetPath(*pTmpPath);
485 pEventArg = new (std::nothrow) _SqlDataControlEventArg(_DATACONTROL_REQUEST_TYPE_SQL_QUERY, static_cast <RequestId>(reqId),
486 *pProviderId, *pDataId, pResultSetEnum, -1, providerResult, pErrorMsg);
487 SysTryCatch(NID_APP, pEventArg != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
488 pSqlDataControlEvent->Fire(*pEventArg);
492 r = File::Remove(*pTmpPath); // Remove temporary file after releasing _ResultSetEnumerator.
493 SysTryLog(NID_APP, !IsFailed(r), "Failed to remove temp file for result set: %ls", pTmpPath->GetPointer());
498 case _DATACONTROL_REQUEST_TYPE_SQL_INSERT:
500 long long insertRowId = -1;
501 if (providerResult == true)
503 pInsertRowId = dynamic_cast< String* >(pResultList->GetAt(2)); // result list[2]
504 SysTryCatch(NID_APP, pInsertRowId, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid result");
506 LongLong::Parse(*pInsertRowId, insertRowId);
509 pEventArg = new (std::nothrow) _SqlDataControlEventArg(_DATACONTROL_REQUEST_TYPE_SQL_INSERT, static_cast <RequestId>(reqId),
510 *pProviderId, *pDataId, null, insertRowId, providerResult, pErrorMsg);
511 SysTryCatch(NID_APP, pEventArg != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
512 pSqlDataControlEvent->Fire(*pEventArg);
515 case _DATACONTROL_REQUEST_TYPE_SQL_UPDATE:
517 pEventArg = new (std::nothrow) _SqlDataControlEventArg(_DATACONTROL_REQUEST_TYPE_SQL_UPDATE, static_cast <RequestId>(reqId),
518 *pProviderId, *pDataId, null, -1, providerResult, pErrorMsg);
519 SysTryCatch(NID_APP, pEventArg != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
520 pSqlDataControlEvent->Fire(*pEventArg);
523 case _DATACONTROL_REQUEST_TYPE_SQL_DELETE:
525 pEventArg = new (std::nothrow) _SqlDataControlEventArg(_DATACONTROL_REQUEST_TYPE_SQL_DELETE, static_cast <RequestId>(reqId),
526 *pProviderId, *pDataId, null, -1, providerResult, pErrorMsg);
527 SysTryCatch(NID_APP, pEventArg != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
528 pSqlDataControlEvent->Fire(*pEventArg);
535 pResultList->RemoveAll(true);
541 p = appsvc_get_data(pArg->GetBundle(), OSP_K_REQUEST_ID);
542 SysTryCatch(NID_APP, p, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid bundle");
543 launchReqId = atoi(p);
550 pResultList->RemoveAll(true);
559 _SqlDataControlImpl::Insert(const String& dataId, const IMap& insertMap, RequestId& reqId)
561 SysTryReturnResult(NID_APP, (__access & _DATACONTROL_ACCESS_WRITE) > 0, E_ILLEGAL_ACCESS,
562 "The INSERT query is not permitted by DataControl provider.");
568 IMapEnumerator* pMapEnum = null;
569 _PackageManagerImpl* pPkgMgrImpl = null;
570 unique_ptr< String > pProviderAppId(null);
571 result r = E_SUCCESS;
572 SysLog(NID_APP, "[DC_CALLER_SEND] SqlDataControl INSERT");
574 columnCount = insertMap.GetCount();
575 SysTryReturnResult(NID_APP, columnCount > 0, E_INVALID_ARG, "The specified insertMap parameter is empty.");
577 ArrayList* pArgList = new (std::nothrow) ArrayList();
578 pArgList->Construct();
580 pArgList->Add(new (std::nothrow) String(dataId)); // list[0]: data ID
581 long long argSize = dataId.GetLength() * sizeof(wchar_t);
583 pArgList->Add(new (std::nothrow) String(Integer::ToString(columnCount))); // list[1]: inserted column count
584 SysLog(NID_APP, "[DC_CALLER_SEND] inserted column count: %d", columnCount);
586 #ifdef DATACONTROL_PROTOCOL_VER_2_1_0_2
587 String tmpPath(_DATACONTROL_REQUEST_DIR);
588 tmpPath.Append(App::GetInstance()->GetAppId());
590 _DataControlManager* pDcMgr = _DataControlManager::GetInstance();
591 SysTryCatch(NID_APP, pDcMgr != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Getting _DataControlManager instance failed.");
592 uniqueId = pDcMgr->GetUniqueId();
594 tmpPath.Append(uniqueId);
595 SysLog(NID_APP, "[DC_CALLER_SEND] request: %ls", tmpPath.GetPointer());
597 r = request.Construct(tmpPath, L"w+", true);
598 SysTryCatch(NID_APP, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[%s] Failed to create request (%ls).",
599 GetErrorMessage(r), tmpPath.GetPointer());
601 pArgList->Add(new (std::nothrow) String(tmpPath)); // list[2]: path
604 pMapEnum = const_cast< IMap* >(&insertMap)->GetMapEnumeratorN();
605 while (pMapEnum->MoveNext() == E_SUCCESS) // list: column-value pairs
607 #ifdef DATACONTROL_PROTOCOL_VER_2_1_0_2
609 String* pColumn = null;
610 String* pValue = null;
611 unique_ptr< char[] > pData(null);
613 pColumn = dynamic_cast< String* >(pMapEnum->GetKey());
614 SysTryCatch(NID_APP, pColumn != null, r = E_INVALID_ARG, E_INVALID_ARG,
615 "[E_INVALID_ARG] The object is not String class.");
617 pData.reset(_StringConverter::CopyToCharArrayN(*pColumn));
618 SysTryCatch(NID_APP, pData != null, r = GetLastResult(), GetLastResult(), "[%s] Invalid request value",
619 GetErrorMessage(GetLastResult()));
621 length = strlen(pData.get());
622 r = request.Write(&length, sizeof(int)); // data length
623 SysTryCatch(NID_APP, !IsFailed(r), , E_SYSTEM, "[%s] Failed to send request.", GetErrorMessage(r));
625 r = request.Write(pData.get(), length); // data
626 SysTryCatch(NID_APP, !IsFailed(r), , E_SYSTEM, "[%s] Failed to send request.", GetErrorMessage(r));
628 pValue = dynamic_cast< String* >(pMapEnum->GetValue());
629 SysTryCatch(NID_APP, pValue != null, r = E_INVALID_ARG, E_INVALID_ARG,
630 "[E_INVALID_ARG] The object is not String class.");
632 pData.reset(_StringConverter::CopyToCharArrayN(*pValue));
633 SysTryCatch(NID_APP, pData != null, r = GetLastResult(), GetLastResult(), "[%s] Invalid request value",
634 GetErrorMessage(GetLastResult()));
636 length = strlen(pData.get());
637 r = request.Write(&length, sizeof(int)); // data length
638 SysTryCatch(NID_APP, !IsFailed(r), , E_SYSTEM, "[%s] Failed to send request.", GetErrorMessage(r));
640 r = request.Write(pData.get(), length); // data
641 SysTryCatch(NID_APP, !IsFailed(r), , E_SYSTEM, "[%s] Failed to send request.", GetErrorMessage(r));
643 argSize += pColumn->GetLength() * sizeof(wchar_t);
644 argSize += pValue->GetLength() * sizeof(wchar_t);
646 String* pColumn = dynamic_cast< String* >(pMapEnum->GetKey());
647 SysTryCatch(NID_APP, pColumn != null, r = E_INVALID_ARG, E_INVALID_ARG,
648 "[E_INVALID_ARG] The object is not String class.");
650 pArgList->Add(*(new String(*pColumn)));
651 SysLog(NID_APP, "[DC_CALLER_SEND] pColumn[%d]: %ls", i, pColumn->GetPointer());
653 String* pValue = dynamic_cast< String* >(pMapEnum->GetValue());
654 SysTryCatch(NID_APP, pValue != null, r = E_INVALID_ARG, E_INVALID_ARG,
655 "[E_INVALID_ARG] The object is not String class.");
657 pArgList->Add(*(new String(*pValue)));
658 SysLog(NID_APP, "[DC_CALLER_SEND] pValue[%d]: %ls", i, pValue->GetPointer());
660 argSize += pColumn->GetLength() * sizeof(wchar_t);
661 argSize += pValue->GetLength() * sizeof(wchar_t);
665 SysTryCatch(NID_APP, argSize <= _MAX_REQUEST_ARGUMENT_SIZE, r = E_MAX_EXCEEDED, E_MAX_EXCEEDED,
666 "[E_MAX_EXCEEDED] The size of sending argument (%lld) exceeds the maximum limit.", argSize);
668 #ifdef DATACONTROL_PROTOCOL_VER_2_1_0_2
671 #ifdef DATACONTROL_PROTOCOL_VER_2_1_0_3
672 pPkgMgrImpl = _PackageManagerImpl::GetInstance();
673 pProviderAppId.reset(pPkgMgrImpl->GetAppIdOfDataControlN(this->__providerId.GetPointer()));
674 SysTryCatch(NID_APP, pProviderAppId != null, r = E_SYSTEM, E_SYSTEM,
675 "[E_SYSTEM] The method cannot proceed due to a severe system error.");
676 r = pDcMgr->AllowAccess(*(pProviderAppId.get()));
677 SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Propagating to caller...", GetErrorMessage(r));
680 r = StartSqlDataControl(_DATACONTROL_REQUEST_TYPE_SQL_INSERT, pArgList, &id);
681 SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Propagating to caller...", GetErrorMessage(r));
683 reqId = static_cast< RequestId >(id);
685 SysLog(NID_APP, "[DC_CALLER_SEND] data: %ls, insertMap: 0x%x, req: %d", dataId.GetPointer(), &insertMap, reqId);
689 pArgList->RemoveAll(true);
697 _SqlDataControlImpl::Update(const String& dataId, const IMap& updateMap, const String* pWhere, RequestId& reqId)
699 SysTryReturnResult(NID_APP, (__access & _DATACONTROL_ACCESS_WRITE) > 0, E_ILLEGAL_ACCESS,
700 "The UPDATE query is not permitted by DataControl provider.");
706 IMapEnumerator* pMapEnum = null;
707 _PackageManagerImpl* pPkgMgrImpl = null;
708 unique_ptr< String > pProviderAppId(null);
709 result r = E_SUCCESS;
710 SysLog(NID_APP, "[DC_CALLER_SEND] SqlDataControl UPDATE");
712 columnCount = updateMap.GetCount();
713 SysTryReturnResult(NID_APP, columnCount > 0, E_INVALID_ARG, "The specified insertMap parameter is empty.");
715 ArrayList* pArgList = new ArrayList();
716 pArgList->Construct();
718 pArgList->Add(new (std::nothrow) String(dataId)); // list[0]: data ID
719 long long argSize = dataId.GetLength() * sizeof(wchar_t);
721 pArgList->Add(new (std::nothrow) String(Integer::ToString(columnCount))); // list[1]: updated column count
722 SysLog(NID_APP, "[DC_CALLER_SEND] updated column count: %d", columnCount);
724 #ifdef DATACONTROL_PROTOCOL_VER_2_1_0_2
725 String tmpPath(_DATACONTROL_REQUEST_DIR);
726 tmpPath.Append(App::GetInstance()->GetAppId());
728 _DataControlManager* pDcMgr = _DataControlManager::GetInstance();
729 SysTryCatch(NID_APP, pDcMgr != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Getting _DataControlManager instance failed.");
730 uniqueId = pDcMgr->GetUniqueId();
732 tmpPath.Append(uniqueId);
733 SysLog(NID_APP, "[DC_CALLER_SEND] request: %ls", tmpPath.GetPointer());
735 r = request.Construct(tmpPath, L"w+", true);
736 SysTryCatch(NID_APP, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[%s] Failed to create request (%ls).",
737 GetErrorMessage(r), tmpPath.GetPointer());
739 pArgList->Add(new (std::nothrow) String(tmpPath)); // list[2]: path
742 pMapEnum = const_cast< IMap* >(&updateMap)->GetMapEnumeratorN();
743 while (pMapEnum->MoveNext() == E_SUCCESS) // list: column-value pairs
745 #ifdef DATACONTROL_PROTOCOL_VER_2_1_0_2
747 String* pColumn = null;
748 String* pValue = null;
749 unique_ptr< char[] > pData(null);
751 pColumn = dynamic_cast< String* >(pMapEnum->GetKey());
752 SysTryCatch(NID_APP, pColumn != null, r = E_INVALID_ARG, E_INVALID_ARG,
753 "[E_INVALID_ARG] The object is not String class.");
755 pData.reset(_StringConverter::CopyToCharArrayN(*pColumn));
756 SysTryCatch(NID_APP, pData != null, r = GetLastResult(), GetLastResult(), "[%s] Invalid request value",
757 GetErrorMessage(GetLastResult()));
759 length = strlen(pData.get());
760 r = request.Write(&length, sizeof(int)); // data length
761 SysTryCatch(NID_APP, !IsFailed(r), , E_SYSTEM, "[%s] Failed to send request.", GetErrorMessage(r));
763 r = request.Write(pData.get(), length); // data
764 SysTryCatch(NID_APP, !IsFailed(r), , E_SYSTEM, "[%s] Failed to send request.", GetErrorMessage(r));
766 pValue = dynamic_cast< String* >(pMapEnum->GetValue());
767 SysTryCatch(NID_APP, pValue != null, r = E_INVALID_ARG, E_INVALID_ARG,
768 "[E_INVALID_ARG] The object is not String class.");
770 pData.reset(_StringConverter::CopyToCharArrayN(*pValue));
771 SysTryCatch(NID_APP, pData != null, r = GetLastResult(), GetLastResult(), "[%s] Invalid request value",
772 GetErrorMessage(GetLastResult()));
774 length = strlen(pData.get());
775 r = request.Write(&length, sizeof(int)); // data length
776 SysTryCatch(NID_APP, !IsFailed(r), , E_SYSTEM, "[%s] Failed to send request.", GetErrorMessage(r));
778 r = request.Write(pData.get(), length); // data
779 SysTryCatch(NID_APP, !IsFailed(r), , E_SYSTEM, "[%s] Failed to send request.", GetErrorMessage(r));
781 argSize += pColumn->GetLength() * sizeof(wchar_t);
782 argSize += pValue->GetLength() * sizeof(wchar_t);
784 String* pColumn = dynamic_cast< String* >(pMapEnum->GetKey());
785 SysTryCatch(NID_APP, pColumn != null, r = E_INVALID_ARG, E_INVALID_ARG,
786 "[E_INVALID_ARG] The object is not String class.");
788 pArgList->Add(*(new String(*pColumn)));
789 SysLog(NID_APP, "[DC_CALLER_SEND] pColumn[%d]: %ls", i, pColumn->GetPointer());
791 String* pValue = dynamic_cast< String* >(pMapEnum->GetValue());
792 SysTryCatch(NID_APP, pValue != null, r = E_INVALID_ARG, E_INVALID_ARG,
793 "[E_INVALID_ARG] The object is not String class.");
795 pArgList->Add(*(new String(*pValue)));
796 SysLog(NID_APP, "[DC_CALLER_SEND] pValue[%d]: %ls", i, pValue->GetPointer());
798 argSize += pColumn->GetLength() * sizeof(wchar_t);
799 argSize += pValue->GetLength() * sizeof(wchar_t);
804 #ifdef DATACONTROL_PROTOCOL_VER_2_1_0_2
808 if (pWhere != null) // list: where clause
810 pArgList->Add(new (std::nothrow) String(*pWhere));
811 argSize += pWhere->GetLength() * sizeof(wchar_t);
812 SysLog(NID_APP, "[DC_CALLER_SEND] pWhere: %ls", pWhere->GetPointer());
816 pArgList->Add(new (std::nothrow) String(L"NULL"));
818 SysTryCatch(NID_APP, argSize <= _MAX_REQUEST_ARGUMENT_SIZE, r = E_MAX_EXCEEDED, E_MAX_EXCEEDED,
819 "[E_MAX_EXCEEDED] The size of sending argument (%lld) exceeds the maximum limit.", argSize);
821 #ifdef DATACONTROL_PROTOCOL_VER_2_1_0_3
822 pPkgMgrImpl = _PackageManagerImpl::GetInstance();
823 pProviderAppId.reset(pPkgMgrImpl->GetAppIdOfDataControlN(this->__providerId.GetPointer()));
824 SysTryCatch(NID_APP, pProviderAppId != null, r = E_SYSTEM, E_SYSTEM,
825 "[E_SYSTEM] The method cannot proceed due to a severe system error.");
826 r = pDcMgr->AllowAccess(*(pProviderAppId.get()));
827 SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Propagating to caller...", GetErrorMessage(r));
830 r = StartSqlDataControl(_DATACONTROL_REQUEST_TYPE_SQL_UPDATE, pArgList, &id);
831 SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Propagating to caller...", GetErrorMessage(r));
833 reqId = static_cast< RequestId >(id);
835 SysLog(NID_APP, "[DC_CALLER_SEND] data: %ls, updateMap: 0x%x, pWhere: 0x%x, req: %d",
836 dataId.GetPointer(), &updateMap, pWhere, reqId);
840 pArgList->RemoveAll(true);
848 _SqlDataControlImpl::Delete(const String& dataId, const String* pWhere, RequestId& reqId)
850 SysTryReturnResult(NID_APP, (__access & _DATACONTROL_ACCESS_WRITE) > 0, E_ILLEGAL_ACCESS,
851 "The DELETE query is not permitted by DataControl provider.");
854 result r = E_SUCCESS;
855 SysLog(NID_APP, "[DC_CALLER_SEND] SqlDataControl DELETE");
857 ArrayList* pArgList = new ArrayList();
858 pArgList->Construct();
860 pArgList->Add(*(new String(dataId))); // list(0): data ID
861 long long argSize = dataId.GetLength() * sizeof(wchar_t);
863 if (pWhere != null) // list(1): where clause
865 pArgList->Add(*(new String(*pWhere)));
866 argSize += pWhere->GetLength() * sizeof(wchar_t);
867 SysLog(NID_APP, "[DC_CALLER_SEND] pWhere: %ls", pWhere->GetPointer());
871 pArgList->Add(*(new String(L"NULL")));
873 SysTryCatch(NID_APP, argSize <= _MAX_ARGUMENT_SIZE, r = E_MAX_EXCEEDED, E_MAX_EXCEEDED,
874 "[E_MAX_EXCEEDED] The size of sending argument (%lld) exceeds the maximum limit.", argSize);
876 r = StartSqlDataControl(_DATACONTROL_REQUEST_TYPE_SQL_DELETE, pArgList, &id);
877 SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Propagating to caller...", GetErrorMessage(r));
879 reqId = static_cast< RequestId >(id);
881 SysLog(NID_APP, "[DC_CALLER_SEND] data: %ls, pWhere: 0x%x, req: %d", dataId.GetPointer(), pWhere, reqId);
885 pArgList->RemoveAll(true);
892 _SqlDataControlImpl::SetSqlDataControlResponseListener(ISqlDataControlResponseListener* pListener)
894 result r = E_SUCCESS;
896 if (__pPreviousListener != null)
898 r = __pSqlDataControlEvent->RemoveListener(*__pPreviousListener);
899 SysTryReturnResult(NID_APP, !IsFailed(r), E_SYSTEM, "Remove listener failed.");
900 __pPreviousListener = null;
903 if (pListener != null)
905 r = __pSqlDataControlEvent->AddListener(*pListener);
910 case E_OBJ_ALREADY_EXIST:
912 case E_INVALID_OPERATION:
913 SysLogException(NID_APP, E_SYSTEM, "[E_SYSTEM] The thread setting the listener is worker thread.");
916 SysLogException(NID_APP, r, "[%s] Propagating to caller...", GetErrorMessage(r));
922 __pPreviousListener = pListener;
929 _SqlDataControlImpl::CreateSqlDataControl(const String& appId, const String& providerId, const String& access)
931 unique_ptr<SqlDataControl> pDc(new (std::nothrow) SqlDataControl);
932 SysTryReturn(NID_APP, pDc != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient");
934 _SqlDataControlImpl* pDcImpl = _SqlDataControlImpl::GetInstance(*pDc);
935 pDcImpl->__appId = appId;
936 pDcImpl->__providerId = providerId;
937 unique_ptr<_SqlDataControlEvent> pSqlDataControlEvent(new (std::nothrow) _SqlDataControlEvent);
938 SysTryReturn(NID_IO, pSqlDataControlEvent != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
940 pDcImpl->__pRequestList = new (std::nothrow) LinkedList(SingleObjectDeleter);
941 SysTryReturn(NID_IO, pDcImpl->__pRequestList != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
943 pDcImpl->__pSqlDataControlEvent = pSqlDataControlEvent.release();
945 if (access == L"readonly")
947 pDcImpl->__access = _DATACONTROL_ACCESS_READ;
949 else if (access == L"writeonly")
951 pDcImpl->__access = _DATACONTROL_ACCESS_WRITE;
953 else if (access == L"readwrite")
955 pDcImpl->__access = _DATACONTROL_ACCESS_READWRITE;
959 pDcImpl->__access = _DATACONTROL_ACCESS_UNDEFINED;
960 SysLog(NID_IO, "The accessibility of DataControl provider is invalid.");
963 return pDc.release();