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