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

Generated by: LCOV version 1.10