/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_connectivity.hxx"
#include "connectivity/TKeys.hxx"
#include "connectivity/TKey.hxx"
#include <com/sun/star/sdbc/XRow.hpp>
#include <com/sun/star/sdbc/XResultSet.hpp>
#include <com/sun/star/sdbcx/KeyType.hpp>
#include <com/sun/star/sdbc/KeyRule.hpp>
#include "connectivity/dbtools.hxx"
#include <comphelper/extract.hxx>
#include <comphelper/types.hxx>
#include <comphelper/property.hxx>
#include "TConnection.hxx"

namespace connectivity
{
using namespace comphelper;
using namespace connectivity::sdbcx;
using namespace dbtools;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::sdbcx;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::lang;



OKeysHelper::OKeysHelper(	OTableHelper* _pTable,
		::osl::Mutex& _rMutex,
		const TStringVector& _rVector
		) : OKeys_BASE(*_pTable,sal_True,_rMutex,_rVector,sal_True)
	,m_pTable(_pTable)
{
}
// -------------------------------------------------------------------------
sdbcx::ObjectType OKeysHelper::createObject(const ::rtl::OUString& _rName)
{
	sdbcx::ObjectType xRet = NULL;

	if(_rName.getLength())
	{
        OTableKeyHelper* pRet = new OTableKeyHelper(m_pTable,_rName,m_pTable->getKeyProperties(_rName));
		xRet = pRet;
	}

	if(!xRet.is()) // we have a primary key with a system name
	{
		OTableKeyHelper* pRet = new OTableKeyHelper(m_pTable,_rName,m_pTable->getKeyProperties(_rName));
		xRet = pRet;
	}

	return xRet;
}
// -------------------------------------------------------------------------
void OKeysHelper::impl_refresh() throw(RuntimeException)
{
	m_pTable->refreshKeys();
}
// -------------------------------------------------------------------------
Reference< XPropertySet > OKeysHelper::createDescriptor()
{
	return new OTableKeyHelper(m_pTable);
}
// -----------------------------------------------------------------------------
/** returns the keyrule string for the primary key
*/
::rtl::OUString getKeyRuleString(sal_Bool _bUpdate,sal_Int32 _nKeyRule)
{
	const char* pKeyRule = NULL;
	switch ( _nKeyRule )
	{
		case KeyRule::CASCADE:
			pKeyRule = _bUpdate ? " ON UPDATE CASCADE " : " ON DELETE CASCADE ";
			break;
		case KeyRule::RESTRICT:
			pKeyRule = _bUpdate ? " ON UPDATE RESTRICT " : " ON DELETE RESTRICT ";
			break;
		case KeyRule::SET_NULL:
			pKeyRule = _bUpdate ? " ON UPDATE SET NULL " : " ON DELETE SET NULL ";
			break;
		case KeyRule::SET_DEFAULT:
			pKeyRule = _bUpdate ? " ON UPDATE SET DEFAULT " : " ON DELETE SET DEFAULT ";
			break;
		default:
			;
	}
	::rtl::OUString sRet;
	if ( pKeyRule )
		sRet = ::rtl::OUString::createFromAscii(pKeyRule);
	return sRet;
}
// -------------------------------------------------------------------------
void OKeysHelper::cloneDescriptorColumns( const sdbcx::ObjectType& _rSourceDescriptor, const sdbcx::ObjectType& _rDestDescriptor )
{
	Reference< XColumnsSupplier > xColSupp( _rSourceDescriptor, UNO_QUERY_THROW );
	Reference< XIndexAccess > xSourceCols( xColSupp->getColumns(), UNO_QUERY_THROW );

    xColSupp.set( _rDestDescriptor, UNO_QUERY_THROW );
	Reference< XAppend > xDestAppend( xColSupp->getColumns(), UNO_QUERY_THROW );

    sal_Int32 nCount = xSourceCols->getCount();
	for ( sal_Int32 i=0; i< nCount; ++i )
	{
        Reference< XPropertySet > xColProp( xSourceCols->getByIndex(i), UNO_QUERY );
		xDestAppend->appendByDescriptor( xColProp );
	}
}
// -------------------------------------------------------------------------
// XAppend
sdbcx::ObjectType OKeysHelper::appendObject( const ::rtl::OUString& _rForName, const Reference< XPropertySet >& descriptor )
{
    Reference< XConnection> xConnection = m_pTable->getConnection();
    if ( !xConnection.is() )
        return NULL;
	if ( m_pTable->isNew() )
    {
		Reference< XPropertySet > xNewDescriptor( cloneDescriptor( descriptor ) );
        cloneDescriptorColumns( descriptor, xNewDescriptor );
        return xNewDescriptor;
    }

    const ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap();
    sal_Int32 nKeyType		= getINT32(descriptor->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_TYPE)));
    sal_Int32 nUpdateRule = 0, nDeleteRule = 0;
    ::rtl::OUString sReferencedName;

    if ( nKeyType == KeyType::FOREIGN )
    {
	    descriptor->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_REFERENCEDTABLE)) >>= sReferencedName;
        descriptor->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_UPDATERULE)) >>= nUpdateRule;
        descriptor->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_DELETERULE)) >>= nDeleteRule;
    }

    if ( m_pTable->getKeyService().is() )
    {
        m_pTable->getKeyService()->addKey(m_pTable,descriptor);
    }
    else
    {
        // if we're here, we belong to a table which is not new, i.e. already exists in the database.
        // In this case, really append the new index.
	    ::rtl::OUStringBuffer aSql;
        aSql.appendAscii("ALTER TABLE ");
	    ::rtl::OUString aQuote	= m_pTable->getConnection()->getMetaData()->getIdentifierQuoteString(  );
	    ::rtl::OUString aDot	= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("."));

        aSql.append(composeTableName( m_pTable->getConnection()->getMetaData(), m_pTable, ::dbtools::eInTableDefinitions, false, false, true ));
        aSql.appendAscii(" ADD ");

	    if ( nKeyType == KeyType::PRIMARY )
	    {
		    aSql.appendAscii(" PRIMARY KEY (");
	    }
	    else if ( nKeyType == KeyType::FOREIGN )
	    {
		    aSql.appendAscii(" FOREIGN KEY (");
	    }
	    else
		    throw SQLException();

	    Reference<XColumnsSupplier> xColumnSup(descriptor,UNO_QUERY);
	    Reference<XIndexAccess> xColumns(xColumnSup->getColumns(),UNO_QUERY);
	    Reference< XPropertySet > xColProp;
	    for(sal_Int32 i = 0 ; i < xColumns->getCount() ; ++i)
	    {
            if ( i > 0 )
                aSql.appendAscii(",");
		    ::cppu::extractInterface(xColProp,xColumns->getByIndex(i));
		    aSql.append( ::dbtools::quoteName( aQuote,getString(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME)))) );
            
	    }
        aSql.appendAscii(")");

	    if ( nKeyType == KeyType::FOREIGN )
	    {
		    aSql.appendAscii(" REFERENCES ");
            aSql.append(::dbtools::quoteTableName(m_pTable->getConnection()->getMetaData(),sReferencedName,::dbtools::eInTableDefinitions));
		    aSql.appendAscii(" (");

		    for(sal_Int32 i=0;i<xColumns->getCount();++i)
		    {
                if ( i > 0 )
                    aSql.appendAscii(",");
			    xColumns->getByIndex(i) >>= xColProp;
			    aSql.append(::dbtools::quoteName( aQuote,getString(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_RELATEDCOLUMN)))));
                
		    }
		    aSql.appendAscii(")");
		    aSql.append(getKeyRuleString(sal_True	,nUpdateRule));
		    aSql.append(getKeyRuleString(sal_False	,nDeleteRule));
	    }

	    Reference< XStatement > xStmt = m_pTable->getConnection()->createStatement(  );
	    xStmt->execute(aSql.makeStringAndClear());
    }
	// find the name which the database gave the new key
    ::rtl::OUString sNewName( _rForName );
	try
	{
		::rtl::OUString aSchema,aTable;
		m_pTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_SCHEMANAME))	>>= aSchema;
		m_pTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME))		>>= aTable;
		Reference< XResultSet > xResult; 
		sal_Int32 nColumn = 12;
		if ( nKeyType == KeyType::FOREIGN )
			xResult = m_pTable->getMetaData()->getImportedKeys( m_pTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_CATALOGNAME))
																					,aSchema
																					,aTable);
		else
		{
			xResult = m_pTable->getMetaData()->getPrimaryKeys( m_pTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_CATALOGNAME))
																					,aSchema
																					,aTable);
			nColumn = 6;
		}
		if ( xResult.is() )
		{
			Reference< XRow > xRow(xResult,UNO_QUERY);
			while( xResult->next() )
			{
				::rtl::OUString sName = xRow->getString(nColumn);
				if ( !m_pElements->exists(sName) ) // this name wasn't inserted yet so it must be te new one
				{
					descriptor->setPropertyValue( rPropMap.getNameByIndex( PROPERTY_ID_NAME ), makeAny( sName ) );
                    sNewName = sName;
					break;
				}
			}
			::comphelper::disposeComponent(xResult);
		}
	}
	catch(const SQLException&)
	{
	}

    m_pTable->addKey(sNewName,sdbcx::TKeyProperties(new sdbcx::KeyProperties(sReferencedName,nKeyType,nUpdateRule,nDeleteRule)));

    return createObject( sNewName );
}
// -----------------------------------------------------------------------------
::rtl::OUString OKeysHelper::getDropForeignKey() const
{
    return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" DROP CONSTRAINT "));
}
// -------------------------------------------------------------------------
// XDrop
void OKeysHelper::dropObject(sal_Int32 _nPos,const ::rtl::OUString _sElementName)
{
    Reference< XConnection> xConnection = m_pTable->getConnection();
	if ( xConnection.is() && !m_pTable->isNew() )
	{
        Reference<XPropertySet> xKey(getObject(_nPos),UNO_QUERY);
        if ( m_pTable->getKeyService().is() )
        {
            m_pTable->getKeyService()->dropKey(m_pTable,xKey);
        }
        else
        {
		    ::rtl::OUStringBuffer aSql;
            aSql.appendAscii("ALTER TABLE ");

		    aSql.append( composeTableName( m_pTable->getConnection()->getMetaData(), m_pTable,::dbtools::eInTableDefinitions, false, false, true ));

		    sal_Int32 nKeyType = KeyType::PRIMARY;
		    if ( xKey.is() )
		    {
			    ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap();
			    xKey->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_TYPE)) >>= nKeyType;
		    }
		    if ( KeyType::PRIMARY == nKeyType )
		    {
			    aSql.appendAscii(" DROP PRIMARY KEY");
		    }
		    else
		    {
			    aSql.append(getDropForeignKey());
			    const ::rtl::OUString aQuote	= m_pTable->getConnection()->getMetaData()->getIdentifierQuoteString();
			    aSql.append( ::dbtools::quoteName( aQuote,_sElementName) );
		    }

		    Reference< XStatement > xStmt = m_pTable->getConnection()->createStatement(  );
		    if ( xStmt.is() )
		    {
			    xStmt->execute(aSql.makeStringAndClear());
			    ::comphelper::disposeComponent(xStmt);
		    }
        }
	}
}
// -----------------------------------------------------------------------------
} // namespace connectivity
// -----------------------------------------------------------------------------
