Merge "Flow control for DataControl" into tizen_2.1
[platform/framework/native/appfw.git] / src / io / FIo_DataRowImpl.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2013 Samsung Electronics Co., Ltd.
4 //
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
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
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.
16 //
17
18 /**
19  * @file        FIo_DataRowImpl.cpp
20  * @brief       This is the implementation file for _DataRowImpl class.
21  */
22
23 #include <unique_ptr.h>
24
25 #include <FBaseInteger.h>
26 #include <FBaseLongLong.h>
27 #include <FBaseDouble.h>
28 #include <FBaseString.h>
29 #include <FBaseByteBuffer.h>
30 #include <FBaseDateTime.h>
31 #include <FBaseSysLog.h>
32 #include <FBaseCol.h>
33
34 #include <FBase_StringConverter.h>
35 #include <FBase_NativeError.h>
36 #include <FIo_DataRowImpl.h>
37
38 using namespace std;
39 using namespace Tizen::Base;
40 using namespace Tizen::Base::Collection;
41 using namespace Tizen::App;
42
43 namespace Tizen { namespace Io
44 {
45 _DataItem::_DataItem(void)
46         : type(DB_COLUMNTYPE_NULL)
47         , size(0)
48         , intValue(0)
49         , int64Value(0)
50         , doubleValue(0)
51         , pObj(null)
52 {
53 }
54
55 _DataItem::~_DataItem(void)
56 {
57         delete pObj;
58 }
59
60 int
61 _DataItem::GetHashCode(void) const
62 {
63         int hash = 0;
64
65         String str;
66
67         str.Append(static_cast<int>(type));
68         str.Append(size);
69         str.Append(intValue);
70         str.Append(int64Value);
71         str.Append(doubleValue);
72         hash += str.GetHashCode();
73
74         if (type == DB_COLUMNTYPE_TEXT )
75                 hash += ((String*)pObj)->GetHashCode();
76         else if (type == DB_COLUMNTYPE_BLOB)
77                 hash += ((ByteBuffer*)pObj)->GetHashCode();
78
79         return hash;
80 }
81
82 _DataRowImpl::_DataRowImpl(void)
83         : __pDataRow(null)
84         , __pColumnTypeList(null)
85         , __columnCount(0)
86 {
87 }
88
89 _DataRowImpl::~_DataRowImpl(void)
90 {
91 }
92
93 result
94 _DataRowImpl::SetBlobAt(int columnIndex, Tizen::Base::ByteBuffer* pValue)
95 {
96         result r = E_SUCCESS;
97         Integer* pColumnType = null;
98         int nColumnType = DB_COLUMNTYPE_UNDEFINED;
99
100         SysTryReturnResult(NID_IO, columnIndex >= 0 && columnIndex < __columnCount, E_INVALID_ARG,
101                                    "Wrong column index.");
102         SysTryReturnResult(NID_IO, pValue != null, E_INVALID_ARG, "pValue is null");
103
104         pColumnType = static_cast<Integer*>(__pColumnTypeList->GetAt(columnIndex));
105         nColumnType = pColumnType->ToInt();
106         SysTryReturnResult(NID_IO, nColumnType == DB_COLUMNTYPE_BLOB || nColumnType == DB_COLUMNTYPE_NULL,
107                 E_TYPE_MISMATCH, "Type mismatch");
108
109         unique_ptr<_DataItem>pItem(new (std::nothrow) _DataItem());
110         SysTryReturnResult(NID_IO, pItem != null, E_OUT_OF_MEMORY,
111                         "The memory is insufficient.");
112
113         pItem->type =  DB_COLUMNTYPE_BLOB;
114         pItem->size = pValue->GetLimit();
115         pItem->pObj = pValue;
116
117         _DataItem* pOldItem = static_cast<_DataItem*>(__pDataRow->GetAt(columnIndex));
118         r = __pDataRow->SetAt(pItem.release(), columnIndex);
119         SysTryReturnResult(NID_IO, r == E_SUCCESS, E_OUT_OF_MEMORY,
120                         "The memory is insufficient. Set failed");
121         delete pOldItem;
122
123         if (nColumnType == DB_COLUMNTYPE_NULL)
124         {
125                 __pColumnTypeList->SetAt(new Integer(DB_COLUMNTYPE_BLOB), columnIndex);
126                 delete pColumnType;
127         }
128
129         return r;
130 }
131
132 result
133 _DataRowImpl::SetDateTimeAt(int columnIndex, const Tizen::Base::DateTime& value)
134 {
135         result r = E_SUCCESS;
136         Integer* pColumnType = null;
137         int nColumnType = DB_COLUMNTYPE_UNDEFINED;
138         char* pDateTimeStr;
139
140         SysTryReturnResult(NID_IO, columnIndex >= 0 && columnIndex < __columnCount, E_INVALID_ARG,
141                                    "Wrong column index.");
142
143         pColumnType = static_cast<Integer*>(__pColumnTypeList->GetAt(columnIndex));
144         nColumnType = pColumnType->ToInt();
145         SysTryReturnResult(NID_IO, nColumnType == DB_COLUMNTYPE_TEXT || nColumnType == DB_COLUMNTYPE_NULL,
146                 E_TYPE_MISMATCH, "Type mismatch");
147
148         unique_ptr<_DataItem>pItem(new (std::nothrow) _DataItem());
149         pDateTimeStr = _StringConverter::CopyToCharArrayN(value.ToString());
150         unique_ptr<String> pString(new (std::nothrow) String(pDateTimeStr));
151         delete pDateTimeStr;
152         SysTryReturnResult(NID_IO, pItem != null && pString != null, E_OUT_OF_MEMORY,
153                         "The memory is insufficient.");
154
155         pItem->type =  DB_COLUMNTYPE_TEXT;
156         pItem->size = pString->GetLength();
157         pItem->pObj = pString.release();
158
159         _DataItem* pOldItem = static_cast<_DataItem*>(__pDataRow->GetAt(columnIndex));
160         r = __pDataRow->SetAt(pItem.release(), columnIndex);
161         SysTryReturnResult(NID_IO, r == E_SUCCESS, E_OUT_OF_MEMORY,
162                         "The memory is insufficient. Set failed");
163         delete pOldItem;
164
165         if (nColumnType == DB_COLUMNTYPE_NULL)
166         {
167                 __pColumnTypeList->SetAt(new Integer(DB_COLUMNTYPE_TEXT), columnIndex);
168                 delete pColumnType;
169         }
170
171         return r;
172
173 }
174
175 result
176 _DataRowImpl::SetDoubleAt(int columnIndex, double value)
177 {
178         result r = E_SUCCESS;
179         int size = sizeof(double);
180         Integer* pColumnType = null;
181         int nColumnType = DB_COLUMNTYPE_UNDEFINED;
182
183         SysTryReturnResult(NID_IO, columnIndex >= 0 && columnIndex < __columnCount, E_INVALID_ARG,
184                                    "Wrong column index.");
185
186         pColumnType = static_cast<Integer*>(__pColumnTypeList->GetAt(columnIndex));
187         nColumnType = pColumnType->ToInt();
188         SysTryReturnResult(NID_IO, nColumnType == DB_COLUMNTYPE_DOUBLE || nColumnType == DB_COLUMNTYPE_NULL,
189                 E_TYPE_MISMATCH, "Type mismatch");
190
191         unique_ptr<_DataItem>pItem(new (std::nothrow) _DataItem());
192         SysTryReturnResult(NID_IO, pItem != null, E_OUT_OF_MEMORY,
193                         "The memory is insufficient.");
194
195         pItem->type =  DB_COLUMNTYPE_DOUBLE;
196         pItem->size = size;
197         pItem->doubleValue = value;
198
199         _DataItem* pOldItem = static_cast<_DataItem*>(__pDataRow->GetAt(columnIndex));
200         r = __pDataRow->SetAt(pItem.release(), columnIndex);
201         SysTryReturnResult(NID_IO, r == E_SUCCESS, E_OUT_OF_MEMORY,
202                         "The memory is insufficient. Set failed");
203         delete pOldItem;
204
205         if (nColumnType == DB_COLUMNTYPE_NULL)
206         {
207                 __pColumnTypeList->SetAt(new Integer(DB_COLUMNTYPE_DOUBLE), columnIndex);
208                 delete pColumnType;
209         }
210
211         return r;
212
213 }
214
215 result
216 _DataRowImpl::SetIntAt(int columnIndex, int value)
217 {
218         result r = E_SUCCESS;
219         int size = sizeof(int);
220         Integer* pColumnType = null;
221         int nColumnType = DB_COLUMNTYPE_UNDEFINED;
222
223         SysTryReturnResult(NID_IO, columnIndex >= 0 && columnIndex < __columnCount, E_INVALID_ARG,
224                                    "Wrong column index.");
225
226         pColumnType = static_cast<Integer*>(__pColumnTypeList->GetAt(columnIndex));
227         nColumnType = pColumnType->ToInt();
228         SysTryReturnResult(NID_IO, nColumnType == DB_COLUMNTYPE_INT || nColumnType == DB_COLUMNTYPE_NULL,
229                 E_TYPE_MISMATCH, "Type mismatch");
230
231         unique_ptr<_DataItem>pItem(new (std::nothrow) _DataItem());
232         SysTryReturnResult(NID_IO, pItem != null , E_OUT_OF_MEMORY,
233                         "The memory is insufficient.");
234
235         pItem->type =  DB_COLUMNTYPE_INT;
236         pItem->size = size;
237         pItem->intValue = value;
238
239         _DataItem* pOldItem = static_cast<_DataItem*>(__pDataRow->GetAt(columnIndex));
240         r = __pDataRow->SetAt(pItem.release(), columnIndex);
241         SysTryReturnResult(NID_IO, r == E_SUCCESS, E_OUT_OF_MEMORY,
242                         "The memory is insufficient. Set failed");
243         delete pOldItem;
244
245         if (nColumnType == DB_COLUMNTYPE_NULL)
246         {
247                 __pColumnTypeList->SetAt(new Integer(DB_COLUMNTYPE_INT), columnIndex);
248                 delete pColumnType;
249         }
250
251         return r;
252 }
253
254 result
255 _DataRowImpl::SetInt64At(int columnIndex, long long value)
256 {
257         result r = E_SUCCESS;
258         int size = sizeof(long long);
259         Integer* pColumnType = null;
260         int nColumnType = DB_COLUMNTYPE_UNDEFINED;
261
262         SysTryReturnResult(NID_IO, columnIndex >= 0 && columnIndex < __columnCount, E_INVALID_ARG,
263                                    "Wrong column index.");
264
265         pColumnType = static_cast<Integer*>(__pColumnTypeList->GetAt(columnIndex));
266         nColumnType = pColumnType->ToInt();
267         SysTryReturnResult(NID_IO, nColumnType == DB_COLUMNTYPE_INT64 || nColumnType == DB_COLUMNTYPE_NULL,
268                 E_TYPE_MISMATCH, "Type mismatch");
269
270         unique_ptr<_DataItem>pItem(new (std::nothrow) _DataItem());
271         SysTryReturnResult(NID_IO, pItem != null, E_OUT_OF_MEMORY,
272                         "The memory is insufficient.");
273
274         pItem->type =  DB_COLUMNTYPE_INT64;
275         pItem->size = size;
276         pItem->int64Value = value;
277
278         _DataItem* pOldItem = static_cast<_DataItem*>(__pDataRow->GetAt(columnIndex));
279         r = __pDataRow->SetAt(pItem.release(), columnIndex);
280         SysTryReturnResult(NID_IO, r == E_SUCCESS, E_OUT_OF_MEMORY,
281                         "The memory is insufficient. Set failed");
282         delete pOldItem;
283
284         if (nColumnType == DB_COLUMNTYPE_NULL)
285         {
286                 __pColumnTypeList->SetAt(new Integer(DB_COLUMNTYPE_INT64), columnIndex);
287                 delete pColumnType;
288         }
289
290         return r;
291 }
292
293 result
294 _DataRowImpl::SetStringAt(int columnIndex, const Tizen::Base::String& value)
295 {
296         result r = E_SUCCESS;
297         Integer* pColumnType = null;
298         int nColumnType = DB_COLUMNTYPE_UNDEFINED;
299
300         SysTryReturnResult(NID_IO, columnIndex >= 0 && columnIndex < __columnCount, E_INVALID_ARG,
301                                    "Wrong column index.");
302
303         pColumnType = static_cast<Integer*>(__pColumnTypeList->GetAt(columnIndex));
304         nColumnType = pColumnType->ToInt();
305         SysTryReturnResult(NID_IO, nColumnType == DB_COLUMNTYPE_TEXT || nColumnType == DB_COLUMNTYPE_NULL,
306                 E_TYPE_MISMATCH, "Type mismatch");
307
308         unique_ptr<_DataItem>pItem(new (std::nothrow) _DataItem());
309         unique_ptr<String> pString(new (std::nothrow) String(value));
310         SysTryReturnResult(NID_IO, pItem != null && pString != null, E_OUT_OF_MEMORY,
311                         "The memory is insufficient.");
312
313         pItem->type =  DB_COLUMNTYPE_TEXT;
314         pItem->size = value.GetLength();
315         pItem->pObj = pString.release();
316
317         _DataItem* pOldItem = static_cast<_DataItem*>(__pDataRow->GetAt(columnIndex));
318         r = __pDataRow->SetAt(pItem.release(), columnIndex);
319         SysTryReturnResult(NID_IO, r == E_SUCCESS, E_OUT_OF_MEMORY,
320                         "The memory is insufficient. Set failed");
321         delete pOldItem;
322
323         if (nColumnType == DB_COLUMNTYPE_NULL)
324         {
325                 __pColumnTypeList->SetAt(new Integer(DB_COLUMNTYPE_TEXT), columnIndex);
326                 delete pColumnType;
327         }
328
329         return r;
330 }
331
332 result
333 _DataRowImpl::Clone(const ArrayList* pOthersRowArrayList) const
334 {
335         result r = E_SUCCESS;
336
337         for (int i = 0; i < __columnCount; i++)
338         {
339                 const _DataItem* pOthersItem = static_cast<const _DataItem*>(pOthersRowArrayList->GetAt(i));
340
341                 unique_ptr<_DataItem>pItem(new (std::nothrow) _DataItem());
342                 SysTryReturnResult(NID_IO, pItem != null, E_OUT_OF_MEMORY,
343                                 "The memory is insufficient.");
344
345                 pItem->type = pOthersItem->type;
346                 pItem->size = pOthersItem->size;
347                 pItem->intValue = pOthersItem->intValue;
348                 pItem->int64Value = pOthersItem->int64Value;
349                 pItem->doubleValue = pOthersItem->doubleValue;
350
351                 if ( pItem->type == DB_COLUMNTYPE_TEXT)
352                 {
353                         pItem->pObj = new (std::nothrow) String(*static_cast<String*>(pOthersItem->pObj));
354                         SysTryReturnResult(NID_IO, pItem->pObj != null, E_OUT_OF_MEMORY,
355                                         "The memory is insufficient.");
356                 }
357                 else if (pItem->type == DB_COLUMNTYPE_BLOB)
358                 {
359                         ByteBuffer* pBuffer;
360                         pBuffer = new (std::nothrow) ByteBuffer();
361                         SysTryReturnResult(NID_IO, pBuffer != null, E_OUT_OF_MEMORY,
362                                         "The memory is insufficient.");
363
364                         r = pBuffer->Construct(static_cast<ByteBuffer*>(pOthersItem->pObj)->GetCapacity());
365                         SysTryLog(NID_IO, r == E_SUCCESS, "ByteBuffer construct failed");
366                         r = static_cast<ByteBuffer*>(pOthersItem->pObj)->SetPosition(0);
367                         SysTryLog(NID_IO, r == E_SUCCESS, "ByteBuffer SetPosition failed");
368                         r = pBuffer->CopyFrom(*static_cast<ByteBuffer*>(pOthersItem->pObj));
369                         SysTryReturnResult(NID_IO, r == E_SUCCESS, E_OUT_OF_MEMORY,
370                                         "ByteBuffer copy failed.");
371
372                         pItem->pObj = pBuffer;
373                 }
374
375                 _DataItem* pOldItem = static_cast<_DataItem*>(__pDataRow->GetAt(i));
376                 r = __pDataRow->SetAt(pItem.release(), i);
377                 delete pOldItem;
378                 if (r != E_SUCCESS)
379                         break;
380         }
381
382         return r;
383 }
384
385 ArrayList*
386 _DataRowImpl::GetRowArrayList(void) const
387 {
388         return __pDataRow;
389 }
390
391 _DataRowImpl*
392 _DataRowImpl::GetInstance(DataRow& dataRow)
393 {
394         return dataRow.__pDataRowImpl;
395 }
396
397 const _DataRowImpl*
398 _DataRowImpl::GetInstance(const DataRow& dataRow)
399 {
400         return dataRow.__pDataRowImpl;
401 }
402
403 DataRow*
404 _DataRowImpl::CreateDataRowInstanceN(int columnCount, ArrayList* pArrayListRow)
405 {
406         unique_ptr<DataRow> pDataRow(new (std::nothrow) DataRow());
407         SysTryReturn(NID_IO, pDataRow != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
408
409         pDataRow->__pDataRowImpl->__pDataRow = pArrayListRow;
410         pDataRow->__pDataRowImpl->__columnCount = columnCount;
411
412         for (int i = 0 ; i < columnCount ; i++)
413         {
414                 result r = pArrayListRow->Add(new (std::nothrow) _DataItem());
415                 SysTryReturn(NID_IO, r == E_SUCCESS, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
416         }
417
418         return pDataRow.release();
419 }
420
421 int
422 _DataRowImpl::GetHashCode(const ArrayList* pRowArrayList)
423 {
424         int hash = 0;
425
426         for (int i = 0; i < pRowArrayList->GetCount(); i++)
427         {
428                 const _DataItem* pItem = static_cast<const _DataItem*>(pRowArrayList->GetAt(i));
429                 hash += pItem->GetHashCode();
430         }
431
432         return hash;
433 }
434
435 }} // Tizen::Io
436