560 lines
20 KiB
C++
560 lines
20 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*************************************************************************
|
|
*
|
|
* Effective License of whole file:
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License version 2.1, as published by the Free Software Foundation.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
* MA 02111-1307 USA
|
|
*
|
|
* Parts "Copyright by Sun Microsystems, Inc" prior to August 2011:
|
|
*
|
|
* The Contents of this file are made available subject to the terms of
|
|
* the GNU Lesser General Public License Version 2.1
|
|
*
|
|
* Copyright: 2000 by Sun Microsystems, Inc.
|
|
*
|
|
* Contributor(s): Joerg Budischewski
|
|
*
|
|
* All parts contributed on or after August 2011:
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
************************************************************************/
|
|
|
|
#include <sal/config.h>
|
|
|
|
#include <string_view>
|
|
|
|
#include <o3tl/safeint.hxx>
|
|
#include <o3tl/string_view.hxx>
|
|
#include <rtl/ref.hxx>
|
|
#include <rtl/ustrbuf.hxx>
|
|
#include <sal/log.hxx>
|
|
#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
|
|
#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
|
|
#include <com/sun/star/sdbc/SQLException.hpp>
|
|
#include <com/sun/star/sdbc/XRow.hpp>
|
|
#include <com/sun/star/sdbc/ColumnValue.hpp>
|
|
|
|
#include <cppuhelper/exc_hlp.hxx>
|
|
#include <utility>
|
|
|
|
#include "pq_xcolumns.hxx"
|
|
#include "pq_xcolumn.hxx"
|
|
#include "pq_statics.hxx"
|
|
#include "pq_tools.hxx"
|
|
|
|
using osl::MutexGuard;
|
|
|
|
|
|
using com::sun::star::beans::XPropertySet;
|
|
|
|
using com::sun::star::uno::Any;
|
|
using com::sun::star::uno::UNO_QUERY;
|
|
using com::sun::star::uno::Reference;
|
|
using com::sun::star::uno::RuntimeException;
|
|
|
|
using com::sun::star::sdbc::XRow;
|
|
using com::sun::star::sdbc::XStatement;
|
|
using com::sun::star::sdbc::XResultSet;
|
|
using com::sun::star::sdbc::XDatabaseMetaData;
|
|
using com::sun::star::sdbc::SQLException;
|
|
|
|
namespace pq_sdbc_driver
|
|
{
|
|
|
|
static Any isCurrency( std::u16string_view typeName )
|
|
{
|
|
return Any( o3tl::equalsIgnoreAsciiCase(typeName, u"money") );
|
|
}
|
|
|
|
// static sal_Bool isAutoIncrement8( const OUString & typeName )
|
|
// {
|
|
// return typeName.equalsIgnoreAsciiCase("serial8") ||
|
|
// typeName.equalsIgnoreAsciiCase("bigserial");
|
|
// }
|
|
|
|
static Any isAutoIncrement( std::u16string_view defaultValue )
|
|
{
|
|
bool ret = o3tl::starts_with( defaultValue, u"nextval(" );
|
|
// printf( "%s %d\n",
|
|
// OUStringToOString(defaultValue, RTL_TEXTENCODING_ASCII_US).getStr(),
|
|
// ret );
|
|
// {
|
|
// static const char * const serials[] =
|
|
// {
|
|
// "serial", "serial4", "serial8", "bigserial", 0
|
|
// };
|
|
// s sal_Bool b = sal_False;
|
|
// for( int i = 0; !b && serials[i] ; i ++ )
|
|
// {
|
|
// b = b || typeName.equalsIgnoreAsciiCaseAscii( serials[i] );
|
|
// }
|
|
return Any ( ret );
|
|
}
|
|
|
|
Columns::Columns(
|
|
const ::rtl::Reference< comphelper::RefCountedMutex > & refMutex,
|
|
const css::uno::Reference< css::sdbc::XConnection > & origin,
|
|
ConnectionSettings *pSettings,
|
|
OUString schemaName,
|
|
OUString tableName)
|
|
: Container( refMutex, origin, pSettings, u"COLUMN"_ustr ),
|
|
m_schemaName(std::move( schemaName )),
|
|
m_tableName(std::move( tableName ))
|
|
{}
|
|
|
|
Columns::~Columns()
|
|
{}
|
|
|
|
OUString columnMetaData2SDBCX(
|
|
ReflectionBase *pBase, const css::uno::Reference< css::sdbc::XRow > &xRow )
|
|
{
|
|
Statics & st = getStatics();
|
|
|
|
// 1. TABLE_CAT string => table catalog (may be NULL)
|
|
// => not supported
|
|
// 2. TABLE_SCHEM string => table schema (may be NULL)
|
|
// => pg_namespace.nspname
|
|
// 3. TABLE_NAME string => table name
|
|
// => pg_class.relname
|
|
// 4. COLUMN_NAME string => column name
|
|
// => pg_attribute.attname
|
|
// 5. DATA_TYPE short => SQL type from java.sql.Types
|
|
// => pg_type.typname => sdbc.DataType
|
|
// 6. TYPE_NAME string => Data source dependent type name, for a UDT the
|
|
// type name is fully qualified
|
|
// => pg_type.typname
|
|
// 7. COLUMN_SIZE long => column size. For char or date types this is
|
|
// the maximum number of characters, for numeric
|
|
// or decimal types this is precision.
|
|
// => pg_type.typlen ( TODO: What is about variable size ? )
|
|
// 8. BUFFER_LENGTH is not used.
|
|
// => not used
|
|
// 9. DECIMAL_DIGITS long => the number of fractional digits
|
|
// => don't know ! TODO !
|
|
// 10. NUM_PREC_RADIX long => Radix (typically either 10 or 2)
|
|
// => TODO ??
|
|
// 11. NULLABLE long => is NULL allowed?
|
|
// NO_NULLS - might not allow NULL values
|
|
// NULABLE - definitely allows NULL values
|
|
// NULLABLE_UNKNOWN - nullability unknown
|
|
// => pg_attribute.attnotnull
|
|
// 12. REMARKS string => comment describing column (may be NULL )
|
|
// => Don't know, there does not seem to exist something like
|
|
// that in postgres
|
|
// 13. COLUMN_DEF string => default value (may be NULL)
|
|
// => pg_type.typdefault
|
|
// 14. SQL_DATA_TYPE long => unused
|
|
// => empty
|
|
// 15. SQL_DATETIME_SUB long => unused
|
|
// => empty
|
|
// 16. CHAR_OCTET_LENGTH long => for char types the maximum number of
|
|
// bytes in the column
|
|
// => pg_type.typlen
|
|
// 17. ORDINAL_POSITION int => index of column in table (starting at 1)
|
|
// pg_attribute.attnum
|
|
// 18. IS_NULLABLE string => "NO" means column definitely does not allow
|
|
// NULL values; "YES" means the column might
|
|
// allow NULL values. An empty string means
|
|
// nobody knows.
|
|
// => pg_attribute.attnotnull
|
|
|
|
static const int COLUMN_NAME = 4;
|
|
static const int DATA_TYPE = 5;
|
|
static const int TYPE_NAME = 6;
|
|
static const int COLUMN_SIZE = 7;
|
|
static const int DECIMAL_DIGITS = 9;
|
|
static const int IS_NULLABLE = 11;
|
|
static const int DESCRIPTION = 12;
|
|
static const int DEFAULT_VALUE = 13;
|
|
|
|
OUString name = xRow->getString( COLUMN_NAME );
|
|
OUString typeName = xRow->getString( TYPE_NAME );
|
|
|
|
pBase->setPropertyValue_NoBroadcast_public(
|
|
st.NAME, Any( name ) );
|
|
|
|
pBase->setPropertyValue_NoBroadcast_public(
|
|
st.TYPE, Any( xRow->getInt( DATA_TYPE ) ) );
|
|
|
|
pBase->setPropertyValue_NoBroadcast_public(
|
|
st.TYPE_NAME, Any( typeName ) );
|
|
|
|
pBase->setPropertyValue_NoBroadcast_public(
|
|
st.PRECISION, Any( xRow->getInt( COLUMN_SIZE ) ) );
|
|
|
|
pBase->setPropertyValue_NoBroadcast_public(
|
|
st.SCALE, Any( xRow->getInt( DECIMAL_DIGITS ) ) );
|
|
|
|
pBase->setPropertyValue_NoBroadcast_public(
|
|
st.IS_NULLABLE, Any( xRow->getInt( IS_NULLABLE ) ) );
|
|
|
|
pBase->setPropertyValue_NoBroadcast_public(
|
|
st.DEFAULT_VALUE, Any( xRow->getString( DEFAULT_VALUE ) ) );
|
|
|
|
// pBase->setPropertyValue_NoBroadcast_public(
|
|
// st.DESCRIPTION, makeAny( xRow->getString( DESCRIPTION ) ) );
|
|
|
|
// if( pBase->getPropertySetInfo()->hasPropertyByName( st.HELP_TEXT ) )
|
|
// pBase->setPropertyValue_NoBroadcast_public(
|
|
// st.HELP_TEXT, makeAny( xRow->getString( DESCRIPTION ) ) );
|
|
// else // for key columns, etc. ...
|
|
pBase->setPropertyValue_NoBroadcast_public(
|
|
st.DESCRIPTION, Any( xRow->getString( DESCRIPTION ) ) );
|
|
|
|
|
|
// maybe a better criterion than the type name can be found in future
|
|
pBase->setPropertyValue_NoBroadcast_public(
|
|
st.IS_AUTO_INCREMENT, isAutoIncrement(xRow->getString( DEFAULT_VALUE )) );
|
|
|
|
pBase->setPropertyValue_NoBroadcast_public(
|
|
st.IS_CURRENCY, isCurrency( typeName));
|
|
return name;
|
|
}
|
|
|
|
|
|
// class CommentChanger : public cppu::WeakImplHelper< XPropertyChangeListener >
|
|
// {
|
|
// ::rtl::Reference< comphelper::RefCountedMutex > m_xMutex;
|
|
// css::uno::Reference< css::sdbc::XConnection > m_connection;
|
|
// ConnectionSettings *m_pSettings;
|
|
// OUString m_schema;
|
|
// OUString m_table;
|
|
// OUString m_column;
|
|
|
|
// public:
|
|
// CommentChanger(
|
|
// const ::rtl::Reference< comphelper::RefCountedMutex > & refMutex,
|
|
// const css::uno::Reference< css::sdbc::XConnection > & connection,
|
|
// ConnectionSettings *pSettings,
|
|
// const OUString & schema,
|
|
// const OUString & table,
|
|
// const OUString & column ) :
|
|
// m_xMutex( refMutex ),
|
|
// m_connection( connection ),
|
|
// m_pSettings( pSettings ),
|
|
// m_schema ( schema ),
|
|
// m_table ( table ),
|
|
// m_column ( column )
|
|
// {}
|
|
|
|
|
|
// // Methods
|
|
// virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) throw (css::uno::RuntimeException)
|
|
// {
|
|
// osl::MutexGuard guard( m_xMutex->GetMutex() );
|
|
// m_connection.clear();
|
|
// }
|
|
// // Methods
|
|
// virtual void SAL_CALL propertyChange( const css::beans::PropertyChangeEvent& evt ) throw (css::uno::RuntimeException)
|
|
// {
|
|
// osl::MutexGuard guard( m_xMutex->GetMutex() );
|
|
// OUStringBuffer buf( 128 );
|
|
// OUString comment;
|
|
// evt.NewValue >>= comment;
|
|
// buf.append( "COMMENT ON COLUMN" );
|
|
// bufferQuoteQualifiedIdentifier( buf, m_schema, m_table , m_column );
|
|
// buf.append( "IS " );
|
|
// bufferQuoteConstant( buf, comment,m_pSettings->encoding);
|
|
|
|
// printf( "changing comment of column %s to %s\n",
|
|
// OUStringToOString( m_column, RTL_TEXTENCODING_ASCII_US ).getStr(),
|
|
// OUStringToOString( comment, RTL_TEXTENCODING_ASCII_US ).getStr() );
|
|
|
|
// m_connection->createStatement()->executeUpdate( buf.makeStringAndClear() );
|
|
// }
|
|
// };
|
|
|
|
void Columns::refresh()
|
|
{
|
|
try
|
|
{
|
|
SAL_INFO("connectivity.postgresql", "sdbcx.Columns get refreshed for table " << m_schemaName << "." << m_tableName);
|
|
osl::MutexGuard guard( m_xMutex->GetMutex() );
|
|
|
|
Statics &st = getStatics();
|
|
Reference< XDatabaseMetaData > meta = m_origin->getMetaData();
|
|
|
|
Reference< XResultSet > rs =
|
|
meta->getColumns( Any(), m_schemaName, m_tableName, st.cPERCENT );
|
|
|
|
DisposeGuard disposeIt( rs );
|
|
Reference< XRow > xRow( rs , UNO_QUERY );
|
|
|
|
String2IntMap map;
|
|
|
|
m_values.clear();
|
|
int columnIndex = 0;
|
|
while( rs->next() )
|
|
{
|
|
rtl::Reference<Column> pColumn =
|
|
new Column( m_xMutex, m_origin, m_pSettings );
|
|
Reference< css::beans::XPropertySet > prop = pColumn;
|
|
|
|
OUString name = columnMetaData2SDBCX( pColumn.get(), xRow );
|
|
// pColumn->addPropertyChangeListener(
|
|
// st.HELP_TEXT,
|
|
// new CommentChanger(
|
|
// m_xMutex,
|
|
// m_origin,
|
|
// m_pSettings,
|
|
// m_schemaName,
|
|
// m_tableName,
|
|
// name ) );
|
|
|
|
{
|
|
m_values.emplace_back(prop);
|
|
map[ name ] = columnIndex;
|
|
++columnIndex;
|
|
}
|
|
}
|
|
m_name2index.swap( map );
|
|
}
|
|
catch ( css::sdbc::SQLException & e )
|
|
{
|
|
css::uno::Any anyEx = cppu::getCaughtException();
|
|
throw css::lang::WrappedTargetRuntimeException( e.Message,
|
|
nullptr, anyEx );
|
|
}
|
|
fire( RefreshedBroadcaster( *this ) );
|
|
}
|
|
|
|
|
|
void alterColumnByDescriptor(
|
|
std::u16string_view schemaName,
|
|
std::u16string_view tableName,
|
|
ConnectionSettings *settings,
|
|
const Reference< XStatement > &stmt,
|
|
const css::uno::Reference< css::beans::XPropertySet > & past,
|
|
const css::uno::Reference< css::beans::XPropertySet > & future)
|
|
{
|
|
Statics & st = getStatics();
|
|
|
|
// if( past->getPropertyValue( st.TABLE_NAME ) != future->getPropertyValue( st.TABLE_NAME ) ||
|
|
// past->getPropertyValue( st.SCHEMA_NAME ) != future->getPropertyValue( st.SCHEMA_NAME ))
|
|
// {
|
|
// OUStringBuffer buf(128);
|
|
// buf.append( "Can't move column " );
|
|
// buf.append( extractStringProperty( past, st.COLUMN_NAME ) );
|
|
// buf.append( " from table " );
|
|
// buf.append( extractStringProperty( past, st.TABLE_NAME ) );
|
|
// buf.append( " to table " );
|
|
// buf.append( extractStringProperty( past, st.TABLE_NAME ) );
|
|
// throw SQLException( buf.makeStringAndClear() );
|
|
// }
|
|
|
|
// OUString tableName = extractStringProperty( past, st.TABLE_NAME );
|
|
// OUString schemaName = extractStringProperty( past, st.SCHEMA_NAME );
|
|
OUString pastColumnName = extractStringProperty( past, st.NAME );
|
|
OUString futureColumnName = extractStringProperty( future, st.NAME );
|
|
OUString pastTypeName = sqltype2string( past );
|
|
OUString futureTypeName = sqltype2string( future );
|
|
|
|
TransactionGuard transaction( stmt );
|
|
|
|
OUStringBuffer buf( 128 );
|
|
if( ! pastColumnName.getLength())
|
|
{
|
|
// create a new column
|
|
buf.append( "ALTER TABLE" );
|
|
bufferQuoteQualifiedIdentifier( buf, schemaName, tableName, settings );
|
|
buf.append( "ADD COLUMN" );
|
|
bufferQuoteIdentifier( buf, futureColumnName, settings );
|
|
buf.append( futureTypeName );
|
|
transaction.executeUpdate( buf.makeStringAndClear() );
|
|
}
|
|
else
|
|
{
|
|
if( pastTypeName != futureTypeName )
|
|
{
|
|
throw RuntimeException(
|
|
u"Can't modify column types, drop the column and create a new one"_ustr );
|
|
}
|
|
|
|
if( pastColumnName != futureColumnName )
|
|
{
|
|
buf.append( "ALTER TABLE" );
|
|
bufferQuoteQualifiedIdentifier( buf, schemaName, tableName, settings );
|
|
buf.append( "RENAME COLUMN" );
|
|
bufferQuoteIdentifier( buf, pastColumnName, settings );
|
|
buf.append( "TO" );
|
|
bufferQuoteIdentifier( buf, futureColumnName, settings );
|
|
transaction.executeUpdate( buf.makeStringAndClear() );
|
|
}
|
|
}
|
|
|
|
OUString futureDefaultValue = extractStringProperty( future, st.DEFAULT_VALUE );
|
|
OUString pastDefaultValue = extractStringProperty( past, st.DEFAULT_VALUE );
|
|
if( futureDefaultValue != pastDefaultValue )
|
|
{
|
|
buf.truncate();
|
|
buf.append( "ALTER TABLE" );
|
|
bufferQuoteQualifiedIdentifier( buf, schemaName, tableName, settings );
|
|
buf.append( "ALTER COLUMN" );
|
|
bufferQuoteIdentifier( buf, futureColumnName, settings );
|
|
// LEM TODO: check out
|
|
// default value is not quoted, caller needs to quote himself (otherwise
|
|
// how to pass e.g. nextval('something' ) ????
|
|
buf.append( "SET DEFAULT " + futureDefaultValue );
|
|
// bufferQuoteConstant( buf, defaultValue, encoding );
|
|
transaction.executeUpdate( buf.makeStringAndClear() );
|
|
}
|
|
|
|
sal_Int32 futureNullable = extractIntProperty( future, st.IS_NULLABLE );
|
|
sal_Int32 pastNullable = extractIntProperty( past, st.IS_NULLABLE );
|
|
if( futureNullable != pastNullable )
|
|
{
|
|
buf.truncate();
|
|
buf.append( "ALTER TABLE" );
|
|
bufferQuoteQualifiedIdentifier( buf, schemaName, tableName, settings );
|
|
buf.append( "ALTER COLUMN" );
|
|
bufferQuoteIdentifier( buf, futureColumnName, settings );
|
|
if( futureNullable == css::sdbc::ColumnValue::NO_NULLS )
|
|
{
|
|
buf.append( "SET" );
|
|
}
|
|
else
|
|
{
|
|
buf.append( "DROP" );
|
|
}
|
|
buf.append( " NOT NULL" );
|
|
transaction.executeUpdate( buf.makeStringAndClear() );
|
|
}
|
|
|
|
// OUString futureComment = extractStringProperty( future, st.HELP_TEXT );
|
|
// OUString pastComment = extractStringProperty( past, st.HELP_TEXT );
|
|
// printf( "past Comment %s, futureComment %s\n",
|
|
// OUStringToOString( pastComment, RTL_TEXTENCODING_ASCII_US ).getStr(),
|
|
// OUStringToOString( futureComment, RTL_TEXTENCODING_ASCII_US ).getStr() );
|
|
OUString futureComment = extractStringProperty( future, st.DESCRIPTION );
|
|
OUString pastComment = extractStringProperty( past, st.DESCRIPTION );
|
|
|
|
if( futureComment != pastComment )
|
|
{
|
|
buf.truncate();
|
|
buf.append( "COMMENT ON COLUMN" );
|
|
bufferQuoteQualifiedIdentifier( buf, schemaName, tableName , futureColumnName, settings );
|
|
buf.append( "IS " );
|
|
bufferQuoteConstant( buf, futureComment, settings );
|
|
transaction.executeUpdate( buf.makeStringAndClear() );
|
|
}
|
|
transaction.commit();
|
|
}
|
|
|
|
void Columns::appendByDescriptor(
|
|
const css::uno::Reference< css::beans::XPropertySet >& future )
|
|
{
|
|
osl::MutexGuard guard( m_xMutex->GetMutex() );
|
|
Statics & st = getStatics();
|
|
Reference< XPropertySet > past = createDataDescriptor();
|
|
past->setPropertyValue( st.IS_NULLABLE, Any( css::sdbc::ColumnValue::NULLABLE ) );
|
|
alterColumnByDescriptor(
|
|
m_schemaName, m_tableName, m_pSettings, m_origin->createStatement() , past, future );
|
|
|
|
refresh();
|
|
}
|
|
|
|
// void Columns::dropByName( const OUString& elementName )
|
|
// throw (css::sdbc::SQLException,
|
|
// css::container::NoSuchElementException,
|
|
// css::uno::RuntimeException)
|
|
// {
|
|
// String2IntMap::const_iterator ii = m_name2index.find( elementName );
|
|
// if( ii == m_name2index.end() )
|
|
// {
|
|
// OUStringBuffer buf( 128 );
|
|
// buf.appendAscii( "Column " );
|
|
// buf.append( elementName );
|
|
// buf.appendAscii( " is unknown in table " );
|
|
// buf.append( m_schemaName );
|
|
// buf.appendAscii( "." );
|
|
// buf.append( m_tableName );
|
|
// buf.appendAscii( ", so it can't be dropped" );
|
|
// throw css::container::NoSuchElementException(
|
|
// buf.makeStringAndClear(), *this );
|
|
// }
|
|
// dropByIndex( ii->second );
|
|
// }
|
|
|
|
void Columns::dropByIndex( sal_Int32 index )
|
|
{
|
|
osl::MutexGuard guard( m_xMutex->GetMutex() );
|
|
if( index < 0 || o3tl::make_unsigned(index) >= m_values.size() )
|
|
{
|
|
throw css::lang::IndexOutOfBoundsException(
|
|
"COLUMNS: Index out of range (allowed 0 to "
|
|
+ OUString::number(m_values.size() -1)
|
|
+ ", got " + OUString::number( index ) + ")",
|
|
*this );
|
|
}
|
|
|
|
Reference< XPropertySet > set;
|
|
m_values[index] >>= set;
|
|
Statics &st = getStatics();
|
|
OUString name;
|
|
set->getPropertyValue( st.NAME ) >>= name;
|
|
|
|
OUStringBuffer update( 128 );
|
|
update.append( "ALTER TABLE ONLY");
|
|
bufferQuoteQualifiedIdentifier( update, m_schemaName, m_tableName, m_pSettings );
|
|
update.append( "DROP COLUMN" );
|
|
bufferQuoteIdentifier( update, name, m_pSettings );
|
|
Reference< XStatement > stmt = m_origin->createStatement( );
|
|
DisposeGuard disposeIt( stmt );
|
|
stmt->executeUpdate( update.makeStringAndClear() );
|
|
|
|
Container::dropByIndex( index );
|
|
}
|
|
|
|
|
|
css::uno::Reference< css::beans::XPropertySet > Columns::createDataDescriptor()
|
|
{
|
|
return new ColumnDescriptor( m_xMutex, m_origin, m_pSettings );
|
|
}
|
|
|
|
Reference< css::container::XNameAccess > Columns::create(
|
|
const ::rtl::Reference< comphelper::RefCountedMutex > & refMutex,
|
|
const css::uno::Reference< css::sdbc::XConnection > & origin,
|
|
ConnectionSettings *pSettings,
|
|
const OUString &schemaName,
|
|
const OUString &tableName,
|
|
rtl::Reference<Columns> *ppColumns)
|
|
{
|
|
*ppColumns = new Columns(
|
|
refMutex, origin, pSettings, schemaName, tableName );
|
|
(*ppColumns)->refresh();
|
|
|
|
return *ppColumns;
|
|
}
|
|
|
|
|
|
ColumnDescriptors::ColumnDescriptors(
|
|
const ::rtl::Reference< comphelper::RefCountedMutex > & refMutex,
|
|
const css::uno::Reference< css::sdbc::XConnection > & origin,
|
|
ConnectionSettings *pSettings )
|
|
: Container( refMutex, origin, pSettings, u"COLUMN-DESCRIPTOR"_ustr )
|
|
{}
|
|
|
|
|
|
Reference< css::beans::XPropertySet > ColumnDescriptors::createDataDescriptor()
|
|
{
|
|
return new ColumnDescriptor( m_xMutex, m_origin, m_pSettings );
|
|
}
|
|
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|