1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <com/sun/star/sdbc/DataType.hpp>
21 #include <com/sun/star/sdbc/XRow.hpp>
22 
23 #include <svl/zforlist.hxx>
24 
25 #include <dbdocutl.hxx>
26 #include <document.hxx>
27 #include <formula/errorcodes.hxx>
28 #include <stringutil.hxx>
29 
30 using namespace ::com::sun::star;
31 
StrData()32 ScDatabaseDocUtil::StrData::StrData() :
33     mbSimpleText(true), mnStrLength(0)
34 {
35 }
36 
PutData(ScDocument & rDoc,SCCOL nCol,SCROW nRow,SCTAB nTab,const uno::Reference<sdbc::XRow> & xRow,sal_Int32 nRowPos,tools::Long nType,bool bCurrency,StrData * pStrData)37 void ScDatabaseDocUtil::PutData(ScDocument& rDoc, SCCOL nCol, SCROW nRow, SCTAB nTab,
38                                 const uno::Reference<sdbc::XRow>& xRow, sal_Int32 nRowPos,
39                                 tools::Long nType, bool bCurrency, StrData* pStrData)
40 {
41     OUString aString;
42     double nVal = 0.0;
43     bool bValue = false;
44     bool bEmptyFlag = false;
45     bool bError = false;
46     sal_uLong nFormatIndex = 0;
47 
48     // wasNull calls only if null value was found?
49 
50     try
51     {
52         switch ( nType )
53         {
54             case sdbc::DataType::BIT:
55             case sdbc::DataType::BOOLEAN:
56                 //TODO: use language from doc (here, date/time and currency)?
57                 nFormatIndex = rDoc.GetFormatTable()->GetStandardFormat(
58                                     SvNumFormatType::LOGICAL, ScGlobal::eLnge );
59                 nVal = (xRow->getBoolean(nRowPos) ? 1 : 0);
60                 bEmptyFlag = ( nVal == 0.0 ) && xRow->wasNull();
61                 bValue = true;
62                 break;
63 
64             case sdbc::DataType::TINYINT:
65             case sdbc::DataType::SMALLINT:
66             case sdbc::DataType::INTEGER:
67             case sdbc::DataType::BIGINT:
68             case sdbc::DataType::FLOAT:
69             case sdbc::DataType::REAL:
70             case sdbc::DataType::DOUBLE:
71             case sdbc::DataType::NUMERIC:
72             case sdbc::DataType::DECIMAL:
73                 //TODO: do the conversion here?
74                 nVal = xRow->getDouble(nRowPos);
75                 bEmptyFlag = ( nVal == 0.0 ) && xRow->wasNull();
76                 bValue = true;
77                 break;
78 
79             case sdbc::DataType::CHAR:
80             case sdbc::DataType::VARCHAR:
81             case sdbc::DataType::LONGVARCHAR:
82                 aString = xRow->getString(nRowPos);
83                 bEmptyFlag = ( aString.isEmpty() ) && xRow->wasNull();
84                 break;
85 
86             case sdbc::DataType::DATE:
87                 {
88                     util::Date aDate = xRow->getDate(nRowPos);
89                     bEmptyFlag = xRow->wasNull();
90                     if (bEmptyFlag)
91                         nVal = 0.0;
92                     else
93                     {
94                         SvNumberFormatter* pFormTable = rDoc.GetFormatTable();
95                         nFormatIndex = pFormTable->GetStandardFormat(
96                                 SvNumFormatType::DATE, ScGlobal::eLnge );
97                         nVal = Date( aDate ) - pFormTable->GetNullDate();
98                     }
99                     bValue = true;
100                 }
101                 break;
102 
103             case sdbc::DataType::TIME:
104                 {
105                     SvNumberFormatter* pFormTable = rDoc.GetFormatTable();
106                     nFormatIndex = pFormTable->GetStandardFormat(
107                                         SvNumFormatType::TIME, ScGlobal::eLnge );
108 
109                     util::Time aTime = xRow->getTime(nRowPos);
110                     nVal = aTime.Hours       / static_cast<double>(::tools::Time::hourPerDay)   +
111                            aTime.Minutes     / static_cast<double>(::tools::Time::minutePerDay) +
112                            aTime.Seconds     / static_cast<double>(::tools::Time::secondPerDay) +
113                            aTime.NanoSeconds / static_cast<double>(::tools::Time::nanoSecPerDay);
114                     bEmptyFlag = xRow->wasNull();
115                     bValue = true;
116                 }
117                 break;
118 
119             case sdbc::DataType::TIMESTAMP:
120                 {
121                     SvNumberFormatter* pFormTable = rDoc.GetFormatTable();
122                     nFormatIndex = pFormTable->GetStandardFormat(
123                                         SvNumFormatType::DATETIME, ScGlobal::eLnge );
124 
125                     util::DateTime aStamp = xRow->getTimestamp(nRowPos);
126                     if (aStamp.Year != 0)
127                     {
128                         nVal = ( Date( aStamp.Day, aStamp.Month, aStamp.Year ) -
129                                                     pFormTable->GetNullDate() ) +
130                                aStamp.Hours       / static_cast<double>(::tools::Time::hourPerDay)   +
131                                aStamp.Minutes     / static_cast<double>(::tools::Time::minutePerDay) +
132                                aStamp.Seconds     / static_cast<double>(::tools::Time::secondPerDay) +
133                                aStamp.NanoSeconds / static_cast<double>(::tools::Time::nanoSecPerDay);
134                         bEmptyFlag = xRow->wasNull();
135                         bValue = true;
136                     }
137                 }
138                 break;
139 
140             case sdbc::DataType::SQLNULL:
141                 bEmptyFlag = true;
142                 break;
143 
144             case sdbc::DataType::BINARY:
145             case sdbc::DataType::VARBINARY:
146             case sdbc::DataType::LONGVARBINARY:
147             default:
148                 bError = true;      // unknown type
149         }
150     }
151     catch ( uno::Exception& )
152     {
153         bError = true;
154     }
155 
156     if ( bValue && bCurrency )
157         nFormatIndex = rDoc.GetFormatTable()->GetStandardFormat(
158                             SvNumFormatType::CURRENCY, ScGlobal::eLnge );
159 
160     ScAddress aPos(nCol, nRow, nTab);
161     if (bEmptyFlag)
162         rDoc.SetEmptyCell(aPos);
163     else if (bError)
164     {
165         rDoc.SetError( nCol, nRow, nTab, FormulaError::NotAvailable );
166     }
167     else if (bValue)
168     {
169         rDoc.SetValue(aPos, nVal);
170         if (nFormatIndex)
171             rDoc.SetNumberFormat(aPos, nFormatIndex);
172     }
173     else
174     {
175         if (!aString.isEmpty())
176         {
177             if (ScStringUtil::isMultiline(aString))
178             {
179                 rDoc.SetEditText(aPos, aString);
180                 if (pStrData)
181                     pStrData->mbSimpleText = false;
182             }
183             else
184             {
185                 ScSetStringParam aParam;
186                 aParam.setTextInput();
187                 rDoc.SetString(aPos, aString, &aParam);
188                 if (pStrData)
189                     pStrData->mbSimpleText = true;
190             }
191 
192             if (pStrData)
193                 pStrData->mnStrLength = aString.getLength();
194         }
195         else
196             rDoc.SetEmptyCell(aPos);
197     }
198 }
199 
200 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
201