/**************************************************************
 * 
 * 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 "adabas/BTable.hxx"
#include "adabas/BTables.hxx"
#include "adabas/BIndexes.hxx"
#include "adabas/BColumns.hxx"
#include "adabas/BKeys.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 <cppuhelper/typeprovider.hxx>
#include <com/sun/star/lang/DisposedException.hpp>
#include <com/sun/star/sdbc/ColumnValue.hpp>
#include <comphelper/sequence.hxx>
#include <comphelper/extract.hxx>
#include <comphelper/types.hxx>
#include "connectivity/dbtools.hxx"
#include "adabas/BCatalog.hxx"


using namespace ::comphelper;
using namespace connectivity::adabas;
using namespace connectivity;
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;

OAdabasTable::OAdabasTable(	sdbcx::OCollection* _pTables,
						   OAdabasConnection* _pConnection)
	:OTable_TYPEDEF(_pTables,_pConnection,sal_True)
	,m_pConnection(_pConnection)
{
	construct();
}
// -------------------------------------------------------------------------
OAdabasTable::OAdabasTable(	sdbcx::OCollection* _pTables,
						   OAdabasConnection* _pConnection,
					const ::rtl::OUString& _Name,
					const ::rtl::OUString& _Type,
					const ::rtl::OUString& _Description ,
					const ::rtl::OUString& _SchemaName,
					const ::rtl::OUString& _CatalogName
				) : OTableHelper(	_pTables,
									_pConnection,
									sal_True,
									_Name,
									_Type,
									_Description,
									_SchemaName,
									_CatalogName)
				,m_pConnection(_pConnection)
{
	construct();
}
// -----------------------------------------------------------------------------
sdbcx::OCollection* OAdabasTable::createColumns(const TStringVector& _rNames)
{
	return new OColumns(this,m_aMutex,_rNames);
}
// -----------------------------------------------------------------------------
sdbcx::OCollection* OAdabasTable::createKeys(const TStringVector& _rNames)
{
	return new OKeys(this,m_aMutex,_rNames);
}
// -----------------------------------------------------------------------------
sdbcx::OCollection* OAdabasTable::createIndexes(const TStringVector& _rNames)
{
	return new OIndexes(this,m_aMutex,_rNames);
}
//--------------------------------------------------------------------------
Sequence< sal_Int8 > OAdabasTable::getUnoTunnelImplementationId()
{
	static ::cppu::OImplementationId * pId = 0;
	if (! pId)
	{
		::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
		if (! pId)
		{
			static ::cppu::OImplementationId aId;
			pId = &aId;
		}
	}
	return pId->getImplementationId();
}

// com::sun::star::lang::XUnoTunnel
//------------------------------------------------------------------
sal_Int64 OAdabasTable::getSomething( const Sequence< sal_Int8 > & rId ) throw (RuntimeException)
{
	return (rId.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(),  rId.getConstArray(), 16 ) )
				? reinterpret_cast< sal_Int64 >( this )
				: OTable_TYPEDEF::getSomething(rId);
}
// -------------------------------------------------------------------------
// XAlterTable
void SAL_CALL OAdabasTable::alterColumnByName( const ::rtl::OUString& colName, const Reference< XPropertySet >& descriptor ) throw(SQLException, NoSuchElementException, RuntimeException)
{
	::osl::MutexGuard aGuard(m_aMutex);
	checkDisposed(
#ifdef GCC
		::connectivity::sdbcx::OTableDescriptor_BASE::rBHelper.bDisposed
#else
		rBHelper.bDisposed
#endif
		);

	if(m_pColumns && !m_pColumns->hasByName(colName))
		throw NoSuchElementException(colName,*this);


	if(!isNew())
	{
		beginTransAction();

		try
		{
			// first we have to check what should be altered
			Reference<XPropertySet> xProp;
			m_pColumns->getByName(colName) >>= xProp;
			// first check the types
			sal_Int32 nOldType = 0,nNewType = 0,nOldPrec = 0,nNewPrec = 0,nOldScale = 0,nNewScale = 0;

			xProp->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE))			>>= nOldType;
			descriptor->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE))	>>= nNewType;
			// and precsions and scale
			xProp->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PRECISION))	>>= nOldPrec;
			descriptor->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PRECISION))>>= nNewPrec;
			xProp->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE))		>>= nOldScale;
			descriptor->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE))	>>= nNewScale;

			if(nOldType != nNewType || nOldPrec != nNewPrec || nOldScale != nNewScale)
				alterColumnType(colName,descriptor);

			// second: check the "is nullable" value
			sal_Int32 nOldNullable = 0,nNewNullable = 0;
			xProp->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISNULLABLE))		>>= nOldNullable;
			descriptor->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISNULLABLE))	>>= nNewNullable;
			if(nNewNullable != nOldNullable)
				alterNotNullValue(nNewNullable,colName);

			// third: check the default values
			::rtl::OUString sNewDefault,sOldDefault;
			xProp->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DEFAULTVALUE))		>>= sOldDefault;
			descriptor->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DEFAULTVALUE)) >>= sNewDefault;

			if(sOldDefault.getLength())
			{
				if(sNewDefault.getLength() && sOldDefault != sNewDefault)
					alterDefaultValue(sNewDefault,colName);
				else if(!sNewDefault.getLength())
					dropDefaultValue(colName);
			}
			else if(!sOldDefault.getLength() && sNewDefault.getLength())
				addDefaultValue(sNewDefault,colName);

			// now we should look if the name of the column changed
			::rtl::OUString sNewColumnName;
			descriptor->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME)) >>= sNewColumnName;
			if(!sNewColumnName.equalsIgnoreAsciiCase(colName))
			{
				const ::rtl::OUString sQuote = m_pConnection->getMetaData()->getIdentifierQuoteString(  );
				const ::rtl::OUString& sDot = OAdabasCatalog::getDot();

				::rtl::OUString sSql = ::rtl::OUString::createFromAscii("RENAME COLUMN ") ;
				sSql += ::dbtools::quoteName(sQuote,m_SchemaName) + sDot + ::dbtools::quoteName(sQuote,m_Name);
				sSql += sDot + ::dbtools::quoteName(sQuote,colName);
				sSql += ::rtl::OUString::createFromAscii(" TO ");
				sSql += ::dbtools::quoteName(sQuote,sNewColumnName);

				Reference< XStatement > xStmt = m_pConnection->createStatement(  );
				if(xStmt.is())
				{
					xStmt->execute(sSql);
					::comphelper::disposeComponent(xStmt);
				}
			}
			m_pColumns->refresh();
		}
		catch(const SQLException&)
		{
			rollbackTransAction();
			throw;
		}
		endTransAction();
	}
	else
	{
		if(m_pColumns)
		{
			m_pColumns->dropByName(colName);
			m_pColumns->appendByDescriptor(descriptor);
		}
	}

}
// -------------------------------------------------------------------------
::rtl::OUString SAL_CALL OAdabasTable::getName() throw(::com::sun::star::uno::RuntimeException)
{
	::rtl::OUString sName = m_SchemaName;
	if(m_SchemaName.getLength())
	{
		const ::rtl::OUString& sDot = OAdabasCatalog::getDot();
		sName += sDot;
	}
	sName += m_Name;
	return sName;
}
// -----------------------------------------------------------------------------
void OAdabasTable::alterColumnType(const ::rtl::OUString& _rColName, const Reference<XPropertySet>& _xDescriptor)
{
	::rtl::OUString sSql = getAlterTableColumnPart(_rColName);
	sSql += ::rtl::OUString::createFromAscii(" ");
	sSql += OTables::getColumnSqlType(_xDescriptor);

	Reference< XStatement > xStmt = m_pConnection->createStatement(  );
	if(xStmt.is())
	{
		xStmt->execute(sSql);
		::comphelper::disposeComponent(xStmt);
	}
}
// -----------------------------------------------------------------------------
void OAdabasTable::alterNotNullValue(sal_Int32 _nNewNullable,const ::rtl::OUString& _rColName)
{
	::rtl::OUString sSql = getAlterTableColumnPart(_rColName);

	if(_nNewNullable == ColumnValue::NO_NULLS)
	{
		sSql += ::rtl::OUString::createFromAscii(" NOT NULL");
	}
	else
	{
		sSql += ::rtl::OUString::createFromAscii(" DEFAULT NULL");
	}

	Reference< XStatement > xStmt = m_pConnection->createStatement();
	if(xStmt.is())
	{
		xStmt->execute(sSql);
		::comphelper::disposeComponent(xStmt);
	}
}
// -----------------------------------------------------------------------------
void OAdabasTable::alterDefaultValue(const ::rtl::OUString& _sNewDefault,const ::rtl::OUString& _rColName)
{
	::rtl::OUString sSql = getAlterTableColumnPart(_rColName);
	sSql += ::rtl::OUString::createFromAscii(" ALTER ") + _sNewDefault;

	Reference< XStatement > xStmt = m_pConnection->createStatement();
	if(xStmt.is())
	{
		xStmt->execute(sSql);
		::comphelper::disposeComponent(xStmt);
	}
}
// -----------------------------------------------------------------------------
void OAdabasTable::dropDefaultValue(const ::rtl::OUString& _rColName)
{
	::rtl::OUString sSql = getAlterTableColumnPart(_rColName);
	sSql += ::rtl::OUString::createFromAscii(" DROP DEFAULT");

	Reference< XStatement > xStmt = m_pConnection->createStatement();
	if(xStmt.is())
	{
		xStmt->execute(sSql);
		::comphelper::disposeComponent(xStmt);
	}
}
// -----------------------------------------------------------------------------
void OAdabasTable::addDefaultValue(const ::rtl::OUString& _sNewDefault,const ::rtl::OUString& _rColName)
{
	::rtl::OUString sSql = getAlterTableColumnPart(_rColName);
	sSql += ::rtl::OUString::createFromAscii(" ADD ") + _sNewDefault;

	Reference< XStatement > xStmt = m_pConnection->createStatement();
	if(xStmt.is())
	{
		xStmt->execute(sSql);
		::comphelper::disposeComponent(xStmt);
	}
}
// -----------------------------------------------------------------------------
void OAdabasTable::beginTransAction()
{
	try
	{
		Reference< XStatement > xStmt = m_pConnection->createStatement();
		if(xStmt.is())
		{
			xStmt->execute(::rtl::OUString::createFromAscii("SUBTRANS BEGIN") );
			::comphelper::disposeComponent(xStmt);
		}
	}
	catch(const Exception&)
	{
	}
}
// -----------------------------------------------------------------------------
void OAdabasTable::endTransAction()
{
	try
	{
		Reference< XStatement > xStmt = m_pConnection->createStatement();
		if(xStmt.is())
		{
			xStmt->execute(::rtl::OUString::createFromAscii("SUBTRANS END") );
			::comphelper::disposeComponent(xStmt);
		}
	}
	catch(const Exception&)
	{
	}
}
// -----------------------------------------------------------------------------
void OAdabasTable::rollbackTransAction()
{
	try
	{
		Reference< XStatement > xStmt = m_pConnection->createStatement();
		if(xStmt.is())
		{
			xStmt->execute(::rtl::OUString::createFromAscii("SUBTRANS ROLLBACK") );
			::comphelper::disposeComponent(xStmt);
		}
	}
	catch(const Exception&)
	{
	}
}
// -----------------------------------------------------------------------------
::rtl::OUString OAdabasTable::getAlterTableColumnPart(const ::rtl::OUString& _rsColumnName )
{
	::rtl::OUString sSql = ::rtl::OUString::createFromAscii("ALTER TABLE ");
	const ::rtl::OUString sQuote = m_pConnection->getMetaData()->getIdentifierQuoteString(  );
	const ::rtl::OUString& sDot = OAdabasCatalog::getDot();

	sSql += ::dbtools::quoteName(sQuote,m_SchemaName) + sDot + ::dbtools::quoteName(sQuote,m_Name)
		 + ::rtl::OUString::createFromAscii(" COLUMN ")
		 + ::dbtools::quoteName(sQuote,_rsColumnName);
	return sSql;
}
// -----------------------------------------------------------------------------



