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_connectivity.hxx"
30 #include "TDatabaseMetaDataBase.hxx"
31 #include "RowFunctionParser.hxx"
32 
33 #include <comphelper/sequenceashashmap.hxx>
34 #include <comphelper/evtlistenerhlp.hxx>
35 #include <com/sun/star/lang/XComponent.hpp>
36 #include "resource/sharedresources.hxx"
37 #include "resource/common_res.hrc"
38 #include <connectivity/dbexception.hxx>
39 
40 using namespace com::sun::star::uno;
41 using namespace com::sun::star::lang;
42 using namespace com::sun::star::sdbc;
43 using namespace com::sun::star::lang;
44 using namespace com::sun::star::beans;
45 using namespace comphelper;
46 using namespace connectivity;
47 
48 
49 ODatabaseMetaDataBase::ODatabaseMetaDataBase(const Reference< XConnection >& _rxConnection,const Sequence< PropertyValue >& _rInfo)
50     : m_aConnectionInfo(_rInfo)
51     ,m_isCatalogAtStart(false,sal_False)
52     ,m_sCatalogSeparator(false,::rtl::OUString())
53     ,m_sIdentifierQuoteString(false,::rtl::OUString())
54     ,m_supportsCatalogsInTableDefinitions(false,sal_False)
55     ,m_supportsSchemasInTableDefinitions(false,sal_False)
56     ,m_supportsCatalogsInDataManipulation(false,sal_False)
57     ,m_supportsSchemasInDataManipulation(false,sal_False)
58     ,m_supportsMixedCaseQuotedIdentifiers(false,sal_False)
59     ,m_supportsAlterTableWithAddColumn(false,sal_False)
60     ,m_supportsAlterTableWithDropColumn(false,sal_False)
61     ,m_MaxStatements(false,0)
62     ,m_MaxTablesInSelect(false,0)
63     ,m_storesMixedCaseQuotedIdentifiers(false,sal_False)
64 	, m_xConnection(_rxConnection)
65 {
66 	osl_incrementInterlockedCount( &m_refCount );
67 	{
68 		m_xListenerHelper = new OEventListenerHelper(this);
69 		Reference<XComponent> xCom(m_xConnection,UNO_QUERY);
70 		if(xCom.is())
71 			xCom->addEventListener(m_xListenerHelper);
72 	}
73 	osl_decrementInterlockedCount( &m_refCount );
74 }
75 // -------------------------------------------------------------------------
76 ODatabaseMetaDataBase::~ODatabaseMetaDataBase()
77 {
78 }
79 
80 // -----------------------------------------------------------------------------
81 Sequence< PropertyValue > SAL_CALL ODatabaseMetaDataBase::getConnectionInfo(  ) throw (RuntimeException)
82 {
83     return m_aConnectionInfo;
84 }
85 
86 // -----------------------------------------------------------------------------
87 void SAL_CALL ODatabaseMetaDataBase::disposing( const EventObject& /*Source*/ ) throw(RuntimeException)
88 {
89 	// cut off all references to the connection
90 m_xConnection.clear();
91 m_xListenerHelper.clear();
92 }
93 // -----------------------------------------------------------------------------
94 Reference< XResultSet > SAL_CALL ODatabaseMetaDataBase::getTypeInfo(  ) throw(SQLException, RuntimeException)
95 {
96     ::osl::MutexGuard aGuard( m_aMutex );
97     if ( m_aTypeInfoRows.empty() )
98     {
99         Reference< XResultSet > xRet = impl_getTypeInfo_throw();
100         Reference< XRow > xRow(xRet,UNO_QUERY);
101         ::comphelper::SequenceAsHashMap aMap(m_aConnectionInfo);
102         Sequence< Any > aTypeInfoSettings;
103         aTypeInfoSettings = aMap.getUnpackedValueOrDefault(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TypeInfoSettings")),aTypeInfoSettings);
104 
105         if ( xRow.is() )
106         {
107             static sal_Int32 pTypes[] = {
108                                         DataType::VARCHAR
109                                         ,DataType::INTEGER
110                                         ,DataType::INTEGER
111                                         ,DataType::VARCHAR
112                                         ,DataType::VARCHAR
113                                         ,DataType::VARCHAR
114                                         ,DataType::INTEGER
115                                         ,DataType::BOOLEAN
116                                         ,DataType::INTEGER
117                                         ,DataType::BOOLEAN
118                                         ,DataType::BOOLEAN
119                                         ,DataType::BOOLEAN
120                                         ,DataType::VARCHAR
121                                         ,DataType::INTEGER
122                                         ,DataType::INTEGER
123                                         ,DataType::INTEGER
124                                         ,DataType::INTEGER
125                                         ,DataType::INTEGER
126                                     };
127             ::std::vector<ExpressionNodeSharedPtr> aConditions;
128             if ( aTypeInfoSettings.getLength() > 1 && ((aTypeInfoSettings.getLength() % 2) == 0) )
129             {
130                 const Any* pIter = aTypeInfoSettings.getConstArray();
131                 const Any* pEnd	 = pIter + aTypeInfoSettings.getLength();
132                 try
133                 {
134                     for(;pIter != pEnd;++pIter)
135                         aConditions.push_back(FunctionParser::parseFunction(::comphelper::getString(*pIter)));
136                 }
137                 catch(ParseError&)
138                 {
139                     ::connectivity::SharedResources aResources;
140                     const ::rtl::OUString sError( aResources.getResourceString(STR_FORMULA_WRONG));
141                     ::dbtools::throwGenericSQLException(sError,*this);
142                 }
143             }
144 
145             ::connectivity::ODatabaseMetaDataResultSet::ORows aTypeInfoRows;
146             while( xRet->next() )
147             {
148                 ::connectivity::ODatabaseMetaDataResultSet::ORow aRow;
149                 aRow.push_back(ODatabaseMetaDataResultSet::getEmptyValue());
150                 sal_Int32* pType = pTypes;
151                 for (sal_Int32 i = 1; i <= sal_Int32(sizeof(pTypes)/sizeof(pTypes[0])); ++i,++pType)
152                 {
153                     ORowSetValue aValue;
154                     aValue.fill(i,*pType,xRow);
155                     aRow.push_back(new ORowSetValueDecorator(aValue));
156                 }
157 
158                 ::std::vector<ExpressionNodeSharedPtr>::iterator aIter = aConditions.begin();
159                 ::std::vector<ExpressionNodeSharedPtr>::iterator aEnd = aConditions.end();
160                 for (; aIter != aEnd; ++aIter)
161                 {
162                     if ( (*aIter)->evaluate(aRow)->getValue().getBool() )
163                     {
164                         ++aIter;
165                         (*aIter)->fill(aRow);
166                     }
167                     else
168                         ++aIter;
169                 }
170                 aTypeInfoRows.push_back(aRow);
171             }
172             m_aTypeInfoRows = aTypeInfoRows;
173         }
174     }
175     ::connectivity::ODatabaseMetaDataResultSet* pResult = new ::connectivity::ODatabaseMetaDataResultSet(::connectivity::ODatabaseMetaDataResultSet::eTypeInfo);
176 	Reference< XResultSet > xRet = pResult;
177 	pResult->setRows(m_aTypeInfoRows);
178     return xRet;
179 }
180 // -------------------------------------------------------------------------
181 Reference< XResultSet > SAL_CALL ODatabaseMetaDataBase::getExportedKeys(
182         const Any& /*catalog*/, const ::rtl::OUString& /*schema*/, const ::rtl::OUString& /*table*/ ) throw(SQLException, RuntimeException)
183 {
184     return new ODatabaseMetaDataResultSet( ODatabaseMetaDataResultSet::eExportedKeys );
185 }
186 // -------------------------------------------------------------------------
187 Reference< XResultSet > SAL_CALL ODatabaseMetaDataBase::getImportedKeys(
188         const Any& /*catalog*/, const ::rtl::OUString& /*schema*/, const ::rtl::OUString& /*table*/ ) throw(SQLException, RuntimeException)
189 {
190     return new ODatabaseMetaDataResultSet( ODatabaseMetaDataResultSet::eImportedKeys );
191 }
192 // -------------------------------------------------------------------------
193 Reference< XResultSet > SAL_CALL ODatabaseMetaDataBase::getPrimaryKeys(
194         const Any& /*catalog*/, const ::rtl::OUString& /*schema*/, const ::rtl::OUString& /*table*/ ) throw(SQLException, RuntimeException)
195 {
196     return new ODatabaseMetaDataResultSet( ODatabaseMetaDataResultSet::ePrimaryKeys );
197 }
198 // -------------------------------------------------------------------------
199 Reference< XResultSet > SAL_CALL ODatabaseMetaDataBase::getIndexInfo(
200         const Any& /*catalog*/, const ::rtl::OUString& /*schema*/, const ::rtl::OUString& /*table*/,
201         sal_Bool /*unique*/, sal_Bool /*approximate*/ ) throw(SQLException, RuntimeException)
202 {
203     return new ODatabaseMetaDataResultSet( ODatabaseMetaDataResultSet::eIndexInfo );
204 }
205 // -------------------------------------------------------------------------
206 Reference< XResultSet > SAL_CALL ODatabaseMetaDataBase::getBestRowIdentifier(
207         const Any& /*catalog*/, const ::rtl::OUString& /*schema*/, const ::rtl::OUString& /*table*/, sal_Int32 /*scope*/,
208         sal_Bool /*nullable*/ ) throw(SQLException, RuntimeException)
209 {
210     return new ODatabaseMetaDataResultSet( ODatabaseMetaDataResultSet::eBestRowIdentifier );
211 }
212 // -------------------------------------------------------------------------
213 Reference< XResultSet > SAL_CALL ODatabaseMetaDataBase::getCrossReference(
214         const Any& /*primaryCatalog*/, const ::rtl::OUString& /*primarySchema*/,
215         const ::rtl::OUString& /*primaryTable*/, const Any& /*foreignCatalog*/,
216         const ::rtl::OUString& /*foreignSchema*/, const ::rtl::OUString& /*foreignTable*/ ) throw(SQLException, RuntimeException)
217 {
218     return new ODatabaseMetaDataResultSet( ODatabaseMetaDataResultSet::eCrossReference );
219 }
220 // -------------------------------------------------------------------------
221 Reference< XConnection > SAL_CALL ODatabaseMetaDataBase::getConnection(  ) throw(SQLException, RuntimeException)
222 {
223     return m_xConnection;
224 }
225 // -------------------------------------------------------------------------
226 Reference< XResultSet > SAL_CALL ODatabaseMetaDataBase::getProcedureColumns(
227         const Any& /*catalog*/, const ::rtl::OUString& /*schemaPattern*/,
228         const ::rtl::OUString& /*procedureNamePattern*/, const ::rtl::OUString& /*columnNamePattern*/ ) throw(SQLException, RuntimeException)
229 {
230     return new ODatabaseMetaDataResultSet( ODatabaseMetaDataResultSet::eProcedureColumns );
231 }
232 // -------------------------------------------------------------------------
233 Reference< XResultSet > SAL_CALL ODatabaseMetaDataBase::getProcedures(
234         const Any& /*catalog*/, const ::rtl::OUString& /*schemaPattern*/,
235         const ::rtl::OUString& /*procedureNamePattern*/ ) throw(SQLException, RuntimeException)
236 {
237     return new ODatabaseMetaDataResultSet( ODatabaseMetaDataResultSet::eProcedures );
238 }
239 // -------------------------------------------------------------------------
240 Reference< XResultSet > SAL_CALL ODatabaseMetaDataBase::getVersionColumns(
241         const Any& /*catalog*/, const ::rtl::OUString& /*schema*/, const ::rtl::OUString& /*table*/ ) throw(SQLException, RuntimeException)
242 {
243     return new ODatabaseMetaDataResultSet( ODatabaseMetaDataResultSet::eVersionColumns );
244 }
245 // -------------------------------------------------------------------------
246 Reference< XResultSet > SAL_CALL ODatabaseMetaDataBase::getSchemas(  ) throw(SQLException, RuntimeException)
247 {
248     return new ODatabaseMetaDataResultSet( ODatabaseMetaDataResultSet::eSchemas );
249 }
250 // -------------------------------------------------------------------------
251 Reference< XResultSet > SAL_CALL ODatabaseMetaDataBase::getColumnPrivileges(
252         const Any& /*catalog*/, const ::rtl::OUString& /*schema*/, const ::rtl::OUString& /*table*/,
253         const ::rtl::OUString& /*columnNamePattern*/ ) throw(SQLException, RuntimeException)
254 {
255     return new ODatabaseMetaDataResultSet( ODatabaseMetaDataResultSet::eColumnPrivileges );
256 }
257 // -------------------------------------------------------------------------
258 Reference< XResultSet > SAL_CALL ODatabaseMetaDataBase::getTablePrivileges(
259         const Any& /*catalog*/, const ::rtl::OUString& /*schema*/, const ::rtl::OUString& /*table*/) throw(SQLException, RuntimeException)
260 {
261     return new ODatabaseMetaDataResultSet( ODatabaseMetaDataResultSet::eTablePrivileges );
262 }
263 // -------------------------------------------------------------------------
264 Reference< XResultSet > SAL_CALL ODatabaseMetaDataBase::getCatalogs(  ) throw(SQLException, RuntimeException)
265 {
266     return new ODatabaseMetaDataResultSet( ODatabaseMetaDataResultSet::eCatalogs );
267 }
268 // -----------------------------------------------------------------------------
269 ::rtl::OUString SAL_CALL ODatabaseMetaDataBase::getIdentifierQuoteString(  ) throw(SQLException, RuntimeException)
270 {
271     return callImplMethod(m_sIdentifierQuoteString,::std::mem_fun_t< ::rtl::OUString ,ODatabaseMetaDataBase>(&ODatabaseMetaDataBase::impl_getIdentifierQuoteString_throw));
272 }
273 // -----------------------------------------------------------------------------
274 sal_Bool SAL_CALL ODatabaseMetaDataBase::isCatalogAtStart(  ) throw(SQLException, RuntimeException)
275 {
276     return callImplMethod(m_isCatalogAtStart,::std::mem_fun_t< sal_Bool,ODatabaseMetaDataBase>(&ODatabaseMetaDataBase::impl_isCatalogAtStart_throw));
277 }
278 // -----------------------------------------------------------------------------
279 ::rtl::OUString SAL_CALL ODatabaseMetaDataBase::getCatalogSeparator(  ) throw(SQLException, RuntimeException)
280 {
281     return callImplMethod(m_sCatalogSeparator,::std::mem_fun_t< ::rtl::OUString,ODatabaseMetaDataBase>(&ODatabaseMetaDataBase::impl_getCatalogSeparator_throw));
282 }
283 // -----------------------------------------------------------------------------
284 sal_Bool SAL_CALL ODatabaseMetaDataBase::supportsCatalogsInTableDefinitions(  ) throw(SQLException, RuntimeException)
285 {
286     return callImplMethod(m_supportsCatalogsInTableDefinitions,::std::mem_fun_t< sal_Bool,ODatabaseMetaDataBase>(&ODatabaseMetaDataBase::impl_supportsCatalogsInTableDefinitions_throw));
287 }
288 // -----------------------------------------------------------------------------
289 sal_Bool SAL_CALL ODatabaseMetaDataBase::supportsSchemasInTableDefinitions(  ) throw(SQLException, RuntimeException)
290 {
291     return callImplMethod(m_supportsSchemasInTableDefinitions,::std::mem_fun_t< sal_Bool,ODatabaseMetaDataBase>(&ODatabaseMetaDataBase::impl_supportsSchemasInTableDefinitions_throw));
292 }
293 // -----------------------------------------------------------------------------
294 sal_Bool SAL_CALL ODatabaseMetaDataBase::supportsCatalogsInDataManipulation(  ) throw(SQLException, RuntimeException)
295 {
296     return callImplMethod(m_supportsCatalogsInDataManipulation,::std::mem_fun_t< sal_Bool,ODatabaseMetaDataBase>(&ODatabaseMetaDataBase::impl_supportsCatalogsInDataManipulation_throw));
297 }
298 // -----------------------------------------------------------------------------
299 sal_Bool SAL_CALL ODatabaseMetaDataBase::supportsSchemasInDataManipulation(  ) throw(SQLException, RuntimeException)
300 {
301     return callImplMethod(m_supportsSchemasInDataManipulation,::std::mem_fun_t< sal_Bool,ODatabaseMetaDataBase>(&ODatabaseMetaDataBase::impl_supportsSchemasInDataManipulation_throw));
302 }
303 // -----------------------------------------------------------------------------
304 sal_Bool SAL_CALL ODatabaseMetaDataBase::supportsMixedCaseQuotedIdentifiers(  ) throw(SQLException, RuntimeException)
305 {
306     return callImplMethod(m_supportsMixedCaseQuotedIdentifiers,::std::mem_fun_t< sal_Bool,ODatabaseMetaDataBase>(&ODatabaseMetaDataBase::impl_supportsMixedCaseQuotedIdentifiers_throw));
307 }
308 // -----------------------------------------------------------------------------
309 sal_Bool SAL_CALL ODatabaseMetaDataBase::supportsAlterTableWithAddColumn(  ) throw(SQLException, RuntimeException)
310 {
311     return callImplMethod(m_supportsAlterTableWithAddColumn,::std::mem_fun_t< sal_Bool,ODatabaseMetaDataBase>(&ODatabaseMetaDataBase::impl_supportsAlterTableWithAddColumn_throw));
312 }
313 // -----------------------------------------------------------------------------
314 sal_Bool SAL_CALL ODatabaseMetaDataBase::supportsAlterTableWithDropColumn(  ) throw(SQLException, RuntimeException)
315 {
316     return callImplMethod(m_supportsAlterTableWithDropColumn,::std::mem_fun_t< sal_Bool,ODatabaseMetaDataBase>(&ODatabaseMetaDataBase::impl_supportsAlterTableWithDropColumn_throw));
317 }
318 // -----------------------------------------------------------------------------
319 sal_Int32 SAL_CALL ODatabaseMetaDataBase::getMaxStatements(  ) throw(SQLException, RuntimeException)
320 {
321     return callImplMethod(m_MaxStatements,::std::mem_fun_t< sal_Int32,ODatabaseMetaDataBase>(&ODatabaseMetaDataBase::impl_getMaxStatements_throw));
322 }
323 // -----------------------------------------------------------------------------
324 sal_Int32 SAL_CALL ODatabaseMetaDataBase::getMaxTablesInSelect(  ) throw(SQLException, RuntimeException)
325 {
326     return callImplMethod(m_MaxTablesInSelect,::std::mem_fun_t< sal_Int32,ODatabaseMetaDataBase>(&ODatabaseMetaDataBase::impl_getMaxTablesInSelect_throw));
327 }
328 // -----------------------------------------------------------------------------
329 sal_Bool SAL_CALL ODatabaseMetaDataBase::storesMixedCaseQuotedIdentifiers(  ) throw(SQLException, RuntimeException)
330 {
331     return callImplMethod(m_storesMixedCaseQuotedIdentifiers,::std::mem_fun_t< sal_Bool,ODatabaseMetaDataBase>(&ODatabaseMetaDataBase::impl_storesMixedCaseQuotedIdentifiers_throw));
332 }
333 // -----------------------------------------------------------------------------
334