1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
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/.
10 #include "Columns.hxx"
11 #include "Indexes.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
,
40 const uno::Reference
< XConnection
>& rConnection
):
50 Table::Table(Tables
* pTables
,
52 const uno::Reference
< XConnection
>& rConnection
,
53 const OUString
& rName
,
54 const OUString
& rType
,
55 const OUString
& rDescription
):
70 void Table::construct()
72 OTableHelper::construct();
76 // TODO: get privileges when in non-embedded mode.
77 m_nPrivileges
= Privilege::DROP
|
78 Privilege::REFERENCE
|
86 registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PRIVILEGES
),
87 PROPERTY_ID_PRIVILEGES
,
88 PropertyAttribute::READONLY
,
90 cppu::UnoType
<decltype(m_nPrivileges
)>::get());
92 //----- OTableHelper ---------------------------------------------------------
93 OCollection
* Table::createColumns(const ::std::vector
< OUString
>& rNames
)
95 return new Columns(*this,
100 OCollection
* Table::createKeys(const ::std::vector
< OUString
>& rNames
)
102 return new Keys(this,
107 OCollection
* Table::createIndexes(const ::std::vector
< OUString
>& rNames
)
109 return new Indexes(this,
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
);
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
);
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
,
186 OUString sNewDefault
;
187 rDescriptor
->getPropertyValue(u
"DefaultValue"_ustr
) >>= sNewDefault
;
190 if (sNewDefault
.isEmpty())
191 sSql
= getAlterTableColumn(rColName
) + "DROP DEFAULT";
193 sSql
= getAlterTableColumn(rColName
) + "SET DEFAULT " + sNewDefault
;
195 getConnection()->createStatement()->execute(sSql
);
197 // TODO: quote identifiers as needed.
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")
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: */