Use COMReference to handle COM pointers in CreateShortcut
[LibreOffice.git] / connectivity / source / drivers / firebird / Table.cxx
blobc12ea8439333d09429c31c04b8a9b45f505ed169
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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 */
10 #include "Columns.hxx"
11 #include "Indexes.hxx"
12 #include "Keys.hxx"
13 #include "Table.hxx"
15 #include <TConnection.hxx>
17 #include <sal/log.hxx>
18 #include <comphelper/sequence.hxx>
19 #include <connectivity/dbtools.hxx>
21 #include <com/sun/star/sdbc/ColumnValue.hpp>
22 #include <com/sun/star/sdbcx/Privilege.hpp>
23 #include <com/sun/star/beans/PropertyAttribute.hpp>
25 using namespace ::connectivity;
26 using namespace ::connectivity::firebird;
27 using namespace ::connectivity::sdbcx;
29 using namespace ::osl;
31 using namespace ::com::sun::star;
32 using namespace ::com::sun::star::beans;
33 using namespace ::com::sun::star::container;
34 using namespace ::com::sun::star::sdbc;
35 using namespace ::com::sun::star::sdbcx;
36 using namespace ::com::sun::star::uno;
38 Table::Table(Tables* pTables,
39 Mutex& rMutex,
40 const uno::Reference< XConnection >& rConnection):
41 OTableHelper(pTables,
42 rConnection,
43 true),
44 m_rMutex(rMutex),
45 m_nPrivileges(0)
47 construct();
50 Table::Table(Tables* pTables,
51 Mutex& rMutex,
52 const uno::Reference< XConnection >& rConnection,
53 const OUString& rName,
54 const OUString& rType,
55 const OUString& rDescription):
56 OTableHelper(pTables,
57 rConnection,
58 true,
59 rName,
60 rType,
61 rDescription,
62 u""_ustr,
63 u""_ustr),
64 m_rMutex(rMutex),
65 m_nPrivileges(0)
67 construct();
70 void Table::construct()
72 OTableHelper::construct();
73 if (isNew())
74 return;
76 // TODO: get privileges when in non-embedded mode.
77 m_nPrivileges = Privilege::DROP |
78 Privilege::REFERENCE |
79 Privilege::ALTER |
80 Privilege::CREATE |
81 Privilege::READ |
82 Privilege::DELETE |
83 Privilege::UPDATE |
84 Privilege::INSERT |
85 Privilege::SELECT;
86 registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PRIVILEGES),
87 PROPERTY_ID_PRIVILEGES,
88 PropertyAttribute::READONLY,
89 &m_nPrivileges,
90 cppu::UnoType<decltype(m_nPrivileges)>::get());
92 //----- OTableHelper ---------------------------------------------------------
93 OCollection* Table::createColumns(const ::std::vector< OUString>& rNames)
95 return new Columns(*this,
96 m_rMutex,
97 rNames);
100 OCollection* Table::createKeys(const ::std::vector< OUString>& rNames)
102 return new Keys(this,
103 m_rMutex,
104 rNames);
107 OCollection* Table::createIndexes(const ::std::vector< OUString>& rNames)
109 return new Indexes(this,
110 m_rMutex,
111 rNames);
114 //----- XAlterTable -----------------------------------------------------------
115 void SAL_CALL Table::alterColumnByName(const OUString& rColName,
116 const uno::Reference< XPropertySet >& rDescriptor)
118 MutexGuard aGuard(m_rMutex);
119 checkDisposed(WeakComponentImplHelperBase::rBHelper.bDisposed);
121 uno::Reference< XPropertySet > xColumn(m_xColumns->getByName(rColName), UNO_QUERY);
123 // sdbcx::Descriptor
124 const bool bNameChanged = xColumn->getPropertyValue(u"Name"_ustr) != rDescriptor->getPropertyValue(u"Name"_ustr);
125 // sdbcx::ColumnDescriptor
126 const bool bTypeChanged = xColumn->getPropertyValue(u"Type"_ustr) != rDescriptor->getPropertyValue(u"Type"_ustr);
127 const bool bTypeNameChanged = xColumn->getPropertyValue(u"TypeName"_ustr) != rDescriptor->getPropertyValue(u"TypeName"_ustr);
128 const bool bPrecisionChanged = xColumn->getPropertyValue(u"Precision"_ustr) != rDescriptor->getPropertyValue(u"Precision"_ustr);
129 const bool bScaleChanged = xColumn->getPropertyValue(u"Scale"_ustr) != rDescriptor->getPropertyValue(u"Scale"_ustr);
130 const bool bIsNullableChanged = xColumn->getPropertyValue(u"IsNullable"_ustr) != rDescriptor->getPropertyValue(u"IsNullable"_ustr);
131 const bool bIsAutoIncrementChanged = xColumn->getPropertyValue(u"IsAutoIncrement"_ustr) != rDescriptor->getPropertyValue(u"IsAutoIncrement"_ustr);
133 // TODO: remainder -- these are all "optional" so have to detect presence and change.
135 bool bDefaultChanged = xColumn->getPropertyValue(u"DefaultValue"_ustr)
136 != rDescriptor->getPropertyValue(u"DefaultValue"_ustr);
138 if (bTypeChanged || bTypeNameChanged || bPrecisionChanged || bScaleChanged)
140 // If bPrecisionChanged this will only succeed if we have increased the
141 // precision, otherwise an exception is thrown -- however the base
142 // gui then offers to delete and recreate the column.
143 OUString sSql(getAlterTableColumn(rColName) + "TYPE " +
144 ::dbtools::createStandardTypePart(rDescriptor, getConnection()));
145 getConnection()->createStatement()->execute(sSql);
146 // TODO: could cause errors e.g. if incompatible types, deal with them here as appropriate.
147 // possibly we have to wrap things in Util::evaluateStatusVector.
150 if (bIsNullableChanged)
152 sal_Int32 nNullable = 0;
153 rDescriptor->getPropertyValue(u"IsNullable"_ustr) >>= nNullable;
155 if (nNullable != ColumnValue::NULLABLE_UNKNOWN)
158 OUString sSql(getAlterTableColumn(rColName));
159 if (nNullable == ColumnValue::NULLABLE)
161 sSql += "DROP NOT NULL";
163 else if (nNullable == ColumnValue::NO_NULLS)
165 sSql += "SET NOT NULL";
167 getConnection()->createStatement()->execute(sSql);
169 else
171 SAL_WARN("connectivity.firebird", "Attempting to set Nullable to NULLABLE_UNKNOWN");
175 if (bIsAutoIncrementChanged)
177 ::dbtools::throwSQLException(
178 u"Changing autoincrement property of existing column is not supported"_ustr,
179 ::dbtools::StandardSQLState::FUNCTION_NOT_SUPPORTED,
180 *this);
184 if (bDefaultChanged)
186 OUString sNewDefault;
187 rDescriptor->getPropertyValue(u"DefaultValue"_ustr) >>= sNewDefault;
189 OUString sSql;
190 if (sNewDefault.isEmpty())
191 sSql = getAlterTableColumn(rColName) + "DROP DEFAULT";
192 else
193 sSql = getAlterTableColumn(rColName) + "SET DEFAULT " + sNewDefault;
195 getConnection()->createStatement()->execute(sSql);
197 // TODO: quote identifiers as needed.
198 if (bNameChanged)
200 OUString sNewColName;
201 rDescriptor->getPropertyValue(u"Name"_ustr) >>= sNewColName;
202 OUString sSql(getAlterTableColumn(rColName)
203 + " TO \"" + sNewColName + "\"");
205 getConnection()->createStatement()->execute(sSql);
209 m_xColumns->refresh();
212 // ----- XRename --------------------------------------------------------------
213 void SAL_CALL Table::rename(const OUString&)
215 throw RuntimeException(u"Table renaming not supported by Firebird."_ustr);
218 // ----- XInterface -----------------------------------------------------------
219 Any SAL_CALL Table::queryInterface(const Type& rType)
221 if (rType.getTypeName() == "com.sun.star.sdbcx.XRename")
222 return Any();
224 return OTableHelper::queryInterface(rType);
227 OUString Table::getAlterTableColumn(std::u16string_view rColumn)
229 return ("ALTER TABLE \"" + getName() + "\" ALTER COLUMN \"" + rColumn + "\" ");
232 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */