1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: BTable.cxx,v $
10 * $Revision: 1.36.56.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_connectivity.hxx"
33 #include "adabas/BTable.hxx"
34 #include "adabas/BTables.hxx"
35 #include "adabas/BIndexes.hxx"
36 #include "adabas/BColumns.hxx"
37 #include "adabas/BKeys.hxx"
38 #include <com/sun/star/sdbc/XRow.hpp>
39 #include <com/sun/star/sdbc/XResultSet.hpp>
40 #include <com/sun/star/sdbcx/KeyType.hpp>
41 #include <com/sun/star/sdbc/KeyRule.hpp>
42 #include <cppuhelper/typeprovider.hxx>
43 #include <com/sun/star/lang/DisposedException.hpp>
44 #include <com/sun/star/sdbc/ColumnValue.hpp>
45 #include <comphelper/sequence.hxx>
46 #include <comphelper/extract.hxx>
47 #include <comphelper/types.hxx>
48 #include "connectivity/dbtools.hxx"
49 #include "adabas/BCatalog.hxx"
52 using namespace ::comphelper
;
53 using namespace connectivity::adabas
;
54 using namespace connectivity
;
55 using namespace ::com::sun::star::uno
;
56 using namespace ::com::sun::star::beans
;
57 using namespace ::com::sun::star::sdbcx
;
58 using namespace ::com::sun::star::sdbc
;
59 using namespace ::com::sun::star::container
;
60 using namespace ::com::sun::star::lang
;
62 OAdabasTable::OAdabasTable( sdbcx::OCollection
* _pTables
,
63 OAdabasConnection
* _pConnection
)
64 :OTable_TYPEDEF(_pTables
,_pConnection
,sal_True
)
65 ,m_pConnection(_pConnection
)
69 // -------------------------------------------------------------------------
70 OAdabasTable::OAdabasTable( sdbcx::OCollection
* _pTables
,
71 OAdabasConnection
* _pConnection
,
72 const ::rtl::OUString
& _Name
,
73 const ::rtl::OUString
& _Type
,
74 const ::rtl::OUString
& _Description
,
75 const ::rtl::OUString
& _SchemaName
,
76 const ::rtl::OUString
& _CatalogName
77 ) : OTableHelper( _pTables
,
85 ,m_pConnection(_pConnection
)
89 // -----------------------------------------------------------------------------
90 sdbcx::OCollection
* OAdabasTable::createColumns(const TStringVector
& _rNames
)
92 return new OColumns(this,m_aMutex
,_rNames
);
94 // -----------------------------------------------------------------------------
95 sdbcx::OCollection
* OAdabasTable::createKeys(const TStringVector
& _rNames
)
97 return new OKeys(this,m_aMutex
,_rNames
);
99 // -----------------------------------------------------------------------------
100 sdbcx::OCollection
* OAdabasTable::createIndexes(const TStringVector
& _rNames
)
102 return new OIndexes(this,m_aMutex
,_rNames
);
104 //--------------------------------------------------------------------------
105 Sequence
< sal_Int8
> OAdabasTable::getUnoTunnelImplementationId()
107 static ::cppu::OImplementationId
* pId
= 0;
110 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
113 static ::cppu::OImplementationId aId
;
117 return pId
->getImplementationId();
120 // com::sun::star::lang::XUnoTunnel
121 //------------------------------------------------------------------
122 sal_Int64
OAdabasTable::getSomething( const Sequence
< sal_Int8
> & rId
) throw (RuntimeException
)
124 return (rId
.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(), rId
.getConstArray(), 16 ) )
125 ? reinterpret_cast< sal_Int64
>( this )
126 : OTable_TYPEDEF::getSomething(rId
);
128 // -------------------------------------------------------------------------
130 void SAL_CALL
OAdabasTable::alterColumnByName( const ::rtl::OUString
& colName
, const Reference
< XPropertySet
>& descriptor
) throw(SQLException
, NoSuchElementException
, RuntimeException
)
132 ::osl::MutexGuard
aGuard(m_aMutex
);
135 ::connectivity::sdbcx::OTableDescriptor_BASE::rBHelper
.bDisposed
141 if(m_pColumns
&& !m_pColumns
->hasByName(colName
))
142 throw NoSuchElementException(colName
,*this);
151 // first we have to check what should be altered
152 Reference
<XPropertySet
> xProp
;
153 m_pColumns
->getByName(colName
) >>= xProp
;
154 // first check the types
155 sal_Int32 nOldType
= 0,nNewType
= 0,nOldPrec
= 0,nNewPrec
= 0,nOldScale
= 0,nNewScale
= 0;
157 xProp
->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE
)) >>= nOldType
;
158 descriptor
->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE
)) >>= nNewType
;
159 // and precsions and scale
160 xProp
->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PRECISION
)) >>= nOldPrec
;
161 descriptor
->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PRECISION
))>>= nNewPrec
;
162 xProp
->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE
)) >>= nOldScale
;
163 descriptor
->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE
)) >>= nNewScale
;
165 if(nOldType
!= nNewType
|| nOldPrec
!= nNewPrec
|| nOldScale
!= nNewScale
)
166 alterColumnType(colName
,descriptor
);
168 // second: check the "is nullable" value
169 sal_Int32 nOldNullable
= 0,nNewNullable
= 0;
170 xProp
->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISNULLABLE
)) >>= nOldNullable
;
171 descriptor
->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISNULLABLE
)) >>= nNewNullable
;
172 if(nNewNullable
!= nOldNullable
)
173 alterNotNullValue(nNewNullable
,colName
);
175 // third: check the default values
176 ::rtl::OUString sNewDefault
,sOldDefault
;
177 xProp
->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DEFAULTVALUE
)) >>= sOldDefault
;
178 descriptor
->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DEFAULTVALUE
)) >>= sNewDefault
;
180 if(sOldDefault
.getLength())
182 if(sNewDefault
.getLength() && sOldDefault
!= sNewDefault
)
183 alterDefaultValue(sNewDefault
,colName
);
184 else if(!sNewDefault
.getLength())
185 dropDefaultValue(colName
);
187 else if(!sOldDefault
.getLength() && sNewDefault
.getLength())
188 addDefaultValue(sNewDefault
,colName
);
190 // now we should look if the name of the column changed
191 ::rtl::OUString sNewColumnName
;
192 descriptor
->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME
)) >>= sNewColumnName
;
193 if(!sNewColumnName
.equalsIgnoreAsciiCase(colName
))
195 const ::rtl::OUString sQuote
= m_pConnection
->getMetaData()->getIdentifierQuoteString( );
196 const ::rtl::OUString
& sDot
= OAdabasCatalog::getDot();
198 ::rtl::OUString sSql
= ::rtl::OUString::createFromAscii("RENAME COLUMN ") ;
199 sSql
+= ::dbtools::quoteName(sQuote
,m_SchemaName
) + sDot
+ ::dbtools::quoteName(sQuote
,m_Name
);
200 sSql
+= sDot
+ ::dbtools::quoteName(sQuote
,colName
);
201 sSql
+= ::rtl::OUString::createFromAscii(" TO ");
202 sSql
+= ::dbtools::quoteName(sQuote
,sNewColumnName
);
204 Reference
< XStatement
> xStmt
= m_pConnection
->createStatement( );
207 xStmt
->execute(sSql
);
208 ::comphelper::disposeComponent(xStmt
);
211 m_pColumns
->refresh();
213 catch(const SQLException
&)
215 rollbackTransAction();
224 m_pColumns
->dropByName(colName
);
225 m_pColumns
->appendByDescriptor(descriptor
);
230 // -------------------------------------------------------------------------
231 ::rtl::OUString SAL_CALL
OAdabasTable::getName() throw(::com::sun::star::uno::RuntimeException
)
233 ::rtl::OUString sName
= m_SchemaName
;
234 if(m_SchemaName
.getLength())
236 const ::rtl::OUString
& sDot
= OAdabasCatalog::getDot();
242 // -----------------------------------------------------------------------------
243 void OAdabasTable::alterColumnType(const ::rtl::OUString
& _rColName
, const Reference
<XPropertySet
>& _xDescriptor
)
245 ::rtl::OUString sSql
= getAlterTableColumnPart(_rColName
);
246 sSql
+= ::rtl::OUString::createFromAscii(" ");
247 sSql
+= OTables::getColumnSqlType(_xDescriptor
);
249 Reference
< XStatement
> xStmt
= m_pConnection
->createStatement( );
252 xStmt
->execute(sSql
);
253 ::comphelper::disposeComponent(xStmt
);
256 // -----------------------------------------------------------------------------
257 void OAdabasTable::alterNotNullValue(sal_Int32 _nNewNullable
,const ::rtl::OUString
& _rColName
)
259 ::rtl::OUString sSql
= getAlterTableColumnPart(_rColName
);
261 if(_nNewNullable
== ColumnValue::NO_NULLS
)
263 sSql
+= ::rtl::OUString::createFromAscii(" NOT NULL");
267 sSql
+= ::rtl::OUString::createFromAscii(" DEFAULT NULL");
270 Reference
< XStatement
> xStmt
= m_pConnection
->createStatement();
273 xStmt
->execute(sSql
);
274 ::comphelper::disposeComponent(xStmt
);
277 // -----------------------------------------------------------------------------
278 void OAdabasTable::alterDefaultValue(const ::rtl::OUString
& _sNewDefault
,const ::rtl::OUString
& _rColName
)
280 ::rtl::OUString sSql
= getAlterTableColumnPart(_rColName
);
281 sSql
+= ::rtl::OUString::createFromAscii(" ALTER ") + _sNewDefault
;
283 Reference
< XStatement
> xStmt
= m_pConnection
->createStatement();
286 xStmt
->execute(sSql
);
287 ::comphelper::disposeComponent(xStmt
);
290 // -----------------------------------------------------------------------------
291 void OAdabasTable::dropDefaultValue(const ::rtl::OUString
& _rColName
)
293 ::rtl::OUString sSql
= getAlterTableColumnPart(_rColName
);
294 sSql
+= ::rtl::OUString::createFromAscii(" DROP DEFAULT");
296 Reference
< XStatement
> xStmt
= m_pConnection
->createStatement();
299 xStmt
->execute(sSql
);
300 ::comphelper::disposeComponent(xStmt
);
303 // -----------------------------------------------------------------------------
304 void OAdabasTable::addDefaultValue(const ::rtl::OUString
& _sNewDefault
,const ::rtl::OUString
& _rColName
)
306 ::rtl::OUString sSql
= getAlterTableColumnPart(_rColName
);
307 sSql
+= ::rtl::OUString::createFromAscii(" ADD ") + _sNewDefault
;
309 Reference
< XStatement
> xStmt
= m_pConnection
->createStatement();
312 xStmt
->execute(sSql
);
313 ::comphelper::disposeComponent(xStmt
);
316 // -----------------------------------------------------------------------------
317 void OAdabasTable::beginTransAction()
321 Reference
< XStatement
> xStmt
= m_pConnection
->createStatement();
324 xStmt
->execute(::rtl::OUString::createFromAscii("SUBTRANS BEGIN") );
325 ::comphelper::disposeComponent(xStmt
);
328 catch(const Exception
&)
332 // -----------------------------------------------------------------------------
333 void OAdabasTable::endTransAction()
337 Reference
< XStatement
> xStmt
= m_pConnection
->createStatement();
340 xStmt
->execute(::rtl::OUString::createFromAscii("SUBTRANS END") );
341 ::comphelper::disposeComponent(xStmt
);
344 catch(const Exception
&)
348 // -----------------------------------------------------------------------------
349 void OAdabasTable::rollbackTransAction()
353 Reference
< XStatement
> xStmt
= m_pConnection
->createStatement();
356 xStmt
->execute(::rtl::OUString::createFromAscii("SUBTRANS ROLLBACK") );
357 ::comphelper::disposeComponent(xStmt
);
360 catch(const Exception
&)
364 // -----------------------------------------------------------------------------
365 ::rtl::OUString
OAdabasTable::getAlterTableColumnPart(const ::rtl::OUString
& _rsColumnName
)
367 ::rtl::OUString sSql
= ::rtl::OUString::createFromAscii("ALTER TABLE ");
368 const ::rtl::OUString sQuote
= m_pConnection
->getMetaData()->getIdentifierQuoteString( );
369 const ::rtl::OUString
& sDot
= OAdabasCatalog::getDot();
371 sSql
+= ::dbtools::quoteName(sQuote
,m_SchemaName
) + sDot
+ ::dbtools::quoteName(sQuote
,m_Name
)
372 + ::rtl::OUString::createFromAscii(" COLUMN ")
373 + ::dbtools::quoteName(sQuote
,_rsColumnName
);
376 // -----------------------------------------------------------------------------