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