LibreOffice Module connectivity (master) 1
YTable.cxx
Go to the documentation of this file.
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 <mysql/YTable.hxx>
21#include <mysql/YTables.hxx>
22#include <com/sun/star/beans/PropertyAttribute.hpp>
23#include <com/sun/star/sdbcx/Privilege.hpp>
26#include <comphelper/types.hxx>
31#include <mysql/YColumns.hxx>
32#include <TConnection.hxx>
33
34using namespace ::comphelper;
35using namespace connectivity::mysql;
36using namespace connectivity::sdbcx;
37using namespace connectivity;
38using namespace ::com::sun::star::uno;
39using namespace ::com::sun::star::beans;
40using namespace ::com::sun::star::sdbcx;
41using namespace ::com::sun::star::sdbc;
42using namespace ::com::sun::star::container;
43using namespace ::com::sun::star::lang;
45{
46namespace
47{
48class OMySQLKeysHelper : public OKeysHelper
49{
50protected:
51 virtual OUString getDropForeignKey() const override { return " DROP FOREIGN KEY "; }
52
53public:
54 OMySQLKeysHelper(OTableHelper* _pTable, ::osl::Mutex& _rMutex,
55 const ::std::vector<OUString>& _rVector)
56 : OKeysHelper(_pTable, _rMutex, _rVector)
57 {
58 }
59};
60}
61}
62
63OMySQLTable::OMySQLTable(sdbcx::OCollection* _pTables, const Reference<XConnection>& _xConnection)
64 : OTableHelper(_pTables, _xConnection, true)
65{
66 // we create a new table here, so we should have all the rights or ;-)
67 m_nPrivileges = Privilege::DROP | Privilege::REFERENCE | Privilege::ALTER | Privilege::CREATE
68 | Privilege::READ | Privilege::DELETE | Privilege::UPDATE | Privilege::INSERT
69 | Privilege::SELECT;
70 construct();
71}
72
73OMySQLTable::OMySQLTable(sdbcx::OCollection* _pTables, const Reference<XConnection>& _xConnection,
74 const OUString& Name, const OUString& Type, const OUString& Description,
75 const OUString& SchemaName, const OUString& CatalogName,
76 sal_Int32 _nPrivileges)
77 : OTableHelper(_pTables, _xConnection, true, Name, Type, Description, SchemaName, CatalogName)
78 , m_nPrivileges(_nPrivileges)
79{
80 construct();
81}
82
84{
86 if (!isNew())
88 PROPERTY_ID_PRIVILEGES, PropertyAttribute::READONLY, &m_nPrivileges,
89 cppu::UnoType<decltype(m_nPrivileges)>::get());
90}
91
93{
94 return doCreateArrayHelper();
95}
96
98{
99 return *static_cast<OMySQLTable_PROP*>(this)->getArrayHelper(isNew() ? 1 : 0);
100}
101
102sdbcx::OCollection* OMySQLTable::createColumns(const ::std::vector<OUString>& _rNames)
103{
104 OMySQLColumns* pColumns = new OMySQLColumns(*this, m_aMutex, _rNames);
105 pColumns->setParent(this);
106 return pColumns;
107}
108
109sdbcx::OCollection* OMySQLTable::createKeys(const ::std::vector<OUString>& _rNames)
110{
111 return new OMySQLKeysHelper(this, m_aMutex, _rNames);
112}
113
114sdbcx::OCollection* OMySQLTable::createIndexes(const ::std::vector<OUString>& _rNames)
115{
116 return new OIndexesHelper(this, m_aMutex, _rNames);
117}
118
119// XAlterTable
120void SAL_CALL OMySQLTable::alterColumnByName(const OUString& colName,
121 const Reference<XPropertySet>& descriptor)
122{
123 ::osl::MutexGuard aGuard(m_aMutex);
125#ifdef __GNUC__
126 ::connectivity::sdbcx::OTableDescriptor_BASE::rBHelper.bDisposed
127#else
128 rBHelper.bDisposed
129#endif
130 );
131
132 if (!m_xColumns || !m_xColumns->hasByName(colName))
133 throw NoSuchElementException(colName, *this);
134
135 if (!isNew())
136 {
137 // first we have to check what should be altered
138 Reference<XPropertySet> xProp;
139 m_xColumns->getByName(colName) >>= xProp;
140 // first check the types
141 sal_Int32 nOldType = 0, nNewType = 0, nOldPrec = 0, nNewPrec = 0, nOldScale = 0,
142 nNewScale = 0;
143
145 xProp->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_TYPE)) >>= nOldType;
146 descriptor->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_TYPE)) >>= nNewType;
147 // and precisions and scale
148 xProp->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_PRECISION)) >>= nOldPrec;
149 descriptor->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_PRECISION)) >>= nNewPrec;
150 xProp->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_SCALE)) >>= nOldScale;
151 descriptor->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_SCALE)) >>= nNewScale;
152 // second: check the "is nullable" value
153 sal_Int32 nOldNullable = 0, nNewNullable = 0;
154 xProp->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_ISNULLABLE)) >>= nOldNullable;
155 descriptor->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_ISNULLABLE)) >>= nNewNullable;
156
157 // check also the auto_increment
158 bool bOldAutoIncrement = false, bAutoIncrement = false;
159 xProp->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_ISAUTOINCREMENT))
160 >>= bOldAutoIncrement;
161 descriptor->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_ISAUTOINCREMENT))
162 >>= bAutoIncrement;
163 bool bColumnNameChanged = false;
164 OUString sOldDesc, sNewDesc;
165 xProp->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_DESCRIPTION)) >>= sOldDesc;
166 descriptor->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_DESCRIPTION)) >>= sNewDesc;
167
168 if (nOldType != nNewType || nOldPrec != nNewPrec || nOldScale != nNewScale
169 || nNewNullable != nOldNullable || bOldAutoIncrement != bAutoIncrement
170 || sOldDesc != sNewDesc)
171 {
172 // special handling because they changed the type names to distinguish
173 // if a column should be an auto_increment one
174 if (bOldAutoIncrement != bAutoIncrement)
175 {
176 OUString sTypeName;
177 descriptor->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_TYPENAME))
178 >>= sTypeName;
179
180 static const char s_sAutoIncrement[] = "auto_increment";
181 if (bAutoIncrement)
182 {
183 if (sTypeName.indexOf(s_sAutoIncrement) == -1)
184 {
185 sTypeName += OUString::Concat(" ") + s_sAutoIncrement;
186 descriptor->setPropertyValue(rProp.getNameByIndex(PROPERTY_ID_TYPENAME),
187 Any(sTypeName));
188 }
189 }
190 else
191 {
192 if (!sTypeName.isEmpty())
193 {
194 sal_Int32 nIndex = sTypeName.indexOf(s_sAutoIncrement);
195 if (nIndex != -1)
196 {
197 sTypeName = sTypeName.copy(0, nIndex);
198 descriptor->setPropertyValue(rProp.getNameByIndex(PROPERTY_ID_TYPENAME),
199 Any(sTypeName));
200 }
201 }
202 }
203 }
204 alterColumnType(nNewType, colName, descriptor);
205 bColumnNameChanged = true;
206 }
207
208 // third: check the default values
209 OUString sNewDefault, sOldDefault;
210 xProp->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_DEFAULTVALUE)) >>= sOldDefault;
211 descriptor->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_DEFAULTVALUE))
212 >>= sNewDefault;
213
214 if (!sOldDefault.isEmpty())
215 {
216 dropDefaultValue(colName);
217 if (!sNewDefault.isEmpty() && sOldDefault != sNewDefault)
218 alterDefaultValue(sNewDefault, colName);
219 }
220 else if (!sNewDefault.isEmpty())
221 alterDefaultValue(sNewDefault, colName);
222
223 // now we should look if the name of the column changed
224 OUString sNewColumnName;
225 descriptor->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_NAME)) >>= sNewColumnName;
226 if (!sNewColumnName.equalsIgnoreAsciiCase(colName) && !bColumnNameChanged)
227 {
228 const OUString sQuote = getMetaData()->getIdentifierQuoteString();
229 OUString sSql = getAlterTableColumnPart() + " CHANGE "
230 + ::dbtools::quoteName(sQuote, colName) + " "
232 descriptor, getConnection(), static_cast<OTables*>(m_pTables),
234 executeStatement(sSql);
235 }
236 m_xColumns->refresh();
237 }
238 else
239 {
240 if (m_xColumns)
241 {
242 m_xColumns->dropByName(colName);
243 m_xColumns->appendByDescriptor(descriptor);
244 }
245 }
246}
247
248void OMySQLTable::alterColumnType(sal_Int32 nNewType, const OUString& _rColName,
249 const Reference<XPropertySet>& _xDescriptor)
250{
251 const OUString sQuote = getMetaData()->getIdentifierQuoteString();
252 OUString sSql
253 = getAlterTableColumnPart() + " CHANGE " + ::dbtools::quoteName(sQuote, _rColName) + " ";
254
255 rtl::Reference<OColumn> pColumn = new OColumn(true);
256 ::comphelper::copyProperties(_xDescriptor, pColumn);
257 pColumn->setPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE),
258 Any(nNewType));
259
261 pColumn, getConnection(), static_cast<OTables*>(m_pTables), getTypeCreatePattern()));
262 executeStatement(sSql);
263}
264
265OUString OMySQLTable::getTypeCreatePattern() const { return "(M,D)"; }
266
267void OMySQLTable::alterDefaultValue(std::u16string_view _sNewDefault, const OUString& _rColName)
268{
269 const OUString sQuote = getMetaData()->getIdentifierQuoteString();
270 OUString sSql = getAlterTableColumnPart() + " ALTER " + ::dbtools::quoteName(sQuote, _rColName)
271 + " SET DEFAULT '" + _sNewDefault + "'";
272
273 executeStatement(sSql);
274}
275
276void OMySQLTable::dropDefaultValue(const OUString& _rColName)
277{
278 const OUString sQuote = getMetaData()->getIdentifierQuoteString();
279 OUString sSql = getAlterTableColumnPart() + " ALTER " + ::dbtools::quoteName(sQuote, _rColName)
280 + " DROP DEFAULT";
281
282 executeStatement(sSql);
283}
284
286{
287 OUString sSql("ALTER TABLE ");
288
289 OUString sComposedName(
291 ::dbtools::EComposeRule::InTableDefinitions));
292 sSql += sComposedName;
293
294 return sSql;
295}
296
297void OMySQLTable::executeStatement(const OUString& _rStatement)
298{
299 OUString sSQL = _rStatement;
300 if (sSQL.endsWith(","))
301 sSQL = sSQL.replaceAt(sSQL.getLength() - 1, 1, u")");
302
303 Reference<XStatement> xStmt = getConnection()->createStatement();
304 if (xStmt.is())
305 {
306 xStmt->execute(sSQL);
307 ::comphelper::disposeComponent(xStmt);
308 }
309}
310
311OUString OMySQLTable::getRenameStart() const { return "RENAME TABLE "; }
312
313/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
OptionalString sComposedName
::cppu::IPropertyArrayHelper * getArrayHelper(sal_Int32 nId)
void registerProperty(const OUString &_rName, sal_Int32 _nHandle, sal_Int32 _nAttributes, void *_pPointerToMember, const css::uno::Type &_rMemberType)
void setParent(OTableHelper *_pTable)
set the parent of the columns.
::dbtools::OPropertyMap & getPropMap()
Definition: TConnection.cxx:68
css::uno::Reference< css::sdbc::XConnection > const & getConnection() const
virtual css::uno::Reference< css::sdbc::XDatabaseMetaData > getMetaData() const override
virtual void construct() override
Definition: YTable.cxx:83
virtual sdbcx::OCollection * createKeys(const ::std::vector< OUString > &_rNames) override
creates the key collection for the table
Definition: YTable.cxx:109
virtual OUString getTypeCreatePattern() const override
Definition: YTable.cxx:265
OMySQLTable(sdbcx::OCollection *_pTables, const css::uno::Reference< css::sdbc::XConnection > &_xConnection)
void alterColumnType(sal_Int32 nNewType, const OUString &_rColName, const css::uno::Reference< css::beans::XPropertySet > &_xDescriptor)
Definition: YTable.cxx:248
virtual void SAL_CALL alterColumnByName(const OUString &colName, const css::uno::Reference< css::beans::XPropertySet > &descriptor) override
Definition: YTable.cxx:120
void dropDefaultValue(const OUString &_sNewDefault)
Definition: YTable.cxx:276
virtual sdbcx::OCollection * createColumns(const ::std::vector< OUString > &_rNames) override
creates the column collection for the table
Definition: YTable.cxx:102
virtual ::cppu::IPropertyArrayHelper &SAL_CALL getInfoHelper() override
Definition: YTable.cxx:97
void alterDefaultValue(std::u16string_view _sNewDefault, const OUString &_rColName)
Definition: YTable.cxx:267
virtual sdbcx::OCollection * createIndexes(const ::std::vector< OUString > &_rNames) override
creates the index collection for the table
Definition: YTable.cxx:114
void executeStatement(const OUString &_rStatement)
executes the statement.
Definition: YTable.cxx:297
OUString getAlterTableColumnPart() const
returns the ALTER TABLE XXX statement
Definition: YTable.cxx:285
virtual OUString getRenameStart() const override
Returns always "RENAME TABLE " even for views.
Definition: YTable.cxx:311
virtual ::cppu::IPropertyArrayHelper * createArrayHelper(sal_Int32 nId) const override
used to implement the creation of the array helper which is shared amongst all instances of the class...
Definition: YTable.cxx:92
static OUString adjustSQL(const OUString &_sSql)
convert the sql statement to fit MySQL notation
Definition: YTables.cxx:145
::cppu::IPropertyArrayHelper * doCreateArrayHelper() const
helper for derived classes to implement OPropertyArrayUsageHelper::createArrayHelper
Definition: VDescriptor.cxx:66
std::unique_ptr< OCollection > m_xColumns
Definition: VTable.hxx:77
virtual void construct() override
Definition: VTable.cxx:86
OCollection * m_pTables
Definition: VTable.hxx:79
mutable::osl::Mutex m_aMutex
const OUString & getNameByIndex(sal_Int32 _nIndex) const
Definition: propertyids.cxx:95
float u
const char sQuote[]
bool bAutoIncrement
sal_Int32 nIndex
Type
void checkDisposed(bool _bThrow)
Definition: dbtools.cxx:1951
OUString composeTableName(const Reference< XDatabaseMetaData > &_rxMetaData, const OUString &_rCatalog, const OUString &_rSchema, const OUString &_rName, bool _bQuote, EComposeRule _eComposeRule)
Definition: dbtools.cxx:1286
OUString createStandardColumnPart(const Reference< XPropertySet > &xColProp, const Reference< XConnection > &_xConnection, ISQLStatementHelper *_pHelper, std::u16string_view _sCreatePattern)
Definition: dbtools2.cxx:169
OUString quoteName(std::u16string_view _rQuote, const OUString &_rName)
quote the given name with the given quote string.
#define PROPERTY_ID_NAME
Definition: propertyids.hxx:50
#define PROPERTY_ID_TYPE
Definition: propertyids.hxx:51
#define PROPERTY_ID_DESCRIPTION
Definition: propertyids.hxx:58
#define PROPERTY_ID_PRIVILEGES
Definition: propertyids.hxx:94
#define PROPERTY_ID_ISNULLABLE
Definition: propertyids.hxx:55
#define PROPERTY_ID_PRECISION
Definition: propertyids.hxx:53
#define PROPERTY_ID_ISAUTOINCREMENT
Definition: propertyids.hxx:56
#define PROPERTY_ID_TYPENAME
Definition: propertyids.hxx:52
#define PROPERTY_ID_DEFAULTVALUE
Definition: propertyids.hxx:59
#define PROPERTY_ID_SCALE
Definition: propertyids.hxx:54
OUString Name