1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_dbaccess.hxx"
30 
31 #include "TokenWriter.hxx"
32 #include <com/sun/star/sdbc/XColumnLocate.hpp>
33 #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
34 #include "dbu_misc.hrc"
35 #include "sqlmessage.hxx"
36 #include <vcl/msgbox.hxx>
37 #include "dbustrings.hrc"
38 #include <com/sun/star/sdbc/XRowUpdate.hpp>
39 #include <functional>
40 #include <rtl/logfile.hxx>
41 
42 using namespace dbaui;
43 using namespace ::com::sun::star::uno;
44 using namespace ::com::sun::star::beans;
45 using namespace ::com::sun::star::container;
46 using namespace ::com::sun::star::util;
47 using namespace ::com::sun::star::sdbc;
48 using namespace ::com::sun::star::sdb;
49 using namespace ::com::sun::star::lang;
50 //	using namespace ::com::sun::star::sdbcx;
51 
52 // export data
53 ORowSetImportExport::ORowSetImportExport(	Window* _pParent,
54 											const Reference< XResultSetUpdate >& _xResultSetUpdate,
55 											const ::svx::ODataAccessDescriptor& _aDataDescriptor,
56 											const Reference< XMultiServiceFactory >& _rM,
57 											const String& rExchange
58 											)
59 											: ODatabaseImportExport(_aDataDescriptor,_rM,NULL,rExchange)
60 											,m_xTargetResultSetUpdate(_xResultSetUpdate)
61 											,m_xTargetRowUpdate(_xResultSetUpdate,UNO_QUERY)
62 											,m_pParent(_pParent)
63 											,m_bAlreadyAsked(sal_False)
64 {
65     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "misc", "Ocke.Janssen@sun.com", "ORowSetImportExport::ORowSetImportExport" );
66 	OSL_ENSURE(_pParent,"Window can't be null!");
67 }
68 // -----------------------------------------------------------------------------
69 void ORowSetImportExport::initialize()
70 {
71     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "misc", "Ocke.Janssen@sun.com", "ORowSetImportExport::initialize" );
72 	ODatabaseImportExport::initialize();
73 	// do namemapping
74 	Reference<XColumnLocate> xColumnLocate(m_xResultSet,UNO_QUERY);
75 	OSL_ENSURE(xColumnLocate.is(),"The rowset normally should support this");
76 
77 	m_xTargetResultSetMetaData = Reference<XResultSetMetaDataSupplier>(m_xTargetResultSetUpdate,UNO_QUERY)->getMetaData();
78 	if(!m_xTargetResultSetMetaData.is() || !xColumnLocate.is() || !m_xResultSetMetaData.is() )
79         throw SQLException(String(ModuleRes(STR_UNEXPECTED_ERROR)),*this,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("S1000")) ,0,Any());
80 
81 	sal_Int32 nCount = m_xTargetResultSetMetaData->getColumnCount();
82 	m_aColumnMapping.reserve(nCount);
83 	m_aColumnTypes.reserve(nCount);
84 	for (sal_Int32 i = 1;i <= nCount; ++i)
85 	{
86 		sal_Int32 nPos = -1; // -1 means column is autoincrement or doesn't exists
87 		if(!m_xTargetResultSetMetaData->isAutoIncrement(i))
88 		{
89 			try
90 			{
91 				::rtl::OUString sColumnName = m_xTargetResultSetMetaData->getColumnName(i);
92 				nPos = xColumnLocate->findColumn(sColumnName);
93 			}
94 			catch(const SQLException&)
95 			{
96 				if(m_xTargetResultSetMetaData->isNullable(i))
97 					nPos = 0; // column doesn't exists but we could set it to null
98 			}
99 		}
100 
101 		m_aColumnMapping.push_back(nPos);
102 		if(nPos > 0)
103 			m_aColumnTypes.push_back(m_xResultSetMetaData->getColumnType(nPos));
104 		else
105 			m_aColumnTypes.push_back(DataType::OTHER);
106 	}
107 }
108 // -----------------------------------------------------------------------------
109 sal_Bool ORowSetImportExport::Write()
110 {
111     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "misc", "Ocke.Janssen@sun.com", "ORowSetImportExport::Write" );
112 	return sal_True;
113 }
114 // -----------------------------------------------------------------------------
115 sal_Bool ORowSetImportExport::Read()
116 {
117     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "misc", "Ocke.Janssen@sun.com", "ORowSetImportExport::Read" );
118 	// check if there is any column to copy
119 	if(::std::find_if(m_aColumnMapping.begin(),m_aColumnMapping.end(),
120 						::std::bind2nd(::std::greater<sal_Int32>(),0)) == m_aColumnMapping.end())
121 		return sal_False;
122 	sal_Int32 nCurrentRow = 0;
123 	sal_Int32 nRowFilterIndex = 0;
124 	sal_Bool bContinue = sal_True;
125 	if(m_aSelection.getLength())
126 	{
127 		const Any* pBegin = m_aSelection.getConstArray();
128 		const Any* pEnd	  = pBegin + m_aSelection.getLength();
129 		for(;pBegin != pEnd && bContinue;++pBegin)
130 		{
131 			sal_Int32 nPos = -1;
132 			*pBegin >>= nPos;
133 			OSL_ENSURE(nPos != -1,"Invalid posiotion!");
134 			bContinue = (m_xResultSet.is() && m_xResultSet->absolute(nPos) && insertNewRow());
135 		}
136 	}
137 	else
138 	{
139 		Reference<XPropertySet> xProp(m_xResultSet,UNO_QUERY);
140 		sal_Int32 nRowCount = 0;
141 		if ( xProp.is() && xProp->getPropertySetInfo()->hasPropertyByName(PROPERTY_ISROWCOUNTFINAL) )
142 		{
143 			sal_Bool bFinal = sal_False;
144 			xProp->getPropertyValue(PROPERTY_ISROWCOUNTFINAL) >>= bFinal;
145 			if ( !bFinal )
146 				m_xResultSet->afterLast();
147 			xProp->getPropertyValue(PROPERTY_ROWCOUNT) >>= nRowCount;
148 		}
149 		if ( !nRowCount )
150 		{
151 			m_xResultSet->afterLast();
152 			nRowCount = m_xResultSet->getRow();
153 		}
154 		OSL_ENSURE(nRowCount,"RowCount is 0!");
155 		m_xResultSet->beforeFirst();
156 		while(m_xResultSet.is() && m_xResultSet->next() && bContinue && nRowCount )
157 		{
158 			--nRowCount;
159 			++nCurrentRow;
160 			if(!m_pRowMarker || m_pRowMarker[nRowFilterIndex] == nCurrentRow)
161 			{
162 				++nRowFilterIndex;
163 				bContinue = insertNewRow();
164 			}
165 		}
166 	}
167 	return sal_True;
168 }
169 // -----------------------------------------------------------------------------
170 sal_Bool ORowSetImportExport::insertNewRow()
171 {
172     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "misc", "Ocke.Janssen@sun.com", "ORowSetImportExport::insertNewRow" );
173 	try
174 	{
175 		m_xTargetResultSetUpdate->moveToInsertRow();
176 		sal_Int32 i = 1;
177         ::std::vector<sal_Int32>::iterator aEnd = m_aColumnMapping.end();
178 		for (::std::vector<sal_Int32>::iterator aIter = m_aColumnMapping.begin(); aIter != aEnd ;++aIter,++i )
179 		{
180 			if(*aIter > 0)
181 			{
182 				Any aValue;
183 				switch(m_aColumnTypes[i-1])
184 				{
185 					case DataType::CHAR:
186 					case DataType::VARCHAR:
187 						aValue <<= m_xRow->getString(*aIter);
188 						break;
189 					case DataType::DECIMAL:
190 					case DataType::NUMERIC:
191 						aValue <<= m_xRow->getDouble(*aIter);
192 						break;
193 					case DataType::BIGINT:
194 						aValue <<= m_xRow->getLong(*aIter);
195 						break;
196 					case DataType::FLOAT:
197 						aValue <<= m_xRow->getFloat(*aIter);
198 						break;
199 					case DataType::DOUBLE:
200 						aValue <<= m_xRow->getDouble(*aIter);
201 						break;
202 					case DataType::LONGVARCHAR:
203 						aValue <<= m_xRow->getString(*aIter);
204 						break;
205 					case DataType::LONGVARBINARY:
206 						aValue <<= m_xRow->getBytes(*aIter);
207 						break;
208 					case DataType::DATE:
209 						aValue <<= m_xRow->getDate(*aIter);
210 						break;
211 					case DataType::TIME:
212 						aValue <<= m_xRow->getTime(*aIter);
213 						break;
214 					case DataType::TIMESTAMP:
215 						aValue <<= m_xRow->getTimestamp(*aIter);
216 						break;
217 					case DataType::BIT:
218 					case DataType::BOOLEAN:
219 						aValue <<= m_xRow->getBoolean(*aIter);
220 						break;
221 					case DataType::TINYINT:
222 						aValue <<= m_xRow->getByte(*aIter);
223 						break;
224 					case DataType::SMALLINT:
225 						aValue <<= m_xRow->getShort(*aIter);
226 						break;
227 					case DataType::INTEGER:
228 						aValue <<= m_xRow->getInt(*aIter);
229 						break;
230 					case DataType::REAL:
231 						aValue <<= m_xRow->getDouble(*aIter);
232 						break;
233 					case DataType::BINARY:
234 					case DataType::VARBINARY:
235 						aValue <<= m_xRow->getBytes(*aIter);
236 						break;
237 					case DataType::BLOB:
238 						aValue <<= m_xRow->getBlob(*aIter);
239 						break;
240 					case DataType::CLOB:
241 						aValue <<= m_xRow->getClob(*aIter);
242 						break;
243 					default:
244 						OSL_ENSURE(0,"Unknown type");
245 				}
246 				if(m_xRow->wasNull())
247 					m_xTargetRowUpdate->updateNull(i);
248 				else
249 					m_xTargetRowUpdate->updateObject(i,aValue);
250 			}
251 			else if(*aIter == 0)//now we have know that we to set this column to null
252                 m_xTargetRowUpdate->updateNull(i);
253 		}
254 		m_xTargetResultSetUpdate->insertRow();
255 	}
256 	catch(const SQLException&)
257 	{
258 		if(!m_bAlreadyAsked)
259 		{
260 			String sAskIfContinue = String(ModuleRes(STR_ERROR_OCCURED_WHILE_COPYING));
261 			OSQLWarningBox aDlg( m_pParent, sAskIfContinue, WB_YES_NO | WB_DEF_YES );
262 			if(aDlg.Execute() == RET_YES)
263 				m_bAlreadyAsked = sal_True;
264 			else
265 				return sal_False;
266 		}
267 	}
268 	return sal_True;
269 }
270 // -----------------------------------------------------------------------------
271 
272 
273 
274