LCOV - code coverage report
Current view: top level - connectivity/source/drivers/firebird - Table.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 18 87 20.7 %
Date: 2014-11-03 Functions: 5 11 45.5 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : 
      10             : #include "Columns.hxx"
      11             : #include "Indexes.hxx"
      12             : #include "Keys.hxx"
      13             : #include "Table.hxx"
      14             : 
      15             : #include <TConnection.hxx>
      16             : 
      17             : #include <comphelper/sequence.hxx>
      18             : #include <connectivity/dbtools.hxx>
      19             : 
      20             : #include <com/sun/star/sdbc/ColumnValue.hpp>
      21             : #include <com/sun/star/sdbcx/Privilege.hpp>
      22             : 
      23             : using namespace ::connectivity;
      24             : using namespace ::connectivity::firebird;
      25             : using namespace ::connectivity::sdbcx;
      26             : 
      27             : using namespace ::osl;
      28             : 
      29             : using namespace ::com::sun::star;
      30             : using namespace ::com::sun::star::beans;
      31             : using namespace ::com::sun::star::container;
      32             : using namespace ::com::sun::star::sdbc;
      33             : using namespace ::com::sun::star::sdbcx;
      34             : using namespace ::com::sun::star::uno;
      35             : 
      36           0 : Table::Table(Tables* pTables,
      37             :              Mutex& rMutex,
      38             :              const uno::Reference< XConnection >& rConnection):
      39             :     OTableHelper(pTables,
      40             :                  rConnection,
      41             :                  true),
      42             :     m_rMutex(rMutex),
      43           0 :     m_nPrivileges(0)
      44             : {
      45           0 :     construct();
      46           0 : }
      47             : 
      48           2 : Table::Table(Tables* pTables,
      49             :              Mutex& rMutex,
      50             :              const uno::Reference< XConnection >& rConnection,
      51             :              const OUString& rName,
      52             :              const OUString& rType,
      53             :              const OUString& rDescription):
      54             :     OTableHelper(pTables,
      55             :                  rConnection,
      56             :                  true,
      57             :                  rName,
      58             :                  rType,
      59             :                  rDescription,
      60             :                  "",
      61             :                  ""),
      62             :     m_rMutex(rMutex),
      63           2 :     m_nPrivileges(0)
      64             : {
      65           2 :     construct();
      66           2 : }
      67             : 
      68           2 : void Table::construct()
      69             : {
      70           2 :     OTableHelper::construct();
      71           2 :     if (!isNew())
      72             :     {
      73             :         // TODO: get privileges when in non-embedded mode.
      74             :         m_nPrivileges = Privilege::DROP         |
      75             :                         Privilege::REFERENCE    |
      76             :                         Privilege::ALTER        |
      77             :                         Privilege::CREATE       |
      78             :                         Privilege::READ         |
      79             :                         Privilege::DELETE       |
      80             :                         Privilege::UPDATE       |
      81             :                         Privilege::INSERT       |
      82           2 :                         Privilege::SELECT;
      83           2 :         registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PRIVILEGES),
      84             :                          PROPERTY_ID_PRIVILEGES,
      85             :                          PropertyAttribute::READONLY,
      86             :                          &m_nPrivileges,
      87           4 :                          ::getCppuType(&m_nPrivileges));
      88             :     }
      89           2 : }
      90             : //----- OTableHelper ---------------------------------------------------------
      91           2 : OCollection* Table::createColumns(const TStringVector& rNames)
      92             : {
      93             :     return new Columns(*this,
      94             :                        m_rMutex,
      95           2 :                        rNames);
      96             : }
      97             : 
      98           2 : OCollection* Table::createKeys(const TStringVector& rNames)
      99             : {
     100             :     return new Keys(this,
     101             :                     m_rMutex,
     102           2 :                     rNames);
     103             : }
     104             : 
     105           0 : OCollection* Table::createIndexes(const TStringVector& rNames)
     106             : {
     107             :     return new Indexes(this,
     108             :                        m_rMutex,
     109           0 :                        rNames);
     110             : }
     111             : 
     112             : //----- XAlterTable -----------------------------------------------------------
     113           0 : void SAL_CALL Table::alterColumnByName(const OUString& rColName,
     114             :                                        const uno::Reference< XPropertySet >& rDescriptor)
     115             :     throw(SQLException, NoSuchElementException, RuntimeException, std::exception)
     116             : {
     117           0 :     MutexGuard aGuard(m_rMutex);
     118           0 :     checkDisposed(WeakComponentImplHelperBase::rBHelper.bDisposed);
     119             : 
     120           0 :     uno::Reference< XPropertySet > xColumn(m_pColumns->getByName(rColName), UNO_QUERY);
     121             : 
     122             :     // sdbcx::Descriptor
     123           0 :     const bool bNameChanged = xColumn->getPropertyValue("Name") != rDescriptor->getPropertyValue("Name");
     124             :     // sdbcx::ColumnDescriptor
     125           0 :     const bool bTypeChanged = xColumn->getPropertyValue("Type") != rDescriptor->getPropertyValue("Type");
     126           0 :     const bool bTypeNameChanged = xColumn->getPropertyValue("TypeName") != rDescriptor->getPropertyValue("TypeName");
     127           0 :     const bool bPrecisionChanged = xColumn->getPropertyValue("Precision") != rDescriptor->getPropertyValue("Precision");
     128           0 :     const bool bScaleChanged = xColumn->getPropertyValue("Scale") != rDescriptor->getPropertyValue("Scale");
     129           0 :     const bool bIsNullableChanged = xColumn->getPropertyValue("IsNullable") != rDescriptor->getPropertyValue("IsNullable");
     130           0 :     const bool bIsAutoIncrementChanged = xColumn->getPropertyValue("IsAutoIncrement") != rDescriptor->getPropertyValue("IsAutoIncrement");
     131             :     // TODO: remainder -- these are all "optional" so have to detect presence and change.
     132             : 
     133           0 :     bool bDefaultChanged = xColumn->getPropertyValue("DefaultValue")
     134           0 :                                      != rDescriptor->getPropertyValue("DefaultValue");
     135             : 
     136             :     // TODO: quote identifiers as needed.
     137           0 :     if (bNameChanged)
     138             :     {
     139           0 :         OUString sNewTableName;
     140           0 :         rDescriptor->getPropertyValue("Name") >>= sNewTableName;
     141             :         OUString sSql(getAlterTableColumn(rColName)
     142           0 :                                             + " TO \"" + sNewTableName + "\"");
     143             : 
     144           0 :         getConnection()->createStatement()->execute(sSql);
     145             :     }
     146             : 
     147           0 :     if (bTypeChanged || bTypeNameChanged || bPrecisionChanged || bScaleChanged)
     148             :     {
     149             :         // If bPrecisionChanged this will only succeed if we have increased the
     150             :         // precision, otherwise an exception is thrown -- however the base
     151             :         // gui then offers to delete and recreate the column.
     152           0 :         OUString sSql(getAlterTableColumn(rColName) + "TYPE " +
     153           0 :                 ::dbtools::createStandardTypePart(rDescriptor, getConnection()));
     154           0 :         getConnection()->createStatement()->execute(sSql);
     155             :         // TODO: could cause errors e.g. if incompatible types, deal with them here as appropriate.
     156             :         // possibly we have to wrap things in Util::evaluateStatusVector.
     157             :     }
     158             : 
     159           0 :     if (bIsNullableChanged)
     160             :     {
     161           0 :         sal_Int32 nNullabble = 0;
     162           0 :         rDescriptor->getPropertyValue("IsNullable") >>= nNullabble;
     163             : 
     164           0 :         if (nNullabble != ColumnValue::NULLABLE_UNKNOWN)
     165             :         {
     166             : 
     167           0 :             OUString sSql;
     168             :             // Dirty hack: can't change null directly in sql, we have to fiddle
     169             :             // the system tables manually.
     170           0 :             if (nNullabble == ColumnValue::NULLABLE)
     171             :             {
     172           0 :                 sSql = "UPDATE RDB$RELATION_FIELDS SET RDB$NULL_FLAG = NULL "
     173           0 :                        "WHERE RDB$FIELD_NAME = '" + rColName + "' "
     174           0 :                        "AND RDB$RELATION_NAME = '" + getName() + "'";
     175             :             }
     176           0 :             else if (nNullabble == ColumnValue::NO_NULLS)
     177             :             {
     178             :                 // And if we are making NOT NULL then we have to make sure we have
     179             :                 // no nulls left in the column.
     180           0 :                 OUString sFillNulls("UPDATE \"" + getName() + "\" SET \""
     181           0 :                                     + rColName + "\" = 0 "
     182           0 :                                     "WHERE \"" + rColName + "\" IS NULL");
     183           0 :                 getConnection()->createStatement()->execute(sFillNulls);
     184             : 
     185           0 :                 sSql = "UPDATE RDB$RELATION_FIELDS SET RDB$NULL_FLAG = 1 "
     186           0 :                        "WHERE RDB$FIELD_NAME = '" + rColName + "' "
     187           0 :                        "AND RDB$RELATION_NAME = '" + getName() + "'";
     188             :             }
     189           0 :             getConnection()->createStatement()->execute(sSql);
     190             :         }
     191             :         else
     192             :         {
     193             :             SAL_WARN("connectivity.firebird", "Attempting to set Nullable to NULLABLE_UNKNOWN");
     194             :         }
     195             :     }
     196             : 
     197             :     if (bIsAutoIncrementChanged)
     198             :     {
     199             :         // TODO: changeType
     200             :     }
     201             : 
     202           0 :     if (bDefaultChanged)
     203             :     {
     204           0 :         OUString sOldDefault, sNewDefault;
     205           0 :         xColumn->getPropertyValue("DefaultValue") >>= sOldDefault;
     206           0 :         rDescriptor->getPropertyValue("DefaultValue") >>= sNewDefault;
     207             : 
     208           0 :         OUString sSql;
     209           0 :         if (sNewDefault.isEmpty())
     210           0 :             sSql = getAlterTableColumn(rColName) + "DROP DEFAULT";
     211             :         else
     212           0 :             sSql = getAlterTableColumn(rColName) + "SET DEFAULT " + sNewDefault;
     213             : 
     214           0 :         getConnection()->createStatement()->execute(sSql);
     215             :     }
     216             : 
     217           0 :     m_pColumns->refresh();
     218           0 : }
     219             : 
     220             : // ----- XRename --------------------------------------------------------------
     221           0 : void SAL_CALL Table::rename(const OUString& rName)
     222             :     throw(SQLException, ElementExistException, RuntimeException, std::exception)
     223             : {
     224             :     (void) rName;
     225           0 :     throw RuntimeException(); // Firebird doesn't support this.
     226             : }
     227             : 
     228             : // ----- XInterface -----------------------------------------------------------
     229         294 : Any SAL_CALL Table::queryInterface(const Type& rType)
     230             :     throw(RuntimeException, std::exception)
     231             : {
     232         294 :     if (rType.getTypeName() == "com.sun.star.sdbcx.XRename")
     233           0 :         return Any();
     234             : 
     235         294 :     return OTableHelper::queryInterface(rType);
     236             : }
     237             : 
     238             : // ----- XTypeProvider --------------------------------------------------------
     239           0 : uno::Sequence< Type > SAL_CALL Table::getTypes()
     240             :     throw(RuntimeException, std::exception)
     241             : {
     242           0 :     uno::Sequence< Type > aTypes = OTableHelper::getTypes();
     243             : 
     244           0 :     for (int i = 0; i < aTypes.getLength(); i++)
     245             :     {
     246           0 :         if (aTypes[i].getTypeName() == "com.sun.star.sdbcx.XRename")
     247             :         {
     248           0 :             ::comphelper::removeElementAt(aTypes, i);
     249           0 :             break;
     250             :         }
     251             :     }
     252             : 
     253           0 :     return OTableHelper::getTypes();
     254             : }
     255             : 
     256           0 : OUString Table::getAlterTableColumn(const OUString& rColumn)
     257             : {
     258           0 :     return ("ALTER TABLE \"" + getName() + "\" ALTER COLUMN \"" + rColumn + "\" ");
     259             : }
     260             : 
     261             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10